启动Doc / View应用程序隐藏
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了启动Doc / View应用程序隐藏相关的知识,希望对你有一定的参考价值。
使用Visual Studio 2010和MFC Doc / View应用程序我希望我的SDI应用程序启动时完全隐藏,过了一段时间或者从托盘图标接收到一些消息后,它会显示主机,视图等。我在m_pMainWnd->ShowWindow(SW_NORMAL);
中将m_pMainWnd->ShowWindow(SW_HIDE);
行更改为BOOL CMyApp::InitInstance()
,但主框架在执行应用程序后闪烁,然后我们应该做什么才能避免这个问题并保持主框架的显示能力。
通常,如果您有VC2005或更早版本,则以下操作:
// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
m_nCmdShow = SW_HIDE;
// Dispatch commands specified on the command line. Will return FALSE if
// app was launched with /RegServer, /Register, /Unregserver or /Unregister.
if (!ProcessShellCommand(cmdInfo))
return FALSE;
// The one and only window has been initialized, so show and update it
m_pMainWnd->ShowWindow( m_nCmdShow);
m_pMainWnd->UpdateWindow();
请注意,在ProcessShallCommand
之前,m_nCmdShow应设置为SW_HIDE,以防止闪烁发生。
看起来VC2010中可能存在错误。因为我之前已经这样做了,所以它引起了我的兴趣并尝试了一个新的VC2010项目,但它没有用。我注意到问题在于以下MFC功能。
BOOL CFrameWnd::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle,
CWnd* pParentWnd, CCreateContext* pContext)
{
// only do this once
ASSERT_VALID_IDR(nIDResource);
ASSERT(m_nIDHelp == 0 || m_nIDHelp == nIDResource);
m_nIDHelp = nIDResource; // ID for help context (+HID_BASE_RESOURCE)
CString strFullString;
if (strFullString.LoadString(nIDResource))
AfxExtractSubString(m_strTitle, strFullString, 0); // first sub-string
VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));
// attempt to create the window
LPCTSTR lpszClass = GetIconWndClass(dwDefaultStyle, nIDResource);
CString strTitle = m_strTitle;
if (!Create(lpszClass, strTitle, dwDefaultStyle, rectDefault,
pParentWnd, ATL_MAKEINTRESOURCE(nIDResource), 0L, pContext))
{
return FALSE; // will self destruct on failure normally
}
// save the default menu handle
ASSERT(m_hWnd != NULL);
m_hMenuDefault = m_dwMenuBarState == AFX_MBS_VISIBLE ? ::GetMenu(m_hWnd) : m_hMenu;
// load accelerator resource
LoadAccelTable(ATL_MAKEINTRESOURCE(nIDResource));
if (pContext == NULL) // send initial update
SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE);
return TRUE;
}
当此函数执行时,m_nCmdShow仍然是SW_HIDE,但是当if (!Create(lpszClass...
行执行时,它变为SW_SHOWNORMAL。我不知道为什么这只发生在VC2010项目中,听起来像是一个bug。
我的示例项目是SDI。
以下是SDI / MDI应用程序的解决方案:新的MFC(使用VC2010)使用存储在系统注册表中的设置覆盖m_nCmdShow值。要更改此行为,只需覆盖应用程序类中的LoadWindowPlacement虚拟函数。
BOOL CAdVisuoApp::LoadWindowPlacement(CRect& rectNormalPosition, int& nFflags, int& nShowCmd)
{
BOOL b = CWinAppEx::LoadWindowPlacement(rectNormalPosition, nFflags, nShowCmd);
nShowCmd = SW_HIDE;
return b;
}
这来自基于对话框的应用程序,但您也应该能够将其转换为Doc / View应用程序。您需要处理OnWindowPosChanging事件。关键行是if语句中的一行。这允许我的应用程序从视图中完全隐藏。
void CIPViewerDlg::OnWindowPosChanging( WINDOWPOS FAR* lpWindowPosition )
{
if( !m_bVisible )
{
lpWindowPosition->flags &= ~SWP_SHOWWINDOW;
}
CDialog::OnWindowPosChanging( lpWindowPosition );
}
确保您正在关闭CMainFrame :: PreCreateWindow(CREATESTRUCT&cs)中的WS_VISIBLE位。这样的事情应该是:
cs.style &= ~WS_VISIBLE;
我们只是否定了一点而不是关闭它,我们在VS 6.0中侥幸成功,因为这个函数只被调用一次。它在较新版本的Visual Studio中被调用两次,因此在第二次调用中我们再次将其重新打开。 :-O
我尝试了所有Visual Studio 2010并完成了:
class CMainFrame : public CFrameWndEx
{
// ...
// Attributes
public:
BOOL m_bForceHidden;
// ...
// Overrides
public:
virtual void ActivateFrame(int nCmdShow = -1);
//...
};
CMainFrame::CMainFrame() : m_bForceHidden(TRUE)
{
// ...
}
void CMainFrame::ActivateFrame(int nCmdShow)
{
if(m_bForceHidden)
{
nCmdShow = SW_HIDE;
m_bForceHidden = FALSE;
}
CFrameWndEx::ActivateFrame(nCmdShow);
}
其他技巧对我不起作用。
找到解决方案:http://forums.codeguru.com/showthread.php?478882-RESOLVED-Can-a-Doc-view-be-hidden-at-startup
以上是关于启动Doc / View应用程序隐藏的主要内容,如果未能解决你的问题,请参考以下文章