/// <summary>
        /// Defines the common dialog box hook procedure that is overridden to add specific functionality to a common dialog box.
        /// </summary>
        /// <returns>
        /// A zero value if the default dialog box procedure processes the message; a nonzero value if the default dialog box procedure ignores the message.
        /// </returns>
        /// <param name="hWnd">The handle to the dialog box window. </param><param name="msg">The message being received. </param><param name="wparam">Additional information about the message. </param><param name="lparam">Additional information about the message. </param>
        protected override IntPtr HookProc(IntPtr hWnd, int msg, IntPtr wparam, IntPtr lparam)
        {
            // This code is lifted directly from System.Windows.Forms.FontDialog

            switch (msg)
            {
            case NativeMethods.WM_COMMAND:
                if ((int)wparam == 0x402)
                {
                    NativeMethods.LOGFONT lf = new NativeMethods.LOGFONT();
                    NativeMethods.SendMessage(new HandleRef(null, hWnd), NativeMethods.WM_CHOOSEFONT_GETLOGFONT, 0, lf);
                    this.UpdateFont(lf);
                    int index = (int)NativeMethods.SendDlgItemMessage(new HandleRef(null, hWnd), 0x473, NativeMethods.CB_GETCURSEL, IntPtr.Zero, IntPtr.Zero);
                    if (index != NativeMethods.CB_ERR)
                    {
                        this.UpdateColor((int)NativeMethods.SendDlgItemMessage(new HandleRef(null, hWnd), 0x473, NativeMethods.CB_GETITEMDATA, (IntPtr)index, IntPtr.Zero));
                    }

                    try
                    {
                        this.OnApply(EventArgs.Empty);
                    }
                    catch (Exception e)
                    {
                        Application.OnThreadException(e);
                    }
                }
                break;

            case NativeMethods.WM_INITDIALOG:
                if (!this.ShowColor)
                {
                    IntPtr hWndCtl = NativeMethods.GetDlgItem(new HandleRef(null, hWnd), NativeMethods.cmb4);
                    NativeMethods.ShowWindow(new HandleRef(null, hWndCtl), NativeMethods.SW_HIDE);
                    hWndCtl = NativeMethods.GetDlgItem(new HandleRef(null, hWnd), NativeMethods.stc4);
                    NativeMethods.ShowWindow(new HandleRef(null, hWndCtl), NativeMethods.SW_HIDE);
                }
                break;
            }

            return(base.HookProc(hWnd, msg, wparam, lparam));
        }
        /// <summary>
        /// Updates the font described by the specified LOGFONT structure
        /// </summary>
        /// <param name="lf"> The source font. </param>
        private void UpdateFont(NativeMethods.LOGFONT lf)
        {
            Font font;

            try
            {
                // This one line is the whole point of having to write this class as it can
                // throw an exception, which System.Windows.Forms.FontDialog doesn't handle

                font = Font.FromLogFont(lf);
            }
            catch
            {
                font = null;
            }

            if (font != null)
            {
                this.Font = font;
            }
        }
        /// <summary>
        /// When overridden in a derived class, specifies a common dialog box.
        /// </summary>
        /// <returns>
        /// true if the dialog box was successfully run; otherwise, false.
        /// </returns>
        /// <param name="hwndOwner">A value that represents the window handle of the owner window for the common dialog box. </param>
        protected override bool RunDialog(IntPtr hwndOwner)
        {
            NativeMethods.LOGFONT    lf;
            NativeMethods.CHOOSEFONT cf;
            IntPtr plf;
            bool   result;
            int    minSize;
            int    maxSize;
            bool   showColor;

            lf = new NativeMethods.LOGFONT();

            this.Font.ToLogFont(lf);

            plf = Marshal.AllocHGlobal(Marshal.SizeOf(lf));
            Marshal.StructureToPtr(lf, plf, false);

            showColor = this.ShowColor || this.ShowEffects;

            cf             = new NativeMethods.CHOOSEFONT();
            cf.lStructSize = Marshal.SizeOf(typeof(NativeMethods.CHOOSEFONT));
            cf.Flags       = this.GetFlags();
            cf.hwndOwner   = hwndOwner;
            cf.lpfnHook    = this.HookProc;

            minSize = this.MinSize;
            maxSize = this.MaxSize;
            if (minSize > 0 || maxSize > 0)
            {
                cf.nSizeMin = minSize;
                cf.nSizeMax = maxSize > 0 ? maxSize : int.MaxValue;
            }

            cf.rgbColors = ColorTranslator.ToWin32(showColor ? this.Color : Color.Black);

            cf.lpLogFont = plf;

            try
            {
                result = NativeMethods.ChooseFont(ref cf);

                if (result)
                {
                    // create a managed font from the updated LOGFONT
                    lf = (NativeMethods.LOGFONT)Marshal.PtrToStructure(plf, typeof(NativeMethods.LOGFONT));
                    if (!string.IsNullOrEmpty(lf.lfFaceName))
                    {
                        this.UpdateFont(lf);
                    }

                    // and update the color
                    if (showColor)
                    {
                        this.UpdateColor(cf.rgbColors);
                    }
                }
            }
            finally
            {
                // always be freein' allocated memory!
                Marshal.FreeHGlobal(plf);
            }

            return(result);
        }