用钩子hook捕获组合键消息实现MFC程序的显示/隐藏

目前开发的项目和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组合键,就可以显示软件窗口,如果再点击一次组合键,就可以隐藏软件窗口,

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


你可能感兴趣的:(数据采集,MFC窗口隐藏/显示切换,hook)