内存泄露?(100分)

  • 主题发起人 主题发起人 nullbert
  • 开始时间 开始时间
N

nullbert

Unregistered / Unconfirmed
GUEST, unregistred user!
unit Unit2;

interface

uses Windows, SysUtils, Classes, Graphics, Forms, Controls, StdCtrls,
Buttons, ExtCtrls,printers, Dialogs, DB, ADODB,dbgrids;

const
leftblank=1;
rightblank=1;
topblank=1;
bottomblank=2;

type
Tprintdlg = class(TForm)
Panel1: TPanel;
PrinterSetupDialog1: TPrinterSetupDialog;
Button1: TButton;
Button2: TButton;
OKBtn: TButton;
CancelBtn: TButton;
Button3: TButton;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
ScrollBox1: TScrollBox;
Panel2: TPanel;
Image1: TImage;
Button4: TButton;
Button5: TButton;
procedure Button1Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
procedure report(acanvas:tcanvas);
procedure preview;
function execute:boolean;
constructor init(adoquery:tadoquery;datasource:tdatasource;dbgrid:tdbgrid);
private
public
end;

var
ss:string;
j,p:integer;
prepagenum:integer;
pointscale:integer;
mymetafile:array of tmetafile;
rownum:array of integer;
colnum:array of integer;
myadoquery:tadoquery;
mydatasource:tdatasource;
mydbgrid:tdbgrid;
printdlg:tprintdlg;

procedure myprint(adoquery:tadoquery;datasource:tdatasource;dbgrid:tdbgrid);export;

implementation


{$R *.dfm}

procedure myprint(adoquery:tadoquery;datasource:tdatasource;dbgrid:tdbgrid);
var
pointx,pointy:integer;
pointscale,printstep:integer;
i,r,k,pagenum:integer;
x,y:integer;
s:string;
begin
try
printdlg:=tprintdlg.Create(application);
printdlg.init(adoquery,datasource,dbgrid);
with printdlg do
if execute then
begin
PointX:=Trunc(GetDeviceCaps(Printer.Handle,LOGPIXELSX)/2.54);
PointY:=Trunc(GetDeviceCaps(Printer.Handle,LOGPIXELSY)/2.54);
PointScale:=Trunc(GetDeviceCaps(Printer.Handle,LOGPIXELSX)/Screen.PixelsPerInch+1.5);
printer.Canvas.Font.Name:='宋体';
printer.canvas.Font.Size:=10;
s:='出货分类统计表';
PrintStep:=printer.canvas.TextHeight(s)+16;
x:=PointX*LeftBlank;
y:=PointY*TopBlank;
k:=1;
pagenum:=1;
if (adoquery.Active=true) and (adoquery.RecordCount>0) then
begin
printer.BeginDoc;
adoquery.First;
while not adoquery.Eof do
begin
for i:=0 to DBGrid.FieldCount-1 do
begin
if (x+DBGrid.Columns.Items.Width*PointScale)<=(Printer.PageWidth-PointX*RightBlank) then
begin
if i=0 then
begin
printer.Canvas.moveto(x,y+200);
printer.canvas.lineto(x,y+200+printstep);
end;
printer.Canvas.moveto(x,y+200);
printer.Canvas.lineto(x+dbgrid.Columns.Items.Width*pointscale,y+200);
if y=PointY*TopBlank then
begin
printer.Canvas.Font.Name:='黑体';
printer.canvas.Font.Size:=14;
Printer.Canvas.TextOut((Printer.PageWidth-printer.Canvas.TextWidth(s)) div 2,y+8,s);
printer.Canvas.Font.Name:='宋体';
printer.canvas.Font.Size:=10;
Printer.Canvas.TextOut(x+8,y+8+200,DBGrid.Columns.Title.Caption);
printer.canvas.moveto(x+dbgrid.Columns.Items.Width*pointscale,y+200);
printer.Canvas.lineto(x+dbgrid.Columns.Items.Width*pointscale,y+200+printstep);

end
else
begin
Printer.Canvas.TextOut(x+8,y+200+8,DBGrid.Fields.asString);
printer.Canvas.moveto(x+dbgrid.Columns.Items.Width*pointscale,y+200);
printer.Canvas.lineto(x+dbgrid.Columns.Items.Width*pointscale,y+200+printstep);
end;
end;
x:=x+DBGrid.Columns.Items.Width*PointScale;
end;

if not (y=PointY*TopBlank) then
adoquery.next;
x:=PointX*LeftBlank;
y:=y+PrintStep;
if (y+PrintStep)>(Printer.PageHeight-PointY*BottomBlank) then
begin
if k=1 then
begin
r:=adoquery.recno;
pagenum:=trunc(adoquery.recordcount/r)+1;
end;
for i:=0 to colnum[j]-1 do
begin
printer.canvas.moveto(x,y+200);
printer.canvas.lineto(x+dbgrid.Columns.Items.Width*pointscale,y+200);
x:=x+dbgrid.Columns.Items.width*pointscale;
end;
x:=pointx*leftblank;
printer.Canvas.TextOut(x+8,y+200+8,'第'+inttostr(k)+'页'+''+''+'共'+inttostr(pagenum)+'页');
Printer.NewPage;
y:=PointY*TopBlank;
k:=k+1;
end; //换页
end;//adoquery
for i:=0 to colnum[j]-1 do
begin
printer.Canvas.moveto(x,y+200);
printer.canvas.lineto(x+dbgrid.Columns.Items.Width*pointscale,y+200);
x:=x+dbgrid.Columns.Items.width*pointscale;
end;
x:=pointx*leftblank;
printer.Canvas.TextOut(x+8,printer.PageHeight-bottomblank*pointy,'第'+inttostr(k)+'页'+''+''+'共'+inttostr(pagenum)+'页');
printer.EndDoc;
adoquery.First;
showMessage('打印完成 共'+inttostr(pagenum)+'页');
end;
end;
finally
printdlg.free;
end;
end;
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////打印预览/////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
procedure tprintdlg.report(acanvas:tcanvas);
var
i,r:integer;
pointx,pointy:integer;
printstep:integer;
x,y:integer;
s:string;
begin
PointX:=Trunc(GetDeviceCaps(Printer.Handle,LOGPIXELSX)/2.54);
PointY:=Trunc(GetDeviceCaps(Printer.Handle,LOGPIXELSY)/2.54);
PointScale:=Trunc(GetDeviceCaps(Printer.Handle,LOGPIXELSX)/Screen.PixelsPerInch+1.5);
printer.Canvas.Font.Name:='宋体';
printer.canvas.Font.Size:=10;
s:='出货分类统计表';
PrintStep:=printer.canvas.TextHeight(s)+16;
x:=PointX*LeftBlank;
y:=PointY*TopBlank;
with acanvas do
try
if (myadoquery.Active=true) and (myadoquery.RecordCount>0) then
begin
while not myadoquery.Eof do
begin
for i:=0 to myDBGrid.FieldCount-1 do
begin
if (x+myDBGrid.Columns.Items.Width*PointScale)<=(Printer.PageWidth-PointX*RightBlank) then
begin
if i=0 then
begin
moveto(x,y+200);
lineto(x,y+200+printstep);
end;
moveto(x,y+200);lineto(x+mydbgrid.Columns.Items.Width*pointscale,y+200);
if y=PointY*TopBlank then
begin
Font.Name:='黑体';
Font.Size:=96;
TextOut((Printer.PageWidth-printer.Canvas.TextWidth(s)) div 2,y+8,s);
Font.Name:='宋体';
Font.Size:=68;
TextOut(x+8,y+8+200,myDBGrid.Columns.Title.Caption);
moveto(x+mydbgrid.Columns.Items.Width*pointscale,y+200);
lineto(x+mydbgrid.Columns.Items.Width*pointscale,y+200+printstep);
colnum[j]:=colnum[j]+1;
end
else
begin
TextOut(x+8,y+200+8,myDBGrid.Fields.asString);
moveto(x+mydbgrid.Columns.Items.Width*pointscale,y+200);
lineto(x+mydbgrid.Columns.Items.Width*pointscale,y+200+printstep);
end;
end;
x:=x+myDBGrid.Columns.Items.Width*PointScale;
end;
if not (y=PointY*TopBlank) then
myadoquery.next;
x:=PointX*LeftBlank;
y:=y+PrintStep;
if (y+PrintStep)>(Printer.PageHeight-PointY*BottomBlank) then
begin
if j=1 then
begin
r:=myadoquery.recno;
prepagenum:=trunc(myadoquery.recordcount/r)+1;
end;
for i:=0 to colnum[j]-1 do
begin
moveto(x,y+200);lineto(x+mydbgrid.Columns.Items.Width*pointscale,y+200);
x:=x+mydbgrid.Columns.Items.width*pointscale;
end;
x:=pointx*leftblank;
TextOut(x+8,y+200+8,'第'+inttostr(j)+'页'+''+''+'共'+inttostr(prepagenum)+'页');
rownum[j]:=myadoquery.recno-rownum[j-1];
j:=j+1;
mymetafile[j]:=tmetafile.create;
report(tmetafilecanvas.Create(mymetafile[j],printer.handle));
j:=j-1;
end;
end;
if j=prepagenum then
begin
rownum[j]:=myadoquery.recordcount-rownum[j-1];
for i:=0 to colnum[j]-1 do
begin
moveto(x,y+200);lineto(x+mydbgrid.Columns.Items.Width*pointscale,y+200);
x:=x+mydbgrid.Columns.Items.width*pointscale;
end;
x:=pointx*leftblank;
TextOut(x+8,printer.PageHeight-bottomblank*pointy,'第'+inttostr(j)+'页'+''+''+'共'+inttostr(prepagenum)+'页');
end;
end;
finally
free;
end;

end;


procedure tprintdlg.preview;
var
i:integer;
begin
setlength(rownum,20);
setlength(colnum,20);
setlength(mymetafile,20);
for i:=0 to 20-1 do
begin
rownum:=0;
colnum:=0;
end;
j:=1;
prepagenum:=1;
myADOQuery.First;
mymetafile[j]:=tmetafile.Create;
report(tmetafilecanvas.Create(mymetafile[j],printer.handle));
Image1.picture.Metafile.Clear;
Image1.picture.Metafile:=mymetafile[1];
panel2.Height:=trunc(printer.PageHeight/(pointscale-1.5));
panel2.Width:=trunc(printer.PageWidth/(pointscale-1.5));
myadoquery.First;
end;

constructor tprintdlg.init(adoquery:tadoquery;datasource:tdatasource;dbgrid:tdbgrid);
begin
myadoquery:=adoquery;
mydatasource:=datasource;
mydbgrid:=dbgrid;
adoquery.Active:=true;
printer.Orientation:=poportrait;
end;


function tprintdlg.execute:boolean;
begin
preview;
p:=1;
scrollbox1.AutoScroll:=true;
scrollbox1.vertscrollbar.Range:=trunc(panel2.Height)+100;
scrollbox1.HorzScrollBar.Range:=trunc(panel2.Width)+100;

label1.caption:='1'+''+'/'+''+inttostr(prepagenum);
label2.Caption:=inttostr(rownum[1])+'行'+inttostr(colnum[1])+'列';
label3.Caption:='共'+inttostr(myadoquery.RecordCount)+'行'+''+inttostr(myADOQuery.FieldCount)+'列';
if showmodal=mrok then result:=true
else result:=false;

end;

procedure Tprintdlg.Button1Click(Sender: TObject);
begin
with printersetupdialog1 do
begin
if execute then
begin
preview;
p:=1;
scrollbox1.AutoScroll:=true;
scrollbox1.VertScrollBar.Range:=trunc(panel2.Height)+100;
scrollbox1.HorzScrollBar.Range:=trunc(panel2.Width)+100;

label1.caption:='1'+''+'/'+''+inttostr(prepagenum);
label2.Caption:=inttostr(rownum[1])+'行'+inttostr(colnum[1])+'列';
label3.Caption:='共'+inttostr(myadoquery.RecordCount)+'行'+''+inttostr(myADOQuery.FieldCount)+'列';
end;
end;
end;

procedure Tprintdlg.Button3Click(Sender: TObject);
begin
if p<prepagenum then
begin
p:=p+1;
Image1.Picture.Metafile.clear;
Image1.picture.Metafile:=mymetafile[p];
label1.Caption:=inttostr(p)+''+'/'+''+inttostr(prepagenum);
label2.Caption:=inttostr(rownum[p])+'行'+inttostr(colnum[p])+'列';
end;
end;

procedure Tprintdlg.Button2Click(Sender: TObject);
begin
if p>1 then
begin
p:=p-1;
Image1.picture.Metafile.Clear;
Image1.picture.Metafile:=mymetafile[p];
label1.Caption:=inttostr(p)+''+'/'+''+inttostr(prepagenum);
label2.Caption:=inttostr(rownum[p])+'行'+inttostr(colnum[p])+'列';
end;
end;

procedure Tprintdlg.Button4Click(Sender: TObject);
begin
if panel2.height>100 then
begin
panel2.Height:=panel2.Height div 2;
panel2.width:=panel2.Width div 2;
scrollbox1.AutoScroll:=true;
scrollbox1.vertscrollbar.Range:=trunc(panel2.Height)+100;
scrollbox1.HorzScrollBar.Range:=trunc(panel2.Width)+100;
end;
end;

procedure Tprintdlg.Button5Click(Sender: TObject);
begin
if panel2.height<printer.PageHeight then
begin
panel2.Height:=panel2.Height*2;
panel2.Width:=panel2.Width*2;
scrollbox1.AutoScroll:=true;
scrollbox1.vertscrollbar.Range:=trunc(panel2.Height)+100;
scrollbox1.HorzScrollBar.Range:=trunc(panel2.Width)+100;
end;
end;

end.

问题就是这样的,当我按BUTTON1弹出打印设置对话框,然后确定就不行了,
但是第一次预览却挺好
 
晕倒,你一下子给出那么长的代码,看得我头都晕了
 
不好意思你的问题内容太多了,我一下子看不明白。
不知道你用 QuickReport 没有?
以前我在用 QuickReport 时发现有时它与 Word 有冲突。
有进有正常。总之 Word 在用时它就有点不正常,不出来。
也许是我系统的问题。
如果你认为是你程序有内存泄露用 MemProf 看一下就可以了。
 
大家看一下吧,问题在哪儿,是
printdlg:=tprintdlg.Create(application);
吗,这里的application
是创建DLL的APPLICATION还是
调用DLL的APPLICATION,
当我多次调用preview
时,都用这个printdlg窗体,
有问题吗?
大家都发表一下看法吧,我真的很着急!
 
是动态连接的问题
没有做成dll是一切正常,
做成dll就出现上述问题
 
????????????
 
这不是游戏!!!
 
我很失望,
临走之既,我想说说我的看法---

没有人能救你,除了你自己!
 
to nullbert
没有必要失望嘛:)
你的程序太长,问题又比较泛泛,而且你的程序又涉及到了数据库的访问所以我无法
直接粘过来测试,不过我觉得有一些问题:
在你的Preview中有
>>mymetafile[j]:=tmetafile.Create;
^^^^^^^^^^^^^^^^
>>report(tmetafilecanvas.Create(mymetafile[j],printer.handle));
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
创建了,都没有free(释放掉),这怎么可以!
看delphi的例子:
with TMetafileCanvas.Create(MyMetafile, 0) do
try
Draw(0,0,MyMetafile);
Brush.Color := clBlue;
Ellipse(100,100,200,200);
finally
Free;
end;
除此之外,还有其它的一些问题,不过我觉得你先把这个问题仔细检查一下,调试调试。
祝好运!!
 
试过了,没用!
 
设断点!单步跟踪!看在哪里出问题?
 
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Buttons, StdCtrls, ExtCtrls, Menus, Grids, DBGrids, ComCtrls,
DB, ADODB;

type
TForm1 = class(TForm)
Panel1: TPanel;
Button1: TButton;
Button2: TButton;
SpeedButton1: TSpeedButton;
ScrollBox1: TScrollBox;
ScrollBox2: TScrollBox;
TreeView1: TTreeView;
MainMenu1: TMainMenu;
file1: TMenuItem;
edit1: TMenuItem;
pagesetup1: TMenuItem;
help1: TMenuItem;
DBGrid1: TDBGrid;
DataSource1: TDataSource;
ADOQuery1: TADOQuery;
procedure FormCreate(Sender: TObject);
procedure TreeView1Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

procedure myprint(adoquery:tadoquery;datasource:tdatasource;dbgrid:tdbgrid);far;external 'C:/Documents and Settings/Administrator/Projects11/打印3.0/project1.dll'

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
myprint(adoquery1,datasource1,dbgrid1);
end;

end.
 
我又看了你的程序,这里也是有一点问题的:
>>procedure myprint(adoquery:tadoquery;datasource:tdatasource;dbgrid:tdbgrid);
>> .......
>> printdlg:=tprintdlg.Create(application);
一般应该写成:
procedure myprint(AHandle:THandle;adoquery:tadoquery;datasource:tdatasource;dbgrid:tdbgrid);
.......
Application.Handle := AHandle;
printdlg:=tprintdlg.Create(application);
 
调用试把主程序的Application.handle付给myPrint试dll中的窗体真正成为应用程序的模式
窗体。
 
那你就只有对dll慢慢地来做测试了,屏蔽掉其中主要部分,一点一点来。
 
后退
顶部