Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Need to capture a Printer's structure (number of copies, orientation...)


This question is not answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 8 - Last Post: Jul 4, 2014 5:18 AM Last Post By: Stephan St-Denis
Stephan St-Denis

Posts: 8
Registered: 6/18/00
Need to capture a Printer's structure (number of copies, orientation...)  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 3, 2014 7:36 AM
Hi Delphi gurus,

for years, I was able to capture a printer's structure using the _devicemodeW record found in Windows.pas. In my current program, written in Delphi XE, my code still works perfectly on Windows XP but fails on Windows 7 and 8.

I'm using a TPrinterSetupDialog named PrinterSetup.

Here's the code :

   if PrinterSetup.Execute() then begin
 
      // Get printer device mode handle.
      Printer.GetPrinter(ADevice, ADriver, APort, ADevMode);
 
      if ADevmode <> 0 then begin
         DevMode := GlobalLock(ADevmode);  // lock it to get pointer to DEVMODE record
 
         Pos := cbWinPort.Items.IndexOf(String(ADevice));
 
         if Pos <> -1 then begin
            aPrinters[lbDocuments.ItemIndex].WinPrinter := Pos;
            aPrinters[lbDocuments.ItemIndex].WinName    := String(ADevice);
            cbWinPort.ItemIndex                         := Pos;
         end;
 
         if Devmode <> nil then begin
            try
              // Save in our printer array for future use
               aPrinters[lbDocuments.ItemIndex].Duplex      := Devmode^.dmDuplex;
               aPrinters[lbDocuments.ItemIndex].PaperBin    := Devmode^.dmDefaultSource;
               aPrinters[lbDocuments.ItemIndex].PaperSize   := DevMode^.dmPaperSize;
               aPrinters[lbDocuments.ItemIndex].Orientation := DevMode^.dmOrientation;
               aPrinters[lbDocuments.ItemIndex].Copies      := DevMode^.dmCopies;
               aPrinters[lbDocuments.ItemIndex].UseCapture  := True;
            finally
               GlobalUnlock(ADevmode);   // unlock devmode handle.
            end;
         end;
      end;
   end;


What have changed in Windows 7-8 that worked well in XP so that I fix this problem ?

BTW, excuse my poor English.

Stéphan St-Denis
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Need to capture a Printer's structure (number of copies,orientation...)  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 3, 2014 10:35 AM   in response to: Stephan St-Denis in response to: Stephan St-Denis
Stephan wrote:

for years, I was able to capture a printer's structure using the
_devicemodeW record found in Windows.pas. In my current program,
written in Delphi XE, my code still works perfectly on Windows XP but
fails on Windows 7 and 8.

Fails in what way exactly? Please be more specific.

--
Remy Lebeau (TeamB)
Stephan St-Denis

Posts: 8
Registered: 6/18/00
Re: Need to capture a Printer's structure (number of copies,orientation...)  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 3, 2014 10:49 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Stephan wrote:

for years, I was able to capture a printer's structure using the
_devicemodeW record found in Windows.pas. In my current program,
written in Delphi XE, my code still works perfectly on Windows XP but
fails on Windows 7 and 8.

Fails in what way exactly? Please be more specific.

--
Remy Lebeau (TeamB)

Sorry, my question was indeed incomplete.

When PrinterSetup.Execute() returns, the DevMode structure doesn't contain the parameters I changed in the printer setup dialog. For example, if I changed the number of copies from 1 to 3 or changed the orientation from portrait to landscape, the DevMode structure won't reflect the changes. It works well in XP but the same code fails in Windows 7-8.

Thanks for taking your precious time to help me sort this problem out.

Stéphan St-Denis
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Need to capture a Printer's structure (number ofcopies,orientation...)  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 3, 2014 11:33 AM   in response to: Stephan St-Denis in response to: Stephan St-Denis
Stephan wrote:

When PrinterSetup.Execute() returns, the DevMode structure doesn't
contain the parameters I changed in the printer setup dialog. For
example, if I changed the number of copies from 1 to 3 or changed
the orientation from portrait to landscape, the DevMode structure
won't reflect the changes. It works well in XP but the same code fails in
Windows 7-8.

Does Printer.PrinterIndex point at the correct printer index? Does Printer.GetPrinter()
return a non-nil DevMode pointer? Did you verify the device name being returned
is the correct name for the printer you changed setting for?

--
Remy Lebeau (TeamB)
Stephan St-Denis

Posts: 8
Registered: 6/18/00
Re: Need to capture a Printer's structure (number ofcopies,orientation...)  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 3, 2014 12:11 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Stephan wrote:

When PrinterSetup.Execute() returns, the DevMode structure doesn't
contain the parameters I changed in the printer setup dialog. For
example, if I changed the number of copies from 1 to 3 or changed
the orientation from portrait to landscape, the DevMode structure
won't reflect the changes. It works well in XP but the same code fails in
Windows 7-8.

Does Printer.PrinterIndex point at the correct printer index? Does Printer.GetPrinter()
return a non-nil DevMode pointer? Did you verify the device name being returned
is the correct name for the printer you changed setting for?

--
Remy Lebeau (TeamB)

As you can see in the code below, after the PrinterSetup.Execute, I use the Printer's GetPrinter() procedure in order to retrieve the selected printer DevMode structure.

After the call to PrinterSetup.Execute, Printer.PrinterIndex points at the selected printer. Showmessage(String(ADevice)) shows the correct printer name.

I then compare DevMode against NIL to make sure I have a valid pointer to a structure.

I finally store the information I need from the DevMode structure in a local Array that I'll save later.

I also lock and unlock the handle during the operation to make sure everything is OK.

   if PrinterSetup.Execute() then begin
 
      // Get printer device mode handle.
      Printer.GetPrinter(ADevice, ADriver, APort, ADevMode);
 
      if ADevmode <> 0 then begin
         DevMode := GlobalLock(ADevmode);  // lock it to get pointer to DEVMODE record
 
         if Devmode <> nil then begin
            try
               aPrinters[lbDocuments.ItemIndex].Duplex      := Devmode^.dmDuplex;
               aPrinters[lbDocuments.ItemIndex].PaperBin    := Devmode^.dmDefaultSource;
               aPrinters[lbDocuments.ItemIndex].PaperSize   := DevMode^.dmPaperSize;
               aPrinters[lbDocuments.ItemIndex].Orientation := DevMode^.dmOrientation;
               aPrinters[lbDocuments.ItemIndex].Copies      := DevMode^.dmCopies;
               aPrinters[lbDocuments.ItemIndex].UseCapture  := True;
            finally
               GlobalUnlock(ADevmode);   // unlock devmode handle.
            end;
         end;
      end;
   end;
 


As I said, the same code works on Windows XP but fails on Windows 7-8.

Don't forget that I'm using Delphi XE, not XE6.

Thanks again for your help.
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Need to capture a Printer's structure (numberofcopies,orientation...)  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 3, 2014 12:47 PM   in response to: Stephan St-Denis in response to: Stephan St-Denis
Stephan wrote:

As you can see in the code below, after the PrinterSetup.Execute, I
use the Printer's GetPrinter() procedure in order to retrieve the
selected printer DevMode structure.

Do you have the same problem if you call the Win32 API PrintDlg() function
directly?

http://msdn.microsoft.com/en-us/library/windows/desktop/ms646940.aspx

If yes, then the behavior of the API changed.

If no, then TPrinter or TPrinterSetupDialog has a bug.

--
Remy Lebeau (TeamB)
Stephan St-Denis

Posts: 8
Registered: 6/18/00
Re: Need to capture a Printer's structure (numberofcopies,orientation...)  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 3, 2014 1:28 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Stephan wrote:

As you can see in the code below, after the PrinterSetup.Execute, I
use the Printer's GetPrinter() procedure in order to retrieve the
selected printer DevMode structure.

Do you have the same problem if you call the Win32 API PrintDlg() function
directly?

http://msdn.microsoft.com/en-us/library/windows/desktop/ms646940.aspx

If yes, then the behavior of the API changed.

If no, then TPrinter or TPrinterSetupDialog has a bug.

--
Remy Lebeau (TeamB)

I would have hoped not being forced to call the Win32 API directly but if I must, I'll go this way. It'll take some time to understand in full how it works. I'm not an expert in Native APIs, but I'll give it a try if I can't find any other solution.

Thank you for your help.
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Need to capture a Printer's structure(numberofcopies,orientation...)  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 3, 2014 2:13 PM   in response to: Stephan St-Denis in response to: Stephan St-Denis
Stephan wrote:

I would have hoped not being forced to call the Win32 API directly
but if I must, I'll go this way.

I was simply suggesting it as a debugging tool to rule out TPrinterSetupDialog
and/or TPrinter as the culprit.

--
Remy Lebeau (TeamB)
Stephan St-Denis

Posts: 8
Registered: 6/18/00
Re: Need to capture a Printer's structure(numberofcopies,orientation...)  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jul 4, 2014 5:18 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:
Stephan wrote:

I would have hoped not being forced to call the Win32 API directly
but if I must, I'll go this way.

I was simply suggesting it as a debugging tool to rule out TPrinterSetupDialog
and/or TPrinter as the culprit.

--
Remy Lebeau (TeamB)

Oh yes ! Don't worry. I do understand your point. I'll give it a try as soon as I find some free time to experiment with the API.

As i said in my first post... my English is not very good and I probably don't use the correct words and/or expressions. So sometimes, what I write is not exactly what I would like to say in my native language... which is French.

Thanks again !
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02