打印代码,解决了献上100分(0分)

  • 主题发起人 主题发起人 wallysw
  • 开始时间 开始时间
W

wallysw

Unregistered / Unconfirmed
GUEST, unregistred user!
各位大虾,小弟写了一个打印MEMO的函数,但打印多行时就会提示出错,我检查了一天,也不知道错在哪里,代码贴出来,麻烦大家帮我看一下,如果问题解决了,小弟献上100分,分不多,只是麻烦各位帮小弟一个忙了。
procedure TForm1.PrintMemo(AMemo: TMemo);
var
i, CurHeigth, sLine: Integer;
TotalStr, TempStr: WideString;
StrList: TStringList;
Prn: TPrinter;
FRect: TRect;
begin

StrList := TStringList.Create;
Prn := TPrinter.Create;
Prn.Canvas.Font := AMemo.Font;
FRect := Rect(200, 200, Prn.PageWidth - 200, Prn.PageHeight - 200);
{计算每行应打印多少个字}
TotalStr := AMemo.Lines.Text;
for i := 1 to Length(TotalStr)do
begin
if (TotalStr <> #$D) and ((Prn.Canvas.TextWidth(TempStr) * 3) < (FRect.Right - 300)) then
begin
TempStr := TempStr + TotalStr;
end else
begin
StrList.Add(TempStr + TotalStr);

TempStr := '';
end;
end;
StrList.Add(TempStr);
{打印部份}
sLine := 1;
CurHeigth := FRect.Top;

Prn.begin
Doc;
for i := 0 to StrList.Count - 1do
begin
if CurHeigth < (FRect.Bottom - 200) then
begin
CurHeigth := FRect.Top + (Prn.Canvas.TextHeight(StrList.Strings) * sLine);
Prn.Canvas.TextOut(200, CurHeigth, StrList.Strings);
{打印多行时,提示这里出错,无法访问内存地址错误}
sLine := sLine + 1;
end else
begin
Prn.Canvas.TextOut(200, CurHeigth, StrList.Strings);

Prn.NewPage;
CurHeigth := FRect.Top;
sLine := 1;
end;
end;

Prn.EndDoc;
Prn.Free;
StrList.Clear;
StrList.Free;
end;
 
你设置临时变量,
Prn.Canvas.TextOut(200, CurHeigth, StrList.Strings);
{打印多行时,提示这里出错,无法访问内存地址错误}
跟踪i和StrList.Strings的内容,然后再检查。
 
注意检查换行是/r/n ,不知道你有没有注意这一点?
 
TO:wukw
换行我注意了,在读取MEMO里面的文本时,我遇到换行或每行到边距时,我就读取这么多的字放到字符列表(StrList)里面了,后面的打印就好像不关换行的事,读取字符列表里的每行写到打印机画布上面,我想这应该没问题。
TO:zywcd
我跟踪了,由于当前行高CurHeigth控制不好,以下是我重写了这个代码,原理和上面的差不多,我把StrList的每行导入MEMO2里面,显示是正确的,可是打印时还是有问题,不知道是怎么回事,不知道用begin
doc,Enddoc来打印,是否跟Prn.NewPage不兼容,我重写的代码如下,麻烦帮帮忙,这个问题,我已经弄了快三天了,痛苦啊:
procedure TForm1.PrintMemo(AMemo: TMemo);
var
i, j, CurHeigth, sLine, FontHeigth: Integer;
TotalStr, TempStr: WideString;
StrList: TStringList;
Prn: TPrinter;
FRect: TRect;
begin
StrList := TStringList.Create;
Prn := TPrinter.Create;
Prn.Canvas.Font := AMemo.Font;
FRect := Rect(200, 200, Prn.PageWidth - 200, Prn.PageHeight - 200);
TotalStr := AMemo.Lines.Text;
CurHeigth := FRect.Top;
sLine := 1;
FontHeigth := 0;
{求一个字在打印机里面的高度}
for i := 1 to Length(TotalStr)do
begin
if TotalStr <> '' then
TempStr := TotalStr;
if TempStr <> '' then
FontHeigth := Prn.Canvas.TextHeight(TempStr);
if FontHeigth <> 0 then
begin
TempStr := '';
Break;
end;
end;

{计算每行应打印多少个字部份}
for i := 1 to Length(TotalStr)do
begin
if (TotalStr <> #$D) and ((Prn.Canvas.TextWidth(TempStr) * 3) < (FRect.Right - 300)) then
begin
TempStr := TempStr + TotalStr;
end else
begin
StrList.Add(TempStr + TotalStr);
inc(sLine);
TempStr := '';
end;

if (CurHeigth + FontHeigth * sLine) >= FRect.Bottom - 200 then
begin
StrList.Add('CP');
CurHeigth := FRect.Top;
sLine := 1;
end;
end;
StrList.Add(TempStr);

{打印部份}
j := 1;
Prn.begin
Doc;
for i := 0 to StrList.Count - 1do
begin
//Memo2.Lines.Add(StrList.Strings);
if StrList.Strings <> 'CP' then
begin
Prn.Canvas.TextOut(200, (FRect.Top + Prn.Canvas.TextHeight(StrList.Strings) * (j)), StrList.Strings);
j := j + 1;
end else
begin
Prn.NewPage;
j := 1;
end;
end;
Prn.EndDoc;
{释放对象部份}
Prn.Free;
StrList.Clear;
StrList.Free;
end;

-------------这个仍是换页问题,如果打印文本超过一页,就会出错,如果不超出一页,打印是正常的。-----------------
不知道怎么回事,帮帮小弟,这个问题太烦了,哪位大哥来救救小弟啊![:(]
 
怎么没有人理我啊?
 
我测试了你的代码。如果编译好运行没有问题,但是如果单步运行,肯定出问题。
Prn.NewPage;
和Prn.Canvas.TextOut()
都会。不可理解。
 
使用TPrinter对象,不要自己创建一个具体的对象。
因为自己调用TPrinter的Create方法时,并没有创建单元变量FPrinter,
但是在TPrinter的方法中却使用了FPrinter变量,自然导致异常出现。
解决方法:
将“Prn:=TPrinter.Ctreate”改为“Prn:=Printer”
同时屏蔽Prn.Free指令,因为FPrinter单元对象是自动释放的。
建议优化你的代码质量,尤其是代码的异常保护。你的代码在异常情况下,
肯定会出现内存泄漏的。
 
TO:lccc
你说的对,按你的方法去做,我已解决了该问题,谢谢你。
TO:zywcd
谢谢你对本问题的关注与参与。
两位到http://www.delphibbs.com/delphibbs/dispq.asp?lid=3607592 来接分。
 
后退
顶部