1

我想要做的是扩展 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 更改以挂接右侧窗口。

对正确的窗口进行子类化难道没有更好的解决方案吗?

4

0 回答 0