这里主要实现为状态栏添加图片,显示实时数据,实时显示鼠标位置,滚动字幕,进度条显示等功能,其中为状态栏添加图片需要自绘状态栏,然后在主框架中将系统状态栏变量替换成自己定义状态栏的变量;
1. 添加图片:
首先定义class CMyStatus : public CStatusBar,然后重写里面的virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);函数。代码如下:void CMyStatus::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
UINT nID,nStyle;
int nWidth;
GetPaneInfo(lpDrawItemStruct->itemID, nID, nStyle, nWidth);
switch(nID)
{
// 如果是CAPS格则处理
case ID_INDICATOR_CAPS:
//从资源中选择位图
CBitmap pBitmap;
//加载位图
pBitmap.LoadBitmap(IDB_BTM_STATUS);
//将状态条附加到一个CDC对象
CDC dc,SourceDC;
dc.Attach(lpDrawItemStruct->hDC);
//得到状态条窗格的大小和坐标
CRect rect(&lpDrawItemStruct->rcItem);
//将当前位图放入兼容CDC
SourceDC.CreateCompatibleDC(NULL);
CBitmap* pOldBitmap = SourceDC.SelectObject(&pBitmap);
dc.BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &SourceDC, 0, 0, SRCCOPY);
SourceDC.SelectObject(pOldBitmap);
pBitmap.DeleteObject();
dc.Detach();
return;
}
CStatusBar::DrawItem(lpDrawItemStruct);
}
然后在主框架中将系统状态栏变量替换成自己定义状态栏的变量并在intCMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)添加上以下代码即可:
UINT nID,nStyle;
int nPane,nWidth;
nPane = m_mystatus.CommandToIndex(ID_INDICATOR_CAPS);
m_mystatus.GetPaneInfo(nPane, nID, nStyle, nWidth) ;
m_mystatus.SetPaneInfo(nPane, nID, SBPS_OWNERDRAW|SBPS_NOBORDERS,nWidth + 100);
2. 显示实时时间:
首先是在主框架的intCMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)中添加上以下代码:
m_mystatus.SetPaneInfo(nPane+1,ID_SEPARATOR,SBPS_NORMAL,150);
CTime t1;//实时显示时间
t1 =CTime::GetCurrentTime();
m_mystatus.SetPaneText(nPane+1,t1.Format("%H:%M:%S"));
SetTimer(1,1000,NULL);
然后是为主框架添加 afx_msg void OnTimer(UINT nIDEvent);
具体代码如下:
void CMainFrame::OnTimer(UINTnIDEvent)
{
// TODO: Add your message handler code here and/or call default
CTime t1;
t1 = CTime::GetCurrentTime();
m_mystatus.SetPaneText(2,t1.Format("%H:%M:%S"));
CFrameWnd::OnTimer(nIDEvent);
}
3. 实时显示鼠标位置:
这个是要在视图类中捕获鼠标移动的消息从而显示在状态栏中:
即voidCAddBTMToStatusView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
char text[100];
memset(text,0,100);
sprintf(text,"(%04d,%04d)",point.x,point.y);
CMyStatus *pStatus = (CMyStatus*)AfxGetApp()->m_pMainWnd->GetDescendantWindow(AFX_IDW_STATUS_BAR);//调用该成员函数查找子代窗口指定由特定ID
if (pStatus)
{
pStatus->SetPaneText(3,text,TRUE);
}
CView::OnMouseMove(nFlags, point);
}
4. 滚动字幕
首先在主框架的int CMainFrame::OnCreate(LPCREATESTRUCTlpCreateStruct)中添加定时器SetTimer(2,300,NULL);
然后是为主框架添加 afx_msg void OnTimer(UINT nIDEvent);
具体代码如下:
voidCMainFrame::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
static int strID = 0;
if (strID >= (m_StatusText.GetLength() - 1))
{
strID = 0;
} m_wndStatusBar.SetPaneText(m_wndStatusBar.CommandToIndex(ID_SEPARATOR),((LPCSTR)m_StatusText)+strID);//CommandToIndex函数是返回工具栏或者状态栏中对应ID的索引值
strID += 2;
CFrameWnd::OnTimer(nIDEvent);
}
其中的m_StatusText即是你要滚动的字符内容
5. 进度条显示
首先要自绘状态栏,然后引用C++封装的CProgressCtrl类,代码如下:
class CMyProgress : public CStatusBar
{
// Construction
public:
CMyProgress();
// Attributes
public:
CProgressCtrl m_ProgressCtrl;
CProgressCtrl& GetProgress()
{
return m_ProgressCtrl;
}
// Implementation
public:
virtual ~CMyProgress();
// Generated message map functions
protected:
//{{AFX_MSG(CMyProgress)
afx_msg intOnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnSize(UINT nType,int cx, int cy);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
.cpp文件中
CMyProgress::CMyProgress()
{
}
CMyProgress::~CMyProgress()
{
}
BEGIN_MESSAGE_MAP(CMyProgress, CStatusBar)
//{{AFX_MSG_MAP(CMyProgress)
ON_WM_CREATE()
ON_WM_SIZE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
// CMyProgress message handlers
Int CMyProgress::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if(CStatusBar::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specializedcreation code here
m_ProgressCtrl.Create(WS_CHILD|WS_VISIBLE,CRect(0,0,0,0),this,IDS_PROGRESS);
return 0;
}
void CMyProgress::OnSize(UINT nType, int cx, int cy)
{
CStatusBar::OnSize(nType, cx, cy);
// TODO: Add your message handlercode here
CRect rect;
GetItemRect(1,&rect);
m_ProgressCtrl.MoveWindow(rect);
}
然后在主框架的int CMainFrame::OnCreate(LPCREATESTRUCTlpCreateStruct)中添加定时器SetTimer(1,100,NULL);;
然后是为主框架添加 afx_msg void OnTimer(UINT nIDEvent);
具体代码如下:
voidCMainFrame::OnTimer(UINT nIDEvent)
{
// TODO: Add yourmessage handler code here and/or call default
int nLower,nUpper;
m_wndStatusBar.GetProgress().GetRange(nLower,nUpper);
if (m_Pos >= nUpper)
{
m_Pos = 0;
}
m_wndStatusBar.GetProgress().SetPos(m_Pos);
m_Pos += 2;
CFrameWnd::OnTimer(nIDEvent);
}