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 » Inactive Buttons in a CDialogBar flicker permanently Collapse All
Subject Author Date
Peter Schmidt Jun 4, 2007 - 6:56 AM

Hi,

in my application I used a CDialogBar derived class to provide some complex gui elemtents in a sort-of tool bar. This dialog bar is part of CCmdUI / ON_UPDATE_CMD_UI handling (like normal menues).

When I installed CExtButton (instead of CButton) in this CDialogBar class, every inactive button gets permanently redrawn due to frequent OnIdleUpdateCommandUI calls (MFC). If the button is enabled, everything works well. With only 2 inaktive buttons I measure 30% CPU load only with redrawing (which makes a permanent flicker of this button on screen).

I could reproduce the problem with a simple SDI Application from scratch (since my application is confusingly complex and possibly having other pitfalls). I can mail you the whole testing application, here the changes I made from an MFC Wizzard code.

Did I miss anything essential?

Thanks,

Peter.



CTextApp::InitInstance:
...
    if( ! g_PaintManager.PaintManagerStateLoad(
            pApp->m_pszRegistryKey,
            pApp->m_pszProfileName,
            pApp->m_pszProfileName))
    {
        g_PaintManager.InstallPaintManager(
            RUNTIME_CLASS(CExtPaintManagerOffice2007_R2_LunaBlue));
    }

Create a simple dialog bar:
    IDD_DIALOGBAR DIALOGEX 0, 0, 408, 28
    STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU
    FONT 8, "MS Shell Dlg", 400, 0, 0x1
    BEGIN
     DEFPUSHBUTTON "Test2",IDD_TEST2,123,7,50,14
     PUSHBUTTON "Test1",IDD_TEST1,56,7,50,14
    END

Write a handler class "CMyDialogBar":
    class CMyDialogBar : public CDialogBar
    {
    public:
        CMyDialogBar() {};
    
        CExtButton    m_btButton1;
        CExtButton    m_btButton2;

    protected:
        virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
    };

    void CMyDialogBar::DoDataExchange(CDataExchange* pDX)
    {
        CDialogBar::DoDataExchange(pDX);
        //{{AFX_DATA_MAP(CButtonBar)
        DDX_Control(pDX, IDD_TEST1, m_btButton1);
        DDX_Control(pDX, IDD_TEST2, m_btButton2);
    }

In CMainFrame add:
...
CMyDialogBar    m_wndButtonBar;

In CMainFrame add msg handler (leave second button unattached for testing):

    ON_BN_CLICKED(IDD_TEST1, OnTest1)

In CMainFrame::OnCreate add new dialogbar:
    ...
    if (!m_wndButtonBar.Create(this, IDD_DIALOGBAR, CBRS_TOP,
                AFX_IDW_CONTROLBAR_FIRST))
    {
        TRACE0("Failed to create dialog bar.\n");
        return -1; // fail to create
    }
...
    m_wndButtonBar.EnableDocking(CBRS_ALIGN_ANY);
    ...
    DockControlBar(&m_wndButtonBar);
    ...
    m_wndButtonBar.UpdateData(FALSE);    // to simplify control attachment.

That’s it, the inactive button will flicker (visible best when you hover with the mouse over it) and make the CPU glow. :-)

Peter Schmidt Jun 4, 2007 - 9:19 AM

After further testing it seems to me that every call to

pCmdUI->Enable(...);
or
pCmdUI->SetCheck(...);

in an OnUpdateCmdUI handler causes a visible CExt-Control to be redrawn, without considering it’s current state (if redraw is needed or not).

Tnx,
Peter.

Technical Support Jun 4, 2007 - 12:18 PM

If it is possible, could you send us a test project? We cannot say what’s wrong off-hand because the problem can be caused by many factors. For example, the CExtButton class is based on a custom drawn button control rather than on on the push button control (they work differently in different environments).

P.S. There is an alternative design which you may want to consider. You can see how it may look in the ProfStudio sample: the dialogs inside control bars often contain a static toolbar with several toolbar buttons.