因为最近我的不良网页过滤引擎--上帝之手的开发进入实际开发阶段,因此开始了很多方面的系统编程比如说进程隐藏,窗口隐藏等等,因为这是监控类的软件,最好是运行在用户不知情的情况下,所以最好是把窗口隐藏起来,然后通过hotkey来呼唤.在如何实现窗口隐藏的时候,我可以说是费尽周章.
一开始,我想到的是在CMainFrame里的OnCreate写上一句this->ShowWindow(SW_HIDE);,问题倒是得到了解决,但是却出现一闪而过的现象,的确是很不完美.然后我开始在网上找资料,但都有这样的问题,而且有关于窗口隐藏的很多都是基于Dialog的.我决定自己再研究研究. 于是我建立了一个新的空项目,仔细的看代码,发现在CXXApp::InitInstance()里有这么一句:m_pMainWnd->ShowWindow(SW_SHOW);咦,这不是显示主窗口的意思吗?我把它注释掉不就得了,说干就干,注释,编译,运行,我靠,窗口还是正常出现似乎跟这个语句无关啊. 这么说来就是在执行这个语句之前窗口已经显示出来了.因此我在这个语句前面的如下代码段设了断点: if (!ProcessShellCommand(cmdInfo)) return FALSE; 跟踪进去,发现: BOOL CWinApp::ProcessShellCommand(CCommandLineInfo& rCmdInfo) { BOOL bResult = TRUE; switch (rCmdInfo.m_nShellCommand) { case CCommandLineInfo::FileNew: ///. ............ break; // If we've been asked to open a file, call OpenDocumentFile() case CCommandLineInfo::FileOpen: ....................... break; // If the user wanted to print, hide our main window and // fire a message to ourselves to start the printing case CCommandLineInfo::FilePrintTo: case CCommandLineInfo::FilePrint: m_nCmdShow = SW_HIDE; ASSERT(m_pCmdInfo == NULL); OpenDocumentFile(rCmdInfo.m_strFileName); m_pCmdInfo = &rCmdInfo; m_pMainWnd->SendMessage(WM_COMMAND, ID_FILE_PRINT_DIRECT); m_pCmdInfo = NULL; bResult = FALSE; break; // If we're doing DDE, hide ourselves 请注意红色的那句,我发现 case CCommandLineInfo::FileNew:时是没有这执行这一句的,因此我想能不能通过这一句实现窗口隐藏呢? 于是我在 if (!ProcessShellCommand(cmdInfo)) return FALSE; 的面面加上一句 m_nCmdShow = SW_HIDE; 然后编译,运行,窗口不见了!!!也没有出现一闪而过的情况,我成功了!
----------------------------------------------------------------------------------------------------------------------------------- 3. .隐藏基于对话框的MFC应用程序窗口的方法 (推荐这个方法,非常好用) 很多人可能会将窗口创建出来,然后用一个ShowWindow(SW_HIDE)的方法去隐藏窗口,当然这是可以做到隐藏的功能,但是有一点不足的地方就是窗口在隐藏之前会有一下短瞬的闪烁,而以下这种方法可以解决这种问题: 在C***App::InitInstance()的函数中将以下的这一段注释掉: C***Dlg dlg; int nResponse = dlg.DoModal(); // Since the dialog has been closed, return FALSE so that we exit the 换成: C***Dlg *dlg = new C***Dlg;
这是我认为最简单的一种方法,还有另外一种方法,就是在工作区的资源菜单中插入一个新的对话框,然后用ClassWizard新建一个与之对应的类, 而下面 C***Dlg *dlg = new C***Dlg; 这里的C***Dlg和IDD_***_DIALOG改为与你新建的对话框的对应即可,方法的原理与上面的一样,只是麻烦了一点点而已. 另一种隐藏窗口的方法: 在BOOL CBrightnessAdjustDlg::OnInitDialog() 方法中加入两句: // Hide the window body SetWindowPos(&wndNoTopMost,0,0,0,0,SWP_HIDEWINDOW); ModifyStyleEx(WS_EX_APPWINDOW,WS_EX_TOOLWINDOW); 2.隐藏基于单文档的MFC应用程序窗口的方法 1) 最简单的方法是从网上的找到的: "CMainFrame::ActiveFrame() 这里的ActiveFrame函数可以在ClassWizard中添加. 2)第二种方法则相对繁琐得多 第一步,将CMainFrame的构造函数改为public属性(默认是protected的) 第二步,将C***App::InitInstance()里面的下面代码注释掉: CSingleDocTemplate* pDocTemplate; // Parse command line for standard shell commands, DDE, file open // Dispatch commands specified on the command line // The one and only window has been initialized, so show and update it. 换成以下的代码: m_pMainWnd = new CMainFrame(); 这样子编绎出来的程序运行时便不会有主窗口. 纵观上面的隐藏窗口的方法,除了使用ShowWIndow(SW_HIDE)的方法之外,其实都是将程序中m_pMainWnd指针换一下面目,原来是正常显示的,就改为不显示,或者用其它的对话框或者自身新建一个不同类别的框架指针. 我一开始的疑惑是既然C***App会有自已的线程和消息循环机制,那么为什么还必要要这么一个框架类CMainFrame作为它的支撑呢?后来查了一下源码发现在C***App类的Run()函数里面有这么一段(关于Run函数这里不做详细讲解,有兴趣可以去查看"深入浅出MFC"): int CWinApp::Run() 呵呵,原来只要m_pMainWnd不为NULL, 则主线程就可以转起来.至此,所有的问题就迎刃而解. |
[VC/MFC]实现程序运行时隐藏窗口 (多种方法,推荐方法2)
最新推荐文章于 2023-08-22 16:35:28 发布