`
bcyy
  • 浏览: 1823267 次
文章分类
社区版块
存档分类
最新评论

SetWindowRgn函数应用--截图,绘制多边形窗体

 
阅读更多

版权所有,转载请注明出处:http://guangboo.org/2013/02/04/setwindowrgn-application

SetWindowRgn函数用于设置窗体的绘制区域,该区域决定了窗口的形状,并且超出该区域的一切绘制工作都无效的,不会显示在屏幕上。

函数签名

int SetWindowRgn(HWND hWnd, HRGN hRgn, BOOL bRedraw);

其中参数hWnd是要设置区域的窗口句柄;hRgn是区域句柄,该值可以是NULL;bRedraw表示设置完窗口区域后是否重新绘制窗口,True,表示重新绘制,否则不绘,如果窗口可见,bRedraw一般设为True。返回值为非零时表示设置成功,否则失败。

需要注意的是,这里的区域坐标是相对于窗口的左上角而言的,而不是窗口的工作区。一旦方法调用成功,那么系统就获取了这片区域的句柄,并可以在这片区域进行绘制。

C#函数声明

该函数定义在User32.dll中(参考http://msdn.microsoft.com/zh-cn/library/dd145102(v=VS.85).aspx),因此C#可以通过平台调用来引用该win32api,如下声明:

[DllImport("user32.dll")]
private static extern int SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool bRedraw);

其中hWnd可以在Form中使用this.Handle获取,而hRgn则没有类似的定义,也没有对应的结构体。但是C#中有Region类(System.Drawing命名空间),并且该类提供了GetHrgn方法,用来获取Region类的句柄。并且如果你要绘制圆角矩形的窗体,还可以调用CreateRoundRectRgn方法来获取圆角矩形的区域句柄,该方法的在gdi32.dll中定义(参考http://msdn.microsoft.com/zh-cn/library/dd183516.aspx)。声明如下:

[DllImport("gdi32.dll")]
private static extern IntPtr CreateRoundRectRgn(int x1, int y1, int x2, int y2, int cx, int cy);

参数x1,y1表示圆角矩形左上角的坐标,x2,y2表示矩形的宽和高,cx, cy表示圆角所占椭圆的宽和高。如果调用成功,返回值为圆角矩形的区域句柄,否则为NULL。

截图应用

有了SetWindowRgn函数,我们就可以实现对窗口“挖洞”了。类似于QQ的截图功能,它的效果是,整个屏幕都变黑底半透明,然则在屏幕上选择一款矩形区域,并且选择的矩形区域是没有黑底半透明修饰的。那么这样的效果就像对一个全屏的,背景是黑色半透明的窗体,选择一块矩形区域,并将选择的矩形区域“挖空”一样。现在有了SetWindowRgn函数,我们就可以实现“挖空”效果了。一段测试代码,用来绘制“中空”的窗体,只有重写OnPaint方法或在WnProc方法中拦截WM_PAINT消息:

protected override void OnPaint(PaintEventArgs e) {
    System.Drawing.Region region = new System.Drawing.Region();
    region.Union(this.Bounds);
    region.Exclude(new Rectangle(40, 40, 100, 100));
    SetWindowRgn(this.Handle, region.GetHrgn(e.Graphics), true);
    base.OnPaint(e);
}

或者:

protected override void WndProc(ref Message m) {
    switch (m.Msg) {
        case WM_PAINT:
            System.Drawing.Region region = new System.Drawing.Region();
            region.Union(this.Bounds);
            region.Exclude(new Rectangle(40, 40, 100, 100));
            IntPtr dc = GetWindowDC(m.HWnd);
            Graphics g = Graphics.FromHdc(dc);
            SetWindowRgn(m.HWnd, region.GetHrgn(g), true);
            break;
    }
    base.WndProc(ref m);
}

两个代码的效果是一样的,都在相对窗体的(40,40)的位置开始“挖”去一个长宽是100X100的矩形,运行效果如图:

“挖空”的效果已经实现,接着就是将窗体全屏,设置黑色背景,半透明化;然后将“挖空”的矩形改成屏幕选择的区域。这些代码可以参加《C#实现屏幕截图,这里不再贴出代码。

不过有一点需要说明,在选择区域时,应该调用Refresh方法,来刷新界面,否则是不会发出WM_PAINT消息的,也就没有了OnPaint事件了。

绘制多边形窗体

最常用的窗体样式就是圆角窗体了,如果使用SetWindowRgn方法就变的异常简单,只需要简单几行代码即可,如下:

const int WM_PAINT = 0x000F;
const int WM_SIZE = 0x0005;
protected override void WndProc(ref Message m) {
    switch (m.Msg) {
        case WM_PAINT:
        case WM_SIZE:
            SetWindowRgn(m.HWnd, CreateRoundRectRgn(0, 0, this.Width, this.Height, 20, 20), true);
            break;
    }
    base.WndProc(ref m);
}

这里用到了CreateRoundRectRgn函数,用于创建圆角区域,当然你也可以使用Region类来自己手动创建圆角区域。运行效果如下图:

这是在Window Classic主题下的效果。当然,如果希望Window XP主题下(本身就是圆角的窗体主题)使窗体没有圆角效果,只需要将CreateRoundRectRgn(0, 0, this.Width, this.Height, 20, 20)代码修改成CreateRoundRectRgn(0, 0, this.Width, this.Height, 0, 0)即可,运行效果如图:

但这里的示例仅仅用来演示修改窗体形状原理的,一般在实现一个窗体效果时,还需要很多的修饰,具体可以参考《C#重绘Windows窗体标题栏和边框》。上面主要演示了最常用的圆角或实角矩形窗体效果,当然有了Region类和 SetWindowRgn函数,我们可以实现更加丰富的窗体效果,只是这些效果不是很常用。

分享到:
评论

相关推荐

    设定不规则窗体 SetWindowRgn

    设定不规则窗体 SetWindowRgn 不规则窗体 SetWindowRgn

    VC6.0 绘制多边形、圆角或椭圆形窗体的实例.rar

    一个VC 6.0个性化窗体设计实例,绘制矩形、多边形、圆角或椭圆形的窗体,没有了窗口的标题栏和任务栏,以及最大化、最小化按钮,一切看似很简洁,虽然是规则窗口吧,但不属于常规窗口,以后会与大家分享不规则的异型...

    API之网络函数---整理网络函数及功能

    GetTempFileName 这个函数包含了一个临时文件的名字,它可由应用程序使用 GetTempPath 获取为临时文件指定的路径 GetVolumeInformation 获取与一个磁盘卷有关的信息 GetWindowsDirectory 获取Windows目录的完整...

    Windows 中不规则窗体的编程实现

     在绝大多数的Windows应用程序中,其窗体都是使用的正规正矩的矩形窗体,例如我们常用的,“记事本”,“扫雷”,等等。矩形窗体,具有编程实现简单,风格简洁的优点,所以在普通文档应用程序和简单小游戏中使用足矣...

    QQ2006.rar_SetWindowRgn_resizing_对话框 大小_对话框 改变 大小_窗体

    创建异形窗体函数 SetWindowRgn 放到合适的位置,别让拖动窗体改变大小时出现用做 MASK 的紫色区域;再者与大家分享不指定窗体风格 WS_THICKFRAME(对于对话框,相当指定其属性 Border 为 Resizing ),用代码实现...

    SetWindowRgn

    SetWindowRgn对系统滚动条的影响

    MFC框架下简单异形窗口--SetWindowRgn

    一个简单的异形窗口的工程。 用VS2005编译的,使用了MFC做框架。

    VB SetWindowRgn创建椭圆形窗口.rar

    VB创建一个个性化的椭圆形窗口界面,使用 SetWindowRgn创建椭圆形窗口的例子。个性的窗口形状可增加程序的趣味性,可以使程序更具吸引力。见惯了方方正正的矩形窗体,椭圆形窗体更会使用户眼前一亮。本实例设计一个...

    生成椭圆形窗体程序(vb6.0源代码编写)

    '函数声明 Private Declare Function CreateEllipticRgn Lib "gdi32" (ByVal X1 As Long, _ ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long Private Declare Function SetWindowRgn Lib "user32...

    带椭圆空洞的透明窗体,VB源代码.rar

    Then use SetWindowRgn to restrict the form to the resulting region. Disclaimer This example program is provided "as is" with no warranty of any kind. It is intended for demonstration purposes only....

    win32下创建异形窗体

    异型窗口就是一些不规则的窗口,我们平时所见到的窗口如“画图”、word等,它们的窗口都是矩形的,然而,我们实际开发中,项目为了增加交互性和漂亮的UI来吸引用户,产品经理极有可能需要来做一些不规则的窗口。...

    Delphi 透明窗体.rar

    Delphi 透明窗体这个也是同样很简单,点击按钮后窗体边框和标题栏以及主窗体都会消失,只剩下一个按钮了,其实是窗体透明化了,完全100%的窗口透明效果。

    字形窗口_sub_visualbasic_vb6_字形特效窗体_

    3 SelectObject dc OldFont EndPath dc '结束记录窗体轮廓路径 mw = PathToRegion(dc) '把所记录的路径转化为窗体轮廓句柄 SetWindowRgn Me.hWnd mw True '赋予窗体指定的轮廓形状 End Sub

    vb圆形窗体

    Caption = "椭圆窗体" ClientHeight = 3330 ClientLeft = 60 ClientTop = 345 ClientWidth = 4860 FillColor = &H00FF0000& BeginProperty Font Name = "宋体" Size = 12 Charset = 134 Weight = 400 ...

    不规则Window窗体(MFC)

    利用SetWindowRgn()实现不规则对话框,窗体为一个任意图片,可以更改图片,达到不同的不规则窗体

    易语言-API制作有洞的窗体

    API制作有洞的窗体,源码是APICreateRectRgn,CreateEllipticRgn,CombineRgn,SetWindowRgn等函数的应用教程,

    透空窗口 GetGlyphOutline() SetWindowRgn() beginpath(),SetBkMode(),endpath(),StrokePath()

    然后就能够使用GDI绘画函数函数,去绘画! 画完之后,别忘记用Endpath关闭。 在"Delphi help"中的"Path"可以理解成“轮廓”,可以是:文字的轮廓 SetBkMode 指定阴影刷子、虚线画笔以及字符中的空隙的填充方式 我...

    Delphi 用获取路径的方法得到圆形窗体.rar

    Delphi 用获取路径的方法得到圆形窗体,制作实现一个非矩形窗口,可以说是一个不规则窗口了,圆形的窗口,标题栏、状态栏及窗口关闭等操作按钮均不邮了。圆形窗口的基本实现思路是根据路径创建不规则窗体,然后设置...

    VC++界面编程之--使用分层窗口实现界面皮肤

    使用分层界面来实现界面皮肤的好处是:可以保证图片边缘处理不失真,且能用于异形窗口上,如一些不规则的窗口,你很难用SetWindowRgn来达到理想效果。 在很多情况下,界面的漂亮与否,取决于PS的制作及创意,而界面...

    VB不规则窗口设计之沙漏形

    多媒体应用软件中的人机界面设计 一、设计目的和要求: 熟悉基本人机界面的设计,更好的对部件进行控制。 编写一个小程序,要求程序窗体为不规则形(不规则形窗体的控件可在网上下载),并且要求界面背景能在运行中...

Global site tag (gtag.js) - Google Analytics