Sign in to follow this  
Followers 0
tobias7

printdlg - print dialog dll help

12 posts in this topic

I've been trying to get a good way to print with AutoIt. I've found about three different indirect ways to do it on the forums, but I want really good compatibility, especially with Vista and 64 bit computers. Apparently the official way to do it is to call printdlg or printdlgex with a dllcall, but this is way beyond my capability as it requires creating a dll struct with 19 different variables where every variable has to work right. The code I have so far is posted below. I used the get extended error function and every time it gives me error 1, which means that there is something wrong with the structure size variable, even though that is the one part of the function I attempted. Thank you for your help.

If anyone wants to help, the resources I've been using are:

http://msdn.microsoft.com/en-us/library/ms646843(VS.85).aspx - PRINTDLG Structure

http://msdn.microsoft.com/en-us/library/ms646916(VS.85).aspx - Extended error info

http://msdn.microsoft.com/en-us/library/ms646940(VS.85).aspx - PRINTDLG Function

$lpPrintDlg = DllStructCreate("dword;hwnd;ptr;ptr;int;dword;int;int;int;int;int;ptr;ptr;ptr;ptr;ptr;ptr;ptr;ptr")
DllStructSetData($lpPrintDlg, 1, DllStructGetSize($lpPrintDlg))
DllStructSetData($lpPrintDlg, 2, 0)
DllStructSetData($lpPrintDlg, 3, 0)
DllStructSetData($lpPrintDlg, 4, 0)
DllStructSetData($lpPrintDlg, 5, 0)
DllStructSetData($lpPrintDlg, 6, 0)
DllStructSetData($lpPrintDlg, 7, 0)
DllStructSetData($lpPrintDlg, 8, 0)
DllStructSetData($lpPrintDlg, 9, 0)
DllStructSetData($lpPrintDlg, 10, 0)
DllStructSetData($lpPrintDlg, 11, 0)
DllStructSetData($lpPrintDlg, 12, 0)
DllStructSetData($lpPrintDlg, 13, 0)
DllStructSetData($lpPrintDlg, 14, 0)
DllStructSetData($lpPrintDlg, 15, 0)
DllStructSetData($lpPrintDlg, 16, 0)
DllStructSetData($lpPrintDlg, 17, 0)
DllStructSetData($lpPrintDlg, 18, 0)
DllStructSetData($lpPrintDlg, 19, 0)
DllCall("comdlg32.dll", "byte", "PrintDlg", "ptr", DllStructGetPtr($lpPrintDlg))
$error = DllCall("comdlg32.dll", "dword", "CommDlgExtendedError")
MsgBox(0, "", $error[0])

Share this post


Link to post
Share on other sites



I've been trying to get a good way to print with AutoIt. I've found about three different indirect ways to do it on the forums, but I want really good compatibility, especially with Vista and 64 bit computers. Apparently the official way to do it is to call printdlg or printdlgex with a dllcall, but this is way beyond my capability as it requires creating a dll struct with 19 different variables where every variable has to work right. The code I have so far is posted below. I used the get extended error function and every time it gives me error 1, which means that there is something wrong with the structure size variable, even though that is the one part of the function I attempted. Thank you for your help.

If anyone wants to help, the resources I've been using are:

http://msdn.microsoft.com/en-us/library/ms646843(VS.85).aspx - PRINTDLG Structure

http://msdn.microsoft.com/en-us/library/ms646916(VS.85).aspx - Extended error info

http://msdn.microsoft.com/en-us/library/ms646940(VS.85).aspx - PRINTDLG Function

$lpPrintDlg = DllStructCreate("dword;hwnd;ptr;ptr;int;dword;int;int;int;int;int;ptr;ptr;ptr;ptr;ptr;ptr;ptr;ptr")
DllStructSetData($lpPrintDlg, 1, DllStructGetSize($lpPrintDlg))
DllStructSetData($lpPrintDlg, 2, 0)
DllStructSetData($lpPrintDlg, 3, 0)
DllStructSetData($lpPrintDlg, 4, 0)
DllStructSetData($lpPrintDlg, 5, 0)
DllStructSetData($lpPrintDlg, 6, 0)
DllStructSetData($lpPrintDlg, 7, 0)
DllStructSetData($lpPrintDlg, 8, 0)
DllStructSetData($lpPrintDlg, 9, 0)
DllStructSetData($lpPrintDlg, 10, 0)
DllStructSetData($lpPrintDlg, 11, 0)
DllStructSetData($lpPrintDlg, 12, 0)
DllStructSetData($lpPrintDlg, 13, 0)
DllStructSetData($lpPrintDlg, 14, 0)
DllStructSetData($lpPrintDlg, 15, 0)
DllStructSetData($lpPrintDlg, 16, 0)
DllStructSetData($lpPrintDlg, 17, 0)
DllStructSetData($lpPrintDlg, 18, 0)
DllStructSetData($lpPrintDlg, 19, 0)
DllCall("comdlg32.dll", "byte", "PrintDlg", "ptr", DllStructGetPtr($lpPrintDlg))
$error = DllCall("comdlg32.dll", "dword", "CommDlgExtendedError")
MsgBox(0, "", $error[0])
I don't think printdlg will get anything printed.

What methods in the forums have you tried and what are the problems with them?


Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

I don't think printdlg will get anything printed.

What methods in the forums have you tried and what are the problems with them?

To print, I'm going to use Dll Calls to StartDoc, StartPage, EndDoc, and EndPage, but to use them, I need to call CreateDC, which needs the printer driver and name. I'll probably use the first method from http://www.autoitscript.com/forum/index.ph...mp;#entry539523, which I believe you created, to obtain the printer name, and use "winspool" for the driver name.

However, I was hoping to make my print function as compatible as possible, especially with 64bit and Vista computers. I figured the most compatible method would be the one that Microsoft recommends, which is using PrintDlg or PrintDlgEx, but using those with AutoIt looked way too complicated for me to figure out on my own. I wasn't sure if the method mentioned above would be as compatible as Microsoft's PrintDlg, and I currently have no way of testing it on any 64bit or Vista computers.

Share this post


Link to post
Share on other sites

To print, I'm going to use Dll Calls to StartDoc, StartPage, EndDoc, and EndPage, but to use them, I need to call CreateDC, which needs the printer driver and name. I'll probably use the first method from http://www.autoitscript.com/forum/index.ph...mp;#entry539523, which I believe you created, to obtain the printer name, and use "winspool" for the driver name.

However, I was hoping to make my print function as compatible as possible, especially with 64bit and Vista computers. I figured the most compatible method would be the one that Microsoft recommends, which is using PrintDlg or PrintDlgEx, but using those with AutoIt looked way too complicated for me to figure out on my own. I wasn't sure if the method mentioned above would be as compatible as Microsoft's PrintDlg, and I currently have no way of testing it on any 64bit or Vista computers.

Have you seen this thread by GRS? A lot of the work has been done.

My print UDF, shown in my signature, should work ok on 64 bit PCs, but you might not like having to use my dll.


Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

Have you seen this thread by GRS? A lot of the work has been done.

My print UDF, shown in my signature, should work ok on 64 bit PCs, but you might not like having to use my dll.

Thanks to your getdefaultprinter and GRS' printer functions, I've been able to make great progress on a good printer library. I used those functions as a starting point and I think I've gotten my functions to where they'd be simple enough for any AutoIt user to use. All I've used are dllcalls for popular dlls such as user32, winspool.drv, and gdi32, so they should work on most computers. I'm still not sure if it they'll work on 64 bit PCs, but I think they should be compatible enough to suit me. I'll probably upload a library to AutoIt or even submit my code to be turned into a UDF by the end of the summer. Thanks for your help!

Share this post


Link to post
Share on other sites

Thanks to your getdefaultprinter and GRS' printer functions, I've been able to make great progress on a good printer library. I used those functions as a starting point and I think I've gotten my functions to where they'd be simple enough for any AutoIt user to use. All I've used are dllcalls for popular dlls such as user32, winspool.drv, and gdi32, so they should work on most computers. I'm still not sure if it they'll work on 64 bit PCs, but I think they should be compatible enough to suit me. I'll probably upload a library to AutoIt or even submit my code to be turned into a UDF by the end of the summer. Thanks for your help!

I look forward to seeing what you have done. Post sooner rather than later muttley

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

Hi tobias.

I need this PrintDlg API call too. So I looked at yours PrintDlg try here and PrintWinAPI from GRS.

#538328

Here is corrected definition of PRINTDLG structure so it doesn't return CDERR_STRUCTSIZE anymore

but unfortunatelly it returns CDERR_INITIALIZATION error now.

CDERR_INITIALIZATION    The common dialog box function failed during initialization. This error often occurs when sufficient memory is not available.

#cs
typedef struct tagPD {
    DWORD lStructSize;
    HWND hwndOwner;
    HGLOBAL hDevMode;
    HGLOBAL hDevNames;
    HDC hDC;
    DWORD Flags;
    WORD nFromPage;
    WORD nToPage;
    WORD nMinPage;
    WORD nMaxPage;
    WORD nCopies;
    HINSTANCE hInstance;
    LPARAM lCustData;
    LPPRINTHOOKPROC lpfnPrintHook;
    LPSETUPHOOKPROC lpfnSetupHook;
    LPCTSTR lpPrintTemplateName;
    LPCTSTR lpSetupTemplateName;
    HGLOBAL hPrintTemplate;
    HGLOBAL hSetupTemplate;
} PRINTDLG, *LPPRINTDLG;
#ce

Const $PD_RETURNDC = 0x100

;~ $lpPrintDlg = DllStructCreate("dword;hwnd;ptr;ptr;int;dword;int;int;int;int;int;ptr;ptr;ptr;ptr;ptr;ptr;ptr;ptr") ; original from tobias
$lpPrintDlg = DllStructCreate("dword;hwnd;ptr;ptr;ptr;dword;short;short;short;short;short;ptr;lparam;ptr;ptr;str;str;ptr;ptr")

DllStructSetData($lpPrintDlg, 1, DllStructGetSize($lpPrintDlg))
;~ DllStructSetData($lpPrintDlg, 2, 0)
;~ DllStructSetData($lpPrintDlg, 3, 0)
;~ DllStructSetData($lpPrintDlg, 4, 0)
;~ DllStructSetData($lpPrintDlg, 5, 0)
DllStructSetData($lpPrintDlg, 6, $PD_RETURNDC)
;~ DllStructSetData($lpPrintDlg, 7, 0)
;~ DllStructSetData($lpPrintDlg, 8, 0)
;~ DllStructSetData($lpPrintDlg, 9, 0)
;~ DllStructSetData($lpPrintDlg, 10, 0)
;~ DllStructSetData($lpPrintDlg, 11, 0)
;~ DllStructSetData($lpPrintDlg, 12, 0)
;~ DllStructSetData($lpPrintDlg, 13, 0)
;~ DllStructSetData($lpPrintDlg, 14, 0)
;~ DllStructSetData($lpPrintDlg, 15, 0)
;~ DllStructSetData($lpPrintDlg, 16, 0)
;~ DllStructSetData($lpPrintDlg, 17, 0)
;~ DllStructSetData($lpPrintDlg, 18, 0)
;~ DllStructSetData($lpPrintDlg, 19, 0)

$ret = DllCall("comdlg32.dll", "int", "PrintDlgA", "ptr", DllStructGetPtr($lpPrintDlg))
If @error Then
 $error = DllCall("comdlg32.dll", "dword", "CommDlgExtendedError")
 MsgBox(0, "error", $error[0])
Else
 MsgBox(0, "return", $ret[0])
EndIf

$error = DllCall("comdlg32.dll", "dword", "CommDlgExtendedError")
MsgBox(0, "error", $error[0])

; $CDERR_STRUCTSIZE = 0x1
; $CDERR_INITIALIZATION = 0x2

If somebody have any information how to make it work, please share your knowledge ...

Edited by Zedna

Share this post


Link to post
Share on other sites

I have it in my GDI UDFs

http://progandy.co.cc/index.php/component/option,com_remository/Itemid,30/func,fileinfo/id,23/lang,de/

(it should be loacted in Printing.au3)

[OT: i am redesigning my web, so the link will become invalid soon i think.


*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

I have it in my GDI UDFs

http://progandy.co.cc/index.php/component/option,com_remository/Itemid,30/func,fileinfo/id,23/lang,de/

(it should be loacted in Printing.au3)

MANY THANKS ProgAndy!! :)

I will definitely try it. At quick look it looks like exactly what I need.

I thought about adding all these print API functions (GetDefaultPrinter,SetDefaultPrinter,PrintDlg,StartDoc,EndDoc,StartPage,EndPage) to standard WinApi include too.

It's part of standard GDI API and can be used together with paintings API functions to easily directly print what's needed.

Edited by Zedna

Share this post


Link to post
Share on other sites

Well, you saw that i fgot stuck after half of the way. It is really annoying to copy the description from MSDN, convert the func, go to next and do the same. As a result i only make one or two and then do something more interesting and the UDF is still far away from getting ready :)


*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

Well, you saw that i fgot stuck after half of the way. It is really annoying to copy the description from MSDN, convert the func, go to next and do the same. As a result i only make one or two and then do something more interesting and the UDF is still far away from getting ready :)

Yes I know it's LOT of work.

But for printing there is just about 10 base functions so this can be done relative easily.

I like the way Yashied added some new API functions in his WinAPIEx UDF.

http://www.autoitscript.com/forum/index.php?showtopic=98712&hl=WinAPIEx%20&st=0

BTW: Now I noticed he added also _WinAPI_GetDefaultPrinter, _WinAPI_SetDefaultPrinter.

He added missing functions and with each new version added more ones.

Finally he posted it at BugTrac as feature request for adding to standard WinAPI UDF.

I posted this way few new WinAPI functions too already (but not much).

I think it's better than do such overhelming amount of BIG work alone.

Rather post less "ready to launch" functions right now :-)

But it's just my idea.

Edited by Zedna

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0