Click here to Skip to main content
11,502,821 members (51,215 online)
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C# PInvoke printing .NET4
Hi all,

I am developing a windows forms application that selects client ID card designs by whatever client is selected in a datagridview, and then prints them on PVC ID cards using a Magicard Rio Pro card printer.

I want to handle all the printer settings within my application, so that the user does not need to worry about this, and the only setting that I need to control is portrait / landscape orientations.

I am handling the page orientation in my code using the PrinterSettings.DefaultPageSettings.Landscape = true/false, which works fine. But... it does not change the document (page), or in this case "card" orientation when a print job takes place, meaning it prints a landscape image on a portrait document. Now, if printing on A4 paper this is not a problem as there is plenty of room, however, on a small ID card this is not the case!

I have been searching for a solution but none are an easy feet.. I have see another post on CP () which works to some extent, not keen on displaying the printers dialogBox but at this stage I just want it to work.

When I run my application at present and process a print job, I set the orientation to landscape in the printer dialogBox that pops up but this does not change the default setting. In the other post mentioned above it is suggested that the new selected printer settings are not saved back to the defaultPrinterSettings, and when I step through my code it looks as though this is the case.

This is a new area for me re: printing and have only just come across DEVMODE a few days ago, and its quite a chunk to get my head round!

Could someone please help me out with a piece of sample code on how to save selected settings back to the DefaultPrinterSettings, and also how to add (if necessary) the orientation parameter ORIENT_LANDSCAPE.

Your help will be very very gratefully received.

<pre lang="c#">private void OpenPrinterPropertiesDialog()
        {
            var printerSettings = new System.Drawing.Printing.PrinterSettings();
            var printerName = printerSettings.PrinterName;
 
            IntPtr handle;
            OpenPrinter(printerName, out handle, IntPtr.Zero);
 
            IntPtr hDevMode = printerSettings.GetHdevmode(printerSettings.DefaultPageSettings);
            IntPtr pDevMode = GlobalLock(hDevMode);
            int sizeNeeded = DocumentProperties(this.Handle, IntPtr.Zero, printerSettings.PrinterName, IntPtr.Zero, pDevMode, 0);
            IntPtr devModeData = Marshal.AllocHGlobal(sizeNeeded);
            // opens Magicard dialog
            DocumentProperties(this.Handle, handle, printerName, devModeData, pDevMode, DM_IN_BUFFER | DM_PROMPT | DM_OUT_BUFFER);
 
            
            // need to save changes here!!!
            
            ClosePrinter(handle);
            GlobalUnlock(hDevMode);
 
            printerSettings.SetHdevmode(devModeData);
            printerSettings.DefaultPageSettings.SetHdevmode(devModeData);
 
            GlobalFree(hDevMode);
            Marshal.FreeHGlobal(devModeData);
        }
Posted 7-Jan-13 2:36am
Edited 7-Jan-13 2:37am
v2
Comments
Sergey Alexandrovich Kryukov at 7-Jan-13 20:05pm
   
Why, why? Standard print dialogs already allow to save preference — look thoroughly. Using P/Invoke kills the platform compatibility of your code, did you know that?
—SA

1 solution

Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

Hello,

You can use Marshal class and it methods PtrToStructure and StructureToPtr to convert your pDevMode IntPtr. The Unicode version of the structure DEVMODE will be:
[StructLayout(LayoutKind.Explicit,CharSet=CharSet.Unicode)]
public struct DEVMODEW
{
    [FieldOffset(0),MarshalAs(UnmanagedType.ByValTStr,SizeConst=32)]
    public string dmDeviceName;
    [FieldOffset(64),MarshalAs(UnmanagedType.U2)]
    public int dmSpecVersion;
    [FieldOffset(66),MarshalAs(UnmanagedType.U2)]
    public int dmDriverVersion;
    [FieldOffset(68),MarshalAs(UnmanagedType.U2)]
    public int dmSize;
    [FieldOffset(70),MarshalAs(UnmanagedType.U2)]
    public int dmDriverExtra;
    [FieldOffset(74),MarshalAs(UnmanagedType.U4)]
    public int dmFields;
    [FieldOffset(78),MarshalAs(UnmanagedType.I2)]
    public int dmOrientation;
    [FieldOffset(80),MarshalAs(UnmanagedType.I2)]
    public int dmPaperSize;
    [FieldOffset(82),MarshalAs(UnmanagedType.I2)]
    public int dmPaperLength;
    [FieldOffset(84),MarshalAs(UnmanagedType.I2)]
    public int dmPaperWidth;
    [FieldOffset(86),MarshalAs(UnmanagedType.I2)]
    public int dmScale;
    [FieldOffset(88),MarshalAs(UnmanagedType.I2)]
    public int dmCopies;
    [FieldOffset(90),MarshalAs(UnmanagedType.I2)]
    public int dmDefaultSource;
    [FieldOffset(92),MarshalAs(UnmanagedType.I2)]
    public int dmPrintQuality;
    [FieldOffset(78)]
    public Point dmPosition;
    [FieldOffset(86),MarshalAs(UnmanagedType.U4)]
    public int dmDisplayOrientation;
    [FieldOffset(90),MarshalAs(UnmanagedType.U4)]
    public int dmDisplayFixedOutput;
    [FieldOffset(94),MarshalAs(UnmanagedType.I2)]
    public int dmColor;
    [FieldOffset(96),MarshalAs(UnmanagedType.I2)]
    public int dmDuplex;
    [FieldOffset(98),MarshalAs(UnmanagedType.I2)]
    public int dmYResolution;
    [FieldOffset(100),MarshalAs(UnmanagedType.I2)]
    public int dmTTOption;
    [FieldOffset(102),MarshalAs(UnmanagedType.I2)]
    public int dmCollate;
    [FieldOffset(104),MarshalAs(UnmanagedType.ByValTStr,SizeConst=32)]
    public string dmFormName;
    [FieldOffset(168),MarshalAs(UnmanagedType.U2)]
    public int dmLogPixels;
    [FieldOffset(170),MarshalAs(UnmanagedType.U4)]
    public int dmBitsPerPel;
    [FieldOffset(174),MarshalAs(UnmanagedType.U4)]
    public int dmPelsWidth;
    [FieldOffset(178),MarshalAs(UnmanagedType.U4)]
    public int dmPelsHeight;
    [FieldOffset(182),MarshalAs(UnmanagedType.U4)]
    public int dmDisplayFlags;
    [FieldOffset(182),MarshalAs(UnmanagedType.U4)]
    public int dmNup;
    [FieldOffset(186),MarshalAs(UnmanagedType.U4)]
    public int dmDisplayFrequency;
    [FieldOffset(190),MarshalAs(UnmanagedType.U4)]
    public int dmICMMethod;
    [FieldOffset(194),MarshalAs(UnmanagedType.U4)]
    public int dmICMIntent;
    [FieldOffset(198),MarshalAs(UnmanagedType.U4)]
    public int dmMediaType;
    [FieldOffset(202),MarshalAs(UnmanagedType.U4)]
    public int dmDitherType;
    [FieldOffset(206),MarshalAs(UnmanagedType.U4)]
    public int dmReserved1;
    [FieldOffset(210),MarshalAs(UnmanagedType.U4)]
    public int dmReserved2;
    [FieldOffset(214),MarshalAs(UnmanagedType.U4)]
    public int dmPanningWidth;
    [FieldOffset(218),MarshalAs(UnmanagedType.U4)]
    public int dmPanningHeight;
}
Regards,
Maxim.
  Permalink  

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



Advertise | Privacy | Mobile
Web03 | 2.8.150520.1 | Last Updated 10 Jan 2013
Copyright © CodeProject, 1999-2015
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100