最直接的办法就是:
//------ 窗口改变是重绘进度条.
// 到此可见,其实就一个OnPaint()就可以了,什么PostMessage(),自定义消息,实现自定义消息函数都可以不要了.
void CMainFrame::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
CRect rect;
m_wndStatusBar.GetItemRect(2,&rect);
if(m_progress.m_hWnd==NULL) //先判断,如果进度条没创建就创建
{
m_progress.Create(WS_CHILD|WS_VISIBLE,rect,&m_wndStatusBar,123);
m_progress.SetPos(50);
}
else m_progress.MoveWindow(rect);
// Do not call CFrameWnd::OnPaint() for painting messages
}
//------------------- 以下为学习过程.
1.进度栏类:CProgressCtrl是有CWnd派生而来,因此进度条也是窗口
2.CProgressCtrl m_progress; //定义进度栏成员注2:不能用SendMessage(UM_PROGRESS),因为SendMessage()不能立即返回到OnCreate()中.
具体代码:
在头文件MainFrm.h
#define UM_PROGRESS WM_USER +1
CProgressCtrl m_progress; //定义进度栏成员
afx_msg void OnProgress(); //在头文件中申明消息响应函数
在MainFrm.cpp中:
先在OnCreate()中PostMessage(UM_PROGRESS);
然后实现:
//------ 自定义消息UM_PROGRESS的响应函数实现
void CMainFrame::OnProgress()
{
//------创建进度条
if(m_progress.m_hWnd==NULL) //先判断,如果进度条没创建就创建
{
CRect rect;
m_wndStatusBar.GetItemRect(2,&rect);
m_progress.Create(WS_CHILD|WS_VISIBLE,rect,&m_wndStatusBar,123);
m_progress.SetPos(50);
}
}
5. 在CMainFrame的OnPaint()函数中,修改进度条的位置:
到此可见,其实就一个OnPaint()就可以了,什么PostMessage(),自定义消息,实现自定义消息函数都可以不要了.
void CMainFrame::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
CRect rect;
m_wndStatusBar.GetItemRect(2,&rect);
if(m_progress.m_hWnd==NULL) //先判断,如果进度条没创建就创建
{
m_progress.Create(WS_CHILD|WS_VISIBLE,rect,&m_wndStatusBar,123);
m_progress.SetPos(50);
}
else m_progress.MoveWindow(rect);
// Do not call CFrameWnd::OnPaint() for painting messages
}
//---
// MainFrm.cpp : implementation of the CMainFrame class
//
#include "stdafx.h"
#include "Style.h"
#include "MainFrm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CMainFrame
IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
ON_WM_TIMER()
ON_COMMAND(IDM_TEST, OnTest)
ON_COMMAND(ID_VIEW_NEWTOOLBAR, OnViewNewtoolbar)
ON_UPDATE_COMMAND_UI(ID_VIEW_NEWTOOLBAR, OnUpdateViewNewtoolbar)
ON_WM_PAINT()
//}}AFX_MSG_MAP
ON_MESSAGE(UM_PROGRESS,OnProgress)
END_MESSAGE_MAP()
static UINT indicators[] =
{
ID_SEPARATOR, // status line indicator
IDS_TIME, //时间
IDS_PROGRESS, //进度
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};
/
// CMainFrame construction/destruction
CMainFrame::CMainFrame()
{
// TODO: add member initialization code here
}
CMainFrame::~CMainFrame()
{
}
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
//------关联工具栏对象m_wndToolBar与资源IDR_MAINFRAME--- 即创建工具栏,工具栏就是一个窗口,其由CWnd...派生
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
//------创建状态条
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status bar\n");
return -1; // fail to create
}
// TODO: Delete these three lines if you don't want the toolbar to
// be dockable
//CControlBar::EnableDocking,这里是指明工具栏IDR_MAINFRAME是否可以停泊在父窗口上,以及如何停泊
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
// 这是调用的CFrameWnd::EnableDocking,指明主框架窗口可以停泊工具栏,不具体指定哪个工具栏.这样其他任何新建的工具栏也可以停泊了.
EnableDocking(CBRS_ALIGN_ANY);
//停泊工具栏具体的工具栏: 由对象m_wndToolBar关联的工具栏IDR_MAINFRAME
DockControlBar(&m_wndToolBar);
//------自定义工具栏的实现
//------关联工具栏对象m_NewToolBar与资源IDR_TOOLBAR1--- 改在右边CBRS_RIGHT
if (!m_NewToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_RIGHT
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_NewToolBar.LoadToolBar(IDR_TOOLBAR1))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
//CControlBar::EnableDocking,这里是指明工具栏m_NewToolBar是否可以停泊在父窗口上,以及如何停泊
m_NewToolBar.EnableDocking(CBRS_ALIGN_ANY);
//停泊工具栏具体的工具栏: 由对象m_newToolBar关联的工具栏IDR_TOOLBAR1
DockControlBar(&m_NewToolBar);
//------状态栏时间显示
/*
CTime t=CTime::GetCurrentTime(); //获得当前时间,但是这个时间获取后是个静止的,要更新,必须用定时器消息中去更新
CString s = t.Format( "%A, %B %d, %Y, %H:%M:%S" ); //星期,月,日,年,时,分,秒
int index=0;
index = m_wndStatusBar.CommandToIndex(IDS_TIME);
//计算要显示的文本的长度
CClientDC dc(this);
CSize sz = dc.GetTextExtent(s);
m_wndStatusBar.SetPaneInfo(index,IDS_TIME,SBPS_NORMAL,sz.cx);
m_wndStatusBar.SetPaneText(index,s,TRUE);
*/
//------创建进度条
/*
CRect rect;
m_wndStatusBar.GetItemRect(2,&rect);
m_progress.Create(WS_CHILD|WS_VISIBLE,rect,&m_wndStatusBar,123);
m_progress.SetPos(50);
*/
// PostMessage(UM_PROGRESS);//
//------先加载图标到数字m_hIcon[], 用SetClassLong()调用,修改标题图标,放置一个定时器
m_hIcon[0] =LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON1));
extern CStyleApp theApp; // 要用theApp这个全局的应用程序对象,需要申明下它是CStyleApp中定义过的.
m_hIcon[1] =LoadIcon(theApp.m_hInstance,MAKEINTRESOURCE(IDI_ICON2));
m_hIcon[2] =LoadIcon(AfxGetApp()->m_hInstance,MAKEINTRESOURCE(IDI_ICON3));
SetClassLong(this->m_hWnd,GCL_HICON,(LONG)m_hIcon[0]);//把m_hIcon[0]设置为窗口创建后的默认图标
SetTimer(1,1000,NULL); //设置一个定时器,定时产生WM_TIMER消息
return 0;
}
//在窗口创建之前修改,要修改什么,就对编写一个自己的窗口类wc,并注册
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
//------- 定义一个新的窗口类 wc
/*
WNDCLASS wc={0};
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
wc.hCursor =LoadCursor(NULL,IDC_HELP);
wc.hIcon =LoadIcon(NULL,IDI_ERROR);
wc.hInstance = AfxGetInstanceHandle();
wc.lpfnWndProc = ::DefWindowProc;//全局的Win32API
wc.lpszClassName ="sunxin.org"; //这个名称取定了,不能随便改了,这就好比一个资源的名称,
wc.lpszMenuName =NULL;
wc.style =CS_HREDRAW|CS_VREDRAW;
RegisterClass(&wc); //注册
cs.lpszClass = "sunxin.org"; //把注册的类传给cs
*/
//------使用全局函数AfxRegisterWndClass来修改
/*
cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW,
0, //不改光标,因为在框架类总改了也看不到
0,//不改背景,因为在框架类中改了也看不见框架的背景
LoadIcon(NULL,IDI_WARNING) // 能该的就是这个框架图标了
);
*/
return TRUE;
}
/
// CMainFrame diagnostics
#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
CFrameWnd::AssertValid();
}
void CMainFrame::Dump(CDumpContext& dc) const
{
CFrameWnd::Dump(dc);
}
#endif //_DEBUG
/
// CMainFrame message handlers
// 响应定时器SetTimer(1,1000,NULL)的WM_TIMER消息函数
void CMainFrame::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
//------状态栏时间显示
{
CTime t=CTime::GetCurrentTime(); //获得当前时间,但是这个时间获取后是个静止的,要更新,必须用定时器消息中去更新
//CString s = t.Format( "%A, %B %d, %Y, %H:%M:%S" ); //星期,月,日,年,时,分,秒
CString s = t.Format("%H:%M:%S" );
int index=0;
index = m_wndStatusBar.CommandToIndex(IDS_TIME);
//计算要显示的文本的长度
CClientDC dc(this);
CSize sz = dc.GetTextExtent(s);
m_wndStatusBar.SetPaneInfo(index,IDS_TIME,SBPS_NORMAL,sz.cx);
m_wndStatusBar.SetPaneText(index,s,TRUE);
}
static int index =1;
SetClassLong(this->m_hWnd,GCL_HICON,(LONG)m_hIcon[index]);
index++;if(index==3)index=0; // 或者取3的取模运算:index=++index%3;
CFrameWnd::OnTimer(nIDEvent);
}
void CMainFrame::OnTest()
{
// TODO: Add your command handler code here
MessageBox("test");
}
void CMainFrame::OnViewNewtoolbar()
{
// TODO: Add your command handler code here
//----方式1: 调用ShowWindow,RecalcLayout,DockControlBar
/*
static CRect rect; //保存工具栏的位置
if(m_NewToolBar.IsWindowVisible())
{
//m_NewToolBar.GetWindowRect(&rect);
m_NewToolBar.ShowWindow(SW_HIDE);
}
else
{
m_NewToolBar.ShowWindow(SW_SHOW);
//m_NewToolBar.MoveWindow(rect);
}
RecalcLayout(true);//重构窗口layout
DockControlBar(&m_NewToolBar);
*/
//----方式2: 调用ShowControlBar 是CFrameWnd::ShowControlBar 框架类的函数
ShowControlBar(&m_NewToolBar,!m_NewToolBar.IsWindowVisible(),FALSE);
}
// 给子菜单"新工具栏"增加 勾选复选设置
void CMainFrame::OnUpdateViewNewtoolbar(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_NewToolBar.IsWindowVisible());
}
//------ 自定义消息UM_PROGRESS的响应函数实现
void CMainFrame::OnProgress()
{
//------创建进度条
/*
if(m_progress.m_hWnd==NULL) //先判断,如果进度条没创建就创建
{
CRect rect;
m_wndStatusBar.GetItemRect(2,&rect);
m_progress.Create(WS_CHILD|WS_VISIBLE,rect,&m_wndStatusBar,123);
m_progress.SetPos(50);
}
*/
}
//------ 窗口改变是重绘进度条.
// 到此可见,其实就一个OnPaint()就可以了,什么PostMessage(),自定义消息,实现自定义消息函数都可以不要了.
void CMainFrame::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
CRect rect;
m_wndStatusBar.GetItemRect(2,&rect);
if(m_progress.m_hWnd==NULL) //先判断,如果进度条没创建就创建
{
m_progress.Create(WS_CHILD|WS_VISIBLE,rect,&m_wndStatusBar,123);
m_progress.SetPos(50);
}
else m_progress.MoveWindow(rect);
// Do not call CFrameWnd::OnPaint() for painting messages
}