2017-08-31 19 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

こんにちは、ポール あなたの優しい答えをありがとう。 あなたはGlobal Mouseフックでの経験があるようです。 私を助けることができますか? –

答えて

0

ウィンドウをドラッグすると、ウィンドウにメッセージWM_EXITSIZEMOVEが送信されます。 マウスの左ボタンを離すと、マウスの左上のイベントをキャプチャしたウィンドウにWM_EXITSIZEMOVEメッセージが送信されます。 このmsgの処理が完了したら、SetWindowPosメソッドを使用してウィンドウの位置を変更し、うまくいきました。 それだけです。

関連する問題