Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Drucken mittels des PrintDlgEx-Dialogs (https://www.delphipraxis.net/124688-drucken-mittels-des-printdlgex-dialogs.html)

r29d43 23. Nov 2008 15:51

Re: Drucken mittels des PrintDlgEx-Dialogs
 
Zitat:

Zitat von SirThornberry
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)

Die Exception lautete:

---------------------------
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.

r29d43 23. Nov 2008 15:58

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 :(

SirThornberry 23. Nov 2008 16:01

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:

..aber leider geht's immer noch nicht
Bei dieser Fehlerbeschreibung kann dir keiner weiter helfen. Die letzte Fehlermeldung hat ziemlich darauf hingewiesen das ein Pointer erwartet wird. Du hingegen hast dann wohl eine Struktur übergeben. Entsprechend wurde versucht die Anfangswerte in deiner Struktur als Pointer zu interpretieren welcher somit auf Adresse 0 gezeigt hat -> bumm

r29d43 23. Nov 2008 16:23

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.

SirThornberry 23. Nov 2008 16:43

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.

r29d43 23. Nov 2008 19:17

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;

DeddyH 23. Nov 2008 19:21

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:

Namenloser 23. Nov 2008 20:18

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.

Apollonius 23. Nov 2008 20:35

Re: Drucken mittels des PrintDlgEx-Dialogs
 
Wenn man eine Exception haben möchte, sollte man die Funktion etwas umdeklarieren:
Delphi-Quellcode:
procedure PrintDlgEx(var lppd: TPrintDlgEx); safecall;
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.

Namenloser 23. Nov 2008 21:07

Re: Drucken mittels des PrintDlgEx-Dialogs
 
Wieder was dazu gelernt :mrgreen:


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:10 Uhr.
Seite 2 von 2     12   

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