实现ComboBox自定义右键菜单

要实现右键显示自定义菜单,首先当然要屏蔽原来默认的上下文菜单,方法如前。

在方案二(继承ComboBox)的基础上,只需在SubClassHwnd类的WndProc函数中捕获右键消息即可

        if(m.Msg == 0x0205)

                menu.Show(MousePosition);

 

菜单可以在SubClassHwnd构造函数中传入
            ContextMenuStrip menu;
            public SubClassHwnd(ContextMenuStrip m)
            {
                menu = m;
            }

 

如果自定义菜单中有复制、粘贴、剪切等操作,要实现起来也易如反掌。

在各自的响应函数里分别向SubClassHwnd发送相应的消息即可。
            PostMessage(sub.Handle, msg, new IntPtr(0), new IntPtr(0));

 

要发送消息,还得引用API
        [DllImport("user32.dll")]
        static extern IntPtr PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);

 

注意要把ComboBoxEx构造函数中的SubClassHwnd sub定义为类成员。

 

至此,大功告成。完整代码如下:
    public partial class ComboEx : ComboBox
    {
        SubClassHwnd sub;

        [DllImport("user32.dll")]
        static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

        [DllImport("user32.dll")]
        static extern IntPtr PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);

 

        public ComboEx()
        {
            InitializeComponent();
            IntPtr ehWnd = FindWindowEx(base.Handle, IntPtr.Zero, "Edit", "");
            sub = new SubClassHwnd(this, contextMenuStrip);
            sub.AssignHandle(ehWnd);
        }

        public class SubClassHwnd : System.Windows.Forms.NativeWindow
        {
            ContextMenuStrip menu;
            public SubClassHwnd(ContextMenuStrip m)
            {
                menu = m;
            }

            protected override void WndProc(ref   Message m)
            {
                switch (m.Msg)
                {
                    case 0x7b://WM_CONTEXTMENU
                        break;
                    case 0x0205://WM_RBUTTONUP
                        menu.Show(MousePosition);
                        break;
                    default:
                        base.WndProc(ref m);
                        break;
                }
            }
        }

        public void OnCut(object sender, EventArgs e)
        {
            PostMessage(sub.Handle, 0x0300, new IntPtr(0), new IntPtr(0));//send message WM_CUT
        }        
        public void OnCopy(object sender, EventArgs e)
        {
            PostMessage(sub.Handle, 0x0301, new IntPtr(0), new IntPtr(0));//WM_COPY
        }

        public void OnParste(object sender, EventArgs e)
        {
            PostMessage(sub.Handle, 0x0302, new IntPtr(0), new IntPtr(0));//WM_PASTE
        }
    }

 

注:各种系统消息对于的ID定义全部在 Platform\include\winuser.h 文件中。

你可能感兴趣的:(combobox)