2016-10-31 1 views
0

Я создаю окно без границ (WS_POPUP в CreateWindow) и вам нужно изменить его размер, когда мышь закончится и изменится, когда мышь выйдет из приложения. Он работает нормально, но он мерцает, когда я меняю позицию с помощью SetWindowPos. Мне нужно уменьшить y на 30 пикселей и увеличить высоту, поэтому нижняя часть окна остается в том же положении.WinAPI CreateWindow WS_POPUP изменение размера мерцание

Ниже приведен код:

WNDCLASS windowClass; 
ZeroMemory(&windowClass, sizeof(WNDCLASS)); 

windowClass.style = 0;// CS_HREDRAW | CS_VREDRAW; 
windowClass.lpfnWndProc = (WNDPROC) WindowProc; 
windowClass.hInstance = hInst; 
windowClass.lpszClassName = PROCESS_WINDOW_CLASS; 
windowClass.hIcon = NULL; 
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); 
windowClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1); 

windowHandle = CreateWindowEx(
    0, 
    PROCESS_WINDOW_CLASS, 
    L"", 
    WS_POPUP | WS_CLIPSIBLINGS, 
    x, //x 
    y, //y 
    width, //width 
    height, //height 
    NULL, 
    NULL, 
    hInst, 
    NULL); 

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 
switch (uMsg) { 
    case WM_MOUSEMOVE: { 
     if (!mouseOver) { 
      TRACKMOUSEEVENT tme; 

      tme.cbSize = sizeof(TRACKMOUSEEVENT); 
      tme.dwFlags = TME_LEAVE; 
      tme.hwndTrack = hwnd; 
      if (TrackMouseEvent(&tme)) { 
       RECT rect; 
       GetWindowRect(hwnd, &rect); 

       int y = rect.top; 
       int height = rect.bottom - y; 

       y -= BUTTONS_AREA_HEIGHT; 
       height += BUTTONS_AREA_HEIGHT; 
       //tried with MoveWindow, DeferWindowPos - same thing 
       //MoveWindow(hwnd, rect.left, y, rect.right - rect.left, height, TRUE); 

       //HDWP winPos = BeginDeferWindowPos(1); 
       //DeferWindowPos(winPos, hwnd, NULL, rect.left, y, rect.right - rect.left, height, 0); 
       //EndDeferWindowPos(winPos); 

       SetWindowPos(hwnd, NULL, rect.left, y, rect.right - rect.left, height, 
        SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOSENDCHANGING); 
       rect.top = y; 
       rect.bottom = height - y; 
       InvalidateRect(hwnd, &rect, FALSE); 
        //0); 
       RedrawWindow(hwnd, NULL, NULL, RDW_INTERNALPAINT | RDW_INVALIDATE | RDW_NOERASE); 
       mouseOver = TRUE; 
      } 
     } 
    } 
    break; 
    case WM_MOUSELEAVE: { 
     RECT rect; 
     GetWindowRect(hwnd, &rect); 

     int y = rect.top; 
     int height = rect.bottom - y; 

     y += BUTTONS_AREA_HEIGHT; 
     height -= BUTTONS_AREA_HEIGHT; 

     MoveWindow(hwnd, rect.left, y, rect.right - rect.left, height, TRUE); 

     //SetWindowPos(hwnd, NULL, rect.left, y, rect.right - rect.left, height, 
     // SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); 
     //InvalidateRect(hwnd, &rect, FALSE); 
     //SetWindowPos(hwnd, NULL, rect.left, y, rect.right - rect.left, height, 0); 
     mouseOver = FALSE; 
    } 
    case WM_CREATE: { 
     LONG lExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE); 
     lExStyle &= ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | 
      WS_SYSMENU | WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE); 

     SetWindowLongPtr(hwnd, GWL_EXSTYLE, lExStyle | WS_EX_TOOLWINDOW | WS_EX_TOPMOST); 

     SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); 
    } 
     return 0; 
    case WM_DESTROY: 
     PostQuitMessage(EXIT_SUCCESS); 
     break; 
    default: 
     return DefWindowProc(hwnd, uMsg, wParam, lParam); 
} 
return 0; 
} 

Я пробовал все комбинации SetWindowPos, MoveWindow и т.д., но когда курсор мыши находится над окном, кажется, что окно настройки при первом включении Y позиции, то он увеличивает высоту после того, несколько миллисекунд, и это видно.

Кто-нибудь знает, как это можно решить?

+0

Есть ли какие-нибудь дочерние окна? Кстати, почему вы запросили 'WS_CLIPSIBLINGS', но не' WS_CLIPCHILDREN'? – IInspectable

+0

Если мышь перемещается по кнопке или другому дочернему элементу управления, она генерирует сообщение «WM_MOUSELEAVE», и оно изменяет размер окна. Это странное поведение. –

+0

КПП. следующие стили не являются расширенными стилями и поэтому не должны быть изменены как GWL_EXSTYLE: WS_CAPTION, WS_THICKFRAME, WS_MINIMIZE, WS_MAXIMIZE, WS_SYSMENU. Если вы хотите изменить эти стандартные стили, используйте GWL_SYLE. – bkausbk

ответ

0

Я исправил проблему с помощью функции SetWindowRgn. Это все еще не отвечает на вопрос, почему происходит мерцание, но это устранило проблему для меня, поскольку я смог достичь того же. Код ниже:

HRGN region = CreateRectRgn(0, BUTTONS_AREA_HEIGHT, width, height); 
SetWindowRgn(windowHandle, region, TRUE); 
DeleteObject(region); 
+0

Попробуйте отреагировать на ['WM_ERASEBKGND'] (https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms648055 (v = vs.85) .aspx) вручную и ничего не делать, кроме возврата ненулевого , – hidefromkgb

 Смежные вопросы

  • Нет связанных вопросов^_^