我想要做的是扩展 Windows Mobile Winforms 的 MainMenu 以具有第二个菜单级别。如果您在菜单按钮上提示较短,它将执行事件操作,但如果您按下它更长的时间,则应弹出第二个菜单级别。MainMenu 的托管功能非常缺乏,所以我不得不另谋出路。我通过派生 MainMenu 并添加了一些 SubClassing 将其存档。
public delegate IntPtr Win32WndProc(IntPtr hWnd, int msg, int wParam, int lParam);
[DllImport("coredll.dll", EntryPoint = "FindWindow", SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, IntPtr lpWindowName);
[DllImport("coredll.dll")]
public static extern bool EnableWindow(IntPtr hWnd, bool bEnable);
[DllImport("coredll")]
public static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, Win32WndProc newProc);
int GWL_WNDPROC = (-4);
int GW_CHILD = 5;
IntPtr _oldToolbarProc;
IntPtr _oldMenuWorkerProc
void Hookup()
{
//find the window to hook
var hWndHooked = FindWindow("HHTaskbar", IntPtr.Zero);
if (hWndHooked == IntPtr.Zero)
return;
//enable the taskbar, not realy necessary
EnableWindow(hWndHooked, true);
//find the menu_worker window
var menuWorkerWnd = FindWindow("menu_worker", IntPtr.Zero);
if (menuWorkerWnd == IntPtr.Zero)
return;
var toolbarWnd = GetWindow(menuWorkerWnd, GW_CHILD);
if (toolbarWnd == IntPtr.Zero)
return;
Win32WndProc newMenuWorker = MenuWorkerProc;
_oldMenuWorkerProc = SetWindowLong(menuWorkerWnd, GWL_WNDPROC, newMenuWorker);
Win32WndProc newToolbar = ToolbarProc;
_oldToolbarProc = SetWindowLong(newToolbarWnd, GWL_WNDPROC, newToolbar);
}
工具栏子类化测量 WM_LBUTTONDOWN 和 WM_LBUTTONUP 之间的时间,并根据这些事件之间的跳跃时间调用上下文菜单。
如果调用上下文菜单,则 menu_worker 子类必须禁止按下按钮的 WM_COMMAND。
这适用于单个窗口。但是,如果我在第二种形式上使用它,它们将识别相同的工具栏和 menuworker 以及应用程序崩溃。
我尝试的是在父表单的 onFocus /onLostFocus 事件中挂钩和取消挂钩。但遗憾的是 onFocus 在正确的窗口可见之前被调用并且它也得到了错误的窗口句柄:(
我现在所做的(我知道一个非常糟糕的 hack)是在 onFocus 事件中开始一个时间,然后等待 1000 毫秒然后将其连接起来。这导致 50:50 更改以挂接右侧窗口。
对正确的窗口进行子类化难道没有更好的解决方案吗?