C#Windows Mobile 6.5.3扩展Winform MainMenu

时间:2013-04-24 17:14:50

标签: c# winforms windows-mobile subclass

我想要做的是将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。

这适用于单个窗口。但是如果我在第二个表单上使用它,它们将会同时识别相同的工具栏和菜单工作者以及应用程序崩溃。

我尝试的是在父窗体的onFocus / onLostFocus事件中挂钩和取消挂钩。 但遗憾的是onFocus在右侧窗口可见之前调用,它也会得到错误的窗口句柄:(

我现在所做的(我知道一个非常糟糕的黑客)是在onFocus事件中开始一段时间并等待1000毫秒并将其挂起。这导致了50:50的变化以挂钩右窗口。

是否有更好的解决方案来为正确的窗口创建子类?

0 个答案:

没有答案