启动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应用程序隐藏的主要内容,如果未能解决你的问题,请参考以下文章

隐藏在标签栏后面的 View Pager 的片段

片段隐藏在Android中不起作用

启动片段时隐藏ActionBar

关于MFC中App、MainFrame、Doc、View、ChildFrame的关系

Android强制Fragment重建View

片段更改时如何隐藏地图视图(谷歌地图v2)