Tom,
>1) I need to set some data in the OEMDEVMODE portion of the private
>devmode section. Using the GetHdevmode method of the PrinterSettings
[quoted text clipped - 8 lines]
>the standard devmode, do some pointer math, and then retrieve just the
>OEMDEVMODE?
Absolutely. If I got everything rigth, you should find your OEMDEVMODE
like this
IntPtr hDevMode = printerSettings.GetHdevmode();
IntPtr pDevMode = GlobalLock( hDevMode );
DEVMODE devmode = (DEVMODE)Marshal.PtrToStructure( pDevMode,
typeof(DEVMODE) );
int offset = devmode.dmSize + devmode.dmDriverExtra
- Marshal.SizeOf( typeof(OEMDEVMODE) );
IntPtr pOemDevMode = (IntPtr)((int)pDevMode + offset);
OEMDEVMODE oemdevmode = (OEMDEVMODE)Marshal.PtrToStructure(
pOemDevMode, typeof(OEMDEVMODE) );
>However, unlike the success I had
>in retrieving the standard devmode using the GetHdevmode method, the
>data retrieved using the GetHdevnames doesn't look right.
I looked at the GetHdevnames implementation with Anakrino, and it does
look broken, so I'm not surprised you get back unexpected data. It
calculates the offset of the end of the structure as
(8/Marshal.System.DefaultCharSize) (8 being the size of DEVNAMES), so
that explains why you get 4 as the first offset running on a Unicode
OS. It also writes the strings in Unicode format when running on a
Unicode OS, which I think is incorrect (DEVNAMES should be ANSI
strings only AFAICT). I suggest you report this as a bug to Microsoft
and see if there's a fix available.
>Even if the offsets looked
>correct, I'd have to know how to use them (more pointer math?) to
>retrieve the strings.
string driverName = Marshal.PtrToStringAnsi((IntPtr)((int)pDevNames +
devnames.dnDriverOffset));
string deviceName = Marshal.PtrToStringAnsi((IntPtr)((int)pDevNames +
devnames.dnDeviceOffset));
string outputPort = Marshal.PtrToStringAnsi((IntPtr)((int)pDevNames +
devnames.dnOutputOffset));
Mattias

Signature
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/
Please reply only to the newsgroup.
Mattias Sj?gren - 18 Jul 2003 16:01 GMT
>>However, unlike the success I had
>>in retrieving the standard devmode using the GetHdevmode method, the
[quoted text clipped - 9 lines]
>strings only AFAICT). I suggest you report this as a bug to Microsoft
>and see if there's a fix available.
Forget all that. I did some testing, and I was obviously wrong, and
the GetHdevnames implementation is probably correct after all.
To get the correct string byte offset, multiply the value in the
DEVNAMES struct with Marshal.SystemDefaultCharSize.
>string driverName = Marshal.PtrToStringAnsi((IntPtr)((int)pDevNames +
>devnames.dnDriverOffset));
>string deviceName = Marshal.PtrToStringAnsi((IntPtr)((int)pDevNames +
>devnames.dnDeviceOffset));
>string outputPort = Marshal.PtrToStringAnsi((IntPtr)((int)pDevNames +
>devnames.dnOutputOffset));
So this should actually be
string driverName = Marshal.PtrToStringAnsi((IntPtr)((int)pDevNames +
devnames.dnDriverOffset*Marshal.SystemDefaultCharSize));
string deviceName = Marshal.PtrToStringAnsi((IntPtr)((int)pDevNames +
devnames.dnDeviceOffset*Marshal.SystemDefaultCharSize));
string outputPort = Marshal.PtrToStringAnsi((IntPtr)((int)pDevNames +
devnames.dnOutputOffset*Marshal.SystemDefaultCharSize));
Mattias

Signature
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/
Please reply only to the newsgroup.
Mattias Sj?gren - 18 Jul 2003 16:05 GMT
>string driverName = Marshal.PtrToStringAnsi((IntPtr)((int)pDevNames +
>devnames.dnDriverOffset*Marshal.SystemDefaultCharSize));
>string deviceName = Marshal.PtrToStringAnsi((IntPtr)((int)pDevNames +
>devnames.dnDeviceOffset*Marshal.SystemDefaultCharSize));
>string outputPort = Marshal.PtrToStringAnsi((IntPtr)((int)pDevNames +
>devnames.dnOutputOffset*Marshal.SystemDefaultCharSize));
Damn, I can't anything right today. All those PtrToStringAnsi should
actually be PtrToStringAuto.
Mattias

Signature
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/
Please reply only to the newsgroup.
Hello,
Can you share how you solved your problem??
I am trying to read public and private DEVMODE structures
using GethDevMode and SethDevMode commands of PrinterSettings.
This thing has stumped me.
Thanks.
heino
> Answering my question may require some familiarity with printer
> drivers in addition to interop. I'm trying to implement some interop
[quoted text clipped - 49 lines]
> Thanks,
> Tom Demler