C# 自定义组合框,GDI+;

C# 自定义组合框,GDI+;,c#,C#,我的BorderedComboBox中出现了一个问题“GDI+中发生了一般性错误”,它只出现在最终项目中(在新的WinForm应用程序中是可以的)。我想这是关于IntPtr的未管理和坏脾气,但我需要一些帮助来解决 出现错误的代码在以下位置停止: ControlPaint.DrawBorder(gdc, rectBorder, _BorderColor, ButtonBorderStyle.Solid); 提前感谢, using System; using System.Collections.

我的BorderedComboBox中出现了一个问题“GDI+中发生了一般性错误”,它只出现在最终项目中(在新的WinForm应用程序中是可以的)。我想这是关于IntPtr的未管理和坏脾气,但我需要一些帮助来解决

出现错误的代码在以下位置停止:

ControlPaint.DrawBorder(gdc, rectBorder, _BorderColor, ButtonBorderStyle.Solid);
提前感谢,

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

/* Simplified version of Eugenis, BorderedComboBox
 */
namespace mySpace
{
    public partial class BorderedComboBox : ComboBox
    {


        public BorderedComboBox()
            : base()
        {

            hDC = GetDC(Handle);
            gdc = Graphics.FromHdc(hDC);
            rectBorder = new Rectangle(0, 0, Width, Height);

            SetStyle(ControlStyles.DoubleBuffer, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.UserPaint, false);
        }

        private const int WM_ERASEBKGND = 0x14;
        private const int WM_PAINT = 0xF;
        private const int WM_NC_PAINT = 0x85;
        private const int WM_PRINTCLIENT = 0x318;
        private const int WM_MOUSEHOVER = 0x2A1;
        private const int WM_MOUSELEAVE = 0x2A3;

        private IntPtr hDC;
        private Graphics gdc;
        private Rectangle rectBorder;

        private Color _BorderColor = SystemColors.Window;

        [Category("BorderFocusStyle")]
        [Description("User-defined border color.")]
        public Color BorderColor
        {
            get
            {
                return _BorderColor;
            }
            set
            {
                _BorderColor = value;
                this.Refresh();
            }
        }


        protected override void WndProc(ref Message m)
        {
            if (this.DropDownStyle == ComboBoxStyle.Simple)
            {
                base.WndProc(ref m);
                return;
            }

            switch (m.Msg)
            {
                case WM_NC_PAINT:
                    break;
                case WM_PAINT:
                    base.WndProc(ref m);

                    ControlPaint.DrawBorder(gdc, rectBorder, _BorderColor, ButtonBorderStyle.Solid);
                    break;
                default:
                    base.WndProc(ref m);
                    break;
            }
        }


        [DllImport("user32")]
        private static extern IntPtr GetDC(IntPtr hWnd);

        [System.Runtime.InteropServices.DllImport("user32.dll", CharSet = CharSet.Auto)]
        extern static bool DestroyIcon(IntPtr hWnd);
    }
}
OnPaint()建议效果不好,背景不好等。 不过,这是一个工作版本,以防任何人需要。不确定是否要释放和销毁非托管IntPtr。谢谢你的建议

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

/* A color bordered combobox 
 */
namespace yo3hcv
{
    public partial class BorderedComboBox : ComboBox
    {

        public BorderedComboBox()
            : base()
        {

            SetStyle(ControlStyles.DoubleBuffer, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.UserPaint, false);


        }

        private const int WM_SIZE = 0x0005;
        private const int WM_SIZING = 0x0214;
        private const int WM_ERASEBKGND = 0x14;
        private const int WM_PAINT = 0xF;
        private const int WM_NC_PAINT = 0x85;
        private const int WM_PRINTCLIENT = 0x318;
        private const int WM_MOUSEHOVER = 0x2A1;
        private const int WM_MOUSELEAVE = 0x2A3;



        private Color _BorderColor = SystemColors.Window;
        //private Color _BorderColor = Color.Red;

        [Category("BorderFocusStyle")]
        [Description("User-defined border color.")]
        public Color BorderColor
        {
            get
            {
                return _BorderColor;
            }
            set
            {
                _BorderColor = value;
                Invalidate();
            }
        }


        protected override void OnGotFocus(System.EventArgs e)
        {
            Invalidate();
            base.OnGotFocus(e);
        }

        protected override void OnLostFocus(System.EventArgs e)
        {
            Invalidate();
            base.OnLostFocus(e);
        }

        protected override void OnResize(EventArgs e)
        {
            Invalidate();
            base.OnResize(e);
        }

        protected override void OnSelectedValueChanged(EventArgs e)
        {
            Invalidate();
            base.OnSelectedValueChanged(e);
        }

        protected override void WndProc(ref Message m)
        {
            IntPtr hDC;
            Graphics gdc;

            if (this.DropDownStyle == ComboBoxStyle.Simple)
            {
                base.WndProc(ref m);
                return;
            }

            switch (m.Msg)
            {
                case WM_NC_PAINT:
                    break;

                case WM_PAINT:
                    base.WndProc(ref m);

                    hDC = GetDC(this.Handle);
                    gdc = Graphics.FromHdc(hDC);


                    Rectangle rect = new Rectangle(0, 0, this.Width, this.Height);

                    ControlPaint.DrawBorder(gdc, rect, _BorderColor, ButtonBorderStyle.Solid);

                    ReleaseDC(m.HWnd, hDC);

                    break;
                default:
                    base.WndProc(ref m);
                    break;
            }
        }


        [DllImport("user32.dll")]
        static extern Int32 ReleaseDC(IntPtr hwnd, IntPtr hdc);

        [DllImport("user32")]
        private static extern IntPtr GetDC(IntPtr hWnd);


    }
}

你确定
句柄在c'tor中已经有效吗?@UweKeim它肯定无效。OP:你到底为什么要这样做,而不是覆盖
OnPaint
OnPaintBackground
,方法会给你
Graphics
实例?嗯。。不,我不是。但正如我所说,只有在复杂的项目中它才会崩溃,新的WinForm会像预期的那样工作,没有GDI+错误,因为ComboBox没有OnPaint@user1797147再查一遍<代码>组合框
继承自
控件
,每个
控件
都有
OnPaint
。请将信息编辑到问题本身中。
Post Answer
按钮只能用于向线程添加新的解决方案。