51CTO技术论坛_中国领先的IT技术社区's Archiver

黑夜 发表于 2006-8-29 01:20

在C++Builder中自定义预览窗口

Borland C++ Builder是基于C++语言的可视化编程环境,它提供了可重用组件库和一系列RAD设计工具,使得编程者只需用少量的手工代码就可以创建出高效的Windows应用程序,尤其是复杂的数据库访问应用程序,因此深受软件开发人员的喜爱。 ,DV si/|D*C]z
在开发数据库访问应用程序时,会经常涉及到报表的打印问题。C++ Builder中提供了Quick Report(快速报表)组件供编程人员设计报表。Quick Report是挪威的QuSoft AS公司专门为C++ Builder设计的用于制作报表的一组控件,在C++ Builder中关于Quick Report的帮助文档不是很详细。另外它与C++ Builder的其他控件的风格也不太一致。直接使用Quick Report的报表预览功能总是不能达到令人满意的效果,因此有必要自定义快速报表的预览窗口。 [0? }a0L
设置预览窗口 B.[?"?V(z-h
新建工程,在Form1窗体上添加一个ToolBar控件,并在其上添加以下按钮:“打印”、“打印设置”、 7iuld)Ekj.TP
“上一页” 、“下一页”、“放大”、“缩小”和“关闭”。 在Form1窗体上添加一个Panel控件,对齐方式设为alBottom,再在此Panel控件上添加一个ProgressBar控件(对齐方式设为alLeft)和一个Panel控件(Name 为Panel2,对齐方式设为alRight,BevelOuter设为bvLowered),这两个控件分别用来显示报表装载进度和其他提示信息。在Form1窗体上添加一个QRPreview控件,对齐方式设为alClient。 B+I j"x|
-au yyo;X S'sl
再新建一个窗体,设其Name为Form2, 在该窗体上添加TQuickRep控件,设其Name为QuickRep1,其PrinterSetting中的Units属性设为mm(以毫米为计量单位),然后建立报表。 *uG:S*e3iP1@V3k-t
编程实现 #xb$K P*~\e
1.在Form2上选择QuickRep1,在其事件中选择OnPreview,输入以下代码: [!~ S%LSg9\_2m^
Form1->QRPreview1->QRPrinter=Form2->QuickRep1->QRPrinter; 'J N2kn*i5Chp
2.在Form1的头文件中找到对象TForm1的定义,在其中添加以下的代码: -~+k T:t0D6]7v_K
int OldPaperSize;
c0]MZzT int OldOrientation; 9n`(B5yDHW h
int OldTop;
y?e4Iz _z@ int OldBottom; 9B e"COU"n/ka
int OldLeft;
'j%y1J-LB@ int OldRight;
mtUS8dZCS0O void RefreshPanel(); 0rfF-g1IBk
3.选择Form1的Activate事件,输入以下代码: ,wf%g1w8Y
//初始化 S]s n$?i}
OldPaperSize=Form2->QuickRep1->Page->PaperSize; #s"P{S2pf7B-k
OldOrientation=Form2->QuickRep1->Page->Orientation+1;
8lJUq.AS nRB2t#C OldLeft=Form2->QuickRep1->Page->LeftMargin*100; 2INy:P]0y[(MN
OldRight=Form2->QuickRep1->Page->
/g\&i"w8p*{ RightMargin*100;
6z?*~$pw\ f OldTop=Form2->QuickRep1->Page->Top
(bg C ia:S,t-\ Margin*100;
#c N_(w7l-Z*U0l OldBottom=Form2->QuickRep1->Page-> }:W@WM+JV@Z-~
BottomMargin*100;
gW4P T1{8Q(O.t1}c({ Form2->QuickRep1->Prepare(); +w$@URO)F} f5I
RefreshPanel();
C-Av2j t Form2->QuickRep1->Preview(); DDx4Oh.P
4.在Form1中添加更新提示代码: HJO.dD*U)[
void TForm1::RefreshPanel() RL*V4z#l
{ //更新提示信息
4@#t8_+g ?szU Panel2->Caption=“第”+IntToStr(Form1->QRPreview1->PageNumber)+“页”+“共” + IntToStr(Form2->QuickRep1->PageNumber)+“页”; 9t/? A![%I,Sp(H
}
,LC'j8q+fI{ M 5.从Form1中选择QRPreview1,在其事件中选择OnProgressUpdate,输入以下代码:
DP({!C9L //显示报表装载进度 ,\L}#Yz:VO\0pf
ProgressBar1->Position=Progress; Tt0`}7k1d ~?
RefreshPanel(); KE7OE!PP
6.打印:
@;T z*ug1P7fH Form2->QuickRep1->Print(); 0ll_g:}5N
7.打印设置:
X0KE'~2l%?(_ DEVMODE *pDev;
G"V#Q4S3`+|o/}B LPPAGESETUPDLG mylp=new PAGESETUPDLG; ,s)V+}.J+}3a
memset((void *)mylp,0,sizeof \0AZ1XB.CQ
(PAGESETUPDLG));
D"I.]#fLk/{:R mylp->lStructSize=sizeof(PAGESETUPDLG); $c+Qi-Q0rk
mylp->hwndOwner=this->Handle;
a I7\ k{:yC mylp->Flags=PSD_RETURNDEFAULT; Wj(hP*j"]z|4P|
PageSetupDlg( mylp ); `z{|`3g%L
if (mylp->hDevMode!=NULL){ NH"}"qd9b;M z @S@
  pDev=(DEVMODE *)GlobalLock(mylp->hDevMode);
Ua4h6W:@Q   pDev->dmPaperSize =OldPaperSize;
fC6y;l`5M4aq   pDev->dmOrientation =OldOrientation;
XBH-E$wP _9^/D1c:BQ   mylp->rtMargin.left =OldLeft; 2y"},HfL0ZAREa-m/p@
  mylp->rtMargin.right =OldRight; $HG Sg4}
  mylp->rtMargin.top =OldTop; e6[n5i0i CxD
  mylp->rtMargin.bottom=OldBottom;
c+bC?j z&?   GlobalUnlock(mylp->hDevMode); nX'f%F"R#Ds!Ead:{
mylp->Flags=PSD_MARGINS|
?,d3]&i$yL/\ PSD_INHUNDREDTHSOFMILLIMETERS; !EQH*\ y&P~)J
  if(PageSetupDlg(mylp)){ fBFKtB$nS
   pDev=(DEVMODE *)GlobalLock
JhGx6Gd"D3v~ (mylp->hDevMode); dd_t'uM6|/T
   OldPaperSize =pDev->dmPaperSize; M4[V5na:JI
if(OldPaperSize>28)OldPaperSize=9;//A4
1D1d Un2? _ I OldOrientation=pDev->dmOrientation; .u|{;P@"h`2w
OldLeft =mylp->rtMargin.left;
y ] a|| U OldRight =mylp->rtMargin.right; 4{]_~9RWT
OldTop =mylp->rtMargin.top; OqJ;tyj)T
OldBottom =mylp->rtMargin.bottom;
&E(s q }Z(^} Form2->QuickRep1->Page->Orientation =OldOrientation-1; Y+f5n {$N&?^ q
Form2->QuickRep1->Page->PaperSize x*U[ _2~-Fal Z:L&N
=OldPaperSize; o(`1G.A9yc
Form2->QuickRep1->Page->LeftMargin =OldLeft/100; |%i1{/yxT e&G~
Form2->QuickRep1->Page->RightMargin =OldRight/100;
S/_6b o/f$c1H!M:IG Form2->QuickRep1->Page->TopMargin =OldTop/100;
Wq2S"v j ]+\ Form2->QuickRep1->Page->Bottom
l?U0zu(?;`6t Margin=OldBottom/100; o}O/z|zqS$o
  GlobalUnlock(mylp->hDevMode);
!M^lu9iS9Lzm }
W#np|E   GlobalFree(mylp->hDevMode); C$a [s*C,m'f
  } l"opA"LKv3r
delete mylp; )]K9]:}8jUojm4w
QRPreview1->PageNumber=1;
-SWPj!C'oG!KV Form2->QuickRep1->Prepare();
Ozg+y u*I] Form2->QuickRep1->Preview();
(GGo4Mkua 8.向上翻页:
*d/^8V?!b //上一页 ,wDyb;N
if(QRPreview1->PageNumber > 1)
2tkA*M7V9_/zQ/l   QRPreview1->PageNumber--;
\0}*h\ a*V RefreshPanel(); p$s5B3C x M
9.向下翻页: ^G8A1?5y'pmit2P
//下一页 *q G%^XUZ
if(QRPreview1->PageNumber  :\ y._9hHW
QuickRep1->PageNumber)
TT6q#@&H)l[ QRPreview1->PageNumber++; 3?&[4E1DJ YX!R
  RefreshPanel(); 4u]$w B%J4T&} ~k
10.放大处理:
9bi c3nC3Bs9Z7H //放大
u-K&\I!rQ+ihk if(QRPreview1->ZoomZoom+=5; P4bA&WzvO\A U:xc
11.缩小处理:
ax"x/\G0^)B ?p3n6Q //缩小
2fS e K&@ Xe~ if(QRPreview1->Zoom>5) tPUA h`9cU!}#H
  QRPreview1->Zoom-=5;
+M K*C gV/q,V 小 结
od9H;{5{ X O[*f 该方法的核心是使用了Win32 API函数PageSetupDlg(),利用该函数可以获取页面设置的缺省值,包括纸张大小、打印方向以及上下左右空白边的大小等,也可以弹出页面设置对话框来修改这些值。

页: [1]

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.