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 » Custom themes Collapse All
Subject Author Date
Sergio Buonanno May 5, 2006 - 6:26 AM

I have a MDI application with MDI Tabs. Each MDI Child Window contains an CExtResizableDialog dialog box that overlaps the entire client area of the MDI Child Window. The some child dialogs contain TAB controls with static and radio-button controls that do not draw properly when the application run under Windows XP with a theme enabled (they appear black). I found a work around on the problem (see the code below), but when I resize the application controls on the bottom side of the window are still painted black. The application was originally developed without Prof-UIS and I cannot replace all static and radio-buttons because I have hundreds of windows to change, not only this, dialogs may contain some custom ActiveX controls that have the same problem.
How can I manage to create a dialog window that has a bitmap background and transparent static, checkbox, ActiveX and radio-button controls with Prof-UIS ?
I mean, I would like to create an application with custom themes (not only Windows XP themes) using bitmaps as background of CExtResizableDialog dialogs, at the same time, I would like to have the possibility to use Prof-UIS controls, Windows controls and ActiveX controls in my CExtResizableDialog derived windows.

void CDlgProtect::UpdateBackgroundBrush(void)
{
    if (m_bThemeActive == 0)
    {
        HMODULE hinstDll;

        // Check if the application is themed
        hinstDll = LoadLibrary(_T("UxTheme.dll"));
        if (hinstDll)
        {
            typedef BOOL (*ISAPPTHEMEDPROC)();
            ISAPPTHEMEDPROC pIsAppThemed;
            pIsAppThemed = (ISAPPTHEMEDPROC) ::GetProcAddress(hinstDll, "IsAppThemed");

            if(pIsAppThemed)
                m_bThemeActive = pIsAppThemed() ? 0xFF: 1;

            FreeLibrary(hinstDll);
        }
    }

    // Destroy old brush
    m_brushCtrls.DeleteObject();

    // Only do this if the theme is active
    if (m_bThemeActive && !m_bmpBackImage.m_hObject)
    {
        CRect rc;
        CDC memDC;

        GetClientRect(rc);
        m_bmpCtrlsBackground.DeleteObject();
        
        CDC *pdcDlg = GetDC();
        memDC.CreateCompatibleDC(pdcDlg);
        m_bmpCtrlsBackground.CreateCompatibleBitmap(pdcDlg, rc.Width(), rc.Height());
        CBitmap *pOldBmpDest = memDC.SelectObject(&m_bmpCtrlsBackground);
        ReleaseDC(pdcDlg);
        g_PaintManager->PaintControlBarClientArea(memDC, rc, this);
        m_brushCtrls.CreatePatternBrush(&m_bmpCtrlsBackground);
        
        memDC.SelectObject(pOldBmpDest);
    }
}

HBRUSH CDlgProtect::OnCtlColor(CDC* pDC, CWnd *pWnd, UINT nCtlColor)
{
    if (m_bThemeActive)
    {
        CString sClassName;
        GetClassName(*pWnd, sClassName.GetBuffer(128), 128);
        sClassName.ReleaseBuffer();
        if (sClassName.CompareNoCase(_T("button")) == 0 ||
            sClassName.CompareNoCase(_T("static")) == 0 ||
            sClassName.CompareNoCase(_T("#32770")) == 0)//Dialog
        {
            RECT rc;

            // Set the background mode to transparent
            pDC->SetBkMode(TRANSPARENT);

            pWnd->GetWindowRect(&rc);

            // Map coordinates to the upper left corner of parent dialog window
            ScreenToClient(&rc);

            // Adjust the position of the brush for this control (else we see the top left of the brush as background)
            VERIFY(SetBrushOrgEx(*pDC, -rc.left, 0, NULL));
            
            return m_brushCtrls;
        }        
    }
    else
    {
        CString sClassName;
        GetClassName(*pWnd, sClassName.GetBuffer(128), 128);
        sClassName.ReleaseBuffer();
        if (sClassName.CompareNoCase(_T("static")) == 0 ||
            sClassName.CompareNoCase(_T("#32770")) == 0)//Dialog
        {
            pDC->SetBkMode(TRANSPARENT);
            return (HBRUSH)GetStockObject(NULL_BRUSH);
        }
    }
    return CExtResizableDialog::OnCtlColor(pDC, pWnd, nCtlColor);
}

Technical Support May 5, 2006 - 11:37 AM

Please compile and run the TabbedBars sample, select the green "Other Options" tab page and set on two first check marks on it. You will see the custom drawn background which is consistent in all the dialog controls. This is possible because Prof-UIS paint managers support custom background painting. First of all you should invoke the g_PaintManager->m_bCustomBackgroundInharitanceEnabled = true; code to enable the custom background painting for the currently installed paint manager. Second, handle the CExtPaintManager::g_nMsgPaintInheritedBackground registered Windows message in the window which should have a custom background including all the child windows. The CChildView class in the TabbedBars sample application is a One Note tab page container window which handles the CExtPaintManager::g_nMsgPaintInheritedBackground registered Windows message in the CChildView::OnMsgPaintInheritedBackground() method to paint the background of the active page window. This message is also handled in the main frame window to paint custom background of entire frame. You can handle it in each of your dialog window.