Thread View: comp.os.ms-windows.programmer.win32
6 messages
6 total messages
Started by szuchymj
Sun, 04 Sep 2005 00:45
Printing With Win32 API, MSDN example gives error
Author: szuchymj
Date: Sun, 04 Sep 2005 00:45
Date: Sun, 04 Sep 2005 00:45
73 lines
3828 bytes
3828 bytes
I am trying to print using the Win32 API in Delphi. The reason being
that a user has reported problems with TPrinter printing upon switching
to a certain Lexmark printer, even though other applications print
without problems. I have been able to replicate similar behaviour in a
VMWare virtual machine using Windows SP2 and the Docucom PDF driver: my
application and a simple prototype created with TPrinter do not print,
but other applications (notepad, word, IE) print just fine.
Regardless of your opinion of the quality of Docucom PDF driver or
Lexmark printers, the problem remains that other applications are
printing fine on these devices but mine is not. I am guessing these
other applications use MFC classes, Visual Basic 6.0, or the Win32 API.
Because I am using Delphi my only option of the three is Win32 API.
So, I wrote some printing code based on the MSDN example (
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/prntspol_1wfn.asp
) for printing with the Win32 API. It prints without error on
everything except the Docucom PDF driver, for which it says code 6
"invalid handle" upon StartPage. Even though StartDoc works fine. What
is the key difference between my code, and other applications' code,
that causes the Docucom PDF driver to print without error?
procedure printingMain;
var
pd:TPrintDlg;
di:TDocInfo;
begin
//begin setup PRINTDLG structure
FillChar(pd, SizeOf(pd), 0);
pd.lStructSize := sizeof(pd);
pd.hWndOwner:=application.Handle;
pd.hDevMode := thandle(nil);
pd.hDevNames := thandle(nil);
pd.Flags := PD_RETURNDC;
pd.hwndOwner := Application.Handle;
pd.hDC := hdc(nil);
pd.nFromPage := 1;
pd.nToPage := 1;
pd.nMinPage := 1;
pd.nMaxPage := 10;
pd.nCopies := 1;
pd.hInstance := thandle(nil);
pd.lCustData := 0;
pd.lpfnPrintHook := nil;
pd.lpfnSetupHook := nil;
pd.lpPrintTemplateName := pchar(nil);
pd.lpSetupTemplateName := pchar(nil);
pd.hPrintTemplate := thandle(nil);
pd.hSetupTemplate := thandle(nil);
//end setup PRINTDLG structure
PrintDlg(pd);
SetAbortProc(pd.hDC, AbortProc);
//begin setup DOCINFO structure
FillChar(di, SizeOf(di), 0);
di.cbSize := sizeof(di);
di.lpszDocName := pchar('');//'Bitmap Printing Test';
di.lpszOutput := pchar('');
di.lpszDatatype := pchar('');
di.fwType := 0;
//end setup DOCINFO structure
startdoc(pd.hDC, di);
StartPage(pd.hDC);
TextOut(pd.hDC, 10, 10, pchar('test123'),length('test123'));
EndPage(pd.hDC);
EndDoc(pd.hDC);
DeleteDC(pd.hDC);
end;
function AbortProc(Prn: HDC; Error: Integer): Bool; stdcall;
begin
Application.ProcessMessages;
Result := false;
end;
Re: Printing With Win32 API, MSDN example gives error
Author: szuchymj
Date: Sun, 04 Sep 2005 01:16
Date: Sun, 04 Sep 2005 01:16
29 lines
2113 bytes
2113 bytes
Using the example at
http://community.borland.com/article/0,1410,16139,00.html I was able to
fix the problem. Here is my new code.
procedure printMain;
var
Pd : TPrintDlg;
DocInfo: TDocInfo;
begin
FillChar(Pd, sizeof(Pd), 0);
Pd.lStructSize := sizeof(Pd);
Pd.hWndOwner := Form1.Handle;
Pd.Flags := PD_RETURNDC;
if PrintDlg(pd) then
begin
FillChar(DocInfo, sizeof(DocInfo), 0);
DocInfo.cbSize := SizeOf(DocInfo);
StartDoc(Pd.hDc, DocInfo);
StartPage(Pd.hDc);
TextOut(Pd.hDc, 100, 100, 'test123', length('test123'));
EndPage(Pd.hDc);
EndDoc(Pd.hDc);
end;
end;
I do not yet know what was causing the problem in my previous code, but
on first glance it appears that a member of the DOCINFO structure or
the PRINTDLG structure was initialized to something it should not have
been.
Re: Printing With Win32 API, MSDN example gives error
Author: szuchymj
Date: Sun, 04 Sep 2005 01:30
Date: Sun, 04 Sep 2005 01:30
8 lines
1783 bytes
1783 bytes
I found the answer. Calling SetAbortProc after showing the print dialog via PrintDlg causes an error. Call it before PrintDlg, and the error goes away. It is confusing because the MSDN example appears to call SetAbortProc after the PrintDlg call. Actually there is no PrintDlg call in the MSDN example, but it is implied that you have already gotten the printer DC via PrintDlg or CreateDC.
Re: Printing With Win32 API, MSDN example gives error
Author: szuchymj
Date: Sun, 04 Sep 2005 01:36
Date: Sun, 04 Sep 2005 01:36
2 lines
1577 bytes
1577 bytes
Actually that is a bad idea because calling SetAbortProc before PrintDlg renders the abort procedure useless. It never gets called.
Re: Printing With Win32 API, MSDN example gives error
Author: szuchymj
Date: Sun, 04 Sep 2005 01:49
Date: Sun, 04 Sep 2005 01:49
5 lines
1651 bytes
1651 bytes
The Real Solution To The Problem a.k.a. Why I Am An Idiot: AbortProc is supposed to return true if you want the print job to continue. I for some reason assumed the opposite, that it was supposed to return false.
Re: Printing With Win32 API, MSDN example gives error
Author: Kellie Fitton
Date: Sun, 04 Sep 2005 21:33
Date: Sun, 04 Sep 2005 21:33
15 lines
2236 bytes
2236 bytes
Hi, Before calling the API StartDoc(), the application should call the API SetAbortProc() to set the abort procedure, then disables its own window by using the API EnableWindow(), and displays the print-status or the abort modeless dialogBox containing a Cancel button and some statics controls to show the document name and the number of pages printed. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/prntspol_0883.asp http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/keyboardinput/keyboardinputreference/keyboardinputfunctions/enablewindow.asp Hope these information helps, Kellie.
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads