(开源,GPLv3)EbookCopier 实现(2) – 具有半透明和鼠标穿透效果的“取景框”
2009-03-13 14:32
309 查看
设置剪辑区域后,程序会在屏幕上显示“取景框”标出剪辑区域,如下图所示,图中红色边框和和中间的“剪辑区域”字样即是。这个“取景框”像贴在屏幕上一样,不会影响你键盘和鼠标的操作。它事实上是由一个分层窗口(a layered window)实现的。
很高兴的是,在我动手之前看到了 Rui Lopes 为此写的 Per Pixel Alpha Blend in C#,已经实现了这一效果的托管封装,我们的窗体从中派生就可以了。这些代码在项目的 /EbookCopier/Ref/PerPixelAlphaForm.cs 文件中。尽管如此,我们还是看一下实现的原理吧。
Windows 2000操作系统增加了 WS_EX_LAYERED 扩展窗口风格。如果使用了该属性,窗体将具备复合形状、动画、阿尔法混合等方面的视觉特效。为得到一个分层窗口(layered window),必须设置 WS_EX_LAYERED 标志位,这可以在窗体创建时设置,也可以在创建后通过以GWL_EXSTYLE标志调用 SetWindowLong() 来进行设置。在托管代码中可以这样实现:
接下来,可以通过 UpdateLayeredWindows() 函数来更新分层窗口。在具体使用时,需要在位图中绘制出可视区域,并将其与关键色、阿尔法混合参数等一起提供给 UpdateLayeredWindows() 函数。托管代码中需要 DllImport,封装如下:
“取景框”窗体类(class FocusRectForm)在 /EbookCopier/FocusRectForm.cs 中实现,它从 AlphaForm 类派生。根据捕捉状态的不同,它共有四种样子,正常模式如下:
连续捕捉时,显示当前页面:
截取屏幕图像时,需要剪辑区域空白:
截取屏幕后,显示半透明蒙层,以表示已经拷贝完毕:
具体代码比较繁琐,就不贴在文章中了,有兴趣的话请浏览 /EbookCopier/FocusRectForm.cs 文件。
至此,我们就实现了这个“取景框”窗体。
数字图书复印机(EbookCopier) 遵循 GPLv3 协议开源,如果你有更多的创意,欢迎请加入我们。
项目地址:http://code.google.com/p/ebookcopier/
源代码和可执行程序下载:http://code.google.com/p/ebookcopier/downloads/list
本文同时发布到以下位置,以便更多的朋友能够看到本文:
http://chuangen.name/ (我的主页)
http://blog.csdn.net/chuangen (IT 社区)
http://chuangen.cnblogs.com/ (.NET 技术社区)
http://chuangen-cn.spaces.live.com/ (live Spaces)
一、窗体的阿尔法混合透明(Per-Pixel-Alpha)效果
这一实现必须调用 Win32 API,这意味着我们的程序只能在 Windows 下运行,别指望随 Mono 去 Linux 兜风了。很高兴的是,在我动手之前看到了 Rui Lopes 为此写的 Per Pixel Alpha Blend in C#,已经实现了这一效果的托管封装,我们的窗体从中派生就可以了。这些代码在项目的 /EbookCopier/Ref/PerPixelAlphaForm.cs 文件中。尽管如此,我们还是看一下实现的原理吧。
Windows 2000操作系统增加了 WS_EX_LAYERED 扩展窗口风格。如果使用了该属性,窗体将具备复合形状、动画、阿尔法混合等方面的视觉特效。为得到一个分层窗口(layered window),必须设置 WS_EX_LAYERED 标志位,这可以在窗体创建时设置,也可以在创建后通过以GWL_EXSTYLE标志调用 SetWindowLong() 来进行设置。在托管代码中可以这样实现:
protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x00080000; // This form has to have the WS_EX_LAYERED extended style return cp; } }
接下来,可以通过 UpdateLayeredWindows() 函数来更新分层窗口。在具体使用时,需要在位图中绘制出可视区域,并将其与关键色、阿尔法混合参数等一起提供给 UpdateLayeredWindows() 函数。托管代码中需要 DllImport,封装如下:
public const Int32 ULW_COLORKEY = 0x00000001; public const Int32 ULW_ALPHA = 0x00000002; public const Int32 ULW_OPAQUE = 0x00000004; /// /// The UpdateLayeredWindow function updates the position, size, shape, content, /// and translucency of a layered window. /// /// 窗体句柄 /// 窗体的 DC 句柄 /// 窗体左上角位置 /// 窗体大小 /// 要设置的图像源 DC 句柄 /// 图像源位置 /// 要透明的颜色 /// 窗体透明度 /// 标识位,ULW_COLORKEY 为指定颜色透明,ULW_ALPHA 为允许半透明的窗体,ULW_OPAQUE 为不透明 /// 成功=True; 失败=False; [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)] public static extern Bool UpdateLayeredWindow( IntPtr hwnd, IntPtr hdcDst, ref Point pptDst, ref Size psize, IntPtr hdcSrc, ref Point pprSrc, Int32 crKey, ref BLENDFUNCTION pblend, Int32 dwFlags);
二、窗体的鼠标穿透(Click-Through)效果
具有WS_EX_LAYERED 标志的分层窗口,添加 WS_EX_TRANSPARENT 就可以使鼠标穿透。该实现位于 /EbookCopier/AlphaForm.cs 中。我添加了一个 ClickThroughEnable 属性,设置为True,则窗体具有鼠标穿透效果。private bool clickThroughEnable = false; /// /// 获取或设置一个值,指示窗体是否有鼠标穿透功能。 /// /// 如果该实例can penetrate,为true;否则为false。 public bool ClickThroughEnable { get { return clickThroughEnable; } set { clickThroughEnable = value; if (clickThroughEnable) {//使窗口有鼠标穿透功能 uint intExTemp = GetWindowLong(this.Handle, GWL_EXSTYLE); uint oldGWLEx = SetWindowLong(this.Handle, GWL_EXSTYLE, intExTemp | WS_EX_TRANSPARENT | WS_EX_LAYERED); } else {//使窗体恢复正常 this.FormBorderStyle = FormBorderStyle.None; } } }
三、GDI+ 绘图
在实现阿尔法混合透明和鼠标穿透功能后,设置窗体TopMost=true和ShowInTaskbar=false,就得到了我们想要的窗体。接下来GDI+绘制我们想要的图形就可以了。“取景框”窗体类(class FocusRectForm)在 /EbookCopier/FocusRectForm.cs 中实现,它从 AlphaForm 类派生。根据捕捉状态的不同,它共有四种样子,正常模式如下:
连续捕捉时,显示当前页面:
截取屏幕图像时,需要剪辑区域空白:
截取屏幕后,显示半透明蒙层,以表示已经拷贝完毕:
具体代码比较繁琐,就不贴在文章中了,有兴趣的话请浏览 /EbookCopier/FocusRectForm.cs 文件。
至此,我们就实现了这个“取景框”窗体。
数字图书复印机(EbookCopier) 遵循 GPLv3 协议开源,如果你有更多的创意,欢迎请加入我们。
项目地址:http://code.google.com/p/ebookcopier/
源代码和可执行程序下载:http://code.google.com/p/ebookcopier/downloads/list
本文同时发布到以下位置,以便更多的朋友能够看到本文:
http://chuangen.name/ (我的主页)
http://blog.csdn.net/chuangen (IT 社区)
http://chuangen.cnblogs.com/ (.NET 技术社区)
http://chuangen-cn.spaces.live.com/ (live Spaces)
相关文章推荐
- (开源,GPLv3)EbookCopier 实现(2) - 具有半透明和鼠标穿透效果的“取景框”
- [随笔]关于如何实现鼠标穿透窗口和窗口半透明
- (开源,GPLv3)EbookCopier 实现(3) - 使用 iTextSharp 库生成 PDF 文档
- (开源,GPLv3)EbookCopier 实现(1) - 概述
- (开源,GPLv3)EbookCopier 实现(3) - 使用 iTextSharp 库生成 PDF 文档
- (开源,GPLv3)EbookCopier 实现(1) - 概述
- Winform实现鼠标可穿透的窗体镂空效果
- winform和wpf如何实现鼠标穿透的效果
- js实现具有高亮显示效果的多级菜单代码
- 在salesforce中实现鼠标悬停显示提示框效果,并对显示框内容进行微缩页面布局
- 鼠标缩略图遥感图像显示时的连动效果——Qt实现
- 实现鼠标经过,离开,点击三种效果
- 实现一个宽和高都是100像素的div可以用鼠标拖拽移动的效果
- JS+DIV实现鼠标划过切换层效果的方法
- Python基于pygame实现图片代替鼠标移动效果
- Python基于pygame实现图片代替鼠标移动效果
- .net下实现鼠标左右两个按键齐击,就好像扫雷下面的效果
- CSS opacity - 实现图片半透明效果的代码
- JS实现跟随鼠标的链接文字提示框效果
- jquery实现鼠标滑过后动态图片提示效果实例