c - 如何删除任意 HWND 边框 (WinAPI)?

标签 c windows winapi border nonclient-area

长话短说,我正在构建一个 i3 风格的平铺窗口管理器,并且需要覆盖任意窗口的镶边以完全删除边框、标题栏和相关按钮。

在尝试了与 Chrome 相关的 WS_STYLE 和 WS_EX 样式的几乎所有逻辑组合后,我对大多数应用程序一无所获。对于简单的 native 程序来说没问题(终端按预期工作),但对于绝大多数其他应用程序来说,都会出现同样的问题;

Border issue

大多数情况下都会出现上述结果。周围有一个大小相同的边框,但每个应用程序的行为不同。据我所知,这是用于鼠标拖动 HitTest 的“透明”(显然不是在本例中)边框(尽管在样式中禁用了框架,但不应出现该边框)。似乎该区域中的帧缓冲区没有被清除(即,如果窗口调整到自身大小,则边框将被该位置处的先前像素填充)。

这是一个快速的周末项目 - 我的工作与 WinAPI 编程无关,所以这对我来说是全新的,但如果我假设正确,那么这个边界实际上是非客户区域?换句话说,非客户区必须清零,以便客户区占据整个窗口矩形。我尝试通过使用 GWL_WNDPROC 对所有目标窗口进行子类化并将 WM_NCCALCSIZE 归零来处理此问题,但我得到了相同的结果。

如何强制任意窗口(不是我自己创建的)完全删除其整个非客户区?

最佳答案

我使用以下函数来删除/恢复窗口的边框:

void WndSetFrame(HWND hWnd, int bSmall)
{
    static int wwStyle=0;       // remember initial style
    int ww= GetWindowLong(hWnd, GWL_STYLE);

    if (bSmall) {
        wwStyle= ww;
        ww &= ~(WS_OVERLAPPED|WS_CAPTION|WS_MAXIMIZEBOX|WS_MINIMIZEBOX|WS_SIZEBOX|WS_SYSMENU);
        ww |=  (WS_POPUP /*|WS_DLGFRAME*/);
        if (ww==wwStyle) return;
        SetWindowLong(hWnd, GWL_STYLE, ww);
    }
    else {
        if (!wwStyle || ww==wwStyle) return;
        SetWindowLong(hWnd, GWL_STYLE, wwStyle);
    }
    SetWindowPos (hWnd,0,0,0,0,0,SWP_DRAWFRAME|SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER);

}

关于c - 如何删除任意 HWND 边框 (WinAPI)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59838847/

相关文章:

c - 为什么 strtok 只打印第一个字?

c++ - 子进程的标准输出/标准错误文件为空,FILE_FLAG_NO_BUFFERING 不工作

c# - 自制服务器场和远程调试

c - 为什么 makefile 会自动生成目标文件 (*.o) 而没有任何特定规则?

c - popen with/dev/fd/n 匿名管道挂起子进程

多语句函数的 C 预处理器语法?

php - 在 WAMP 64 位架构上加载 Mongo Driver 1.6.x 驱动程序

c# - 无法通过 Windows 8.1 和 Windows 10 上的 Win32 API 从控制面板删除打印机

c++ - 能否从 DLL 中动态调用对象?

c++ - 如何在 C++ 中创建文件映射?