开发环境为windows xp,vc6

主要方案为,创建一个主窗口,不进行截图的时候将其隐藏,并在托盘区创建小图标,截图时使窗口全屏透明,捕捉鼠标行为截图保存,再使窗口隐藏。

以下根据主要步骤将核心内容点出:

(1)注册窗口类时,将背景色定为黑色,以使截图时有灰暗的效果

ATOM MyRegisterClass(PWNDCLASSEX wcex,HINSTANCE hInstance)
{...wcex->hCursor        = LoadCursor(NULL, IDC_CROSS);wcex->hbrBackground   = (HBRUSH)GetStockObject(BLACK_BRUSH);...return RegisterClassEx(wcex);
}

(2)创建窗口时,用到两个扩展风格,WS_EX_LAYERED,WS_EX_TOOLWINDOW

前者是将窗口透明化必须设置的窗口风格,后者使窗口成为一个工具窗口,不显示在任务栏中。

HWND hWnd = CreateWindowEx(WS_EX_LAYERED | WS_EX_TOOLWINDOW, "MYSCREENSHOT", 0, WS_POPUP,CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

(3)注册两套热键,用RegisterHotKey

函数原型为:

BOOL RegisterHotKey(HWND hWnd,         // handle to windowint id,            // hot key identifierUINT fsModifiers,  // key-modifier optionsUINT vk            // virtual-key code
);
    RegisterHotKey(hWnd, 1346, MOD_ALT | MOD_CONTROL, 65);RegisterHotKey(hWnd, 1347, MOD_CONTROL, 222);

65为A的虚键码,222为' or " 的虚键码,适用于左手与右手。

这样当按下这两个组合键时,窗口会受到一个    WM_HOTKEY    消息,其中,lParam的低位字显示了alt或是control键是否被按下,高位字为虚键码,那么我们只需要在窗口函数中处理该消息,发送一个命令消息开始截图:

    case WM_HOTKEY:{if(HIWORD(lParam) == 65 || HIWORD(lParam) == 222)SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(IDM_RUN, 0), 0);}break;

IDM_RUN 是一个开始截图的命令消息

注意窗口销毁时注销热键,在WM_DESTROY中

         UnregisterHotKey(hWnd, 1346);UnregisterHotKey(hWnd, 1347);

(4)在不进行截图时,将窗口最小化到托盘,这里要用到 API函数Shell_NotifyIcon和结构体NOTIFYICONDATA,先来看下NOTIFYICONDATA:

typedef struct _NOTIFYICONDATA {
DWORD cbSize;
HWND hWnd;
UINT uID;
UINT uFlags;
UINT uCallbackMessage;
HICON hIcon;
char szTip[64];
} NOTIFYICONDATA, *PNOTIFYICONDATA; 

其中,

cbSize : 结构的长度,用“位”来做单位。一般在程序中,我们用(DWORD)sizeof(NOTIFYICONDATA) 给它赋值。
HWnd : 一个句柄,如果对托盘中的图标进行操作,相应的消息就传给这个句柄所代表的窗口。自然了,大多数情况下是this->m_hWnd喽。
uID : 在工程中定义的图标ID

uFlags : 这个成员标志着其他哪些成员的数据是有效的,分别为NIF_ICON, NIF_MESSAGE, NIF_TIP,分别代表着数据有效的成员是hIcon, uCallbackMessage, szTip。当然,三个值可以用“|”联系到一起。下面分别对涉及到的成员进行阐述

hIcon : 要增加,删除或修改的图标句柄。如果只知道个uID, 一般可能会用函数LoadIcon来得到句柄。例如LoadIcon ( AfxGetInstanceHandle() ,MAKEINTRESOURCE (IDR_MAINFRAME) )。

uCallbackMessage : 这在对托盘区的操作中,是比较重要的数据成员。这是个消息标志,当用鼠标对托盘区相应图标进行操作的时候,就会传递消息给Hwnd所代表的窗口。所以说,在uFlags中,一般都得标志它有效。这里一般都是自定义的消息。

szTip : 鼠标移动到托盘图标上时的提示文字。

我们这里用一个自定义消息来接收托盘图标的消息:

#define MY_ICON_MESSAGE (WM_USER+1)
...
NOTIFYICONDATA g_nid;
...
g_nid.uCallbackMessage = MY_ICON_MESSAGE;

那么此时,第三个参数可以随便填。接下来处理这个消息,其中,wParam接收的是图标的ID,而lParam接收的是鼠标的行为

 case MY_ICON_MESSAGE:{switch(lParam){case WM_RBUTTONDOWN:{HMENU hMenu = CreateMenu();HMENU hPopupMenu = CreateMenu();AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hPopupMenu, 0);AppendMenu(hPopupMenu, MF_STRING, IDM_RUN, "&Run");AppendMenu(hPopupMenu, MF_SEPARATOR, 0, 0);AppendMenu(hPopupMenu, MF_STRING, IDM_QUIT, "&Quit");POINT point;GetCursorPos(&point);SetForegroundWindow(hWnd);TrackPopupMenu(hPopupMenu, TPM_LEFTALIGN, point.x, point.y, 0, hWnd, 0);}break;case WM_LBUTTONDBLCLK:SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(IDM_RUN, 0), 0);break;}}break;

右键单击时,弹出一个菜单,有两个选项,运行和退出,当左键双击时,与运行截图有相同的作用,发送一个IDM_RUN 的命令消息。注意,TrackPopupMenu之前的SetForegroundWindow是必要的,没有这一句,则弹出的菜单不会自动消失。

(5)接下去来处理IDM_RUN消息:

           case IDM_RUN:{g_nid.hIcon = LoadIcon(g_hInstance, (LPCTSTR)IDI_ON); Shell_NotifyIcon(NIM_MODIFY, &g_nid);hSrcDC = GetDC(GetDesktopWindow());HMODULE hModule = LoadLibrary("User32.dll");lpfnSetLayeredWindowAttributes myfunc = (lpfnSetLayeredWindowAttributes)GetProcAddress(hModule, "SetLayeredWindowAttributes"); FreeLibrary(hModule);ShowWindow(hWnd, SW_MAXIMIZE);myfunc(hWnd, 0, 100, LWA_ALPHA);g_State = TRUE;}break;

首先是一个替换托盘区图标的操作,显示截图正在进行中。

然后先取得桌面DC,(先把全屏给截了,然后再跟踪鼠标的操作来对这张全屏图“剪裁”)hSrcDC是一个窗口消息处理函数的静态局部DC句柄。

接着利用API函数SetLayeredWindowAttributes来设置窗口为透明,其函数原型为:

BOOL SetLayeredWindowAttributes(HWND hwnd,           // handle to the layered windowCOLORREF crKey,      // specifies the color keyBYTE bAlpha,         // value for the blend functionDWORD dwFlags        // action
);

详细的解答请参照MSDN

这里需要申明对该函数的指针,注意,LWA_ALPHA需要自行定义

typedef   BOOL (WINAPI *lpfnSetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD);
...
#define   LWA_ALPHA     0x00000002

g_State 是一个全局变量,用以记录是否在截图状态,在鼠标的消息处理函数中会对此变量进行判断,是的话再进行相应的操作。

(6)接下去跟踪鼠标的行为“剪裁”刚才的桌面DC,先找到需要的矩形块坐标。

主要过程为:

1.在WM_LBUTTONDOWN中记录第一个点,将它保存在静态POINT变量中;

2.在WM_MOUSEMOVE中在透明窗口上实时刷新并画线以显示截图的区域;

3.在WM_LBUTTONUP中记录第二个点,从而取得需要剪裁的区域矩形,用BitBlt复制DC内容,并保存位图文件。最后使窗口隐藏起来,更换托盘区图标等初始化工作。

具体代码在此不再罗嗦了,详见源码。

成品exe及源代码:点击打开链接

转载于:https://www.cnblogs.com/silyvin/archive/2012/05/07/9106906.html

Win32 SDK 编写截图小工具相关推荐

  1. SQL Server编写存储过程小工具(三)

    SQL Server编写存储过程小工具  功能:为给定表创建Update存储过程  语法: sp_GenUpdate <Table Name>,<Primary Key>,&l ...

  2. 截图小工具,用c#语言开发

    一.开发环境及工具 Windows 7 系统,开发软件为Microsoft Visual Studio Ultimate 2012 二.实现的功能 屏幕截屏,保存到图片或者保存到剪切板.截屏范围可以随 ...

  3. 手把手VC截图小工具,附源码

    话说大四陪MM在图书管写论文的时候,图书馆没网,也没登陆QQ之类IM.都晓得论文要图文并茂....于是乎就需要截图.么法之好printscreen然后画图,麻烦到死...就想写个截图小工具还是很好玩的 ...

  4. python 编写实用小工具-toy: python平时积累的笔记以及编写的小工具

    所有人都告诉你怎么活,只有自己没有搞清楚该如何活.相信自己,我们每个人都是主角?? toy Python ?? 献给我亲爱的女朋友--如 ? 介绍 学习 python.matlab 时积累的笔记以及编 ...

  5. python 编写实用小工具-使用Python制作一个打字训练小工具

    一.写在前面 说道程序员,你会想到什么呢?有人认为程序员象征着高薪,有人认为程序员都是死肥宅,还有人想到的则是996和 ICU. 别人眼中的程序员:飞快的敲击键盘.酷炫的切换屏幕.各种看不懂的字符代码 ...

  6. 分享一个自己做的截图小工具(基于Windows平台的批处理文件实现)

    最近项目中要有截图的工作要做,对于我等使用AS的开发人员来说,视频或者截图借用工具也是分分钟的事情,但是公司的业务同事和测试人员不懂怎么使用AS软件,而且犯不着为了截个图就去装AS吧,所以发挥我等程序 ...

  7. FSCapture截图小工具和注册码

     今天给大家推荐一个小的截图截屏工具FSCapture,可在360软件库中下载安装,功能上的介绍网上好多在这就不多言.但是启动时需要注册码,于是乎就在网上找了一些供大家使用 企业版序列号: nam ...

  8. 非常简单的截图小工具

    用QQ截图太麻烦. 我只是想要截个图,然后图片保持在窗口最前端即可. 2020.5.17 解决从下往上拉动鼠标造成错误的情况 增加右击取消截图 import Num.AddNum; import ja ...

  9. Win7系统截图小工具

    第一步:按window键,可以看到 第二步:启动"截图工具"也很简单,单击"开始"菜单,打开"所有程序""附件"&quo ...

最新文章

  1. 将Nodelist快速转换为Array数组
  2. 团队-象棋游戏-模块测试过程
  3. 【NLP】simhash判断文档相似度
  4. 重磅!2021年考研国家线正式公布,部分学科分数线比去年更低!
  5. 20170910校内训练
  6. cycle函数python_Python执行函数的周期实现
  7. MySQL查看数据库相关信息
  8. SQL Server代理(11/12):维护计划作业
  9. Atitit.java swing打印功能 api  attilax总结
  10. linux curl命令验证服务器断点续传支持
  11. 谁在告谁?移动专利混战图
  12. 程序观点下的线性代数
  13. @所有技术人,快来翻开属于你的2021定制日历!
  14. 度假村酒店官方网站模板里面包含7个子页面,适合酒店住宿网站模板下载
  15. R语言中的Factor到底是什么?
  16. Fiddler抓包工具报:The system ptoxy changed. Click to reenable capturing
  17. Using 1.7 requires compiling with Android 4.4 (KitKat); currently using API 10
  18. 用Python实现手机抓包,获取当当图书差评数据!
  19. Python爬虫——Urllib
  20. 小猿圈Java学习分享2019Java面试题

热门文章

  1. YOLOv1 《You Only Look Once》论文笔记
  2. 20200406 托普雷兹矩阵 Toeplitz
  3. Django中重定向页面的时候使用命名空间
  4. 使用vue3.0和element实现后台管理模板
  5. 12月7日 第二冲刺周期个人站立会议内容报告(第七天)
  6. map内置函数分析所得到的思路
  7. mongo数据库数据迁移到muysql数据库
  8. Flask入门flask-script 蓝本 钩子函数(三)
  9. Struts2与Spring整合
  10. tomcat服务器访问网址组成