{
p_h=p_h+rs;
r_h=0;
rect = Rectangle(Point(x[0],p_h),System::Drawing::Size( rect_w[0],rect_h ));
g->DrawString(table->Rows[rcrdNum][0]->ToString()->Trim() , ttlFont, ttlBrush, rect, tabFormat); // 画日期。
if (g->MeasureString(table->Rows[rcrdNum][0]->ToString()->Trim(), ttlFont,System::Drawing::Size( rect_w[0],rect_h ),tabFormat).Height>r_h)
{
r_h=g->MeasureString(table->Rows[rcrdNum][0]->ToString()->Trim(), ttlFont,System::Drawing::Size( rect_w[0],rect_h ),tabFormat).Height;
}
rect = Rectangle(Point(x[1],p_h),System::Drawing::Size( rect_w[1],rect_h ));
g->DrawString(table->Rows[rcrdNum][1]->ToString()->Trim(), ttlFont, ttlBrush, rect, tabFormat); // 画开盘价。
if (g->MeasureString(table->Rows[rcrdNum][1]->ToString()->Trim(), ttlFont,System::Drawing::Size( rect_w[1],rect_h ),tabFormat).Height>r_h)
{
r_h=g->MeasureString(table->Rows[rcrdNum][1]->ToString()->Trim(), ttlFont,System::Drawing::Size( rect_w[1],rect_h ),tabFormat).Height;
}
rect = Rectangle(Point(x[2],p_h),System::Drawing::Size( rect_w[2],rect_h ));
g->DrawString(table->Rows[rcrdNum][2]->ToString()->Trim(), ttlFont, ttlBrush, rect, tabFormat); // 画收盘价。
if (g->MeasureString(table->Rows[rcrdNum][2]->ToString()->Trim(), ttlFont,System::Drawing::Size( rect_w[2],rect_h ),tabFormat).Height>r_h)
{
r_h=g->MeasureString(table->Rows[rcrdNum][2]->ToString()->Trim(), ttlFont,System::Drawing::Size( rect_w[2],rect_h ),tabFormat).Height;
}
rect = Rectangle(Point(x[3],p_h),System::Drawing::Size( rect_w[3],rect_h ));
g->DrawString(table->Rows[rcrdNum][3]->ToString()->Trim(), ttlFont, ttlBrush, rect, tabFormat); // 画成交量。
if (g->MeasureString(table->Rows[rcrdNum][3]->ToString()->Trim(), ttlFont,System::Drawing::Size( rect_w[3],rect_h ),tabFormat).Height>r_h)
{
r_h=g->MeasureString(table->Rows[rcrdNum][3]->ToString()->Trim(), ttlFont,System::Drawing::Size( rect_w[3],rect_h ),tabFormat).Height;
}
rect = Rectangle(Point(x[4],p_h),System::Drawing::Size( rect_w[4],rect_h ));
g->DrawString(table->Rows[rcrdNum][4]->ToString()->Trim(), ttlFont, ttlBrush, rect, tabFormat); // 画最高价。
if (g->MeasureString(table->Rows[rcrdNum][4]->ToString()->Trim(), ttlFont,System::Drawing::Size( rect_w[4],rect_h ),tabFormat).Height>r_h)
{
r_h=g->MeasureString(table->Rows[rcrdNum][4]->ToString()->Trim(), ttlFont,System::Drawing::Size( rect_w[4],rect_h ),tabFormat).Height;
}
rect = Rectangle(Point(x[5],p_h),System::Drawing::Size( rect_w[5],rect_h ));
g->DrawString(table->Rows[rcrdNum][5]->ToString()->Trim(), ttlFont, ttlBrush, rect, tabFormat); // 画最低价。
if (g->MeasureString(table->Rows[rcrdNum][5]->ToString()->Trim(), ttlFont,System::Drawing::Size( rect_w[5],rect_h ),tabFormat).Height>r_h)
{
r_h=g->MeasureString(table->Rows[rcrdNum][50]->ToString()->Trim(), ttlFont,System::Drawing::Size( rect_w[5],rect_h ),tabFormat).Height;
}
p_h=p_h+ r_h;
g->DrawLine(penTab,x[0], p_h,
x[0]+p_width, p_h); // 画横线。
rcrdNum ++;
}
if (rcrdNum < dayCount )
{
e->HasMorePages = true; // 继续打印下一页。
}
else
{
e->HasMorePages = false; // 不再打印。
rcrdNum=0;
}
float vx1=x[0]+cs+width_Date; // 竖线起始点x 坐标。
g->DrawLine(penTab,vx1, vy1,
vx1, p_h); // 画报表细节左起第一条竖线。
vx1=vx1+cs+width_Price+cs;
g->DrawLine(penTab,vx1, vy1,
vx1, p_h); // 画报表细节左起第二条竖线。
vx1=vx1+cs+width_Price+cs;
g->DrawLine(penTab,vx1, vy1,
vx1, p_h); // 画报表细节左起第三条竖线。
vx1=vx1+cs+width_Quantity;
g->DrawLine(penTab,vx1, vy1,
vx1, p_h); // 画报表细节左起第四条竖线。
vx1=vx1+cs+width_Price+cs;
g->DrawLine(penTab,vx1, vy1,
vx1, p_h); // 画报表细节左起第五条竖线。
}
⒊ 窗体“打印”工具条Click事件处理
“打印”工具条Click事件在用户单击工具条时发生。
在工具条Click事件处理程序中调用PrintDocument 实例的Print 方法,就可以分页打印报表。toolStripButton1_Click事件处理程序代码如下:
private: System::Void toolStripButton1_Click(System::Object^ sender, System::EventArgs^ e)
{
try
{
// 假定默认打印机。
printDocument1->Print(); // 打印。
}
catch ( Exception^ ex )
{
MessageBox::Show( "当打印时出现一个错误:"+ ex->ToString() );
}
}
四、预览
在打印前,可以使用 PrintPreviewDialog 控件显示文档。
为了预览报表,将 PrintPreviewDialog 控件添加到窗体,它会出现在 Windows 窗体设计器底部的栏中。然后,编写toolStripButton2_Click事件处理程序:
private: System::Void toolStripButton2_Click(System::Object^ sender, System::EventArgs^ e)
{
printPreviewDialog1->Document =
printDocument1; // 为打印预览对话框指定打印文档。
printPreviewDialog1->ShowDialog(); // 显示打印预览对话框。
}
五、页面设置
在打印或预览前,可以使用 pageSetupDialog 控件对页面进行设置。
为了设置报表页面,将 pageSetupDialog 控件添加到窗体,它会出现在 Windows 窗体设计器底部的栏中。然后,编写toolStripButton3_Click事件处理程序:
private: System::Void toolStripButton3_Click(System::Object^ sender, System::EventArgs^ e)
{
pageSetupDialog1->Document=
printDocument1; // 为打印设置对话框指定打印文档。
pageSetupDialog1->ShowDialog(); // 显示打印设置对话框。
}
六、程序
⑴ 从“文件”菜单中,选择“全部保存”。
⑵ 按 Ctrl+F5 运行应用程序。显示主窗口。
⑶ 从主窗口选择“技术分析”菜单下的“制表”命令,显示“制表”窗口,如图5所示。显示上证指数的行情数据:日期、开盘价、收盘价、成交量、最高价和最低价。

图5 显示报表
⑷ 如果单击“制表”窗口左起第一个工具条,将分页打印报表。

图6 打印预览对话框
⑸ 如果单击第二个工具条,将显示打印预览对话框。这与Windows其他应用程序的打印预览对话框相同,包含打印、放大、显示一页或多页以及关闭此对话框的按钮。如图6所示。
⑹ 如果单击第三个工具条,将显示页面设置对话框,这与Windows其他应用程序的页面设置对话框相同,如图7所示。
可以设置页的详细信息以便打印。例如设置边框和边距、页眉和页脚以及纵向或横向打印。

图7 页面设置对话框
七、结语
1.本讲编程的重点是将需要输出的数据进行格式化,以报表形式显示或打印。编码体现在“制表”窗体的Table方法和PrintDocument 组件的PrintPage 事件处理程序中。前者是显示报表,后者是打印报表。两者输出的内容相同,不同的是后者要对报表进行分页。
2.绘制报表时,所用到的数据虽然不需要折断成多行输出,为不失一般性,编程时考虑了这一问题。
3.为了便于程序调试、功能扩展和系统维护,编码中涉及图形位置或大小、文本格式的数据都尽可能用变量来保存。依赖于其他变量的这类数据,用其他变量的表达式来表示。
参考文献
[1 ] 范晓平。跟着实例学Visual C++ 6.0访问数据库·绘图·制表。北京航空航天大 学出版社,2003.
[2] Microsoft Corporation.MSDN Library for Visual Studio 2005.
|