截图是很常用的功能,windows原生的截图工具一次只能截一张而且需要手动保存。于是我编写了一个工具,可以多次截图,并存储到用户指定的目录。Qt5中提供了截图功能,即QScreen::grabWindow(WId)方法,在Qt4中则是QPixmap::grabWindow(WId),使用起来比较方便,也没有太多的技术细节。这个工具中,比较实用可以借鉴的功能是注册系统热键和单例程序(即本程序只能运行一个),都是使用windows API实现的。
注册系统热键:需要了解一个概念,Atom。它是一种数据类型,它的值代表的是系统原子表中的一个原子值。原子就可以理解为唯一的意思,因为我们要注册系统热键,这个热键必须在系统中可查并且是唯一(重复了就会引起热键冲突)的,Atom起到的就是这个作用。创建一个Atom的语句:
Atom atom = GlobalAddAtom("jietu");
双引号之间的内容可以自由设置。程序运行结束后还要销毁Atom,语句:
GlobalDeleteAtom(atom);
其中的atom就是上句代码中创建的Atom变量。有了原子值以后,就可以创建系统热键了,使用的API是RegisterHotKey(HWND hWnd, int id, UINT fsModifiers, UINT vk)。第一个参数是窗口句柄,因为热键生效后要向指定窗口发消息,以获得激活热键后的处理。一般这个窗口指的就是我们的程序窗口。在Qt中一般这样写:(HWND)this->winId(),就可以获取当前窗口的句柄了。第二个参数id就是原子值,将atom传入即可。最后两个参数是按键,这个API只支持两个按键的组合,比如ctrl+F1,虽然方法中两个按键类型一样,但是传入的宏却不同。fsModifiers参数的宏说明如下(摘自百度百科):
键
| 值 |
含意
|
MOD_ALT
| 0x0001 |
按下的可以是任一Alt键。
|
MOD_SHIFT
| 0x0004 |
按下的可以是任一Shift键。
|
MOD_WIN
| 0x0008 |
按下的可以是任一Windows徽标键。
|
MOD_NOREPEAT
| 0x4000 |
更改热键行为,以便键盘自动重复不会产生多个热键通知。
|
MOD_CONTROL
| 0x0002 |
按下的可以是任一Ctrl键。
|
RegisterHotKey((HWND)this->winId(), atom, MOD_CONTROL, VK_F1);
以上是注册系统热键的内容,热键被激活以后,我们要获得这个消息并进行处理。在Qt中是通过重载bool nativeEvent(const QByteArray &eventType, void *message, long *result)这个方法来实现的,在dialog.h文件中声明后,dialog.cpp中的实现代码如下:
bool Dialog::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
if (eventType == "windows_generic_MSG")
{
MSG *msg = (MSG *)message;
if (msg->message == WM_HOTKEY)
{
qDebug()<<"这里进行处理……";
return true;
}
else
return QDialog::nativeEvent(eventType, message, result);
}
else
return false;
}