2017-04-26 77 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

相关问题