WinForms ComboBox 背景颜色也适用于下拉列表

问题描述 投票:0回答:1

为了设置我正在使用的活动控件的背景颜色

private void ProcessEnter(object sender, EventArgs e)
{
  ((Control)sender).BackColor = Color.LightYellow;
}

但这也改变了下拉列表的背景颜色,看起来很奇怪。我怎样才能防止这种情况发生?

winforms combobox dropdown backcolor
1个回答
1
投票

这段代码似乎有效。

ComboBox
由 3 个独立的句柄(容器、文本编辑、列表)组成。获取
hwndList
窗口的句柄。当列表窗口收到消息并且组合处于下拉状态时,将
BackColor
设置为白色。如果
ComboBox
窗口收到
WM_ERASEBACKGROUND
消息,则将
BackColor
设置回黄色。

public class ComboBox2 : ComboBox {
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern bool GetComboBoxInfo(IntPtr hWnd, ref COMBOBOXINFO pcbi);

    private const UInt32 WM_ERASEBKGND         = 0x0014;

    NW nw = null;
    COMBOBOXINFO cbi;

    public ComboBox2() : base() {
        this.BackColor = Color.Yellow;
        this.Items.AddRange(new Object[] { "", "A", "B", "C" });
    }

    protected override void OnHandleCreated(EventArgs e) {
        base.OnHandleCreated(e);
        cbi = new COMBOBOXINFO();
        cbi.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(cbi);
        GetComboBoxInfo(this.Handle, ref cbi);
        nw = new NW();
        nw.AssignHandle(cbi.hwndList);
        nw.combo = this;
    }

    protected override void Dispose(bool disposing) {
        base.Dispose(disposing);
        if (disposing) {
            if (nw != null) {
                nw.ReleaseHandle();
            }
        }
    }

    protected override void WndProc(ref Message m) {
        if (m.Msg == WM_ERASEBKGND) {
            this.BackColor = Color.Yellow;
        }
        base.WndProc(ref m);
    }

    private class NW : NativeWindow {
        public ComboBox2 combo = null;
        protected override void WndProc(ref Message m) {
            if (combo.DroppedDown)
                combo.BackColor = Color.White;
            base.WndProc(ref m);
        }
    }
}


[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct COMBOBOXINFO {
    public Int32 cbSize;
    public RECT rcItem;
    public RECT rcButton;
    public ComboBoxButtonState buttonState;
    public IntPtr hwndCombo;
    public IntPtr hwndEdit;
    public IntPtr hwndList;
}

[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct RECT {
   public int Left, Top, Right, Bottom;
}

public enum ComboBoxButtonState {
    STATE_SYSTEM_NONE = 0,
    STATE_SYSTEM_INVISIBLE = 0x00008000,
    STATE_SYSTEM_PRESSED = 0x00000008
}
© www.soinside.com 2019 - 2024. All rights reserved.