StatusBar on Dialogs 

MFC allows you to easily add status bars to CFrameWnd-derived windows. However, if you want to add a status bar to a dialog, you're going to find the going just a bit more difficult. 

Basically, it turned out that I had to dig very deep into the MFC documentation in order to find anything to help me out. One example I found is by ZEKSER Cyril. His techniques works fine, but (IMHO) is not very "clean" since you have to place an invisible static object on the dialog as a kind of placeholder for the status bar. However, I do want to thank him very much for showing me the light at the end of the tunnel. 

The technique I came up with works like this: First, you need to develop your dialog (and define its CDialog-based class). Nothing new here so far. 

Then, insert the following code into the CDialog::OnInitDialog function (the m_StatBar variable is of type CStatusBarCtrl). 

BOOL CMyDlg::OnInitDialog() 

{

CDialog::OnInitDialog();

// Set the icon for this dialog.  The framework does this automatically

//  when the application's main window is not a dialog

SetIcon(m_hIcon, TRUE); // Set big icon

SetIcon(m_hIcon, FALSE); // Set small icon

/************************************************************************/

/* Adding STATUSBAR */

/************************************************************************/

int nTotWide; // total width of status bar

CRect rect;

     this->GetWindowRect(&rect);

 rect.top = rect.bottom- 25;

    

m_bRvStatOk = m_StatBar.Create(WS_CHILD | WS_BORDER | WS_VISIBLE ,rect,this,

                 IDC_STATUSBAR);

                             

     if (m_bRvStatOk == NULL)

{

          AfxMessageBox ("Status Bar not created!", NULL, MB_OK );

}

//

    // get size of window, use to configure the status

     // bar with four separate parts

     //

    

CRect rWin;

    this->GetWindowRect(&rWin);

    nTotWide = rWin.right-rWin.left;

//

// Make each part 1/4 of the total width of the window.

//

   

m_Widths[0] = nTotWide / 4;

    m_Widths[1] = nTotWide / 2;

    m_Widths[2] = nTotWide - m_Widths[0];

    m_Widths[3] = -1;

   

m_StatBar.SetMinHeight(25);

m_StatBar.SetParts( 4, m_Widths); 

//

// now lets put some text, different styles into parts of status bar

//

m_StatBar.SetText("WITH BORDER.", 0,0);

m_StatBar.SetText("WITHOUT BORDER.",1,SBT_NOBORDERS);

m_StatBar.SetText("POPUP.",2,SBT_POPOUT);

  //

// make the last part owner-drawn, add a bitmap

//

m_StatBar.SetText(NULL,3, SBT_OWNERDRAW);

// hBmp is a Global Variable of type HBITMAP 

hBmp = ::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP1));

/************************************************************************/

/* End STATUSBAR */

/************************************************************************/

// TODO: Add extra initialization here

return TRUE;  // return TRUE  unless you set the focus to a control

}

The fourth pane of the status bar is owner drawn because it is used to display a bitmap. In order to do this, simply add a message handler for the dialog's WM_DRAWITEM message. Once you've added that function, update it so that when finished it looks like the following. 

void CMyDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct) 

{

// 

// Draw bitmap in status bar

//

HDC hdcMem; // device context for memory

     HGDIOBJ hbmOld;  // old bitmap area we're over-writing

     BITMAP bm; // bitmap we're using

//

     // Create a compatible DC in memory

//

hdcMem = CreateCompatibleDC(lpDrawItemStruct->hDC);

     // Select the "logo.bmp" bitmap into the DC.

     hbmOld = ::SelectObject(hdcMem, hBmp);

     // Get the size of the bitmap

     ::GetObject(hBmp, sizeof(bm), &bm);

     // Blt the bitmap to the part.

     BitBlt(lpDrawItemStruct->hDC,lpDrawItemStruct->rcItem.left,

     lpDrawItemStruct->rcItem.top, bm.bmWidth, bm.bmHeight, 

         hdcMem, 0, 0,SRCCOPY);

//

// Add some text..1st. get bounding rectangle, then position & display text

//

char szText[16];

RECT rText;  // text rectangle

rText.left = lpDrawItemStruct->rcItem.left+24;

rText.top  = lpDrawItemStruct->rcItem.top;

rText.right = lpDrawItemStruct->rcItem.right-20;

rText.bottom = lpDrawItemStruct->rcItem.bottom;

     //

     //  add some text after the logo bitmap here

     //

memset(szText,0,sizeof(szText));

strcpy(szText,"LOGO"); // text to draw

SelectObject( lpDrawItemStruct->hDC, GetStockObject( ANSI_VAR_FONT ) );

::SetBkColor(lpDrawItemStruct->hDC, 0x00c0c0c0);  // set background color

     ExtTextOut(lpDrawItemStruct->hDC, lpDrawItemStruct->rcItem.left+24, lpDrawItemStruct->rcItem.top+4, ETO_OPAQUE, &rText, szText,

     strlen(szText),NULL ); // draw the text in the rectangle rText

// 

// End adding text.  Reselect the original object into the DC.

// 

     SelectObject(hdcMem, hbmOld);

     // Delete the compatible DC. 

     DeleteDC(hdcMem);

}

Make the following changes to the dialog's header file. 

class CMyDlg : public CDialog

{

// Construction

public:

CMyDlg(CWnd* pParent = NULL); // standard constructor

CStatusBarCtrl m_StatBar;

.....................................

...................................

......................................

}

Finally, make the following changes to the resource.h file. 

//{{NO_DEPENDENCIES}}

// Microsoft Developer Studio generated include file.

//

#define IDM_ABOUTBOX 0x0010

#define IDC_STATUSBAR           32500

.....................................

...................................

......................................

That's it! You now have a status bar at the bottom of your dialog!