winforms 如何使用ControlPaint.DrawBorder方法修改组合框的边框颜色?

isr3a4wc  于 2022-11-16  发布在  其他
关注(0)|答案(1)|浏览(142)

我需要设置Combobox控件的边框颜色。
我在Google上搜索了一个实现ControlPaint.Drawborder的示例代码。
我发现的并不理想,边框的颜色没有修改。
在下面的代码中,您将看到两个键函数WndProcPaintControlBorder(),它们用于接收底层windows事件并处理它们。
后者用于绘制控件的边框,用Visual Studio调试后,我发现PaintControlBorder()函数中的代码被执行了。
为什么边框颜色不变?

[ToolboxItem(true)]
public class ModifiedComboBox : ComboBox
{
    new public System.Windows.Forms.DrawMode DrawMode { get; set; }
    public Color HighlightColor { get; set; } //set select item highlight color 
    private IntPtr hDC;
    private Graphics gdc;
    private const int WM_ERASEBKGND = 0x14; // some windows message id 
    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;

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

    public ModifiedComboBox()
    {
        hDC = GetDC(Handle);
        gdc = Graphics.FromHdc(hDC);
        SetStyle(ControlStyles.Selectable, false);
        base.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
        this.HighlightColor = Color.Gray;
        this.DrawItem += new DrawItemEventHandler(AdvancedComboBox_DrawItem); //t bind draw item handler

        rectale = new Rectangle(0, 0, Width, Height);
    }

    public void AdvancedComboBox_DrawItem(object sender, DrawItemEventArgs e)
    {
        if (e.Index < 0)
            return;

        ComboBox combo = sender as ComboBox;
        if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
        {
            e.Graphics.FillRectangle(new SolidBrush(HighlightColor), e.Bounds);
            //e.Graphics.DrawString(combo.Items[e.Index].ToString(), e.Font, new SolidBrush(combo.BackColor), new Point(e.Bounds.X, e.Bounds.Y));

            e.Graphics.DrawString(combo.Items[e.Index].ToString(), e.Font, new SolidBrush(combo.ForeColor), new Point(e.Bounds.X, e.Bounds.Y));
        }
        else
        {
            e.Graphics.FillRectangle(new SolidBrush(combo.BackColor), e.Bounds);
            e.Graphics.DrawString(combo.Items[e.Index].ToString(), e.Font, new SolidBrush(combo.ForeColor), new Point(e.Bounds.X, e.Bounds.Y));
        }
        e.DrawFocusRectangle();
    }

    protected override void WndProc(ref Message m)// windows message handler
    {
        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);

                PaintControlBorder();
                break;
            default:
                base.WndProc(ref m);
                break;
        }
    }
    private void PaintControlBorder()
    {
            ControlPaint.DrawBorder(gdc, this.ClientRectangle, Color.Orange, ButtonBorderStyle.Solid);
    }
}
fslejnso

fslejnso1#

在Windows Form中,您永远不会储存控件的Graphics对象。
您可以使用由Graphics方法(Paint、DrawItem等)之一提供的一个,或者像本例一样,在需要时创建一个新的,然后立即将其处理掉。
在此示例中,隐式地将Graphics对象创建包含在using块中。
这是一个使用ControlPaint.DrawBorder的简单示例,演示如何使用Graphics对象在ComboBox控件周围绘制边框,该对象是从所接收的WM_PAINT消息上的控件Handle(Graphics.FromHwnd(this.Handle))派生的,它覆盖了控件的WndProc
范例自订控件会公开(Expose)公用属性**BorderColor**,可让您变更框缐的色彩。

using System.ComponentModel;
using System.Drawing;
using System.Security.Permissions;
using System.Windows.Forms;

[DesignerCategory("Code")]
class ComboSimpleBorder : ComboBox
{
    private const int WM_PAINT = 0xF;
    private Color m_BorderColor = Color.Red;

    public ComboSimpleBorder() { }

    [Browsable(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
    [EditorBrowsable(EditorBrowsableState.Always), Category("Appearance")]
    [Description("Get or Set the Color of the Control's border")]
    [DefaultValue(typeof(Color), "Red")]
    public Color BorderColor 
    {
        get => m_BorderColor;
        set { m_BorderColor = value; Invalidate(); }
    }

    protected override void WndProc(ref Message m) {
        base.WndProc(ref m);
        if (m.Msg == WM_PAINT) {
            using (var g = Graphics.FromHwnd(this.Handle)) {
                ControlPaint.DrawBorder(g, ClientRectangle, m_BorderColor, ButtonBorderStyle.Solid);
            }
            m.Result = IntPtr.Zero;
        }
    }
}

相关问题