//PD Following is MFC source code. My comments notes with "//PD"
//PD Here's how MFC handles WM_ACTIVATE for frame windows:
void CFrameWnd::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
{
CWnd::OnActivate(nState, pWndOther, bMinimized);
// get top level frame unless this is a child window
// determine if window should be active or not
CFrameWnd* pTopLevel = (GetStyle() & WS_CHILD) ? this : GetTopLevelFrame();
ASSERT(pTopLevel != NULL);
CWnd* pActive = (nState == WA_INACTIVE ? pWndOther : this);
BOOL bStayActive =
(pTopLevel == pActive ||
(pTopLevel == pActive->GetTopLevelFrame() &&
(pActive == pTopLevel ||
pActive->SendMessage(WM_FLOATSTATUS, FS_SYNCACTIVE) != 0)));
pTopLevel->m_nFlags &= ~WF_STAYACTIVE;
if (bStayActive)
pTopLevel->m_nFlags |= WF_STAYACTIVE;
// sync floating windows to the new state
NotifyFloatingWindows(bStayActive ? FS_ACTIVATE : FS_DEACTIVATE);
// get active view (use active frame if no active view)
CView* pActiveView = GetActiveView();
if (pActiveView == NULL)
pActiveView = GetActiveFrame()->GetActiveView();
// when frame gets activated, re-activate current view
if (pActiveView != NULL)
{
if (nState != WA_INACTIVE && !bMinimized)
pActiveView->OnActivateView(TRUE, pActiveView, pActiveView);
// always notify the view of frame activations
pActiveView->OnActivateFrame(nState, this);
}
}
//PD This is the function that causes the bug
//PD
void CFrameWnd::NotifyFloatingWindows(DWORD dwFlags)
{
ASSERT_VALID(this);
ASSERT(m_hWnd != NULL);
// get top level parent frame window first unless this is a child window
CFrameWnd* pParent = (GetStyle() & WS_CHILD) ? this : GetTopLevelFrame();
ASSERT(pParent != NULL);
if (dwFlags & (FS_DEACTIVATE|FS_ACTIVATE))
{
// update parent window activation state
BOOL bActivate = !(dwFlags & FS_DEACTIVATE);
BOOL bEnabled = pParent->IsWindowEnabled();
if (bActivate && bEnabled && pParent != this)
{
//PD Note special code for Excel -- Sheesh!
//PD
// Excel will try to Activate itself when it receives a
// WM_NCACTIVATE so we need to keep it from doing that here.
m_nFlags |= WF_KEEPMINIACTIVE;
pParent->SendMessage(WM_NCACTIVATE, TRUE);
m_nFlags &= ~WF_KEEPMINIACTIVE;
}
else
{
//PD this line contains the bug: should not send WM_NCACTIVATE to
//PD pParent when pParent==this !!
//PD
pParent->SendMessage(WM_NCACTIVATE, FALSE);
}
}
// then update the state of all floating windows owned by the parent
HWND hWnd = ::GetWindow(::GetDesktopWindow(), GW_CHILD);
while (hWnd != NULL)
{
if (AfxIsDescendant(pParent->m_hWnd, hWnd))
::SendMessage(hWnd, WM_FLOATSTATUS, dwFlags, 0);
hWnd = ::GetWindow(hWnd, GW_HWNDNEXT);
}
}
Figure 2 MFC 2.3 WM_ACTIVATE Handler
//PD Here's the WM_ACTIVATE handler from and older version of MFC (2.53)
//PD
void CFrameWnd::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
{
ASSERT_VALID(GetActiveFrame());
// get active view (use active frame if no active view)
CView* pActiveView = GetActiveView();
if (pActiveView == NULL)
pActiveView = GetActiveFrame()->GetActiveView();
if (nState != WA_INACTIVE && !bMinimized)
{
// when frame gets activated, re-activate current view
if (pActiveView != NULL)
pActiveView->OnActivateView(TRUE, pActiveView, pActiveView);
}
// always notify the view of frame activations
if (pActiveView != NULL)
pActiveView->OnActivateFrame(nState, this);
CWnd::OnActivate(nState, pWndOther, bMinimized);
}