HOOK捕获组合键

http://download.csdn.net/detail/handanxiaoliang/4386358

WH_CALLWNDPROC 系统将消息发送到指定窗口之前的“钩子” 
WH_CALLWNDPROCRET 消息已经在窗口中处理的“钩子” 
WH_CBT 基于计算机培训的“钩子” 
WH_DEBUG 差错“钩子” 
WH_FOREGROUNDIDLE 前台空闲窗口“钩子” 
WH_GETMESSAGE 接收消息投递的“钩子” 
WH_JOURNALPLAYBACK 回放以前通过WH_JOURNALRECORD“钩子”记录的输入消息 
WH_JOURNALRECORD 输入消息记录“钩子” 
WH_KEYBOARD 键盘消息“钩子” 
WH_MOUSE 鼠标消息“钩子” 
WH_MSGFILTER 对话框、消息框、菜单或滚动条输入消息“钩子” 
WH_SHELL 外壳“钩子” 
WH_SYSMSGFILTER 系统消息“钩子”


HHOOK SetWindowsHookEx(int idHook;HOOKPROC lpfn;HINSTANCE hMod;DWORD dwThreadId);
                                   
BOOL UnhookWindowsHookEx(HHOOK hhk);

LRESULT CallNextHookEx(HHOOK hhk;int nCode;WPARAM wParam;LPARAM lParam);

BOOL CMouseHook::StartHook(HWND hWnd)
{
 BOOL result = FALSE;
 // 安装钩子
 glhHook = (HWND)SetWindowsHookEx(WH_MOUSE, MouseProc, glhInstance, 0);
 if (glhHook != NULL)
  result = TRUE;
 glhDisplayWnd = hWnd; // 设置显示目标窗口标题编辑框的句柄 
 return result;
}

LRESULT WINAPI MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
 LPMOUSEHOOKSTRUCT pMouseHook = (MOUSEHOOKSTRUCT FAR *) lParam;
 if (nCode >= 0) {
  HWND glhTargetWnd = pMouseHook->hwnd; // 取目标窗口句柄 
  HWND ParentWnd = glhTargetWnd; 
  while (ParentWnd != NULL){
   glhTargetWnd = ParentWnd; 
   ParentWnd = GetParent(glhTargetWnd); // 取应用程序主窗口句柄 
  } 
  if (glhTargetWnd != glhPrevTarWnd) { 
   char szCaption[100]; 
   GetWindowText(glhTargetWnd, szCaption, 100); // 取目标窗口标题 
   if (IsWindow(glhDisplayWnd)) 
    SendMessage(glhDisplayWnd, WM_SETTEXT, 0, (LPARAM)(LPCTSTR)szCaption); 
   glhPrevTarWnd = glhTargetWnd; // 保存目标窗口 
  } 
 }
 // 继续传递消息 
 return CallNextHookEx((HHOOK)glhHook, nCode, wParam, lParam); 
}
BOOL CMouseHook::StopHook()
{
 BOOL result = FALSE;
 if (glhHook){
  result = UnhookWindowsHookEx((HHOOK)glhHook); // 卸载钩子
  if (result) 
   glhDisplayWnd = glhPrevTarWnd = glhHook = NULL;
 }
 return result;
}



目前开发的项目和MES类似,但功能超过了MES,客户的一些设备的运行数据采集是通过一个工控机上MFC程序实现的,可以采集ACCESS、SQL Server 2000数据库表中数据条目,机器数据都是1分钟增加一条历史数据,所以采集的时间间隔也是1分钟左右。但是现场的工人会将数据采集软件关闭,所以取消了关闭按钮的效果,但是还是存在于任务栏里,有的看到了会进行强制关闭,所以现在加了一条可以隐藏的功能,用Ctrl + Q 实现置标志位的功能,定时器实现按照标志位进行数据采集软件的显示和隐藏的效果切换。

具体实现过程如下:


MFC程序APP 源文件中声明钩子程序并实现,g_show_wnd是一个全局变量,在APP源文件要声明为外部的 extern ,用来确定窗口的显示或隐藏:

//一个拦截系统消息的钩子程序事例
static LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);

LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT) lParam;
if (nCode == HC_ACTION)
{
int vKey = LOBYTE(p->vkCode);
//如果为键盘消息
if (wParam == WM_KEYDOWN)
{
switch(vKey)
{
case 'q':
case 'Q':
{
//如果用户按下了Win + D键盘消息
if(::GetKeyState(VK_CONTROL) < 0) 
{
///do anything here///
//AfxMessageBox("QQQ");
g_show_wnd = 1;

}
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
}

在APP源文件的初始化实例函数中调用,其中第一个参数 WH_KEYBOARD_LL 是最底层挂钩 ,监视键盘敲击

BOOL CKApp::InitInstance ()
{
HHOOK hhkKybd  = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc,
AfxGetApp()->m_hInstance, 0);

//...//

...

//...//

}


在窗口源文件中定义全局变量g_show_wnd 赋初始值1,设置定时器在窗口显示前系统调用的函数BOOL CKMainWnd::OnCreateClient (LPCREATESTRUCT lpcs, CCreateContext *pContext)中:

{

//处理窗口显示或者隐藏
SetTimer(SHOW_MAIN_WINDOW ,2000, NULL);

//...

...

//...

}

定时器函数中实现判断,清标志位的效果:

{

if(SHOW_MAIN_WINDOW == nIDEvent)
{
if (1 == g_show_wnd)
{
BOOL bshow = IsWindowVisible();
if (bshow)
{
ShowWindow(SW_HIDE);
}
else
{
ShowWindow(SW_SHOW);
}
g_show_wnd = 0;
}
}


//

...

//

}

通过上面的程序,当程序运行时,如果用户在键盘上点击Ctrl+q组合键,就可以显示软件窗口,如果再点击一次组合键,就可以隐藏软件窗口,

隐藏时任务管理器中应用程序看不到该采集软件,但是进程管理器可以看到。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现在C++中捕获到Notepad的关闭操作,可以使用Windows API中的钩子(hook)技术。具体实现步骤如下: 1. 使用SetWindowsHookEx函数安装一个钩子,这个钩子可以监视Windows消息队列中的所有消息。 2. 在消息处理函数中,判断消息是否为WM_CLOSE消息,如果是,则说明用户正在关闭Notepad。 3. 在消息处理函数中,调用UnhookWindowsHookEx函数卸载钩子。 下面是示例代码: ```c++ #include <Windows.h> // 全局钩子句柄 HHOOK g_hHook = NULL; // 消息处理函数 LRESULT CALLBACK MessageProc(int nCode, WPARAM wParam, LPARAM lParam) { if (nCode == HC_ACTION && wParam == WM_CLOSE) { // 用户正在关闭Notepad MessageBox(NULL, TEXT("Notepad is closing..."), TEXT("Hook"), MB_OK); // 卸载钩子 UnhookWindowsHookEx(g_hHook); } // 将消息传递给下一个钩子或目标窗口 return CallNextHookEx(NULL, nCode, wParam, lParam); } int main() { // 安装钩子 g_hHook = SetWindowsHookEx(WH_GETMESSAGE, MessageProc, NULL, GetCurrentThreadId()); if (g_hHook == NULL) { MessageBox(NULL, TEXT("Failed to install hook"), TEXT("Error"), MB_OK); return -1; } // 启动Notepad ShellExecute(NULL, TEXT("open"), TEXT("notepad.exe"), NULL, NULL, SW_SHOW); // 消息循环 MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; } ``` 注意:为了方便演示,上面的代码直接启动了Notepad,并且在关闭Notepad时弹出了一个MessageBox。实际使用时,可以将启动Notepad和消息循环部分的代码替换为自己的应用程序逻辑。另外,为了避免影响其他应用程序,建议在卸载钩子时使用对应的钩子句柄。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值