2016-10-31 8 views
0

테두리가없는 창 (CreateWindow에서 WS_POPUP)을 만들고 있으므로 마우스가 끝났을 때 크기를 조정하고 마우스가 응용 프로그램에서 벗어 났을 때 다시 변경해야합니다. 그것은 정상적으로 작동하지만 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_CLIPCHILDREN이 아니라'WS_CLIPSIBLINGS'를 요청 했습니까? – IInspectable

+0

마우스가 버튼이나 다른 자식 컨트롤 위로 이동하면'WM_MOUSELEAVE' 메시지가 생성되고 창 크기가 조정됩니다. 이상한 행동입니다. –

+0

Btw. 다음 스타일은 확장 스타일이 아니므로 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)에 반응하고 0이 아닌 값을 반환하는 것 외에는 아무 작업도 수행하지 마십시오 . – hidefromkgb