使用Visual Studio 2010和MFC Doc / View应用程序我希望我的SDI应用程序启动时完全隐藏,过了一段时间或者从托盘图标接收到一些消息后,它会显示主机,视图等。我在m_pMainWnd->ShowWindow(SW_NORMAL);
中将行m_pMainWnd->ShowWindow(SW_HIDE);
更改为BOOL CMyApp::InitInstance()
,但主框架在执行应用程序后只是闪烁然后变成我应该做什么以避免此问题并保持显示能力我想要的主框架。
答案 0 :(得分:2)
以下是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;
}
答案 1 :(得分:1)
通常,如果您有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();
请注意,m_nCmdShow应设置为ProcessShallCommand
之前的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项目中,对我来说听起来像个错误。
我的示例项目是SDI。
答案 2 :(得分:0)
这来自基于对话框的应用程序,但您也应该能够将其转换为Doc / View应用程序。您需要处理OnWindowPosChanging事件。关键行是if语句中的一行。这允许我的应用程序从视图中完全隐藏。
void CIPViewerDlg::OnWindowPosChanging( WINDOWPOS FAR* lpWindowPosition )
{
if( !m_bVisible )
{
lpWindowPosition->flags &= ~SWP_SHOWWINDOW;
}
CDialog::OnWindowPosChanging( lpWindowPosition );
}
答案 3 :(得分:0)
确保正确关闭CMainFrame :: PreCreateWindow(CREATESTRUCT& cs)中的WS_VISIBLE位。这样的事情应该是这样的:
cs.style &= ~WS_VISIBLE;
我们一直在否定这一点而不是关闭它,我们在VS 6.0中侥幸成功,因为这个函数只被调用了一次。它在较新版本的Visual Studio中被调用两次,因此在第二次调用中我们再次将其重新打开。 :-O
答案 4 :(得分:0)
我为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
答案 5 :(得分:0)
我在VS2017中(使用BCGControlBar Pro(这是MFC Feature Pack所基于的))发现,您必须在两个地方处理这些事情:
BOOL CMainFrame::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle, CWnd* pParentWnd, CCreateContext* pContext)
{
if (!__super::LoadFrame(nIDResource, dwDefaultStyle, pParentWnd, pContext))
{
return FALSE;
}
// undo what __super::LoadFrame() does where it will set it to SW_NORMAL if not SW_MAXIMIZED
AfxGetApp()->m_nCmdShow = SW_HIDE;
}
BOOL CTheApp::LoadWindowPlacement(CRect& rectNormalPosition, int& nFflags, int& nShowCmd)
{
BOOL b = __super::LoadWindowPlacement(rectNormalPosition, nFflags, nShowCmd);
nShowCmd = SW_HIDE;
return b;
}