程序最小化后不能还原,一般原因是程序中至少存在一个Popup类型的窗口引起的,因为Popup类型的子窗口即使由于父窗口的隐藏而隐藏,其WS_VISIBLE属性仍然是可见的,当用户再次点击任务栏的程序图标时,Popup窗口会拦截系统(还原)消息,使主程序框架无法接收到系统消息,从而导致主程序无法正常还原。如果将其修改为Child类型的窗口,那么主程序的最小化和还原的功能就可以正常了。不过在实际项目中,往往就需要一个Popup类型的窗口作为子窗口(Popup类型的窗口也可以有父窗口),那么这又如何解决程序最小化后不能还原的问题呢?根据以上分析的原理,只要在主程序最小化时,相应也隐藏掉Popup窗口(ShowWindow(SW_HIDE)),这样系统消息就能够正确传递了;当主程序还原时,再将隐藏的Popup窗口显示出来,这样就既不影响程序的显示效果,又能解决问题了!具体方法如下:
首先需要在主程序(如MainFrame)中拦截系统消息(响应最大化,最小化,还原,关闭等消息的地方)。其消息为WM_SYSCOMMAND.如在MainFrame.h头文件中加入afx_msg void OnSyscommand(UIND nID,LPARAM lParam);在MainFrame.cpp的BEGIN_MAP与END_MAP之间加入ON_WM_SYSCOMMAND,响应函数为
void CMainFrame::OnSyscommand(UIND nID,LPARAM lParam){}。
其次根据系统消息对Popup窗口进行隐藏与显示操作,代码如下:
CWnd* m_pPopupWnd;/// Popup类型的窗口指针
void CMainFrame::OnSyscommand(UIND nID,LPARAM lParam)
{
static BOOL s_bDialogVisible = FALSE;
/// 如果是最小化消息
if(SC_MINIMIZE == nID)
{
if(NULL != m_pPopupWnd && ::IsWindow(m_pPopupWnd->m_hWnd))
{
if(::IsWindowVisible(m_pPopupWnd->m_hWnd))
{
s_bDialogVisible = TRUE;
/// 隐藏Popup类型窗口
m_pPopupWnd->ShowWindow(SW_HIDE);
}
}
}
else
{
if(NULL != m_pPopupWnd && ::IsWindow(m_pPopupWnd->m_hWnd))
{
if(TRUE == s_bDialogVisible)
{
s_bDialogVisible = FALSE;
/// 显示Popup类型窗口
m_pPopupWnd->ShowWindow(SW_SHOW);
}
}
}
CWnd::OnSyscommand(nID,lParam);
}
方法二:拦截系统的还原消息,对其进行自定义的操作,如先设置为活动窗口,然后继续执行还原操作。
BOOL PreTranslateMessage(MSG* pMsg)
{
ASSERT(pMsg);
/// 如果是激活窗口消息
if(pMsg->message == WS_APPACTIVE)
{
/// 如果是按下左键
if(pMsg->wParam == VK_LBUTTON)
{
ASSERT(AfxGetMainFrame());
/// 激活主窗口
SetActiveWindow(AfxGetMainFrame()->m_hWnd);
}
}
/// 可继续向基类传递消息
return C**APP::PreTranslateMessage(pMsg);
}