winapi — c ++: перестановка окна с помощью глобальной мыши

Я пытаюсь разработать приложение, как разделитель рабочего стола.
Я использовал глобальную мышиную зацепку (низкоуровневую мышиную зацепку), потому что при нажатии левой кнопки вверх после перетаскивания окна в определенную позицию окно помещается в определенную позицию и изменяется.
Сначала я попытался переместить окно в левый угол экрана рабочего стола, когда нажата левая кнопка вверх.
Я использовал метод SetWindowPos, чтобы переместить и изменить размер, он не работает хорошо.
Когда я отпустил левую кнопку, окно расположилось в определенной позиции, но оно немедленно вернулось в исходное положение.
При отладке приложения оно хорошо ложится в левый угол экрана.
Я не знаю точно, почему это происходит.
Ниже мой код.

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

Решение

При перетаскивании окна система отправляет в окно сообщение — WM_EXITSIZEMOVE.
После того, как я отпустил левую кнопку мыши, я отправил сообщение WM_EXITSIZEMOVE в окно, в котором было зафиксировано событие нажатия левой кнопки мыши.
После завершения этого сообщения я использовал метод SetWindowPos для изменения положения окна, и это работает хорошо.
Это все.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]