C#软件开发实例.私人订制自己的屏幕截图工具(二)创建项目、注册热键、显示截图主窗口

本实例全部文章目录


开发环境

操作系统:Windows Server 2008 R2

集成开发环境(IDE):Microsoft Visual Studio 2010

开发语言:c#

创建项目

文件》新建》项目


.NET Framework可以选择2.0版本,也可以选择4.0版本;

项目类型选择:Windows窗体应用程序

输入项目名称,确定


项目创建成功,如下图:


修改主窗体属性

修改窗体的“FormBorderStyle”属性为“none”,实现一个没有边框的窗体


修改后窗口设计器中显示如下:


依次按下图修改其它属性,属性值黑体加粗的是修改过的


属性说明:

ShowIcon=False,不显示窗体的图标;

ShowInTaskbar=False,使窗体不在Windows任务栏中出现;

SizeGripStyle=Hide,禁用拖动窗体右下角可以改变大小的功能;

WindowsState=Minimized,窗口启动后最小化;

设置完这些属性后,编译,运行,程序是在运行状态,但是却看不到程序的窗口;

实现热键功能

这里需要使用WindowsAPI

注册热键:RegisterHotKey

该函数定义一个系统范围的热键函数原型:BOOL RegisterHotKey(HWND hWnd,int id,UINT fsModifiers,UINT vk);

取消热键注册:UnregisterHotKey

该函数释放调用线程先前登记的热键。

获取热键ID:GlobalAddAtom

只适用于桌面应用程序。
向全局原子表添加一个字符串,并返回这个字符串的唯一标识符(原子ATOM)。

API及局部变量定义:

[csharp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. /// <summary>  
  2. /// 向全局原子表添加一个字符串,并返回这个字符串的唯一标识符(原子ATOM)。  
  3. /// </summary>  
  4. /// <param name="lpString">自己设定的一个字符串</param>  
  5. /// <returns></returns>  
  6. [System.Runtime.InteropServices.DllImport("Kernel32.dll")]  
  7. public static extern Int32 GlobalAddAtom(string lpString);  
  8.   
  9. /// <summary>  
  10. /// 注册热键  
  11. /// </summary>  
  12. /// <param name="hWnd"></param>  
  13. /// <param name="id"></param>  
  14. /// <param name="fsModifiers"></param>  
  15. /// <param name="vk"></param>  
  16. /// <returns></returns>  
  17. [System.Runtime.InteropServices.DllImport("user32.dll")]  
  18. public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, Keys vk);  
  19.   
  20. /// <summary>  
  21. /// 取消热键注册  
  22. /// </summary>  
  23. /// <param name="hWnd"></param>  
  24. /// <param name="id"></param>  
  25. /// <returns></returns>  
  26. [System.Runtime.InteropServices.DllImport("user32.dll")]  
  27. public static extern bool UnregisterHotKey(IntPtr hWnd, int id);  
  28.   
  29. /// <summary>  
  30. /// 热键ID  
  31. /// </summary>  
  32. public int hotKeyId = 100;  
  33.   
  34. /// <summary>  
  35. /// 热键模式:0=Ctrl + Alt + A, 1=Ctrl + Shift + A  
  36. /// </summary>  
  37. public int HotKeyMode = 1;  
  38.   
  39. /// <summary>  
  40. /// 控制键的类型  
  41. /// </summary>  
  42. public enum KeyModifiers : uint  
  43. {  
  44.     None = 0,  
  45.     Alt = 1,  
  46.     Control = 2,  
  47.     Shift = 4,  
  48.     Windows = 8  
  49. }  
  50.   
  51. /// <summary>  
  52. /// 用于保存截取的整个屏幕的图片  
  53. /// </summary>  
  54. protected Bitmap screenImage;  

注册热键:

[csharp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. private void Form1_Load(object sender, EventArgs e)  
  2. {  
  3.     //隐藏窗口  
  4.     this.Hide();  
  5.   
  6.     //注册快捷键  
  7.     //注:HotKeyId的合法取之范围是0x0000到0xBFFF之间,GlobalAddAtom函数得到的值在0xC000到0xFFFF之间,所以减掉0xC000来满足调用要求。  
  8.     this.hotKeyId = GlobalAddAtom("Screenshot") - 0xC000;  
  9.     if (this.hotKeyId == 0)  
  10.     {  
  11.         //如果获取失败,设定一个默认值;  
  12.         this.hotKeyId = 0xBFFE;   
  13.     }  
  14.   
  15.     if (this.HotKeyMode == 0)  
  16.     {  
  17.         RegisterHotKey(Handle, hotKeyId, (uint)KeyModifiers.Control | (uint)KeyModifiers.Alt, Keys.A);  
  18.     }  
  19.     else  
  20.     {  
  21.         RegisterHotKey(Handle, hotKeyId, (uint)KeyModifiers.Control | (uint)KeyModifiers.Shift, Keys.A);  
  22.     }  
  23. }  

热键响应函数:

[csharp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. /// <summary>  
  2. /// 处理快捷键事件  
  3. /// </summary>  
  4. /// <param name="m"></param>  
  5. protected override void WndProc(ref Message m)  
  6. {  
  7.     //if (m.Msg == 0x0014)  
  8.     //{  
  9.     //    return; // 禁掉清除背景消息  
  10.     //}  
  11.     const int WM_HOTKEY = 0x0312;  
  12.     switch (m.Msg)  
  13.     {  
  14.         case WM_HOTKEY:  
  15.             ShowForm();  
  16.             break;  
  17.         default:  
  18.             break;  
  19.     }  
  20.     base.WndProc(ref m);  
  21. }  

截图窗口实现原理

截图窗口实际是一个没有边框,没有菜单,没有工具栏的一个全屏顶层窗口。

当按下热键时,程序首先获取整个屏幕的图片,保存到“screenImage”变量中;然后添加遮罩层,将其设置为窗体的背景图,将窗口大小设置为主屏幕的大小,显示窗口;让人感觉是在桌面上加一个半透明的遮罩层一样。

代码如下:

[csharp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. /// <summary>  
  2. /// 如果窗口为可见状态,则隐藏窗口;  
  3. /// 否则则显示窗口  
  4. /// </summary>  
  5. protected void ShowForm()  
  6. {  
  7.     if (this.Visible)  
  8.     {  
  9.         this.Hide();  
  10.     }  
  11.     else  
  12.     {  
  13.         Bitmap bkImage = new Bitmap(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height);  
  14.         Graphics g = Graphics.FromImage(bkImage);  
  15.         g.CopyFromScreen(new Point(0, 0), new Point(0, 0), Screen.AllScreens[0].Bounds.Size, CopyPixelOperation.SourceCopy);  
  16.         screenImage = (Bitmap)bkImage.Clone();  
  17.         g.FillRectangle(new SolidBrush(Color.FromArgb(64, Color.Gray)), Screen.PrimaryScreen.Bounds);  
  18.         this.BackgroundImage = bkImage;  
  19.   
  20.         this.ShowInTaskbar = false;  
  21.         this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;  
  22.         this.Width = Screen.PrimaryScreen.Bounds.Width;  
  23.         this.Height = Screen.PrimaryScreen.Bounds.Height;  
  24.         this.Location = Screen.PrimaryScreen.Bounds.Location;  
  25.   
  26.         this.WindowState = FormWindowState.Maximized;  
  27.         this.Show();  
  28.     }  
  29. }  

取消热键注册

关闭窗口时,要取消热键注册,代码如下:

[csharp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. /// <summary>  
  2. /// 当窗口正在关闭时进行验证  
  3. /// </summary>  
  4. /// <param name="sender"></param>  
  5. /// <param name="e"></param>  
  6. private void Form1_FormClosing(object sender, FormClosingEventArgs e)  
  7. {  
  8.     if (e.CloseReason == CloseReason.ApplicationExitCall)  
  9.     {  
  10.         e.Cancel = false;  
  11.         UnregisterHotKey(this.Handle, hotKeyId);  
  12.     }  
  13.     else  
  14.     {  
  15.         this.Hide();  
  16.         e.Cancel = true;  
  17.     }  
  18. }  

到这里,热键注册,截图窗口的显示等功能已经基本完成。

注意:测试本代码时最好在窗体上添加一个按钮,用于关闭或隐藏截图窗口;因为截图窗口是全屏的,不能响应ESC键,所以只能通过任务管理器来结束进程退出。调试时最好是在窗体上添加一个Label控件来显示需要的变量信息,因为截图窗口是顶层的全屏窗口,断点被命中时根本没办法操作VS。

posted @ 2015-09-21 20:50  星空天宇  阅读(159)  评论(0编辑  收藏  举报