【问题标题】:Mouse hook in a specific window特定窗口中的鼠标钩子
【发布时间】:2009-10-28 13:00:54
【问题描述】:

我需要使用 C++、Win API 设置鼠标点击挂钩。因此,当单击桌面上的图标时,我会收到该事件。这将如何发生?我认为我在鼠标钩子事件中获得的唯一信息是鼠标的坐标,对吧?现在如何确保点击的东西是桌面上的图标?

【问题讨论】:

  • 我认为您需要进一步解释您的需求 - 您是否只想在图标启动时注意?您需要一直监控所有图标还是只等待用户在特定情况下单击一个?
  • 不,我需要监视用户是否只需单击一个图标。然后我需要获取图标详细信息、图标名称等。

标签: c++ winapi mouse hook


【解决方案1】:

在 DLL 中实现鼠标钩子并使用 SetWindowsHookEx() 仅为管理桌面窗口的线程安装钩子。使用 GetDesktopWindow() 和 GetWindowThreadProcessId() 获取该线程 ID。然后,每当你的钩子被触发时,钩子都会告诉你用户正在点击哪个窗口,以及正在执行哪个鼠标操作。使用 GetClassName() 确定触发钩子的窗口是否是 ListView,如果是,则使用 ListView API 在提供的鼠标坐标处查询窗口的图标信息。

【讨论】:

  • 我如何知道鼠标按钮被点击的窗口?
  • 钩子为您提供当前鼠标事件发生的窗口的确切 HWND。
  • 请阅读微软关于 WH_MOUSE 钩子的文档。
【解决方案2】:

在 MSDN 上查看 Microsoft Active Accessibility 和 SetWinEventHook。 我认为您可以有效地使用它们来实现它。

【讨论】:

    【解决方案3】:

    此代码在我创建的挂钩 DLL 中工作。我认为这里的问题是从图标中获取文本等内容很容易,但弄清楚如何访问快捷方式下的应用程序完全是另一个问题。这是位于管理列表视图的应用程序中的知识,在本例中为资源管理器。

    请原谅我拼命地过时的代码,我把这个测试硬塞进了一个旧的 ANSI 钩子 DLL。 DebugStr 只是 OutputDebugString 的包装器。该代码基于 Remy 的发布。

    LRESULT DLL_CALL MouseFunc (int nCode, WPARAM  wParam, LPARAM  lParam)
    {
       BOOL bGoActive = TRUE;
       char szDebug [200];
       char szBuff  [100];
    
       MOUSEHOOKSTRUCT * pmhs = (MOUSEHOOKSTRUCT *)lParam;
       LVFINDINFO lvfi;
       LVITEM lvi;
       int iIndexItem;
    
       long lx = pmhs->pt.x;
       long ly = pmhs->pt.y;
    
       if (nCode >= 0)
       {
          if (wParam == WM_LBUTTONDOWN)
          {
             GetClassName (pmhs->hwnd, szBuff, sizeof(szBuff));
    
             wsprintf (szDebug, "wparam=0x%X, nCode=%d, HTC=%d, class='%s', x=%d, y=%d",
                       wParam, nCode, pmhs->wHitTestCode, szBuff, lx, ly);
             DebugStr (szDebug);
    
             if (strcmpi (szBuff, TEXT("SysListView32")) == 0)
             {
                ZeroMemory (&lvfi, sizeof(lvfi));
                lvfi.flags = LVFI_NEARESTXY;
                lvfi.pt.x  = lx;
                lvfi.pt.y  = ly;
                ScreenToClient (pmhs->hwnd, &(lvfi.pt));
                lvfi.vkDirection = VK_NEXT;
                iIndexItem = ListView_FindItem (pmhs->hwnd, -1, &lvfi);
    
                if (iIndexItem != -1)
                {
                   ZeroMemory (&lvi, sizeof(lvi));
                   lvi.mask  = LVIF_TEXT;
                   lvi.iItem = iIndexItem;
                   lvi.pszText = szBuff;
                   lvi.cchTextMax = sizeof(szBuff);
    
                   if (ListView_GetItem (pmhs->hwnd, &lvi))
                   {
                      wsprintf (szDebug, "item text = '%s'", szBuff);
                      DebugStr (szDebug);
                   }
                }
             }
          }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-15
      • 2019-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多