Win32 API 异形窗口:突破传统矩形窗口的限制

零 C语言教程评论91字数 1306阅读4分21秒阅读模式

Win32 API 异形窗口:突破传统矩形窗口的限制

原理探究

Windows 提供了一种叫做"窗口区域"(Window Region)的机制,允许我们自定义窗口的可见区域。通过设置窗口区域,我们可以创建出各种形状的窗口,甚至是带有透明区域的镂空窗口。

实现这个功能主要涉及以下 Win32 API:文章源自灵鲨社区-https://www.0s52.com/bcjc/cyyjc/16407.html

  • SetWindowRgn: 设置窗口的区域
  • CreateRectRgn: 创建矩形区域
  • CombineRgn: 组合多个区域
  • GetWindowRgn: 获取窗口当前的区域
  • SetWindowLong: 修改窗口的样式

实现方案

1. SetWindowRgn 和 GetWindowRgn 获取当前窗口区域

C++

复制代码
    HRGN hrgnWindow;
    //……
    SetWindowRgn(hwnd, hrgnWindow, TRUE);
    int res = GetWindowRgn(hwnd, hrgnWindow);
    if (res == ERROR) {
        DeleteObject(hrgnWindow);
        return;
    }
    //……
  • 当创建一个新窗口时,它默认没有设置特定的窗口区域。在这种情况下,窗口的可见区域就是整个客户区域。
  • 如果窗口没有设置过区域(即从未调用过 SetWindowRgn),GetWindowRgn 通常会返回 ERROR。 一旦调用过 SetWindowRgn,GetWindowRgn 就能够获取到设置的区域。
  • 先调用 SetWindowRgn 再调用 GetWindowRgn 的模式,原因如下:确保有区域可以获取:如前所述,如果没有设置过区域,GetWindowRgn 可能会失败;初始化窗口形状:通常我们需要先设置一个初始的窗口形状,然后在此基础上进行修改。

2. CombineRgn 合成不规则区域

C++

复制代码
    CombineRgn(hrgnWindow, hrgnWindow, hrgn, iMode);

重点是最后一个参数,iMode 参数表示组合模式。文章源自灵鲨社区-https://www.0s52.com/bcjc/cyyjc/16407.html

03_01_combineRgn.png文章源自灵鲨社区-https://www.0s52.com/bcjc/cyyjc/16407.html

3. SetWindowRgn 将组合后的新区域设置为窗口的区域

C++

复制代码
    SetWindowRgn(hwnd, hrgnWindow, TRUE);

当我们改变窗口区域时,Windows 会自动触发窗口的重绘。这就是为什么在调用 SetWindowRgn 时将最后一个参数设置为 TRUE。文章源自灵鲨社区-https://www.0s52.com/bcjc/cyyjc/16407.html

4. SetWindowLong 修改窗口的样式

C++

复制代码
    SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_TRANSPARENT | WS_EX_LAYERED);

如果在前面通过 CombineRgn 将窗口区域设置为镂空的,其实就已经实现了鼠标点击事件的穿透。当然也可以用 SetWindowLong 直接设置鼠标穿透~文章源自灵鲨社区-https://www.0s52.com/bcjc/cyyjc/16407.html

注意

在函数结束时要调用了 DeleteObject(hrgnWindow),因为 GDI 对象(如区域)需要手动释放,否则可能导致资源泄漏。文章源自灵鲨社区-https://www.0s52.com/bcjc/cyyjc/16407.html

实现效果

03_02_gif.gif文章源自灵鲨社区-https://www.0s52.com/bcjc/cyyjc/16407.html

总结

通过使用 Win32 API 中的区域相关函数,我们可以创建出各种形状的窗口,突破传统矩形窗口的限制。这为 UI 设计提供了更多的可能性,可以创建各种有趣的 UI 效果,例如:不规则形状的界面或弹出窗口、带有透明区域的镂空窗口等。还有很多酷炫的效果待我再好好研究研究嘿嘿文章源自灵鲨社区-https://www.0s52.com/bcjc/cyyjc/16407.html 文章源自灵鲨社区-https://www.0s52.com/bcjc/cyyjc/16407.html

零
  • 转载请务必保留本文链接:https://www.0s52.com/bcjc/cyyjc/16407.html
    本社区资源仅供用于学习和交流,请勿用于商业用途
    未经允许不得进行转载/复制/分享

发表评论