感谢CSDN论坛上的Featured(我握着爱情的门票静静排队……) 提供了一个演示程序的下载链接:http://www.bypro.net/PostAttachment.aspx?PostID=21994&AttachmentID=1834
感谢CSDN论坛上的Featured(我握着爱情的门票静静排队……) 提供了本文的链接
http://www.codeguru.com/Cpp/W-D/dislog/toolbarsandstatusbars/article.php/c1955/
Girish Pandit (view profile)
July 28, 1999
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 dialogSetIcon(m_hIcon, TRUE);// Set big iconSetIcon(m_hIcon, FALSE);// Set small icon/************************************************************************//*Adding STATUSBAR*//************************************************************************/int nTotWide;// total width of status barCRect 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 herereturn 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 rectanglerText.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 drawSelectObject( 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{// Constructionpublic:CMyDlg(CWnd* pParent = NULL);// standard constructorCStatusBarCtrlm_StatBar;..............................................................................................................}CStatusBarCtrlm_StatBar;..............................................................................................................}Finally, make the following changes to the resource.h file. //{{NO_DEPENDENCIES}}// Microsoft Developer Studio generated include file.//#define IDM_ABOUTBOX0x0010#define IDC_STATUSBAR 32500..............................................................................................................That's it! You now have a status bar at the bottom of your dialog!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
CStatusBarCtrlm_StatBar;
.....................................
...................................
......................................
}
CStatusBarCtrlm_StatBar;
.....................................
...................................
......................................
}
Finally, make the following changes to the resource.h file.
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
//
#define IDM_ABOUTBOX0x0010
#define IDC_STATUSBAR 32500
.....................................
...................................
......................................
That's it! You now have a status bar at the bottom of your dialog!
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
CStatusBarCtrlm_StatBar;
.....................................
...................................
......................................
}
CStatusBarCtrlm_StatBar;
.....................................
...................................
......................................
}
Finally, make the following changes to the resource.h file.
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
//
#define IDM_ABOUTBOX0x0010
#define IDC_STATUSBAR 32500
.....................................
...................................
......................................
That's it! You now have a status bar at the bottom of your dialog!