Проблема с изменением размера левой стороны окна. После изменения размера левого края, окно начинает дергаться и мигать, как будто находится в двух разных позициях( на видео мигание не видно) почти одновременно.
Но самое что я не могу понять это, почему курсор мыши отдаляется от края окна, чем дольше тяну, тем больше отдаляется. С правым краем такого нет(понятно что у правого края не надо изменять новое значение), край двигается сразу же за курсором. Думаю проблема в WM_MOUSEMOVE, не правильно делаю расчеты, но пробовал по разному, результат тот же.
Видео
Использую стиль WS_POPUP, в WS_PAINT и WS_NCPAINT двойная буферизация
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
static bool dragging = false;
static POINT startPoint;
static RECT startRect;
switch (message)
{
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 = currentPoint.x - startPoint.x;
//int deltaXLeft = startPoint.x + currentPoint.x;
// Новая ширина ЛЕВОЙ СТОРОНЫ ОКНА
int newWidthLeft = startRect.right - startRect.left - deltaXLeft;
// Новая позиция левой стороны
int newCurrentWidthLeft = startRect.left + deltaXLeft;
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);
}
}
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); // Захватываем мышь
break;
}
case WM_LBUTTONUP: {
// Остановка изменения размера окна при отпускании левой кнопки мыши
if (dragging) {
dragging = false;
ReleaseCapture(); // Освобождаем мышь
}
break;
}
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}