2017-04-26 76 views
3

幾乎標題所示。當調整縮小尺寸時創建自定義窗口邊框消失

我試圖做我自己的邊框,就像視覺工作室2015. 一旦我有邊框工作就像它應該我會添加一個子窗口,是我的程序的主窗口,邊框將是父。 一旦我得到它的工作,也會嘗試添加外部發光。

但是我現在有的問題是,當我拖動我的邊框來調整它的大小以使其更小時,根據拖動鼠標的速度,右側或底部開始變細。

有沒有更好的方法來做到這一點,或者有一個簡單的步驟,我可以採取修復它。

#include <windows.h> 

LPTSTR className_ = TEXT("BorderWindow"); 

BOOL WINAPI Init(HINSTANCE hInstance, INT cmdShow); 
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam); 


INT WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, INT nCmdShow) { 
    MSG msg; 
    if (!Init(hInstance, nCmdShow)) { 
     return FALSE; 
    } 

    while (GetMessage(&msg, NULL, 0, 0)) { 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
    } 

    return (INT)msg.wParam; 
} 


BOOL WINAPI Init(HINSTANCE hInstance, INT cmdShow) 
{ 
    WNDCLASSEX wcex{ 0 }; 
    wcex.cbSize = sizeof(WNDCLASSEX); 
    wcex.style = 0; 
    wcex.lpfnWndProc = (WNDPROC)WndProc; 
    wcex.hInstance = hInstance; 
    wcex.hIcon = NULL; 
    wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); 
    wcex.hbrBackground = (HBRUSH)(COLOR_HIGHLIGHT + 1); 
    wcex.lpszClassName = className_; 
    wcex.hIconSm = NULL; 
    if (!RegisterClassEx(&wcex)) { 
     return FALSE; 
    } 

    HWND hwnd_ = CreateWindow(className_, className_, WS_OVERLAPPEDWINDOW, 
     CW_USEDEFAULT, 0, 200, 500, nullptr, nullptr, hInstance, nullptr); 

    if (!hwnd_) 
     return FALSE; 

    ShowWindow(hwnd_, cmdShow); 
    UpdateWindow(hwnd_); 

    return TRUE; 
} 


void CreateHole(HWND hWnd) 
{ 
    HRGN WindowRgn; 
    HRGN HoleRgn; 

    //Get the window region: 
    RECT windowrect; 
    GetWindowRect(hWnd, &windowrect); 

    int width = windowrect.right - windowrect.left; 
    int height = windowrect.bottom - windowrect.top; 
    WindowRgn = CreateRectRgn(0, 0, width, height); 

    //Create the hole region: 
    HoleRgn = CreateRectRgn(2, 2, width - 2, height - 2); 

    CombineRgn(WindowRgn, WindowRgn, HoleRgn, RGN_DIFF); 
    SetWindowRgn(hWnd, WindowRgn, TRUE); 
} 


LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) 
{ 
    switch (message) 
    { 
    case WM_DESTROY: 
     PostQuitMessage(0); 
     return 0; 

    case WM_SIZE: 
     CreateHole(hwnd); 
     return 0; 

    case WM_NCCALCSIZE: 
     // remove default borders 
     return 0; 

    case WM_NCHITTEST: 
    { 
     RECT rc; 
     GetClientRect(hwnd, &rc); 
     POINT pt = { LOWORD(lparam), HIWORD(lparam) }; 
     ScreenToClient(hwnd, &pt); 

     if (pt.y > (rc.bottom - 5)) 
     { 
      if (pt.x > (rc.right - 5)) 
      { 
       return HTBOTTOMRIGHT; 
      } 
     } 

     return HTBORDER; 
    } 

    } 
    return DefWindowProc(hwnd, message, wparam, lparam); 
} 
+0

我們可以看到[mcve]而不是你的部分'BorderWindow'實現嗎?強烈建議刪除任何抽象。 – IInspectable

+0

@IInspectable我更新了代碼,它是完整的,你應該能夠建立它。 – vusuzireru

+0

'LOWORD'和'HIWORD'不是檢索打包到'LPARAM'中的鼠標指針座標的正確方法。改爲使用'GET_X_LPARAM'和'GET_Y_LPARAM'。 –

回答

0

如果你只需要矩形框,一個簡單的解決方案,可以實現如下:

  • 窗口風格應該是這樣的,通常爲整個框架將被顯示(WS_CAPTION|WS_POPUP很適合我)。
  • 撥打電話DwmExtendFrameIntoClientArea()MARGINS{0,0,0,1}
  • 致電SetWindowPos(nullptr, 0, 0, 0, 0, SWP_NOZORDER|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_FRAMECHANGED)重新計算NC區域。
  • 如果wParam爲TRUE,則返回0從WM_NCCALCSIZE。這具有將客戶區擴展到包括框架的窗口大小的效果。常規窗口框架將被刪除,但DWM仍將繪製陰影(另請參閱WM_NCCALCSIZE的備註部分)。
  • WM_PAINT中根據需要繪製您的框架和內容區域,但請確保爲由DwmExtendFrameIntoClientArea()調用定義的邊距設置不透明的Alpha通道。否則,在此區域中可以看到常規框架的一部分。您可以使用GDI +,因爲大多數常規GDI函數忽略Alpha通道。

您可以像往常一樣將子控件放入此窗口中。只要確保子控件不會與DwmExtendFrameIntoClientArea()調用定義的邊距重疊,因爲大多數GDI控件都會忽略Alpha通道。

+0

WM_Paint中的繪製的邊框/框架是否消失在邊緣調整窗口的大小? – vusuzireru

+0

@vusuzireru調用'WM_SIZE'中的'InvalidateRgn()'將幀添加到更新區域。如果框架繪製仍然滯後,請使用'RedrawWindow()'替換調用。確保檢查'WM_PAINT'中的更新區域以僅繪製必要的部分。雖然在調整窗口大小時總會有一點滯後,即使使用常規窗口也可以注意到。你不能做太多的事情。 – zett42

相關問題