Podany poniżej kod działa gdy program jest skompilowany pod windows 10 32bit, natomiast przy kompilacji pod 64bit zwraca komunikat E_INVALIDARG.
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, windows;
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;
PD_RESULT_CANCEL = 0;
PD_RESULT_PRINT = 1;
PD_RESULT_APPLY = 2;
type
tagPDEXW = packed record
lStructSize : DWORD;
hWndOwner : HWND;
hDevMode : HGLOBAL;
hDevNames : HGLOBAL;
hDC : HDC;
Flags : DWORD;
Flags2 : DWORD;
ExclusionFlags : DWORD;
nPageRanges : DWORD;
nMaxPageRanges : DWORD;
lpPageRanges : Pointer;
nMinPage : DWORD;
nMaxPage : DWORD;
nCopies : DWORD;
hInstance : HWND;
lpPrintTemplateName : PWideChar;
lpCallback : Pointer;
nPropertyPages : DWORD;
lphPropertyPages : PtrUInt;
nStartPage : DWORD;
dwResultAction : DWORD;
end;
TPrintDlgEx = tagPDEXW;
PPrintDlgEx = ^TPrintDlgEx;
tagPRINTPAGERANGE = packed record
nFromPage, nToPage : DWord;
end;
TPageRange = tagPRINTPAGERANGE;
type TPrintDlgExFunc = function (lppd : PPrintDlgEx): DWORD; stdcall;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
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
Pointer(PrintDlgEx) := GetProcAddress(hComDlg32,'PrintDlgExW');
if Assigned(PrintDlgEx) then
begin
ZeroMemory(@pdex, sizeof(pdex));
pdex.lStructSize := sizeof(pdex);
pdex.hWndOwner := Handle;
pdex.Flags := PD_ALLPAGES {or PD_NOSELECTION or PD_NOCURRENTPAGE};
pdex.nPageRanges := 1;
pdex.nMaxPageRanges := 3;
PageRangeArray[1].nFromPage := 1;
PageRangeArray[1].nToPage := 10;
pdex.lpPageRanges := @PageRangeArray[1];
pdex.nMinPage := 1;
pdex.nMaxPage := 10;
pdex.nCopies := 1;
pdex.nStartPage := START_PAGE_GENERAL;
PrintDlgExResult := PrintDlgEx(@pdex);
case PrintDlgExResult of
E_OUTOFMEMORY: showMessage('E_OUTOFMEMORY');
E_INVALIDARG: showMessage('E_INVALIDARG');
E_POINTER: showMessage('E_POINTER');
E_HANDLE: showMessage('E_HANDLE');
E_FAIL: showMessage('E_FAIL');
S_OK: begin
case pdex.dwResultAction of
PD_RESULT_CANCEL: ShowMessage('Cancel');
PD_RESULT_PRINT: ShowMessage('Print');
PD_RESULT_APPLY: ShowMessage('Applay');
end;
end;
end;
end;
FreeLibrary(hComDlg32);
end;
end;
end.
Jak zrobić aby ten kod działał nie tylko na win32, ale także na win64.
packed
jednak ma znaczenie po akurat zmiana tego powoduje że błędu nie ma (przynajmniej w Delphi), tamte pozostałe to sugestie... a ostanie z typem Integer to chyba tylko Delphi się ciska, bo pytający normalnie dostawał błądE_INVALIDARG
.packed
zadziałało? Muszę sprawdzić rozmiary tych struktur, spakowanej i nie, bo chyba coś mi umknęło, przez co teoria mija się z praktyką. :Dpacked
84bajty bez też 84 bajty; apka 64 bit zpacked
120 bajtów bez 136 bajtów (obojętne twoja czy jego deklaracja typu)