![]() |
Drucken mittels des PrintDlgEx-Dialogs
Hallo,
"PrintDlgEx" hat ja einige Vorteile gegenüber der nur PrintDlg-Funktion, aber leider findet man hier im Forum so gut wie nichts darüber. Irgendwie scheint auch diese Funktion in der CommDlg-Unit nicht berücksichtigt zu sein. Warum, geht die nicht mit Delphi? Bzw.: Ist es schonmal jemandem gelungen die zu nutzen? Wenn ja, wie? Thx im Voraus, rXdY |
Re: Drucken mittels des PrintDlgEx-Dialogs
woran scheiterst du?
Zitat:
|
Re: Drucken mittels des PrintDlgEx-Dialogs
Zitat:
|
Re: Drucken mittels des PrintDlgEx-Dialogs
Wenn die Funktion nicht in einer Unit definiert ist könntest du sie selbst definieren. Woher weißt du von der Funktion? Aus dem MSDN?
|
Re: Drucken mittels des PrintDlgEx-Dialogs
Zitat:
Zitat:
|
Re: Drucken mittels des PrintDlgEx-Dialogs
Übersetz dir doch die Funktion aus der
![]() |
Re: Drucken mittels des PrintDlgEx-Dialogs
Also, habe es jetzt doch mal versucht, die Funktion selbst zu definieren. Leider aber gibt's bei der Zeile des eigentlichen Funktionsaufrufes dann eine Exception. Hier erstmal der bis dahin nötige Code:
Delphi-Quellcode:
const
PD_ALLPAGES = $00000000; PD_SELECTION = $00000001; PD_PAGENUMS = $00000002; PD_NOSELECTION = $00000004; PD_NOPAGENUMS = $00000008; PD_COLLATE = $00000010; PD_PRINTTOFILE = $00000020; PD_PRINTSETUP = $00000040; PD_NOWARNING = $00000080; PD_RETURNDC = $00000100; PD_RETURNIC = $00000200; PD_RETURNDEFAULT = $00000400; PD_SHOWHELP = $00000800; PD_ENABLEPRINTHOOK = $00001000; PD_ENABLESETUPHOOK = $00002000; PD_ENABLEPRINTTEMPLATE = $00004000; PD_ENABLESETUPTEMPLATE = $00008000; PD_ENABLEPRINTTEMPLATEHANDLE = $00010000; PD_ENABLESETUPTEMPLATEHANDLE = $00020000; PD_USEDEVMODECOPIES = $00040000; PD_USEDEVMODECOPIESANDCOLLATE = $00040000; PD_DISABLEPRINTTOFILE = $00080000; PD_HIDEPRINTTOFILE = $00100000; PD_NONETWORKBUTTON = $00200000; PD_CURRENTPAGE = $00400000; PD_NOCURRENTPAGE = $00800000; PD_EXCLUSIONFLAGS = $01000000; PD_USELARGETEMPLATE = $10000000; type TPrintDlgEx = record lStructSize : Cardinal; hWndOwner : HWnd; hDevMode : Cardinal; hDevNames : Cardinal; hDC : HDC; Flags : Cardinal; Flags2 : Cardinal; ExclusionFlags : Cardinal; nPageRanges : Word; nMaxPageRanges : Word; lpPageRanges : Pointer; nMinPage : Word; nMaxPage : Word; nCopies : Word; hInstance : Cardinal; lpPrintTemplateName : PAnsiChar; lpCallback : Pointer; nPropertyPages : Cardinal; lphPropertyPages : Cardinal; nStartPage : Cardinal; dwResultAction : Cardinal; end; type TPrintDlgExFunc = function (Pdex : TPrintDlgEx): DWord; stdcall; procedure TForm1.Button1Click(Sender: TObject); var hComDlg32 : THandle; PrintDlgEx : TPrintDlgExFunc; pdex : TPrintDlgEx; begin hComDlg32 := LoadLibrary('comdlg32.dll'); if hComDlg32 <> 0 then begin @PrintDlgEx := GetProcAddress(hComDlg32,'PrintDlgExA'); if Assigned(PrintDlgEx) then begin ZeroMemory(@pdex, sizeof(TPrintDlgEx)); pdex.lStructSize := sizeof(TPrintDlgEx); pdex.hWndOwner := Handle; pdex.Flags := PD_ALLPAGES or PD_NOPAGENUMS ; pdex.nCopies := 1; PrintDlgEx (pdex); // <--- Exception hier!!! end; FreeLibrary(hComDlg32); end; end; Event. sieht ja irgendjemand, wo da ein Fehler sein könnte :roteyes: |
Re: Drucken mittels des PrintDlgEx-Dialogs
verrätst du uns auch noch die Exception? Ich würde darauf tippen das der record packed sein sollte (also anstele von "record" einen "packed record" nehmen)
|
Re: Drucken mittels des PrintDlgEx-Dialogs
Vielleicht erwartet die Funktion einen Pointer
|
Re: Drucken mittels des PrintDlgEx-Dialogs
Jepp, steht zumindest so im MSDN.
Zitat:
|
Re: Drucken mittels des PrintDlgEx-Dialogs
Zitat:
--------------------------- Benachrichtigung über Debugger-Exception --------------------------- Im Projekt Project1.exe ist eine Exception der Klasse EAccessViolation mit der Meldung 'Zugriffsverletzung bei Adresse 77AA88A0 in Modul 'comdlg32.dll'. Lesen von Adresse 0000004A' aufgetreten. --------------------------- Anhalten Fortsetzen Hilfe --------------------------- ..und ein packed record brachte leider keine Verbesserung. @NamenLozer & DeddyH, leider gings mit einem Pointer auch nicht. War auch irgendwie zu erwarten, denn wahrscheinlicherweise wird PrintDlgEx hier das gleiche an Parameter-Art erwarten wie PrintDlg auch. Und das ist da nunmal nur der einfache Bezeichner der Variable. Der Rest wird wohl durch die sogenannte Compilermagic erledigt. |
Re: Drucken mittels des PrintDlgEx-Dialogs
Ok, einen Fehler habe ich eben noch gefunden: In der Definition von TPrintDlgEx habe ich fünf "Word"s, die natürlich "DWord"s sein müssen.
..aber leider geht's immer noch nicht :( |
Re: Drucken mittels des PrintDlgEx-Dialogs
Es wird definitiv ein Pointer erwartet. Ich kenne zumindest keine Apifunktion die wirklich die gesamten Daten auf dem Stack erwartet.
Ich würde an deiner Stelle einfach mal einen Packed Record draus machen UND einen Pointer auf die Struktur übergeben. Zitat:
|
Re: Drucken mittels des PrintDlgEx-Dialogs
Logo :wall: , jetzt wo ich die Funktion ja selbst definiert habe, muss da natürlich tatsächlich ein Pointer stehen :wall: :wall: :wall: . Wenn man PrintDlg benutzt ist das nämlich nicht nötig, weil eben die Compilermagic da dann automatisch die Adresse der Variablen hinschreibt. Da ich die ganze Zeit über nur mit PrintDlg arbeitete, habe ich mich da diesbezüglich wohl etwas zu sehr von dem ablenken lassen, was da als Parametertyp tatsächlich steht.
Also, jetzt gibt's zwar keine Exception mehr, aber es taucht auch noch kein Dialog auf. Nehme aber an, jetzt fehlen einfach noch ein paar richtig eingestellte Parameter. |
Re: Drucken mittels des PrintDlgEx-Dialogs
Du kannst ja mit GetLastError schauen warum nichts passiert bzw. gibt Die Funktion vielleicht auch einen Fehler zurück. Compilermagic ist beim Original auch nicht im Spiel. Anstelle eines Pointers kann man es auch per var declarieren dann ist es intern als Pointer übergeben.
Compilermagic kommt eigentilch nur in der system-unit zum Einsatz. |
Re: Drucken mittels des PrintDlgEx-Dialogs
's lag, wie ich vermutet hatte, ein E_INVALIDARG -Error vor. Nachdem ich also die Argumente dann etwas optimiert bzw. vervollständigt hatte, tauchte auch endlich der Dialog auf.
Hier event. nochmal der bis dato resultierende Code hierfür (event. möchte den Dialog ja auch nochmal jemand anderes anwenden):
Delphi-Quellcode:
const
PD_ALLPAGES = $00000000; PD_SELECTION = $00000001; PD_PAGENUMS = $00000002; PD_NOSELECTION = $00000004; PD_NOPAGENUMS = $00000008; PD_COLLATE = $00000010; PD_PRINTTOFILE = $00000020; PD_PRINTSETUP = $00000040; PD_NOWARNING = $00000080; PD_RETURNDC = $00000100; PD_RETURNIC = $00000200; PD_RETURNDEFAULT = $00000400; PD_SHOWHELP = $00000800; PD_ENABLEPRINTHOOK = $00001000; PD_ENABLESETUPHOOK = $00002000; PD_ENABLEPRINTTEMPLATE = $00004000; PD_ENABLESETUPTEMPLATE = $00008000; PD_ENABLEPRINTTEMPLATEHANDLE = $00010000; PD_ENABLESETUPTEMPLATEHANDLE = $00020000; PD_USEDEVMODECOPIES = $00040000; PD_USEDEVMODECOPIESANDCOLLATE = $00040000; PD_DISABLEPRINTTOFILE = $00080000; PD_HIDEPRINTTOFILE = $00100000; PD_NONETWORKBUTTON = $00200000; PD_CURRENTPAGE = $00400000; PD_NOCURRENTPAGE = $00800000; PD_EXCLUSIONFLAGS = $01000000; PD_USELARGETEMPLATE = $10000000; START_PAGE_GENERAL = $ffffffff; type TPrintDlgEx = packed record lStructSize : Cardinal; hWndOwner : HWnd; hDevMode : Cardinal; hDevNames : Cardinal; hDC : HDC; Flags : Cardinal; Flags2 : Cardinal; ExclusionFlags : Cardinal; nPageRanges : DWord; nMaxPageRanges : DWord; lpPageRanges : Pointer; nMinPage : DWord; nMaxPage : DWord; nCopies : DWord; hInstance : Cardinal; lpPrintTemplateName : PAnsiChar; lpCallback : Pointer; nPropertyPages : Cardinal; lphPropertyPages : Cardinal; nStartPage : Cardinal; dwResultAction : Cardinal; end; TPageRange = packed record nFromPage, nToPage : DWord; end; type TPrintDlgExFunc = function (PDEx : Pointer): DWord; stdcall; ... procedure TForm1.Button1Click(Sender: TObject); var hComDlg32 : THandle; PrintDlgEx : TPrintDlgExFunc; PrintDlgExResult : integer; pdex : TPrintDlgEx; PageRangeArray : array[1..3] of TPageRange; begin hComDlg32 := LoadLibrary('comdlg32.dll'); if hComDlg32 <> 0 then begin @PrintDlgEx := GetProcAddress(hComDlg32,'PrintDlgExA'); if Assigned(PrintDlgEx) then begin ZeroMemory(@pdex, sizeof(TPrintDlgEx)); pdex.lStructSize := sizeof(TPrintDlgEx); pdex.hWndOwner := Handle; pdex.Flags := PD_ALLPAGES // or PD_NOCURRENTPAGE ; pdex.nPageRanges := 1; pdex.nMaxPageRanges := 3; PageRangeArray[1].nFromPage := 1; PageRangeArray[1].nToPage := 1; pdex.lpPageRanges := @PageRangeArray[1]; pdex.nMinPage := 1; pdex.nMaxPage := 10; pdex.nCopies := 1; pdex.nStartPage := START_PAGE_GENERAL; PrintDlgExResult := PrintDlgEx(@pdex); if PrintDlgExResult <> S_Ok then begin if PrintDlgExResult = E_OUTOFMEMORY then showMessage('E_OUTOFMEMORY'); if PrintDlgExResult = E_INVALIDARG then showMessage('E_INVALIDARG'); if PrintDlgExResult = E_POINTER then showMessage('E_POINTER'); if PrintDlgExResult = E_HANDLE then showMessage('E_HANDLE'); if PrintDlgExResult = E_FAIL then showMessage('E_FAIL'); end; end; FreeLibrary(hComDlg32); end; . . . end; |
Re: Drucken mittels des PrintDlgEx-Dialogs
Das find ich ja mal cool, dass Du spontan Deine Lösung hier postest (ist leider irgendwie nicht selbstverständlich). Nur würde ich statt der ganzen "if"s am Codeende eine case-Abfrage bevorzugen, aber das kann ja jeder so machen wie er will. :thumb:
|
Re: Drucken mittels des PrintDlgEx-Dialogs
Wo wir schon grade dabei sind: es wäre auch bessre, eine Exception zu erzeugen, statt eine MessageBox. Das kann man dann, je nach dem, was man mal damit vor hat, besser abfangen.
|
Re: Drucken mittels des PrintDlgEx-Dialogs
Wenn man eine Exception haben möchte, sollte man die Funktion etwas umdeklarieren:
Delphi-Quellcode:
Die Aufrufkonvention Safecall führt dazu, dass automatisch eine Exception geworfen wird, wenn die Funktion einen Fehlercode zurückgibt. Der Rückgabewert wird vollständig wegabstrahiert.
procedure PrintDlgEx(var lppd: TPrintDlgEx); safecall;
|
Re: Drucken mittels des PrintDlgEx-Dialogs
Wieder was dazu gelernt :mrgreen:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:51 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz