如何将非客户区扩展到小于 16 像素的窗口?

Posted

技术标签:

【中文标题】如何将非客户区扩展到小于 16 像素的窗口?【英文标题】:How do I extend nonclient area into a window thinner than 16 pixels? 【发布时间】:2014-10-17 20:05:33 【问题描述】:

我正在做一个项目,该项目需要我在屏幕上水平绘制一条细线并垂直拖动它。为了增加一点风格,我尝试将 DWM 玻璃效果添加到窗口,以便它与 Windows 7 和 8 中的窗口边框匹配(尽管我知道我不会在 Windows 8 中获得透明度)。

我已经通过使用 sheet of glass 技巧和 DwmExtendFrameIntoClientArea 创建一个子窗口并将非客户区扩展到客户区来绘制线条,如下所示:

MARGINS margins =  -1, -1, -1, -1 ;
DwmEnableComposition(DWM_EC_ENABLECOMPOSITION);
DwmExtendFrameIntoClientArea(DIV_HWND, &margins);

我创建这样的窗口:

HWND DIV_HWND = CreateWindow(DIV_NAME,
    NULL,
    WS_VISIBLE,
    0, 0, mon_info.rcWork.right, mon_info.rcWork.top + 3,
    top->hwnd, NULL,
    hInstance, NULL);

窗口类是这样的:

const wchar_t DIV_NAME[] = L"DIV";

WNDCLASS DIV = ;
DIV.lpfnWndProc = DIV_PROC;
DIV.hInstance = hInstance;
DIV.lpszClassName = DIV_NAME;
DIV.hCursor = LoadCursor(NULL, IDC_SIZEALL);

RegisterClass(&DIV);

通过处理 WM_GETMINMAXINFO 消息并将 2 作为 ptMinTrackSize.x 和 y 返回,我已将窗口缩小到 16 像素的宽度,并具有我希望在窗口边框周围看到的所有漂亮边框和阴影效果,但我似乎不能让它比这更小。

我可以通过在我用 SetWindowRgn 设置的区域上使用 DwmEnableBlurBehindWindow 来获得一个“玻璃状”窗口,但即使它处于焦点位置,颜色也是背景窗口的颜色。另外我想念轻微的阴影和边框。

由于每个边框的宽度为 8 像素,因此似乎我可能会因边框大小而受到尺寸限制。

非常感谢任何帮助!

【问题讨论】:

当你低于 16 像素时会发生什么? 窗口显示为 16 像素高。我应该注意到窗口没有被边框包围,因为我已经处理了 WM_NCCALCSIZE 返回 0,所以我的窗口大小在创建时发生。 【参考方案1】:

我找到了我的答案,所以我会把它留在这里,以防其他人需要它。我所要做的就是调用DwmSetWindowAttribute(hwmd, DWMWA_NCRENDERING_POLICY, DWMNCRP_ENABLED, sizeof(int)); 以确保DWM 渲染策略不基于窗口样式。这让我可以使用 WS_POPUP 窗口来获得我想要的大小,并带有漂亮的玻璃填充内部。

这里有一些错误:

    如果窗口的 Y 尺寸小于 16 像素,则顶部和底部会出现奇怪的阴影。 在 Vista\7 上,圆形窗口边缘使窗口具有奇怪的椭圆形形状。

【讨论】:

以上是关于如何将非客户区扩展到小于 16 像素的窗口?的主要内容,如果未能解决你的问题,请参考以下文章

16.windows坐标系

表格的宽度不能小于 140 像素。为啥?

当我将屏幕调整为小于 600 像素时,媒体查询不起作用

在移动设备上禁用粘性导航

CUDA如何从屏幕获取像素?

如何在小于 600 像素的屏幕上“打开”页面加载时的 Bootstrap 下拉菜单