捕获普通的组合键消息
基于MFC的程序要捕获普通的组合键消息通常我们会在PreTranslateMessage(MSG* pMsg)函数中处理,
if (pMsg->message == WM_KEYDOWN)
{
BOOL bCtrl=::GetKeyState(VK_CONTROL)&0x8000;
BOOL bShift=::GetKeyState(VK_SHIFT)&0x8000;
CMainFrame* m_pM = (CMainFrame*)AfxGetMainWnd();
if (pMsg->wParam == ‘A’&&bShift)
{
m_pM->OnClose();
return true;
}
}
捕获系统键消息
目标:拦截一些win热键,例如winkey键,Alt+F4等
工作环境:VS2005
操作系统:Win 7
创建一个带静态链接的MFC规则DLL。
不知道什么问题在创建低级钩子的过程中会遇到一个未知的错误不能成功,然后我尝试把一下代码复制到所建工程的cpp文件头部可以解决这个问题。
#define WH_KEYBOARD_LL 13
#define LLKHF_EXTENDED (KF_EXTENDED >> 8)
#define LLKHF_INJECTED 0x00000010
#define LLKHF_ALTDOWN (KF_ALTDOWN >> 8)
#define LLKHF_UP (KF_UP >> 8)
#define LLMHF_INJECTED 0x00000001
这个问题的总结一直忘记了写,具体也记不大清楚,今天我把上述的代码删掉居然也可以正确编译并可用,有点不解。不过留作备用,毕竟遇到过这个问题。
代码给大家参考呵呵
def文件:
; SystemHotKeyHook.def : 声明 DLL 的模块参数。
LIBRARY "SystemHotKeyHook"
EXPORTS
SetHook
UnHook
; 此处可以是显式导出
.cpp文件代码如下:
// SystemHotKeyHook.cpp : 定义 DLL 的初始化例程。
//
#include "stdafx.h"
#include "SystemHotKeyHook.h"
#include <windows.h>
#include <tchar.h>
#include <WinUser.h>
#define WH_KEYBOARD_LL 13
#define LLKHF_EXTENDED (KF_EXTENDED >> 8)
#define LLKHF_INJECTED 0x00000010
#define LLKHF_ALTDOWN (KF_ALTDOWN >> 8)
#define LLKHF_UP (KF_UP >> 8)
#define LLMHF_INJECTED 0x00000001
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
//
//TODO: 如果此 DLL 相对于 MFC DLL 是动态链接的,
// 则从此 DLL 导出的任何调入
// MFC 的函数必须将 AFX_MANAGE_STATE 宏添加到
// 该函数的最前面。
//
// 例如:
//
// extern "C" BOOL PASCAL EXPORT ExportedFunction()
// {
// AFX_MANAGE_STATE(AfxGetStaticModuleState());
// // 此处为普通函数体
// }
//
// 此宏先于任何 MFC 调用
// 出现在每个函数中十分重要。这意味着
// 它必须作为函数中的第一个语句
// 出现,甚至先于所有对象变量声明,
// 这是因为它们的构造函数可能生成 MFC
// DLL 调用。
//
// 有关其他详细信息,
// 请参阅 MFC 技术说明 33 和 58。
//
// CSystemHotKeyHookApp
BEGIN_MESSAGE_MAP(CSystemHotKeyHookApp, CWinApp)
END_MESSAGE_MAP()
// CSystemHotKeyHookApp 构造
CSystemHotKeyHookApp::CSystemHotKeyHookApp()
{
// TODO: 在此处添加构造代码,
// 将所有重要的初始化放置在 InitInstance 中
}
// 唯一的一个 CSystemHotKeyHookApp 对象
CSystemHotKeyHookApp theApp;
// CSystemHotKeyHookApp 初始化
HINSTANCE g_hInstance=NULL;
BOOL CSystemHotKeyHookApp::InitInstance()
{
CWinApp::InitInstance();
g_hInstance = theApp.m_hInstance;
return TRUE;
}
HWND g_hWnd;
HHOOK g_hKeyboard;
bool SetHook(HWND hWnd);
bool UnHook();
LRESULT CALLBACK LowLevelKeyboardProc(int code,WPARAM wParam,LPARAM lParam);
//typedef struct tagKBDLLHOOKSTRUCT { DWORD vkCode; DWORD scanCode; DWORD flags; DWORD time; ULONG_PTR dwExtraInfo; } KBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT;
bool SetHook(HWND hWnd)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
g_hWnd =hWnd;
g_hKeyboard =SetWindowsHookEx(WH_KEYBOARD_LL,LowLevelKeyboardProc,g_hInstance/*GetModuleHandle(_T("Hk"))*/,0);
if (g_hKeyboard==NULL) return false;
return true;
}
bool UnHook()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
BOOL ret =UnhookWindowsHookEx(g_hKeyboard);
if (ret) return true;
return false;
}
LRESULT CALLBACK LowLevelKeyboardProc(int code,WPARAM wParam,LPARAM lParam)
{
BOOL fEatKeystroke =FALSE;
if (code < 0) // do not process message
return(fEatKeystroke?1:CallNextHookEx(NULL,code,wParam,lParam));
if (code==HC_ACTION)
{
PKBDLLHOOKSTRUCT p =(PKBDLLHOOKSTRUCT)lParam;
switch (wParam)
{
case WM_KEYDOWN: //0x0100
case WM_SYSKEYDOWN: //0x0104
case WM_KEYUP: //0x0101
case WM_SYSKEYUP: //0x0105
fEatKeystroke =
((p->vkCode==VK_F4)&&((p->flags&LLKHF_ALTDOWN)!=0))||
((p->vkCode==VK_TAB)&&((p->flags&LLKHF_ALTDOWN)!=0))||
((p->vkCode==VK_ESCAPE)&&((p->flags&LLKHF_ALTDOWN)!= 0))||
((p->vkCode==VK_ESCAPE)&&((GetKeyState(VK_CONTROL)&0x8000)!=0))||
( p->vkCode==VK_LWIN)||(p->vkCode==VK_RWIN)
;
break;
default:
break;
}
}
return(fEatKeystroke?1:CallNextHookEx(NULL,code,wParam,lParam));
}
简单用法:
#pragma comment(lib,"SystemHotKeyHook.lib") //低级别全局钩子 Hk.dll
_declspec(dllimport) bool SetHook(HWND hWnd);
_declspec(dllimport) bool UnHook();