Setting private devmode data via Get/SetHdevmode?

  • Thread starter Thread starter Tom Demler
  • Start date Start date
T

Tom Demler

Our application prints in the background using settings
(including printer name and page size) it retrieves from
a database. We also need to include some proprietary info
in a private portion of the printer devmode. We have
created our own minidriver to use with the UniDrv printer
driver. So far we have been unable to make any changes to
the public or private portions of the devmode for a job
being printed from our application. Here's a snippet of
code:

PrintDocument pd = new PrintDocument();
// Use a standard print controller - to avoid the
status/cancel dialog
pd.PrintController = new StandardPrintController();
// Set the printer name (from the printer device object)
// This name must match the installed Windows printer.
pd.PrinterSettings.PrinterName = m_PrinterName;
if( !pd.PrinterSettings.IsValid )
{ // Log the error and then quit
if (s_Log.IsDebugEnabled)
s_Log.DebugError( string.Format( "Invalid
printer {0} for print job {1}; using default page size.",
m_PrinterName, m_PrintJob.JobUid ) );
// Throw an exception here
} }
// Get a handle to the devmode for this printer
IntPtr hDevMode = pd.PrinterSettings.GetHdevmode();
IntPtr pDevMode = GlobalLock( hDevMode );
// DEVMODE and OEMDEVMODE previously defined.
// Get a local copy
DEVMODE dm = (DEVMODE)Marshal.PtrToStructure
(pDevMode,typeof(DEVMODE));
// Calculate the offset to the oemdevmode
int offset = dm.dmSize + dm.dmDriverExtra
- Marshal.SizeOf( typeof(OEMDEVMODE) );
IntPtr pOemDevMode = (IntPtr)((int)pDevMode + offset);
// Retrieve the oemdevmode
OEMDEVMODE oemdevmode = (OEMDEVMODE)Marshal.PtrToStructure
(
pOemDevMode, typeof(OEMDEVMODE) );
// Add our changes
oemdevmode.dmDICOMsetting = 0x4344;
oemdevmode.dmPrinterID = m_PrintSheet.PrinterUid;
oemdevmode.dmJobID = m_PrintJob.JobUid;
// Save them to the unmanaged area
Marshal.StructureToPtr( dm, pDevMode, true );
Marshal.StructureToPtr( oemdevmode, pOemDevMode, true );
// Set the handle
pd.PrinterSettings.SetHdevmode( hDevMode );
GlobalUnlock( hDevMode );
GlobalFree( hDevMode );


We can successfully read the devmode - all of the default
settings look correct. It's just that setting our changes
doesn't seem to work. Any help would be appreciated.

Also, we've also tried using the win32 api method
DocumentProperties(). But this requires a printer handle.
If we open a printer I suspect that it will be a
different printer instance that the one associated with
our PrintDocument object.

Thanks,
Tom
 
Hello Tom,

Thanks for your post. As I understand, the problem you are facing is that
it does not work as expected after modifying DEVMODE (by calling
PrinterSettings.SetHdevmode). Please correct me if there is any
misunderstanding.

To narrow down the problem, I suggest you to create C/C++ MFC program and
check whether the printer driver handles DEVMODE properly. You can also
check the memory of hDevMode and see if DEVMODE was changed properly.

I look forward to your response.

Have a nice day!

Regards,

HuangTM
Microsoft Online Partner Support
MCSE/MCSD

Get Secure! ¨C www.microsoft.com/security
This posting is provided ¡°as is¡± with no warranties and confers no rights.
 
Hi Tom,

Thanks for your update. Since the same code works properly in Visual C++
app I believe the problem may lies in marshalling the structure. Could you
please tell me how you define DEVMODE and OEMDEVMODE? Is it send me a
sample project which will reproduce the problem with general printer
drivers?

I'm standing by for your response.

Have a nice day!

Regards,

HuangTM
Microsoft Online Partner Support
MCSE/MCSD

Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
Back
Top