孙鑫VC++深入详解:Lesson9 Part6---在状态栏中添加进度条

最直接的办法就是:

//------ 窗口改变是重绘进度条. 
// 到此可见,其实就一个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; //定义进度栏成员
3.在OnCreate()中创建:
    m_progress.Create(WS_CHILD|WS_VISIBLE,CRect(100,100,200,120),this,123);//默认是水平的
m_progress.SetPos(50);//进度条的位置
4.把进度栏放置到状态栏中的进度栏处,实际是覆盖在其上:
   1)先获得状态栏中的进度栏的矩形大小,用状态栏的成员函数CStatusBar::GetItemRect()
   2)调用OnCreate(),其中父窗口要改为状态栏
    CRect rect;
m_wndStatusBar.GetItemRect(2,&rect);
m_progress.Create(WS_CHILD|WS_VISIBLE,rect,&m_wndStatusBar,123);
m_progress.SetPos(50);

  上述代码中的rect其实没有真正得到状态栏的矩形值,是因为在OnCreate中状态栏的初始化工作,即对窗口的摆放还没有完成.
  所以不能获得其真正的矩形位置.
解决办法:让OnCrete()函数完全执行完成后在执行上述代码,把上述代码写成一个用户自定义的消息函数OnProgress(),
          在OnCreate()中Post一个自定义的消息UM_PROGRESS即PostMessage(UM_PROGRESS),并把该消息按照
          消息映射的规则与OnProgress()关联: ON_MESSAGE(UM_PROGRESS,OnProgress).          
注1:#define UM_PROGRESS   WM_USER+1

注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
}

//--- 进度条怎么那么短?

//---




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
孙鑫vc是一种特殊的混合编程语言,它结合了C语言和Verilog语言的特点。在深入详解孙鑫vc代码之前,我们先了解一下它的一些特性。 首先,孙鑫vc具有高度的可定制性。用户可以根据自己的需求选择C语言和Verilog语言的特性来编写代码。这种灵活性使得孙鑫vc可以适用于不同的应用领域。 其次,孙鑫vc支持并行计算。它提供了一种简单而有效的方式来利用硬件资源进行并行计算,提高程序的执行效率。 另外,孙鑫vc还具有强大的调试功能。它能够在运行时对代码进行监控和调试,帮助开发者快速定位问题并进行修复。 深入详解孙鑫vc代码包括以下几个方面: 首先,我们可以从代码的结构和组织方式入手。孙鑫vc代码一般由多个模块组成,每个模块包含了各自的功能和接口。 其次,我们需要了解代码使用的变量和数据类型。在孙鑫vc,可以使用C语言和Verilog语言的数据类型,如整型、浮点型等。了解这些数据类型的使用方法和限制对理解代码非常重要。 然后,我们需要分析代码的控制流和算法。这包括了代码件语句、循环语句等,以及算法的实现细节。通过对控制流和算法的分析,我们可以更好地理解代码的逻辑和实现原理。 最后,我们还需要关注代码的接口和数据传输方式。在孙鑫vc,模块之间通过接口进行数据的传递和交互。了解接口的定义和使用方式对于理解代码的功能和模块之间的关系非常重要。 综上所述,深入详解孙鑫vc代码需要从代码的结构和组织方式、变量和数据类型、控制流和算法、接口和数据传输方式等多个方面进行分析和理解。通过对这些方面的研究,我们可以更好地理解孙鑫vc代码,并且能够对代码进行修改和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值