2017-08-31 100 views
0

我正在尝试开发像桌面分隔线这样的应用程序。 我使用了全局鼠标钩子(低级别的鼠标钩子),因为当把窗口拖动到特定位置后,将窗口放到特定位置并调整大小时,当左键按下时。 首先,我试图将窗口重新放置到桌面屏幕的左角,当左键按下时。 我使用SetWindowPos方法重新定位并调整大小,但效果不佳。 当我释放左边的按钮时,窗口位于特定的位置,但它立即返回到原始位置。 在调试应用程序时,它会很好地进入屏幕的左角。 我不知道为什么会发生这种情况。 以下是我的代码。C++:用全局鼠标钩重新定位窗口

LRESULT CALLBACK LowLevelMouseProc(int code, WPARAM wParam, LPARAM lParam) 
{ 
if (code != HC_ACTION) 
    return CallNextHookEx(hMouseHook, code, wParam, lParam); 
switch (wParam) 
{ 
    case WM_LBUTTONDOWN: 
    { 
     TRACE("Down\n"); 
     // To get window handle from current mouse position 
     ::GetCursorPos(&mouse_pos); 
     hCurrentWnd = ::WindowFromPoint(mouse_pos); 

     LButton_Down = true; 

     Window_Drag = false; // Initialize Window_Drag variable 
     Mouse_Drag = false; 

     while (hCurrentWnd != 0) 
     { 
      style = ::GetWindowLong(hCurrentWnd, GWL_STYLE); 
      const int x = style & (WS_POPUP | WS_CHILD); 

      if ((x == WS_OVERLAPPED) || (x == WS_POPUP)) break; 

      // we also want to manipulate mdi childs that 
      // aren't maximized 
      if ((!(style & WS_MAXIMIZE)) && (::GetWindowLong(hCurrentWnd, GWL_EXSTYLE) & WS_EX_MDICHILD)) break; 

      hCurrentWnd = ::GetParent(hCurrentWnd); 
     } 

     if (IgnoreWindow()) 
     { 
      return CallNextHookEx(hMouseHook, code, wParam, lParam); 
     } 

     // check if the alt key is pressed while a mouse button is pressed 
     // and switch to the appropriate mode 
     switch (wParam) 
     { 
      case WM_LBUTTONDOWN: 
       LButton_Down = true; 
       break; 
      default: 
       return CallNextHookEx(hMouseHook, code, wParam, lParam); 
     } 

     if (hCurrentWnd == 0) 
     { 
      return CallNextHookEx(hMouseHook, code, wParam, lParam); 
     } 

     HWND parent = ::GetParent(hCurrentWnd); 

     // remember the window size and position 
     ::GetWindowRect(hCurrentWnd, &rDown); 
     if ((parent) && ((style & WS_POPUP) == 0)) 
     { 
      ::ScreenToClient(parent, (POINT*)&rDown.left); 
      ::ScreenToClient(parent, (POINT*)&rDown.right); 
     } 

     // we're getting serious - capture the mouse 
     SetCapture(hCurrentWnd); 

     return CallNextHookEx(hMouseHook, code, wParam, lParam); 
    } 

    case WM_MOUSEMOVE: 
    { 
     TRACE("Move\n"); 

     if (!LButton_Down) 
     { 
      return CallNextHookEx(hMouseHook, code, wParam, lParam); 
     } 
     else { 
      Mouse_Drag = true; 

      TRACE("Mouse Drag - True\n"); 

      ::GetWindowRect(hCurrentWnd, &rCurWdrag); 
      if ((rDown.left == rCurWdrag.left) && (rDown.top == rCurWdrag.top)) 
      { 
       Window_Drag = false; 
       TRACE("Window Drag - False\n"); 
      } 
      else { 
       Window_Drag = true; 
       TRACE("Window Drag - True\n"); 
      } 
     } 

     return CallNextHookEx(hMouseHook, code, wParam, lParam) ; 
    } 

    case WM_LBUTTONUP: 
    { 
     TRACE("Up\n"); 

     LButton_Down = false; 

     if (Window_Drag && Mouse_Drag) 
     { 
      Window_Drag = false; 
      Mouse_Drag = false; 
      ::SetWindowPos(hCurrentWnd, 0, 0, 0, 500, 500, SWP_ASYNCWINDOWPOS); 
      TRACE("Window Drag - False\n"); 
      TRACE("Mouse Drag - False\n"); 
     } 
     else 
     { 
      Window_Drag = false; 
      Mouse_Drag = false; 
      TRACE("Window Drag 1 - False\n"); 
      TRACE("Mouse Drag 1 - False\n"); 
     } 
     ReleaseCapture(); 
     return CallNextHookEx(NULL, code, wParam, lParam); 
    } 

    default: 
    { 

     LButton_Down = false; 
     Window_Drag = false; 
     Mouse_Drag = false; 

     return CallNextHookEx(hMouseHook, code, wParam, lParam); 
    } 
} 

}

,这是全球安装鼠标的一部分勾

BOOL CMFCApplication4Dlg::OnInitDialog() 
{ 
CDialogEx::OnInitDialog(); 

// Set the icon for this dialog. The framework does this automatically 
// when the application's main window is not a dialog 
SetIcon(m_hIcon, TRUE);   // Set big icon 
SetIcon(m_hIcon, FALSE);  // Set small icon 

// TODO: Add extra initialization here 

LButton_Down = false; 
Mouse_Drag = false; 
Window_Drag = false; 

hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, (HOOKPROC)LowLevelMouseProc, NULL, (DWORD)NULL); 


return TRUE; // return TRUE unless you set the focus to a control 
} 

我能做些什么?

+0

如果您可以将问题简化为无法按预期工作的单个呼叫(或多个线路),它将帮助其他人帮助您。现在你的问题看起来像:“这是我所有的代码,它不工作”。 – Paul

+0

嗨,保罗 谢谢你的亲切的答案。 看来你有全球鼠标钩的经验。 你能帮我吗? –

回答

0

拖动窗口时,系统发送消息 - WM_EXITSIZEMOVE到窗口。 一旦我释放鼠标左键,我将WM_EXITSIZEMOVE消息发送到捕获鼠标左键事件的窗口。 完成这个msg的过程后,我使用SetWindowPos方法重新定位窗口,并且运行良好。 就是这样。