Как правильно изменять размер окна в winapi
Я пытаюсь сделать изменение размера окна, как со стилем WS_OVERLAPPED, используя WS_POPUP. С правой стороной все получилось, а вот с левой проблемы. Не могу понять почему когда я тяну левый край окна, курсор мыши находится дальше чем край окна, за который я тяну. При этом окно по краям начинает мерцать, а кнопки в не клиентской области как будто одновременно находятся в двух положениях. А если тянуть правый край, то сам край движется прям за курсором( как изменять размер папки в видновс ). Не пойму где проблема, в расчётах новой ширины окна или позиции, или вообще в другом месте кода.
case WM_MOUSEMOVE:
{
if (dragging)
{
POINT currentPoint = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
GetCursorPos(¤tPoint);
ScreenToClient(hwnd, ¤tPoint);
// Смещение для ПРАВОЙ СТОРОНЫ ОКНА
int deltaXRight = currentPoint.x - startPoint.x;
// Новая ширина ПРАВОЙ СТОРОНЫ ОКНА
int newWidth = startRect.right - startRect.left + deltaXRight;
// Может я не правильно делаю рассчет
// Смещение для Левой СТОРОНЫ ОКНА
int deltaXLeft = startPoint.x - currentPoint.x;
// Новая ширина ЛЕВОЙ СТОРОНЫ ОКНА
int newWidthLeft = startRect.right - startRect.left - deltaXRight;
// Новая позиция левой стороны
int newCurrentWidthLeft = startRect.left + deltaXRight;
if (startPoint.x > startRect.right - startRect.left - BORDERWIDTH)
{
SetWindowPos(hwnd, NULL, 0, 0, newWidth, startRect.bottom - startRect.top, SWP_NOZORDER | SWP_NOMOVE);
}
else if (startPoint.x < BORDERWIDTH && newWidthLeft > MIN_WIDTH)
{
SetWindowPos(hwnd, NULL, newCurrentWidthLeft, startRect.top, newWidthLeft, startRect.bottom - startRect.top, SWP_NOZORDER | SWP_NOACTIVATE);
}
}
break;
}
Остальной код
case WM_NCHITTEST:
{
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
ScreenToClient(hwnd, &pt);
RECT closeButton = GetCloseButtonRect(hwnd);
RECT maximizeButton = GetMaximizeButtonRect(hwnd);
RECT minimizeButton = GetMinimizeButtonRect(hwnd);
if (PtInRect(&closeButton, pt)) {
return HTCLOSE;
}
else if (PtInRect(&maximizeButton, pt)) {
return HTMAXBUTTON;
}
else if (PtInRect(&minimizeButton, pt)) {
return HTMINBUTTON;
}
// Если курсор в заголовке, возвращаем HTCAPTION
if (pt.y < GetTitleBarHeight()) {
return HTCAPTION; // Указываем, что курсор в заголовке
}
LRESULT hit = DefWindowProc(hwnd, message, wParam, lParam);
if (hit == HTCLIENT) {
RECT rc;
GetClientRect(hwnd, &rc);
if (pt.x > rc.right - 10) {
return HTRIGHT; // Правый край
}
else if (pt.x < 10) {
return HTLEFT; // Левый край
}
}
return hit;
}
case WM_NCLBUTTONDOWN:
{
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
ScreenToClient(hwnd, &pt);
RECT closeButton = GetCloseButtonRect(hwnd);
RECT maximizeButton = GetMaximizeButtonRect(hwnd);
RECT minimizeButton = GetMinimizeButtonRect(hwnd);
if (PtInRect(&closeButton, pt)) {
PostMessage(hwnd, WM_CLOSE, 0, 0);
}
if (PtInRect(&maximizeButton, pt)) {
ShowWindow(hwnd, IsZoomed(hwnd) ? SW_RESTORE : SW_MAXIMIZE);
}
if (PtInRect(&minimizeButton, pt)) {
SendMessage(hwnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);
}
if (pt.y < GetTitleBarHeight()) {
// Начинаем перетаскивание окна
PostMessage(hwnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, lParam);
return HTCAPTION;
}
dragging = true;
startPoint.x = GET_X_LPARAM(lParam);
startPoint.y = GET_Y_LPARAM(lParam);
GetWindowRect(hwnd, &startRect);
ScreenToClient(hwnd, &startPoint);
SetCapture(hwnd); // Захватываем мышь
return 0;
}
case WM_LBUTTONUP: {
// Остановка изменения размера окна при отпускании левой кнопки мыши
if (dragging) {
dragging = false;
ReleaseCapture(); // Освобождаем мышь
}
break;
}
