Click here to Skip to main content
15,879,535 members
Articles / Desktop Programming / MFC
Article

Bitmap Backgrounds For Dialog Boxes

Rate me:
Please Sign up or sign in to vote.
3.95/5 (15 votes)
28 May 2007CPOL3 min read 98.6K   7.3K   63   11
An article on setting a Bitmap as the Dialog Background. NO API
Screenshot - image002.jpg

Introduction

This article is intended to give a solution for placing a bitmap as the Dialog's background. Setting a bitmap as the background allows you to place controls over the bitmap and not have them obscured. Placing a bitmap into a dialog using the resource editor forces the bitmap to the foreground and hinders the placement of additional controls.

Background

While I was busy with my final year Industrial Engineering project of designing and building a USB Control interface, the final step was to write an application to communicate with the board. I chose an easy-to-use graphic interface. After many hours of drawing the PCB on CAD, I took a screen dump and thought that was it finalised. When I inserted the screen dump into the application using the Resource Editor, I discovered that not a single GUI drawing command had been displayed. Upon removing the bitmap to ensure that the OnPaint instructions were being drawn, I realised that the bitmap was drawn as the foreground with no options in the Resource Editor to force the bitmap into the background. I searched the Internet for a solution. I found a few possible solutions, but they all involved downloading an API written by another author. I challenged myself as to whether it would be possible for me to derive my own solution to this problem. I succeeded and I herewith describe my solution.

Using the code

Step 1: Load the bitmap image into the resource editor under Bitmaps. Change the Depth from 16 Colours to 24Bit True Colour.

Step 2: Assign a Resource ID to the bitmap and resize the dialog to the size of the bitmap. This ensures that Windows does not fill the empty area with a screen dump. Disable the maximize box, failing which the OnSize message will have to be handled to adjust the size of the bitmap to fill the remaining areas. It's preferable to use SW_SHOWNORMAL instead of SW_MAXIMIZE in OnInitDialog();

Step 3: Add a Cbitmap class under Protected in the bitmaps header file, a CSize handle and a CBrush handle, as per the example set out below:

C++
// Dialog Data
enum { IDD = IDD_BITMAPBACKGROUND_DIALOG };
protected:
    virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
    Cbitmap Background; // For Holding The bitmap
    CBrush BrushHol; //For Handling Background of Text in Static Text
    CSize bitmapSize; // For Holding The bitmap Size

Step 4: Load the bitmap in OnInitDialog() and get bitmap dimensions as per the example set out below:

C++
BOOL CbitmapBackgroundDlg::OnInitDialog()
{
    CDialog::OnInitDialog();
    SetIcon(m_hIcon, TRUE);
    SetIcon(m_hIcon, FALSE);
    ShowWindow(SW_SHOWNORMAL);
    //Load bitmap From Resource, Get bitmap Size
    Background.LoadbitmapW(IDB_BACKGROUND); //Load bitmap
    BITMAP bm; //Create bitmap Handle to get dimensions
    Background.Getbitmap(&bm); //Load bitmap into handle
    bitmapSize = CSize(bm.bmWidth, bm.bmHeight); // Get bitmap Sizes;
    Invalidate(1); 
    //Force the dialog to repaint itself;
    //End bitmap Information
    return TRUE; // return TRUE unless you set the focus to a control
}

Step 5: Add a WM_ERASEBKGND Message (OnEraseBkgnd)

Step 6: Edit OnEraseBkgnd and add the following:

C++
BOOL CbitmapBackgroundDlg::OnEraseBkgnd(CDC* pDC)
{
    CDC dcMemory;
    dcMemory.CreateCompatibleDC(pDC);
    Cbitmap* pOldbitmap = dcMemory.SelectObject(&Background);
    CRect rcClient;
    GetClientRect(&rcClient);
    const CSize& sbitmap = bitmapSize;
    pDC->BitBlt(0,0,sbitmap.cx,sbitmap.cy,&dcMemory,0,0,SRCCOPY);
    dcMemory.SelectObject(pOldbitmap);
    return TRUE;
    //return CDialog::OnEraseBkgnd(pDC); Remove and return TRUE
}

Step 7: Add OnDestroy() and free the resources created for the bitmap, as per the example set out below:

C++
void CbitmapBackgroundDlg::OnDestroy()
{
    CDialog::OnDestroy();
    Background.DeleteObject(); // Delete Background bitmap
    BrushHol.DeleteObject(); 
    // Delete Brush
}

Step 8: Handle background colour for controls like Static Text. This will ensure that the text is drawn with a background the same as the bitmap. Add the following to the Dialogs Create function:

C++
CbitmapBackgroundDlg::CbitmapBackgroundDlg(CWnd* pParent /*=NULL*/)
: CDialog(CbitmapBackgroundDlg::IDD, pParent)
{
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    BrushHol.CreateStockObject(HOLLOW_BRUSH); 
    //Used for background painting of text. Add This Line
}

Step 9: Add OnCtlColor. This instructs Windows to make your background mode TRANSPARENT. This can later be used to change the colour of text and controls, as per the example set out below:

C++
HBRUSH CbitmapBackgroundDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
    // HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

    pDC->SetBkMode(TRANSPARENT);
    if( pWnd->GetDlgCtrlID() == IDC_STATIC) 
    //Example of changing Text colour specific to a certain 
    //Static Text Contol in this case IDC_STATIC.
    {
        pDC->SetTextColor(RGB(255, 0, 0));
    }
    // TODO: Return a different brush if the default is not desired
    return BrushHol;
}

Points of interest

I hope you found this experiment in Windows manipulation as interesting as I did. You may wish to eliminate the OnCtlColor by doing your text drawing in the OnPaint() function. This was the method I used.

History

  • 28 May, 2007 - Original version posted

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Engineer Deckel Sportslids (PTY) Ltd.
South Africa South Africa
Engineer, Completed a PhD. Mechanical Engineering focusing on Machine Vision Control. Developed algorithms to allow an automated machine to automatically identify and qualify the product loaded. If the product has been correctly loaded then the machine will execute the correct program for that particular component.

Interested in hardware, PCI, USB, Serial and Parallel along with the software to accompany.

Comments and Discussions

 
GeneralMy vote of 5 Pin
maxspot16-Apr-15 22:41
maxspot16-Apr-15 22:41 
GeneralMy vote of 5 Pin
maxspot16-Apr-15 6:01
maxspot16-Apr-15 6:01 
QuestionArticle usage vs Source code example Pin
The_Inventor11-Dec-12 17:25
The_Inventor11-Dec-12 17:25 
In your example usage in the article for the Dlg header, you use Cbitmap, in a couple of places, and in your code you use (correctly) CBitmap to hold the Background BITMAP. I was wondering if you had written your own version of a class for BITMAP? Poke tongue | ;-P
The World as we think we know it Has a lot more to it than meets the eye.

A Mad Scientist who has seen it for himself....

GeneralThank you very much! Pin
Eric Conrad Peterson22-Apr-09 6:12
Eric Conrad Peterson22-Apr-09 6:12 
Questionwin32 solution? Pin
InstallerGuy21-Oct-08 18:20
InstallerGuy21-Oct-08 18:20 
QuestionUSB Control Pin
inlandchris15-Jul-08 1:53
inlandchris15-Jul-08 1:53 
AnswerRe: USB Control Pin
ImmelmanQ15-Jul-08 2:40
professionalImmelmanQ15-Jul-08 2:40 
GeneralRe: USB Control Pin
inlandchris15-Jul-08 7:29
inlandchris15-Jul-08 7:29 
GeneralText Ghosting Pin
Spliff Masta24-Jan-08 9:08
Spliff Masta24-Jan-08 9:08 
Questionno api? Pin
learn_more6-Jun-07 6:00
learn_more6-Jun-07 6:00 
GeneralOther CP examples... Pin
eFotografo5-Jun-07 0:38
professionaleFotografo5-Jun-07 0:38 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.