C++ MFC SDI 创建子窗口

Posted

技术标签:

【中文标题】C++ MFC SDI 创建子窗口【英文标题】:C++ MFC SDI create child window 【发布时间】:2016-05-03 10:09:02 【问题描述】:

我可能听起来有点像个白痴,因为我不知道更多,但坦率地说,我更倾向于将这件事归咎于缺乏在线帮助。

在听说 MFC 的普遍看法之前,我决定使用 MFC(使用 SDI 和 View/Doc 模型)创建一个新程序。所以我的应用程序包括主框架窗口 (CMainFrame) 和一个子窗口 (CMFCTestView) 和文档 (CMFCTestDoc)。无论如何,我想拥有它,以便当用户按下工具栏上的“新建”按钮时,它会摆脱我当前拥有的子窗口并将其替换为新的、新鲜的子窗口。

我目前拥有的代码是:

void CMainFrame::OnFileNew()

#ifdef _DEBUG
    _cprintf("New Game!");
#endif

    Board b = Board(9, 9, 9);

    theApp.RecieveBoard(b);

   // Create(_T("CMFCTestDoc"), _T("CMFCTestView"), WS_CHILD | WS_VISIBLE,
   //     rectDefault, this);

    CreateEx(NULL, _T("CMFCTestView"), _T("Minesweeper"), WS_CHILD | WS_VISIBLE, rectDefault, this, IDR_MAINFRAME, 0);

我在网上找到的少量信息告诉我,CreateEx 是用于创建新子窗口的函数,所以我尝试将the example here 应用于我的应用程序,但我得到了一个错误,因为它无法制作窗户。我实际上应该如何完成我想做的事情?

奖励:如何将数据传递给新的子窗口?假设您希望窗口在首次向用户显示时设置某些变量/值。我试图跟随this answer,但在基于 CMultiDocTemplate 派生了我自己的类后感到困惑。

【问题讨论】:

为什么要用新的替换子窗口?该视图仅用于显示您在文档类中拥有的任何数据。您不能只更新数据并重绘视图以反映更改吗?顺便说一句,您遵循 MDI MFC 应用程序的示例,而您是 SDI MFC 应用程序。 @bkVnet 这也是一个很酷的选择。这仍然取决于我能否将数据传递给子窗口,我仍然不知道该怎么做。 在使用 SDI MFC 应用程序时,您不需要创建子窗口。您更新文档类中的数据(在此过程中给它任何默认值)并更新视图以反映这些更改。我假设您正在使用视图在文档类中显示您的数据(这是文档/视图架构的全部内容),还是我误解了您的问题? @bkVnet 这确实有助于解释事情。但是,我仍然不知道如何从框架窗口访问文档类。就像我在最初的问题中所说的那样,我可能听起来像个白痴问这个大声笑。 MFC SDI 应用程序将重用同一个文档。您不必从大型机窗口访问文档类。当用户点击新建文件命令CDocument::OnNewDocument文档类的成员函数将被默认实现调用。你可以在那里做你想做的事。 【参考方案1】:

如果我正确理解您的问题,MFC SDI 应用程序将重用相同的文档和默认视图来显示文档的内容。你不必 处理主框架窗口中的new file 命令以创建新视图。当用户点击new file命令时,默认实现会调用文档类的CDocument::OnNewDocument成员函数。从那里您可以重新初始化您的数据。

大概是这样的:

BOOL CMFC_testDoc::OnNewDocument()

    if (!CDocument::OnNewDocument())
        return FALSE;

    //here you reinitialize your data in the document class,which will be presented by the view to the user

    return TRUE;

【讨论】:

你不需要所有这些“魔法”;文档模板(调用OnNewDocument())也将更新框架,进而更新所有视图。您只需在视图类中覆盖 virtual void OnUpdate(...) @VladFeinstein 是的,你是对的,我已经更新了答案。但是,如果我没记错的话,如果您使用OnDraw() 在视图中显示内容,我认为也不需要覆盖OnUpdate(...),因为OnUpdate() 的默认实现使整个客户区无效。 可能不是必需的,但这些函数有不同的用途:OnUpdate() 在文档内容发生更改时调用,而OnDraw() - 当您需要时例如,在窗口未被覆盖时渲染窗口的某些部分。 OnUpdate() 还可以提示具体发生了什么变化。 @ValdFeinstein 你又是对的。我的意思是因为OnUpdate 使整个客户区无效,它会在收到WM_PAINT 消息时标记要绘制的视图,我相信这会导致对OnDraw() 的调用。在这种情况下,由于用户正在创建一个新文档,我假设整个文档都会发生变化,并且您可能无论如何都需要使整个客户区无效(默认实现会这样做)还是我弄错了?。

以上是关于C++ MFC SDI 创建子窗口的主要内容,如果未能解决你的问题,请参考以下文章

MFC 主窗口如何在创建的子窗口前

MFC项目组合:如何将没有文档类的SDI应用程序添加到MDI应用程序中?应该使用子窗口吗?[MFC]

在mfc中 为啥关闭子窗口连带把主窗口关闭了??

MFC窗口和按钮事件-正向与逆向分析

MFC窗口和按钮事件-正向与逆向分析

MFC窗口和按钮事件-正向与逆向分析