/// <summary>
        /// Copies the relevant information out of the handle and into the PageSettings.
        /// </summary>
        public void SetHdevmode(IntPtr hdevmode)
        {
            if (hdevmode == IntPtr.Zero)
            {
                throw new ArgumentException(SR.Format(SR.InvalidPrinterHandle, hdevmode));
            }

            IntPtr pointer = Interop.Kernel32.GlobalLock(hdevmode);

            Interop.Gdi32.DEVMODE mode = (Interop.Gdi32.DEVMODE)Marshal.PtrToStructure(pointer, typeof(Interop.Gdi32.DEVMODE)) !;

            if ((mode.dmFields & SafeNativeMethods.DM_COLOR) == SafeNativeMethods.DM_COLOR)
            {
                _color = (mode.dmColor == SafeNativeMethods.DMCOLOR_COLOR);
            }

            if ((mode.dmFields & SafeNativeMethods.DM_ORIENTATION) == SafeNativeMethods.DM_ORIENTATION)
            {
                _landscape = (mode.dmOrientation == SafeNativeMethods.DMORIENT_LANDSCAPE);
            }

            _paperSize         = PaperSizeFromMode(mode);
            _paperSource       = PaperSourceFromMode(mode);
            _printerResolution = PrinterResolutionFromMode(mode);

            Interop.Kernel32.GlobalUnlock(hdevmode);
        }
 private PrinterResolution PrinterResolutionFromMode(Interop.Gdi32.DEVMODE mode)
 {
     PrinterResolution[] resolutions = printerSettings.Get_PrinterResolutions();
     for (int i = 0; i < resolutions.Length; i++)
     {
         if (mode.dmPrintQuality >= 0 && ((mode.dmFields & SafeNativeMethods.DM_PRINTQUALITY) == SafeNativeMethods.DM_PRINTQUALITY) &&
             ((mode.dmFields & SafeNativeMethods.DM_YRESOLUTION) == SafeNativeMethods.DM_YRESOLUTION))
         {
             if (resolutions[i].X == unchecked ((int)(PrinterResolutionKind)mode.dmPrintQuality) &&
                 resolutions[i].Y == unchecked ((int)(PrinterResolutionKind)mode.dmYResolution))
             {
                 return(resolutions[i]);
             }
         }
         else
         {
             if ((mode.dmFields & SafeNativeMethods.DM_PRINTQUALITY) == SafeNativeMethods.DM_PRINTQUALITY)
             {
                 if (resolutions[i].Kind == (PrinterResolutionKind)mode.dmPrintQuality)
                 {
                     return(resolutions[i]);
                 }
             }
         }
     }
     return(new PrinterResolution(PrinterResolutionKind.Custom,
                                  mode.dmPrintQuality, mode.dmYResolution));
 }
        private PaperSize GetPaperSize(IntPtr modeHandle)
        {
            if (_paperSize == null)
            {
                bool ownHandle = false;
                if (modeHandle == IntPtr.Zero)
                {
                    modeHandle = printerSettings.GetHdevmode();
                    ownHandle  = true;
                }

                IntPtr modePointer         = Interop.Kernel32.GlobalLock(modeHandle);
                Interop.Gdi32.DEVMODE mode = (Interop.Gdi32.DEVMODE)Marshal.PtrToStructure(modePointer, typeof(Interop.Gdi32.DEVMODE)) !;

                PaperSize result = PaperSizeFromMode(mode);

                Interop.Kernel32.GlobalUnlock(modeHandle);

                if (ownHandle)
                {
                    Interop.Kernel32.GlobalFree(modeHandle);
                }

                return(result);
            }
            else
            {
                return(_paperSize);
            }
        }
 private PaperSource PaperSourceFromMode(Interop.Gdi32.DEVMODE mode)
 {
     PaperSource[] sources = printerSettings.Get_PaperSources();
     if ((mode.dmFields & SafeNativeMethods.DM_DEFAULTSOURCE) == SafeNativeMethods.DM_DEFAULTSOURCE)
     {
         for (int i = 0; i < sources.Length; i++)
         {
             // the dmDefaultSource == to the RawKind in the Papersource.. and Not the Kind...
             // if the PaperSource is populated with CUSTOM values...
             if (unchecked ((short)sources[i].RawKind) == mode.dmDefaultSource)
             {
                 return(sources[i]);
             }
         }
     }
     return(new PaperSource((PaperSourceKind)mode.dmDefaultSource, "unknown"));
 }
 private PaperSize PaperSizeFromMode(Interop.Gdi32.DEVMODE mode)
 {
     PaperSize[] sizes = printerSettings.Get_PaperSizes();
     if ((mode.dmFields & SafeNativeMethods.DM_PAPERSIZE) == SafeNativeMethods.DM_PAPERSIZE)
     {
         for (int i = 0; i < sizes.Length; i++)
         {
             if ((int)sizes[i].RawKind == mode.dmPaperSize)
             {
                 return(sizes[i]);
             }
         }
     }
     return(new PaperSize(PaperKind.Custom, "custom",
                          //mode.dmPaperWidth, mode.dmPaperLength);
                          PrinterUnitConvert.Convert(mode.dmPaperWidth, PrinterUnit.TenthsOfAMillimeter, PrinterUnit.Display),
                          PrinterUnitConvert.Convert(mode.dmPaperLength, PrinterUnit.TenthsOfAMillimeter, PrinterUnit.Display)));
 }
        /// <summary>
        /// Copies the relevant information out of the PageSettings and into the handle.
        /// </summary>
        public void CopyToHdevmode(IntPtr hdevmode)
        {
            IntPtr modePointer = Interop.Kernel32.GlobalLock(hdevmode);

            Interop.Gdi32.DEVMODE mode = (Interop.Gdi32.DEVMODE)Marshal.PtrToStructure(modePointer, typeof(Interop.Gdi32.DEVMODE)) !;

            if (_color.IsNotDefault && ((mode.dmFields & SafeNativeMethods.DM_COLOR) == SafeNativeMethods.DM_COLOR))
            {
                mode.dmColor = unchecked ((short)(((bool)_color) ? SafeNativeMethods.DMCOLOR_COLOR : SafeNativeMethods.DMCOLOR_MONOCHROME));
            }
            if (_landscape.IsNotDefault && ((mode.dmFields & SafeNativeMethods.DM_ORIENTATION) == SafeNativeMethods.DM_ORIENTATION))
            {
                mode.dmOrientation = unchecked ((short)(((bool)_landscape) ? SafeNativeMethods.DMORIENT_LANDSCAPE : SafeNativeMethods.DMORIENT_PORTRAIT));
            }

            if (_paperSize != null)
            {
                if ((mode.dmFields & SafeNativeMethods.DM_PAPERSIZE) == SafeNativeMethods.DM_PAPERSIZE)
                {
                    mode.dmPaperSize = unchecked ((short)_paperSize.RawKind);
                }

                bool setWidth  = false;
                bool setLength = false;

                if ((mode.dmFields & SafeNativeMethods.DM_PAPERLENGTH) == SafeNativeMethods.DM_PAPERLENGTH)
                {
                    // dmPaperLength is always in tenths of millimeter but paperSizes are in hundredth of inch ..
                    // so we need to convert :: use PrinterUnitConvert.Convert(value, PrinterUnit.TenthsOfAMillimeter /*fromUnit*/, PrinterUnit.Display /*ToUnit*/)
                    int length = PrinterUnitConvert.Convert(_paperSize.Height, PrinterUnit.Display, PrinterUnit.TenthsOfAMillimeter);
                    mode.dmPaperLength = unchecked ((short)length);
                    setLength          = true;
                }
                if ((mode.dmFields & SafeNativeMethods.DM_PAPERWIDTH) == SafeNativeMethods.DM_PAPERWIDTH)
                {
                    int width = PrinterUnitConvert.Convert(_paperSize.Width, PrinterUnit.Display, PrinterUnit.TenthsOfAMillimeter);
                    mode.dmPaperWidth = unchecked ((short)width);
                    setWidth          = true;
                }

                if (_paperSize.Kind == PaperKind.Custom)
                {
                    if (!setLength)
                    {
                        mode.dmFields |= SafeNativeMethods.DM_PAPERLENGTH;
                        int length = PrinterUnitConvert.Convert(_paperSize.Height, PrinterUnit.Display, PrinterUnit.TenthsOfAMillimeter);
                        mode.dmPaperLength = unchecked ((short)length);
                    }
                    if (!setWidth)
                    {
                        mode.dmFields |= SafeNativeMethods.DM_PAPERWIDTH;
                        int width = PrinterUnitConvert.Convert(_paperSize.Width, PrinterUnit.Display, PrinterUnit.TenthsOfAMillimeter);
                        mode.dmPaperWidth = unchecked ((short)width);
                    }
                }
            }

            if (_paperSource != null && ((mode.dmFields & SafeNativeMethods.DM_DEFAULTSOURCE) == SafeNativeMethods.DM_DEFAULTSOURCE))
            {
                mode.dmDefaultSource = unchecked ((short)_paperSource.RawKind);
            }

            if (_printerResolution != null)
            {
                if (_printerResolution.Kind == PrinterResolutionKind.Custom)
                {
                    if ((mode.dmFields & SafeNativeMethods.DM_PRINTQUALITY) == SafeNativeMethods.DM_PRINTQUALITY)
                    {
                        mode.dmPrintQuality = unchecked ((short)_printerResolution.X);
                    }
                    if ((mode.dmFields & SafeNativeMethods.DM_YRESOLUTION) == SafeNativeMethods.DM_YRESOLUTION)
                    {
                        mode.dmYResolution = unchecked ((short)_printerResolution.Y);
                    }
                }
                else
                {
                    if ((mode.dmFields & SafeNativeMethods.DM_PRINTQUALITY) == SafeNativeMethods.DM_PRINTQUALITY)
                    {
                        mode.dmPrintQuality = unchecked ((short)_printerResolution.Kind);
                    }
                }
            }

            Marshal.StructureToPtr(mode, modePointer, false);

            // It's possible this page has a DEVMODE for a different printer than the DEVMODE passed in here
            // (Ex: occurs when Doc.DefaultPageSettings.PrinterSettings.PrinterName != Doc.PrinterSettings.PrinterName)
            //
            // if the passed in devmode has fewer bytes than our buffer for the extrainfo, we want to skip the merge as it will cause
            // a buffer overrun
            if (mode.dmDriverExtra >= ExtraBytes)
            {
                int retCode = Interop.Winspool.DocumentProperties(NativeMethods.NullHandleRef, NativeMethods.NullHandleRef, printerSettings.PrinterName, modePointer, modePointer, SafeNativeMethods.DM_IN_BUFFER | SafeNativeMethods.DM_OUT_BUFFER);
                if (retCode < 0)
                {
                    Interop.Kernel32.GlobalFree(modePointer);
                }
            }

            Interop.Kernel32.GlobalUnlock(hdevmode);
        }