2016-10-31 3 views
0

Ich erstelle ein Fenster ohne Grenzen (WS_POPUP in CreateWindow) und muss die Größe ändern, wenn die Maus über ist und wieder ändern, wenn die Maus aus der Anwendung ist. Es funktioniert, aber es flackert, wenn ich die Position mit SetWindowPos ändere. Ich muss y um 30 Pixel verkleinern und die Höhe erhöhen, so dass der untere Teil des Fensters in der gleichen Position bleibt.WinAPI CreateWindow WS_POPUP Größe ändern flackern

Unten ist der Code:

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; 
} 

ich alle Kombinationen von SetWindowPos versucht, Movewindow usw., aber wenn die Maus über das Fenster ist, scheint es, dass Fenster erste Einstellungen Y-Position ist, dann erhöht sich die Höhe nach einer einige Millisekunden und das ist sichtbar.

Kennt jemand eine Lösung dafür?

+0

Gibt es irgendwelche Kind Windows? Übrigens, warum haben Sie 'WS_CLIPSIBLINGS', aber nicht' WS_CLIPCHILDREN' angefordert? – IInspectable

+0

Wenn die Maus über eine Schaltfläche oder ein anderes untergeordnetes Steuerelement bewegt wird, wird die Meldung "WM_MOUSELEAVE" generiert und die Größe des Fensters wird geändert. Das ist komisches Verhalten. –

+0

BTW. Die folgenden Stile sind keine erweiterten Stile und sollten daher nicht als GWL_EXSTYLE: WS_CAPTION, WS_THICKFRAME, WS_MINIMIZE, WS_MAXIMIZE, WS_SYSMENU geändert werden. Wenn Sie diese Standardstile ändern möchten, verwenden Sie GWL_SYLE. – bkausbk

Antwort

0

Ich habe das Problem mit der SetWindowRgn-Funktion behoben. Dies beantwortet immer noch nicht die Frage, warum Flimmern auftritt, aber es hat das Problem für mich behoben, da ich das gleiche erreichen konnte. Code ist unter:

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

Versuchen Sie, manuell auf ['WM_ERASEBKGND'] (https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms648055 (v = V.85) .aspx) zu reagieren, und führen Sie dort nichts aus, außer dass Sie ungleich Null zurückgeben . – hidefromkgb