65.9K
CodeProject 正在变化。 阅读更多。
Home

中间鼠标按钮(或滚轮)模拟双击(VC6)

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.67/5 (17投票s)

2007年7月9日

CPOL

2分钟阅读

viewsIcon

87298

downloadIcon

2134

这是一个我每天都在使用的实用小工具。它将鼠标中键点击转换为左键双击。

配置 GUI

  • 显示功能状态
  • 启用/禁用双击功能
  • 选择是否确认应用程序退出
Screenshot - MBtn2DblClickVC.jpg

引言

我曾经有一款罗技鼠标,一切都很好!

罗技提供了一个名为 EMEXEC.exe 的实用程序,它允许你设置可用按钮的行为。我最常用的功能是将鼠标中键/滚轮的单击转换为左键双击。但是,如果你卸载了鼠标软件,或者需要在没有 LogiMouse 的机器上工作会怎么样?在连接 LogiMouse 之前,你无法安装 MouseWare。很快,我就开始怀念罗技的这个很棒的功能,并告诉自己要编写一个实现这个功能的工具。就这样...

问题

我面临的最棘手的部分是,应用程序必须获取当前运行的所有其他应用程序的点击事件。因此,必须设置一个全局鼠标钩子,这可能有点棘手。你必须将鼠标钩子回调代码放在一个具有自定义代码段的外部 DLL 中。我使用了 MouseHook.cpp - 我在浏览网页时发现的,但我不记得是从哪里找到的了(抱歉!)。如果这是你的 MouseHook.cpp,请留言告诉我。

设置 MouseHook

__declspec(dllexport) BOOL setMyHook(HWND hWnd) {
    if(hWndServer != NULL)
        return FALSE; // already hooked!
    
    hook = SetWindowsHookEx(WH_MOUSE_LL,
        (HOOKPROC)msghook,
               hInst,
               0);
    if(hook != NULL) { /* success */
        hWndServer = hWnd;
        return TRUE;
    } /* success */

    return FALSE; // failed to set hook
} // setMyHook

...
//Hook-Function:

...

static LRESULT CALLBACK msghook(UINT nCode, WPARAM wParam, LPARAM lParam) {
    if(nCode < 0) { /* pass it on */
        CallNextHookEx(hook, nCode, wParam, lParam);
        return 0;
    } /* pass it on */
    
    if(wParam == WM_MBUTTONUP ){
        PostMessage(hWndServer, UWM_MBTNCLICK, 0, 0);
    }
    
    return CallNextHookEx(hook, nCode, wParam, lParam);
} // msghook

清除钩子

__declspec(dllexport) BOOL clearMyHook(HWND hWnd) {
    if(hWnd != hWndServer || hWnd == NULL)
        return FALSE;
    
    BOOL unhooked = UnhookWindowsHookEx(hook);
    
    if(unhooked)
        hWndServer = NULL;
    
    return unhooked;
} // clearMyHook

转换点击

BEGIN_MESSAGE_MAP(CMBtn2DblClickDlg, CDialog)
    ON_REGISTERED_MESSAGE(UWM_MBTNCLICK, OnMyMbtnClick)

....
LRESULT CMBtn2DblClickDlg::OnMyMbtnClick(WPARAM wParam, LPARAM lParam) {
    CPoint pt;
    GetCursorPos(&pt);
    
    // width
    int cx = GetSystemMetrics(SM_CXSCREEN);
    // height
    int cy = GetSystemMetrics(SM_CYSCREEN);
  
    //Reformat screen coordinates
    int x2 = ( 65535 * pt.x ) / cx;
    int y2 = ( 65535 * pt.y ) / cy;
 
    INPUT input[2];
    
    input[0].type = INPUT_MOUSE;
    input[0].mi.dx = x2;
    input[0].mi.dy = y2;
    input[0].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN;
    input[0].mi.mouseData   = 0L; 
    input[0].mi.time        = 0L; 
    input[0].mi.dwExtraInfo = 0L;

    input[1].type = INPUT_MOUSE;
    input[1].mi.dx = x2;
    input[1].mi.dy = y2;
    input[1].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTUP;
    input[1].mi.mouseData   = 0L; 
    input[1].mi.time        = 0L; 
    input[1].mi.dwExtraInfo = 0L;
    
    SendInput( 1, &input[0], sizeof(input[0]));
    SendInput( 1, &input[1], sizeof(input[1]));

    Sleep(40);
    
    SendInput( 1, &input[0], sizeof(input[0]));
    SendInput( 1, &input[1], sizeof(input[1]));
    
    return 0;
} // MBtn2DblClickDlg::OnMyMouseMove

致谢

  • CReadOnlyEdit by Kevin Bond
  • CRegistry by Shane Martin
  • CSimpleTray by T1TAN / SprdSoft Inc.
  • CWinStartup (by unknown)

我希望这篇文章对任何人都有用,或者有助于理解鼠标钩子的工作原理。如果你对一个好的 MouseHook DLL 的源代码感兴趣,我建议你下载这个源代码,因为 MouseHookManager 的原始位置已经消失,而且到目前为止我无法在网上找到它。所以希望你喜欢,祝一切顺利 - 希望你也能阅读我的下一篇文章。

祝好,Kim

历史

  • 2007 年 7 月 9 日:初始发布
  • 2010 年 4 月 15 日:修复了启动时注册表设置持久化和其他配置设置的错误
  • 2010 年 7 月 24 日:更新了源代码和应用程序,使其适用于 x64 系统上的 Windows 7
© . All rights reserved.