我继承了一些遗留代码,需要将它们与现代 C# GUI 集成。代码库是一个 MFC MDI 应用程序,它创建类型库并注册 COM 组件以向外部应用程序和脚本公开应用程序 API。
在整个 MFC 应用程序(此后我将 MFC 代码称为“应用程序”)中,有一个函数可以检查事件的 MDI 文档并返回它,或者返回 null。该方法是从继承 CMDIFrameWnd 的“MainFrame”类调用的。它看起来像这样:
CMDIChildWnd * pChildFrame = MDIGetActive();
if (pChildFrame)
{
CDocument *pDoc = (CDocument *) pChildFrame->GetActiveDocument();
if (pDoc)
{
return(pDoc);
} else {
return NULL;
}
我已经创建了一个测试 C# 控制台应用程序,可以成功导入 COM 组件并访问 API,并对其进行调用。问题是,每当我通过 API 调用需要事件文档的内容时,MDIGetActive() 都会返回 null。例如,我可以通过 API 打开文档,并且可以直观地确认它在正在运行的 MFC 应用程序中打开。但如果我调用 API 方法来保存该文件,则事件文档为空。但如果我通过应用程序 GUI 调用相同的方法,则效果很好。都是同一个函数调用,暴露的API方法只是一个包装器。
奇怪的是,当我通过 API 方法打开文件时,它最终会对事件文档执行相同的检查并成功。获取事件文档后,它调用 CDocument::UpdateAllViews() 来更新 UI。此后通过 API 进行的任何调用都将导致没有事件文档。
我在这里不知所措,我不明白为什么事件文档为空。我仍在研究 MFC 文档,但没有找到任何可以说明为什么会出现这种情况的内容。有谁知道吗?
最佳答案
避免任何 GetActiveWhatever()
方法的另一种方法是使用以下代码,可以从您的 CYourApp
类调用该代码:
POSITION posDoc, pos = GetFirstDocTemplatePosition();
while (NULL != pos)
{
CDocTemplate* pDocTemplate = (CDocTemplate*)GetNextDocTemplate(pos);
posDoc = pDocTemplate->GetFirstDocPosition();
while(NULL != posDoc)
{
CDocument* pDoc = pDocTemplate->GetNextDoc(posDoc);
if(NULL != pDoc)
pDoc->UpdateAllViews(pSender, lHint, pHint);
}
}
当然,一旦您拥有该文档,您就会获得该文档附加的任何 View 。
关于c++ - 从外部代码调用时,CMDIFrameWnd::MDIGetActive 返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71419168/