b_vaneck
asked on
Updating printersettings
Hi,
I'm having a printerproblem. I've created my own printerdialog. Everythings goes ok like selecting a printer, changing the papersize and setting a number of copies. But when I want to change the properties of a printer is all goes wrong... Access Violation...
BTW: I'm working with Delphi 4
Here's my code for changing the properties:
procedure TMyPrintDlg.printInstellin genBtnClic k(Sender: TObject);
var
SpaceNeeded : word; // for pDriverinfo2
pDBuff : _devicemodeA; // dummy
aDevMode : PDeviceModeA;
pDMode : PDEVMODE;
Driver_info_2 : pDriverinfo2;
DevModeSize : integer;
dPtr : Pointer;
hPrinter : THandle;
begin
//Printername is a private variable of TMyPrintDlg
OpenPrinter(PChar(Printern ame), hPrinter, nil);
pDMode := GlobalLock(hPrinter);
GetPrinter(hPrinter, 2, 0, 0, @SpaceNeeded);
GetMem(Driver_info_2, SpaceNeeded);
GetPrinter(hPrinter, 2, Driver_info_2, SpaceNeeded, @SpaceNeeded);
DevModeSize := DocumentProperties(0, hPrinter, PChar(Printername), pDBuff, pDBuff, 0);
dPtr := allocmem(DevModeSize);
aDevMode := pDevmode(dPtr);
//all goes ok until this point. When changing the properties of the printer, I get a unexpected Access Violation.
DocumentProperties(0, hPrinter, PChar(PrinterName), aDevMode^, aDevMode^, DM_IN_BUFFER or DM_IN_PROMPT);
//update the printersettings
ResetDC(hPrinter, aDevMode^);
ClosePrinter(hPrinter);
end;
Thankx in advance,
Benjamin
I'm having a printerproblem. I've created my own printerdialog. Everythings goes ok like selecting a printer, changing the papersize and setting a number of copies. But when I want to change the properties of a printer is all goes wrong... Access Violation...
BTW: I'm working with Delphi 4
Here's my code for changing the properties:
procedure TMyPrintDlg.printInstellin
var
SpaceNeeded : word; // for pDriverinfo2
pDBuff : _devicemodeA; // dummy
aDevMode : PDeviceModeA;
pDMode : PDEVMODE;
Driver_info_2 : pDriverinfo2;
DevModeSize : integer;
dPtr : Pointer;
hPrinter : THandle;
begin
//Printername is a private variable of TMyPrintDlg
OpenPrinter(PChar(Printern
pDMode := GlobalLock(hPrinter);
GetPrinter(hPrinter, 2, 0, 0, @SpaceNeeded);
GetMem(Driver_info_2, SpaceNeeded);
GetPrinter(hPrinter, 2, Driver_info_2, SpaceNeeded, @SpaceNeeded);
DevModeSize := DocumentProperties(0, hPrinter, PChar(Printername), pDBuff, pDBuff, 0);
dPtr := allocmem(DevModeSize);
aDevMode := pDevmode(dPtr);
//all goes ok until this point. When changing the properties of the printer, I get a unexpected Access Violation.
DocumentProperties(0, hPrinter, PChar(PrinterName), aDevMode^, aDevMode^, DM_IN_BUFFER or DM_IN_PROMPT);
//update the printersettings
ResetDC(hPrinter, aDevMode^);
ClosePrinter(hPrinter);
end;
Thankx in advance,
Benjamin
ASKER
Well Russell,
I've tried your code and it compiles and runs, but when I change any printer properties it will not keep the changes. When I for instance change the lay-out of a page to landscape, instead of portrait, it still prints on a portrait lay-out. Some way or another it doesn't keep the changes of the printer properties...
Thankx,
Benjamin
I've tried your code and it compiles and runs, but when I change any printer properties it will not keep the changes. When I for instance change the lay-out of a page to landscape, instead of portrait, it still prints on a portrait lay-out. Some way or another it doesn't keep the changes of the printer properties...
Thankx,
Benjamin
You indicated your problem was with an access violation, and I corrected your code so that it was syntactically and functionally correct. Now if you want this to work, then you should not be using ResetDC(...) which was meant to take an HDC handle, not a printer handle.
What you should be using is SetPrinter, passing the following:
SetPrinter(hPrinter, 2, lpdmMode, 0);
----
Russell
ASKER
Hi Russell,
yes, my code is now syntactically correct and works almost fine. So thanks for that.
But when I try to apply the settings to change the printer properties it will give a winspool.drv error at SetPrinter(hPrinter, 2, lpdmMode, 0);. I tried the program on a different computer and still it give the winspool.drv error. So something goes wrong here.
Thankx,
Benjamin
yes, my code is now syntactically correct and works almost fine. So thanks for that.
But when I try to apply the settings to change the printer properties it will give a winspool.drv error at SetPrinter(hPrinter, 2, lpdmMode, 0);. I tried the program on a different computer and still it give the winspool.drv error. So something goes wrong here.
Thankx,
Benjamin
Do you mind sharing the error then? (it would make it easier to figure the problem out)
Russell
Russell
ASKER
Okay, the full error:
exception raised class EAccessViolation with message 'Access violation at address 73001AE5 in module 'winspool.drv'. Read of address 39464450. Process stopped.
It occurs when clicking the 'OK' button of the printer document properties dialog.
Benjamin
exception raised class EAccessViolation with message 'Access violation at address 73001AE5 in module 'winspool.drv'. Read of address 39464450. Process stopped.
It occurs when clicking the 'OK' button of the printer document properties dialog.
Benjamin
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Hey Russell,
well it worked eventually... So thankx, now I can finally move on to the next problem...
Benjamin
well it worked eventually... So thankx, now I can finally move on to the next problem...
Benjamin
Im not sure what your trying to do with the GlobalLock on the printer handle.... but its not right. The bigger problems are this:
1.) SpaceNeeded is defined as word, and should be DWORD. (this is the second occurrence of the same problem that I have seen in about a week?....)
2.) for DocumentProperties (the second call) you are specifying DM_IN_BUFFER but are passing in an empty structure??? You have basically told the api to use the values in the buffer (some of which are pointers to char strings) and provided the api with junk... resulting in a gpf.
Try the following, which should work correctly for you.
var dwSpaceNeeded: DWORD;
dwDMSize: DWORD;
dmMode: TDeviceMode;
lpdmMode: PDeviceMode;
lpPrintInfo2: PPrinterInfo2;
hPrinter: THandle;
PrinterName: String;
begin
// For demo only ** REPLACE WITH YOUR CODE **
PrinterName:=Printer.Print
// Set structure memory to nil
lpPrintInfo2:=nil;
// Open the printer
if (OpenPrinter(PChar(Printer
begin
// Get required memory size
GetPrinter(hPrinter, 2, lpPrintInfo2, 0, @dwSpaceNeeded);
// Allocate memory
lpPrintInfo2:=AllocMem(dwS
// Resource protection
try
// Get printer info
GetPrinter(hPrinter, 2, lpPrintInfo2, dwSpaceNeeded, @dwSpaceNeeded);
// Get dev mode size
dwDMSize:=DocumentProperti
// Allocate memory for the device mode
lpdmMode:=AllocMem(dwDMSiz
// Resource protection
try
DocumentProperties(Handle,
// Update the printer settings
ResetDC(hPrinter, lpdmMode^);
finally
// Free allocated memory
FreeMem(lpdmMode);
end;
finally
// Free allocated memory
FreeMem(lpPrintInfo2);
end;
// Close printer handle
ClosePrinter(hPrinter);
end;
end;
--
Regards,
Russell