protected unsafe override bool RunDialog(IntPtr hwndOwner) { var hookProcPtr = new User32.WNDPROCINT(HookProc); var cc = new Comdlg32.CHOOSECOLORW { lStructSize = (uint)Marshal.SizeOf <Comdlg32.CHOOSECOLORW>() }; IntPtr custColorPtr = Marshal.AllocCoTaskMem(64); try { Marshal.Copy(_customColors, 0, custColorPtr, 16); cc.hwndOwner = hwndOwner; cc.hInstance = Instance; cc.rgbResult = ColorTranslator.ToWin32(_color); cc.lpCustColors = custColorPtr; Comdlg32.CC flags = (Comdlg32.CC)Options | Comdlg32.CC.RGBINIT | Comdlg32.CC.ENABLEHOOK; // Our docs say AllowFullOpen takes precedence over FullOpen; ChooseColor implements the opposite if (!AllowFullOpen) { flags &= ~Comdlg32.CC.FULLOPEN; } cc.Flags = flags; cc.lpfnHook = hookProcPtr; if (!Comdlg32.ChooseColorW(ref cc).IsTrue()) { return(false); } if (cc.rgbResult != ColorTranslator.ToWin32(_color)) { _color = ColorTranslator.FromOle(cc.rgbResult); } Marshal.Copy(custColorPtr, _customColors, 0, 16); return(true); } finally { Marshal.FreeCoTaskMem(custColorPtr); } }
private unsafe bool ShowPrintDialog(IntPtr hwndOwner) { PRINTDLGW data; if (IntPtr.Size == 4) { data = new PRINTDLGW_32 { lStructSize = (uint)sizeof(PRINTDLGW_32) }; } else { data = new PRINTDLGW_64 { lStructSize = (uint)sizeof(PRINTDLGW_64) }; } data.nFromPage = 1; data.nToPage = 1; data.nMinPage = 0; data.nMaxPage = 9999; data.Flags = GetFlags(); data.nCopies = (ushort)PrinterSettings.Copies; data.hwndOwner = hwndOwner; User32.WNDPROCINT wndproc = new User32.WNDPROCINT(HookProc); data.lpfnPrintHook = Marshal.GetFunctionPointerForDelegate(wndproc); try { if (PageSettings is null) { data.hDevMode = PrinterSettings.GetHdevmode(); } else { data.hDevMode = PrinterSettings.GetHdevmode(PageSettings); } data.hDevNames = PrinterSettings.GetHdevnames(); } catch (InvalidPrinterException) { // Leave those fields null; Windows will fill them in data.hDevMode = IntPtr.Zero; data.hDevNames = IntPtr.Zero; } try { // Windows doesn't like it if page numbers are invalid if (AllowSomePages) { if (PrinterSettings.FromPage < PrinterSettings.MinimumPage || PrinterSettings.FromPage > PrinterSettings.MaximumPage) { throw new ArgumentException(string.Format(SR.PDpageOutOfRange, "FromPage")); } if (PrinterSettings.ToPage < PrinterSettings.MinimumPage || PrinterSettings.ToPage > PrinterSettings.MaximumPage) { throw new ArgumentException(string.Format(SR.PDpageOutOfRange, "ToPage")); } if (PrinterSettings.ToPage < PrinterSettings.FromPage) { throw new ArgumentException(string.Format(SR.PDpageOutOfRange, "FromPage")); } data.nFromPage = (ushort)PrinterSettings.FromPage; data.nToPage = (ushort)PrinterSettings.ToPage; data.nMinPage = (ushort)PrinterSettings.MinimumPage; data.nMaxPage = (ushort)PrinterSettings.MaximumPage; } if (PrintDlg(ref data).IsFalse()) { var result = CommDlgExtendedError(); return(false); } UpdatePrinterSettings(data.hDevMode, data.hDevNames, (short)data.nCopies, data.Flags, settings, PageSettings); PrintToFile = (data.Flags & PD.PRINTTOFILE) != 0; PrinterSettings.PrintToFile = PrintToFile; if (AllowSomePages) { PrinterSettings.FromPage = data.nFromPage; PrinterSettings.ToPage = data.nToPage; } // When the flag PD_USEDEVMODECOPIESANDCOLLATE is not set, // PRINTDLG.nCopies or PRINTDLG.nCopies indicates the number of copies the user wants // to print, and the PD_COLLATE flag in the Flags member indicates // whether the user wants to print them collated. if ((data.Flags & PD.USEDEVMODECOPIESANDCOLLATE) == 0) { PrinterSettings.Copies = (short)data.nCopies; PrinterSettings.Collate = (data.Flags & PD.COLLATE) == PD.COLLATE; } return(true); } finally { GC.KeepAlive(wndproc); Kernel32.GlobalFree(data.hDevMode); Kernel32.GlobalFree(data.hDevNames); } }