Professional UI Solutions
Site Map   /  Register
 
 

Forum

Please Log In to post a new message or reply to an existing one. If you are not registered, please register.

NOTE: Some forums may be read-only if you are not currently subscribed to our technical support services.

Forums » Prof-UIS Tech Support » VC6 and Prof-UIS version 253 problem with MDI child activation Collapse All
Subject Author Date
Roger Taplin Mar 24, 2006 - 4:11 AM

After rebuilding my application with version 253, switching between MDI child windows is unacceptably slow. When child windows are maximised, the redrawing is preceded by drawing in the normal state before maximisation. Your MDIDOCVIEW example has exactly the same problem.

For both the MDIDOCVIEW sample and my application, inactive child windows are also not drawn correctly when the active child is changed from maximised to normal.

The overrides of OnNCPaint() and OnWindowPosChanged() have no effect.

I need some way to suppress the display of an MDI child until its drawing is complete, as well as to ensure that its drawing is as efficient as possible.

Any suggestions will be much appreciated.

Thanks,

Roger Taplin

Raffaele Cappelli Mar 27, 2006 - 7:34 AM

I was going to send a message to the forum about this issue, but since there is already this one, I will continue the thread.

I noted the same problem with v2.53; actually, in my opinion, the MDI flickering problem (due to an XP bug and not to Prof-UIS) was not totally solved even in the previous versions: in fact in some cases I got some flickering and also in some cases when restoring a maximized MDI child, the NC areas of the other child windows where not repainted correctly due to the code in OnNCPaint() and OnWindowPosChanged().

This is how I fixed the problem in my application. It seems to work very well to me, but I am not sure it may create other problems or it can solve all the problems reported by Roger.

1) Remove the overrides of OnNCPaint() and OnWindowPosChanged() from any MDI child windows (if you are using dynamic bars, you need to modify the CExtDynamicMDIChildWnd::WindowProc to remove WM_NCPAINT and WM_WINDOWPOSCHANGED handling or derive your own class from CExtDynamicMDIChildWnd and override WindowProc ).

2) Add the following class:

class CExtMDIClient : public CWnd {
protected:
    virtual LRESULT WindowProc(UINT message,WPARAM wParam,LPARAM lParam) {
        if (message==WM_MDICREATE) {
            HWND hWndChild;
            LPMDICREATESTRUCT lpMDICreateStruct = (LPMDICREATESTRUCT) lParam;
            
            BOOL bMaximizeNewChild = (WS_MAXIMIZE == (lpMDICreateStruct->style & WS_MAXIMIZE));
            if (!bMaximizeNewChild) {
                // If WS_MAXIMIZE wasn’t requested, check if the currently
                // active MDI child (if there is one) is maximized. If so,
                // maximize the new child window to match.
                SendMessage(WM_MDIGETACTIVE, 0, (LPARAM)&bMaximizeNewChild);
            }

            if (bMaximizeNewChild) {
                SetRedraw(FALSE);
                // We’ll ShowWindow(SW_SHOWMAXIMIZED) instead of using
                // WS_MAXIMIZE (which would cause visual anomolies in some cases)
                lpMDICreateStruct->style &= (~WS_MAXIMIZE);
            }

            hWndChild = (HWND)__super::WindowProc(message,wParam,lParam);

            if (bMaximizeNewChild) {
                ::ShowWindow(hWndChild, SW_SHOWMAXIMIZED);
                SetRedraw();
                RedrawWindow( NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN);
            }
            return (LRESULT)hWndChild;
        }
        else if (message==WM_MDIACTIVATE) {
            LRESULT nResult = 0;
            HWND hWndNew = (HWND)wParam;
            BOOL bOldWasMaximized=FALSE;
            HWND hWndOld = (HWND)SendMessage(WM_MDIGETACTIVE,0,(LPARAM)&bOldWasMaximized);
            if (bOldWasMaximized) {
                ASSERT(::IsZoomed(hWndOld));
                SetRedraw(FALSE);
            }

            if (::IsIconic(hWndNew)) {
                //::ShowWindow(hWndNew, SW_RESTORE);
                SendMessage(WM_MDIRESTORE,(WPARAM)hWndNew);
            }
            
            nResult = __super::WindowProc(message,wParam,lParam);

            if (bOldWasMaximized) {
                SetRedraw(TRUE);
                RedrawWindow( NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN);
            }
            return nResult;
        }
        return __super::WindowProc(message,wParam,lParam);
    }
};

static CExtMDIClient m_MDIClientWnd;

3) in your CMainFrame::OnCreate, add:

VERIFY(m_MDIClientWnd.SubclassWindow(m_hWndMDIClient));

--
Hope this helps.

Technical Support Mar 28, 2006 - 7:57 AM

We are working on the problem submitted by Roger. We tried your solution and it mostly works but we do not want to subclass MDI client area to avoid potential problems that may arise when somebody wants to subclass it with some third party component. We have the first fixed version so please contact us by e-mail so we can tell you how to download it via ftp.