VC窗口启动隐藏时闪烁问题解决方法(原创)
2009-12-24 15:16
585 查看
VC窗口启动隐藏时闪烁问题解决方法(原创)
最近由于项目需要,做了一个VC托盘程序,让该程序在后台执行,当程序启动时我需要将窗口隐藏,但总是在隐藏前会闪烁一下再隐藏,于是我跟踪代码到MFC类库里终于发现问题给解决了。
下面都是针对创建的单文档程序而讲的,因为我创建的是单文档工程,其它的类型工程我没试过,多文档工程应该也可以用下面的方法,好了,开始讲解了。
如果你使用VC6做的单文档程序,那么只需在BOOL CXXXXApp::InitInstance()方法中添加如下代码:
m_nCmdShow = SW_HIDE;
if (!ProcessShellCommand(cmdInfo))
return FALSE;
即在"if (!ProcessShellCommand(cmdInfo))”在这一句的上方加一句代码"m_nCmdShow = SW_HIDE;"即可
如果使用VC2008建立的单文档程序,那么需要在BOOL CXXXXApp::InitInstance()方法中添加如下代码:
m_nCmdShow = SW_HIDE;
m_bLoadWindowPlacement=FALSE;
if (!ProcessShellCommand(cmdInfo))
return FALSE;
即在"if (!ProcessShellCommand(cmdInfo))”在这一句的上方加两行代码"m_nCmdShow = SW_HIDE;"和"m_bLoadWindowPlacement=FALSE;"
大家可能觉得奇怪,为什么不一样呢?
原因是在VC2008建立的单文档程序中,CXXXXApp默认继承的CWinAppEx类,该类中新添加了一些处理。如果你在"if (!ProcessShellCommand(cmdInfo))”处打上断点按F11,走到一个方法后继续按F11跟踪进去直到代码走到下面这个方法:
BOOL CWinAppEx::LoadState(LPCTSTR lpszSectionName /*=NULL*/, CFrameImpl* pFrameImpl /*= NULL*/)
而在该方法中有下面一段代码,问题就出在这里:
if (m_bLoadWindowPlacement)
{
//--------------------------------------------------------
// Set frame default(restored) size:
//--------------------------------------------------------
ReloadWindowPlacement(pFrameImpl->m_pFrame);
}
我们再继续跟进BOOL CWinAppEx::ReloadWindowPlacement(CFrameWnd* pFrameWnd),其实现代码如下:
BOOL CWinAppEx::ReloadWindowPlacement(CFrameWnd* pFrameWnd)
{
ASSERT_VALID(pFrameWnd);
CCommandLineInfo cmdInfo;
AfxGetApp()->ParseCommandLine(cmdInfo);
if (cmdInfo.m_bRunEmbedded || cmdInfo.m_bRunAutomated)
{
//Don't show the main window if Application
//was run with /Embedding or /Automation.
return FALSE;
}
CRect rectNormal;
int nFlags = 0;
int nShowCmd = SW_SHOWNORMAL;
BOOL bRet = FALSE;
if (LoadWindowPlacement(rectNormal, nFlags, nShowCmd))
{
WINDOWPLACEMENT wp;
wp.length = sizeof(WINDOWPLACEMENT);
if (pFrameWnd->GetWindowPlacement(&wp))
{
wp.rcNormalPosition = rectNormal;
wp.showCmd = nShowCmd;
RECT rectDesktop;
SystemParametersInfo(SPI_GETWORKAREA,0, (PVOID)&rectDesktop,0);
OffsetRect(&wp.rcNormalPosition, -rectDesktop.left, -rectDesktop.top);
pFrameWnd->SetWindowPlacement(&wp);
bRet = TRUE;
}
}
if (pFrameWnd->IsKindOf(RUNTIME_CLASS(CMDIFrameWndEx)))
{
CDockingManager *pDockingManager = ((CMDIFrameWndEx *)pFrameWnd)->GetDockingManager();
pDockingManager->ShowDelayShowMiniFrames(TRUE);
}
else if (pFrameWnd->IsKindOf(RUNTIME_CLASS(CFrameWndEx)))
{
CDockingManager *pDockingManager = ((CFrameWndEx *)pFrameWnd)->GetDockingManager();
pDockingManager->ShowDelayShowMiniFrames(TRUE);
}
return bRet;
}
看我加了下划线加粗的代码行,发现我之前设置的"m_nCmdShow = SW_HIDE;"在这里被更改,所以会闪烁,那么看到这里问题就可以解决了。
我们发现之所以会进ReloadWindowPlacement方法,是因为m_bLoadWindowPlacement=TRUE的原因,这个值在CWinAppEx的构造函数中初始化为TRUE了,那么我们就应该想办法将m_bLoadWindowPlacement置为FALSE,所以我们使用VC2008开发时就应该在调用ReloadWindowPlacement方法前把m_bLoadWindowPlacement置为FALSE,于是就有了文章开头我说的修改方法。
最近由于项目需要,做了一个VC托盘程序,让该程序在后台执行,当程序启动时我需要将窗口隐藏,但总是在隐藏前会闪烁一下再隐藏,于是我跟踪代码到MFC类库里终于发现问题给解决了。
下面都是针对创建的单文档程序而讲的,因为我创建的是单文档工程,其它的类型工程我没试过,多文档工程应该也可以用下面的方法,好了,开始讲解了。
如果你使用VC6做的单文档程序,那么只需在BOOL CXXXXApp::InitInstance()方法中添加如下代码:
m_nCmdShow = SW_HIDE;
if (!ProcessShellCommand(cmdInfo))
return FALSE;
即在"if (!ProcessShellCommand(cmdInfo))”在这一句的上方加一句代码"m_nCmdShow = SW_HIDE;"即可
如果使用VC2008建立的单文档程序,那么需要在BOOL CXXXXApp::InitInstance()方法中添加如下代码:
m_nCmdShow = SW_HIDE;
m_bLoadWindowPlacement=FALSE;
if (!ProcessShellCommand(cmdInfo))
return FALSE;
即在"if (!ProcessShellCommand(cmdInfo))”在这一句的上方加两行代码"m_nCmdShow = SW_HIDE;"和"m_bLoadWindowPlacement=FALSE;"
大家可能觉得奇怪,为什么不一样呢?
原因是在VC2008建立的单文档程序中,CXXXXApp默认继承的CWinAppEx类,该类中新添加了一些处理。如果你在"if (!ProcessShellCommand(cmdInfo))”处打上断点按F11,走到一个方法后继续按F11跟踪进去直到代码走到下面这个方法:
BOOL CWinAppEx::LoadState(LPCTSTR lpszSectionName /*=NULL*/, CFrameImpl* pFrameImpl /*= NULL*/)
而在该方法中有下面一段代码,问题就出在这里:
if (m_bLoadWindowPlacement)
{
//--------------------------------------------------------
// Set frame default(restored) size:
//--------------------------------------------------------
ReloadWindowPlacement(pFrameImpl->m_pFrame);
}
我们再继续跟进BOOL CWinAppEx::ReloadWindowPlacement(CFrameWnd* pFrameWnd),其实现代码如下:
BOOL CWinAppEx::ReloadWindowPlacement(CFrameWnd* pFrameWnd)
{
ASSERT_VALID(pFrameWnd);
CCommandLineInfo cmdInfo;
AfxGetApp()->ParseCommandLine(cmdInfo);
if (cmdInfo.m_bRunEmbedded || cmdInfo.m_bRunAutomated)
{
//Don't show the main window if Application
//was run with /Embedding or /Automation.
return FALSE;
}
CRect rectNormal;
int nFlags = 0;
int nShowCmd = SW_SHOWNORMAL;
BOOL bRet = FALSE;
if (LoadWindowPlacement(rectNormal, nFlags, nShowCmd))
{
WINDOWPLACEMENT wp;
wp.length = sizeof(WINDOWPLACEMENT);
if (pFrameWnd->GetWindowPlacement(&wp))
{
wp.rcNormalPosition = rectNormal;
wp.showCmd = nShowCmd;
RECT rectDesktop;
SystemParametersInfo(SPI_GETWORKAREA,0, (PVOID)&rectDesktop,0);
OffsetRect(&wp.rcNormalPosition, -rectDesktop.left, -rectDesktop.top);
pFrameWnd->SetWindowPlacement(&wp);
bRet = TRUE;
}
}
if (pFrameWnd->IsKindOf(RUNTIME_CLASS(CMDIFrameWndEx)))
{
CDockingManager *pDockingManager = ((CMDIFrameWndEx *)pFrameWnd)->GetDockingManager();
pDockingManager->ShowDelayShowMiniFrames(TRUE);
}
else if (pFrameWnd->IsKindOf(RUNTIME_CLASS(CFrameWndEx)))
{
CDockingManager *pDockingManager = ((CFrameWndEx *)pFrameWnd)->GetDockingManager();
pDockingManager->ShowDelayShowMiniFrames(TRUE);
}
return bRet;
}
看我加了下划线加粗的代码行,发现我之前设置的"m_nCmdShow = SW_HIDE;"在这里被更改,所以会闪烁,那么看到这里问题就可以解决了。
我们发现之所以会进ReloadWindowPlacement方法,是因为m_bLoadWindowPlacement=TRUE的原因,这个值在CWinAppEx的构造函数中初始化为TRUE了,那么我们就应该想办法将m_bLoadWindowPlacement置为FALSE,所以我们使用VC2008开发时就应该在调用ReloadWindowPlacement方法前把m_bLoadWindowPlacement置为FALSE,于是就有了文章开头我说的修改方法。
相关文章推荐
- VC窗口启动隐藏时闪烁问题解决方法
- VC窗口启动隐藏时闪烁问题解决方法
- 解决列表框更新数据的时候的闪烁问题(VC防止窗口及其控件(如CListCtrl)闪烁的简单方法(一组有用的宏) )
- [转]winform 窗口闪烁问题解决方法
- VC++ 实现VC程序启动时最小化到任务栏(完美解决闪烁问题)
- 实现VC程序启动时最小化到任务栏(完美解决闪烁问题)
- VC++ 实现VC程序启动时最小化到任务栏(完美解决闪烁问题)
- VC++ 实现VC程序启动时最小化到任务栏(完美解决闪烁问题)
- 启动tomcat时cmd窗口一闪而过解决方法【尤其注意配置问题】
- 实现VC程序启动时最小化到任务栏(完美解决闪烁问题)收藏
- MFC隐藏窗口时解决窗口闪烁问题
- 实现VC程序启动时最小化到任务栏(完美解决闪烁问题)
- 实现VC程序启动时最小化到任务栏(完美解决闪烁问题)
- 实现VC程序启动时最小化到任务栏(完美解决闪烁问题)
- 实现VC程序启动时最小化到任务栏(完美解决闪烁问题)
- 实现VC程序启动时最小化到任务栏(完美解决闪烁问题)
- 让 Windows7 - 64bit 支持 VC++ 6.0 的解决方法(无法启动此程序,因为计算机中丢失 MSVCRTD.dll。尝试重新安装该程序以解决此问题)
- 双缓冲方法解决屏幕刷新闪烁的问题
- c#解决窗口背景贴图刷新,放大后图像闪烁问题
- [原创]IE6下wbox弹出iframe窗口加载页面空白问题解决