On the preview screen if I click on printer setup icon it shows HP
LaserJet2200 in the setup window with all of it's properties etc.
Has anyone seen this problem or have a solution?
Thanks IN Advance!
Alan
Reported by Jordan Russel
If your PC is connected to a network printer and the system hosting the
network printer
is not online, the following snippet of code likely will cause an access
violation
in GDI32.DLL:
uses
Printers;
procedure TForm1.Button1Click(Sender: TObject);
var
W: Integer;
begin
W := Printer.PageWidth; // AV on this line
Caption := IntToStr(W);
end;
I say "likely" because, as we all know, access violations can sometimes be
difficult
to reproduce, although on my Windows 2000 system the access violation occurs
almost every time.
The access violation is caused by a bug in the TPrinter.SetPrinter procedure
of Printers.pas, in this section of code:
DeviceMode := GlobalAlloc(GHND,
DocumentProperties(0, FPrinterHandle, ADevice, StubDevMode,
StubDevMode, 0));
if DeviceMode <> 0 then
begin
DevMode := GlobalLock(DeviceMode);
if DocumentProperties(0, FPrinterHandle, ADevice, DevMode^,
DevMode^, DM_OUT_BUFFER) < 0 then
begin
GlobalUnlock(DeviceMode);
GlobalFree(DeviceMode);
DeviceMode := 0;
end
end;
Notice that if DocumentProperties fails (returns < 0), DeviceMode is freed,
but DevMode is never reset back to "nil". Certain functions of TPrinter will
then pass this now-invalid pointer to GDI functions, resulting in access
violations.
I also tested on Delphi 1 but was not able to reproduce the bug, however
that
isn't to say the same bug isn't there, since I don't have access to the
Delphi 1 VCL source code to check.
Workaround / Fix
The solution requires modifying Printers.pas. To fix the bug,
you simply need to add a "DevMode := nil;" line above the
GlobalUnlock call, i.e.:
DeviceMode := GlobalAlloc(GHND,
DocumentProperties(0, FPrinterHandle, ADevice, StubDevMode,
StubDevMode, 0));
if DeviceMode <> 0 then
begin
DevMode := GlobalLock(DeviceMode);
if DocumentProperties(0, FPrinterHandle, ADevice, DevMode^,
DevMode^, DM_OUT_BUFFER) < 0 then
begin
DevMode := nil; // ADD THIS LINE
GlobalUnlock(DeviceMode);
GlobalFree(DeviceMode);
DeviceMode := 0;
end
end;
If you decide to make this change, you might as well fix a similar bug in
the same procedure too.
At the top of the procedure, there is another instance where DeviceMode is
freed,
but DevMode is not reset back to "nil":
if ADeviceMode <> DeviceMode then
begin // free the devmode block we have, and take the one we're given
if DeviceMode <> 0 then
begin
DevMode := nil; // ADD THIS LINE
GlobalUnlock(DeviceMode);
GlobalFree(DeviceMode);
end;
DeviceMode := ADeviceMode;
end;
I haven't personally seen an access violation occur from this second bug,
but the same potential is there.
Printers.Pas bug: 'There is no default printer currently selected'
http://buglist.jrsoftware.org/generated/entry0616.htm
Reported by Eivind Bakkestuen
Even if the machine in question does have a default network printer
selected, this message would crop up and the user would have to select
a local printer manually within our program to be able to print.
Reproducing it: it's probably related to using login script functionality
to get the list of printers from the server upon workstation startup.
It is a bug, since the machine most definitely does have a default
printer selected (that it is a network printer shouldn't matter).
Cause:
The TPrinter.SetToDefaultPrinter routine in Printers.Pas makes an
assumption that all printer names returned from win32 api functions
will always be capitalized exactly the same. It is this line inside
the loop that determines the default printer (line 867 in D5's printers.pas)
that's the cause of the problem:
if TPrinterDevice(Objects[I]).Device = Device then
After perusing a log file from the client, generated by a log-enabled
version
of this routine, it turned out that Device was something like
"HP Printer something" while the devicelist contained "HP PRINTER
SOMETHING",
leading the comparison to fail.
Workaround / Fix
The workaround is simple enough: I stuck an AnsiUpperCase() call
on each side of the equals sign, and then the default printer
was recognized as such.
"Alan Miller" <amil...@san.rr.com> schreef in bericht
news:3DD3E2FC...@san.rr.com...
> a simple solution in win 2000 is to use print.execute instead of
> preview.execute.
> in win xp this does not solve the problem.
Gert, we'd all appreciate it if you would not quote 160 lines of text
to make a 3 line response.
--
Bill
"No man's life, liberty or property are safe while the legislature is in
session." - Mark Twain
http://www.borland.com/newsgroups/ Borland newsgroup descriptions
http://www.borland.com/newsgroups/netiquette.html netiquette
regards,
alan
This has to do with the PaperSize property of the QuickReport control. To
rectify it,try this:
Select the QuickReport control; go the the object inspector and open the
Page property.Then set the PaperSize property to A4.
I'm sure this property is set to letter,that's why.
emmanuel
This has to do with the PaperSize property of the QuickReport control. To
rectify it,try this:
Select the QuickReport control; go the the object inspector and open the
Page property.Then set the PaperSize property to A4.
I'm sure this property is set to letter,that's why.
emmanuel
This might or might not be related but I've been working through a
printers.pas issue where you get a "no default printer" (or no printing at
all) errors, but the code
GetProfileString('windows', 'device', '', DefaultPrinter,
SizeOf(DefaultPrinter) - 1);
returns a valid default printer...(although if I look in Settings..Printers
I don't see any of my printers checked as the default printer).
What seems to be happening is that when printers.pas is asked to
SetToDefaultPrinter it tries to match a printer name from its list printers
to the name returned by GetProfileString above. BUT, if an application such
as MS-Word executes a VBA script such as :
Application.ActivePrinter =
"\\MyLocalMachineName\DocumentsAdmin"
then the DefaultPrinter returned by GetProfileString changes to
\\MyLocalMachineName\DocumentsAdmin and not just the printer name
"DocumentsAdmin" - the code that looks through the printer names in
SetToDefaultPrinter will never find this "local" printer.
The workaround I've put in place at the moment is to modify
SetToDefaultPrinter to first check to see if the printer returned by
GetProfileString has a full UNC path, if so, any printers that don't have a
UNC path are prefixed with the UNC of the local computer name.
I'm now able to print to the default printer returned to GetProfileString
regardless of whether Settings..Printers has a default printer set or not.
If may be that there is a similar issue with your network printer.
Regards,
Jeremy.
"Alan Miller" <amil...@san.rr.com> wrote in message
news:3DD3E2FC...@san.rr.com...