要实现右键显示自定义菜单,首先当然要屏蔽原来默认的上下文菜单,方法如前。
在方案二(继承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 文件中。