windows本身没有提供针对整个桌面全局模态对话框的实现方式,需要自己实现。
两种方法:
1、弹出一个全屏幕透明的对话框,再在它的基础上弹出模态框
2、当鼠标在弹出框外时,禁用键盘、鼠标所有功能
第一种不好的是可能有闪一下的效果,影响体验;而且还要让修改密码框在它上面,还要考虑到这个窗口的释放。
第二种相对来说较方便,但是需要多一个动态库来实现全局钩子。
笔者只实现了第二种方法。
实现方法:
// 用此函数判断是否在内,以决定是否使能鼠标 BOOL CMFC_MouseMoveTest2Dlg::IsInWindow() { CPoint curPoint; ::GetCursorPos(&curPoint); CRect wndRect; this->GetWindowRect(wndRect); if ( curPoint.x < wndRect.right && curPoint.x > wndRect.left && curPoint.y < wndRect.bottom && curPoint.y > wndRect.top ) { return TRUE; } return FALSE; }新建一个定时器,在定时器内调用动态库里的钩子:
void CMFC_MouseMoveTest2Dlg::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default SetHook(!IsInWindow()); CDialog::OnTimer(nIDEvent); }钩子的代码:
#include <windows.h> #include <stdio.h> #define MYAPI extern "C" _declspec(dllexport) //导出函数声明,extern "C"要放在最前面 HHOOK hHook = NULL; LRESULT CALLBACK MouseProc(int code, WPARAM wParam, LPARAM lParam) { if (code >= 0) return 1; //消息不再传递个下一个HOOK子程,也不会再发送给目的窗口 else return CallNextHookEx(hHook, HC_ACTION, wParam, lParam); } MYAPI int SetHook(BOOL bHook) { if( TRUE == bHook ) { if( NULL == hHook) { hHook = SetWindowsHookEx(WH_MOUSE, MouseProc, GetModuleHandleA("G_Hook_Dll.dll"), 0); if (NULL == hHook) { return -1; } } } else { if(hHook) { if (UnhookWindowsHookEx(hHook) == FALSE) { return -1; } else { hHook = NULL; } } } return 0; }
示例工程源码