user2790954
user2790954

Reputation: 111

CMDIFrameWnd::MDIGetActive returns null when called from external code

I have inherited some legacy code that i'm required to integrate with a modern c# GUI. The codebase is a MFC MDI application, that creates a type library and registers a COM component to expose the application API for external applications and scripting.

Throughout the MFC application (henceforth I will refer to the MFC code as "the application") there is a function that checks for an active MDI document and returns it, or null. This method is called from a "MainFrame" class which inherits CMDIFrameWnd. it looks something like this:

CMDIChildWnd * pChildFrame = MDIGetActive();
if (pChildFrame)
{
    CDocument *pDoc = (CDocument *) pChildFrame->GetActiveDocument();
    if (pDoc)
    {
        return(pDoc);
    } else { 
        return NULL; 
}

I have created a test c# console application and can successfully import the COM component and access the API, and make calls to it. The problem is that whenever I call something that requires an active document via the API, MDIGetActive() returns null. For example, I can open a document via the API, and I can visually confirm it opens in the running MFC application. But if I call the API method to save this file, the active document is null. But if I call the same method via the application GUI, this works fine. It is the same function call, the exposed API method is just a wrapper.

Strangely enough when I open a file via the API method, it eventually executes the same check for an active document which succeeds. After getting the active document, it calls CDocument::UpdateAllViews() to update the UI. Any calls made after this via the API will result in no active document.

I'm at a loss here, I can't understand why the active document is null. I'm still working my way through MFC documentation but I haven't found anything that would suggest why this is the case. Does anyone know?

Upvotes: 2

Views: 369

Answers (1)

Flaviu_
Flaviu_

Reputation: 1356

Another way to avoid any GetActiveWhatever() method is the following code, which can be called from your CYourApp class:

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);
    }
}

Of course, once you have the document, you'll have any view attached from that document.

Upvotes: 2

Related Questions