几乎如标题所说。
我正在尝试制作自己的边框,就像 visual studio 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);
}
最佳答案
如果只需要矩形边框,可以采用如下更简单的解决方案:
- 窗口样式应该是这样的,通常整个框架都会显示(
WS_CAPTION|WS_POPUP
对我来说效果很好)。 - 使用
MARGINS{0,0,0,1}
调用DwmExtendFrameIntoClientArea()
。 - 调用
SetWindowPos(nullptr, 0, 0, 0, 0, SWP_NOZORDER|SWP_NOOWNERZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_FRAMECHANGED)
重新计算 NC 区域。 - 如果 wParam 为
TRUE
,则从WM_NCCALCSIZE
返回 0。这具有将客户区扩展到包括框架在内的窗口大小的效果。常规窗口框架将被删除,但阴影仍将由 DWM 绘制(另请参见 WM_NCCALCSIZE 的备注部分)。 - 在
WM_PAINT
中绘制您喜欢的框架和内容区域,但确保为DwmExtendFrameIntoClientArea()
调用定义的边距设置不透明的 alpha channel 。否则部分常规框架将在此区域可见。您可以为此使用 GDI+,因为大多数常规 GDI 函数会忽略 alpha channel 。
您可以像往常一样将子控件放入此窗口中。只需确保子控件不与 DwmExtendFrameIntoClientArea()
调用定义的边距重叠,因为大多数 GDI 控件会忽略 alpha channel 。
关于c++ - 创建自定义窗口边框边缘在调整大小时消失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43622839/