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 » Defining a custom window class (WNDCLASS) Collapse All
Subject Author Date
Chris Thomas Jan 2, 2008 - 3:17 PM

Our application has a lengthy startup time, and sometimes we see a white client area before the app "catches up". I’ve tried handling OnEraseBkgGrnd but that doesn’t get called until after the first CFrameWnd::ActivateWindow() call is called. I tried to define a custom class for the frame window that would have a black brush instead of the default white brush, but I that didn’t work, but perhaps I did that incorrectly.

Is there a place in the prof-uis source, or somewhere in my app, where I can get a black background instead of white? We notice the white background because our CView displays a black background, so there is a flash of white.

Thanks

Technical Support Jan 5, 2008 - 12:30 PM

As we said above, the background brush in the window class of the main frame window, WM_PAINT and WM_ERASEBKGND window message handlers of the main frame window are absolutely have no any effect on the background of the main frame because it’s completely covered by child windows. So, the problem is hidden somewhere else or we have misunderstood you. Please send us two screen shots to the support mail box at this web site demonstrating what you can see and what you want to see.

Technical Support Jan 3, 2008 - 5:37 AM

A frame window like any other window consists of two areas: client and non-client. You can always see the non-client area of the frame window: its border and caption. But you will never see the client area of any frame window because it’s always completely covered by child windows which are control bars and main SDI view or MDI client area window. So, you should not try to re-paint frame windows or change their window class because this will not affect anything. Let us discuss the standard startup process of frame window based application step by step:

1) The InitInstance() virtual method of your CWinApp-derived class is invoked. This method should initialize some window-less parts of your application and finally create the main frame, show and activate it. This method can also display a splash screen.

2) The main frame is typically created in the CFrameWnd::LoadFrame() method which creates a frame window handle and, as a result, the CFrameWnd-derived object handles the WM_CREATE standard message. The frame window is completely invisible at this step. It will be displayed only after InitInstance(). So, all the things invoked in the OnCreate() handler method of the main frame window are performed when the frame is invisible. You should spend some time to ensure there are no pieces of code in your project which show the main frame window before the OnCreate() handler method is complete. It’s convenient to check this on the double monitor computer or wide single monitor computer where Visual Studio window is not intersected with the main frame window of your application running on the desktop. We suppose your project may have some components which affect the visibility of the main frame window and show it before it become completely created.

3) It’s often needed to perform additional initialization of the application after its main frame is created and displayed. Such application should support at least two states: when it’s just loaded and main frame window is displayed and when it’s completely initialized. Sometimes a database or any other component may be located on a remote server and it’s not always possible to connect to it very quickly or at all. In this case some delayed initialization can be the option. The main frame window is already created and displayed, but most of commands in toolbars and menus are disabled until remote component becomes available. So you should establish a connection to the remote component in a standalone thread to make all the windows in the main UI thread re-painted correctly. We used the term remote component just for example. You may need to spend some time for loading large amount of data from local computer instead of accessing remote component. In this case delayed initialization in the parallel thread is also suggested.

We need to know more details about your project so we can give you some additional advice.

Chris Thomas Jan 3, 2008 - 11:41 AM

I’m sorry that I forgot to provide some critical information. I see this problem only on Vista with Aero enabled, and only with prof-uis. I made two test projects, both SDI, one with straight MFC, and the other with prof-uis (via the respective appwizards). In both, I override mainframe’s ActivateFrame, and PreCreateWindow. I can put a breakpoint on each project’s ActivateFrame and single step over the base CFrameWnd::ActivateFrame() call, and see a white window. So that’s why I want to change the WNDCLASS to use a black brush instead of the default white.

So in PreCreateWindow() I make a new class that has a black brush. It works in the MFC app, but not in the prof-uis app. Using the ActivateFrame breakpoint, the MFC app now shows a black background, but the prof-uis app continues to show white.

Where in the prof-uis code can I modify the window class to use a black brush?

Thanks

Chris Thomas Jan 3, 2008 - 11:42 AM

here is my PreCreateWindow()

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
    CString csClass = ::AfxRegisterWndClass(CS_DBLCLKS,
        (HCURSOR)::LoadCursor(::AfxGetInstanceHandle(), IDC_ARROW),
        (HBRUSH)::GetStockObject(BLACK_BRUSH),
        (HICON)::LoadIcon(::AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME)));

    if( !CFrameWnd::PreCreateWindow(cs) )
        return FALSE;
    // TODO: Modify the Window class or styles here by modifying
    // the CREATESTRUCT cs

    return TRUE;
}

Chris Thomas Jan 3, 2008 - 12:14 PM

oops, I’m sorry, the class code wasn’t in PreCreateWindow, but rather in Create(). The code was on another computer and I should have checked it first.

This is what I do, which works with MFC but not with prof-uis. In this case I use a gray brush. I also override the CView’s OnPaint and draw a black rectangle. For MFC I call CFrameWnd, not CExtNCW<CFrameWnd>.

--------------------

BOOL CMainFrame::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle , const RECT& rect , CWnd* pParentWnd , LPCTSTR lpszMenuName , DWORD dwExStyle , CCreateContext* pContext)
{
    // TODO: Add your specialized code here and/or call the base class

    LPCTSTR lpszMyClassName = AfxRegisterWndClass(CS_DBLCLKS,
        NULL,
        (HBRUSH)::GetStockObject(GRAY_BRUSH), //BLACK_BRUSH),
        ::LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME))
        );
    if (!CExtNCW<CFrameWnd>::Create(lpszMyClassName, lpszWindowName, dwStyle, rect, pParentWnd, lpszMenuName, dwExStyle, pContext))
        return FALSE;

    ShowWindow(SW_SHOW);
    return TRUE;
}