2017-08-31 52 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方法重新定位窗口,並且運行良好。 就是這樣。