MFC通用控件使用详解(8)

2019-03-23 13:08

要正确保存和恢复应用程序界面状态,必须对应用程序窗口和工具条窗口等均进行保存和恢复,这需要完善应用程序的建立和关闭过程。具体步骤如下:

(1)首先利用类向导ClassWizard为应用程序增加窗口关闭WM_CLOSE消息处理功能OnClose();

(2)在MainFrm.cpp中为应用程序状态设置成员变量 static TCHAR BASED_CODE szSection[]=_T(\ static TCHAR BASED_CODE szWindowPos[]=_T(\ static TCHAR szFormat[]=_T(\ (3)编制窗口位置状态读取和写入函数

static BOOL PASCAL NEAR ReadWindowPlacement(LPWINDOWPLACEMENT pwp) { //窗口位置状态读取函数,从INI文件中

CString strBuffer=AfxGetApp()->GetProfileString(szSection,szWindowPos); if (strBuffer.IsEmpty()) return FALSE; WINDOWPLACEMENT wp;//窗口位置数据结构 int nRead=_stscanf(strBuffer,szFormat, &wp.flags,&wp.showCmd,//为数据结构读取数值 &wp.ptMinPosition.x,&wp.ptMinPosition.y, &wp.ptMaxPosition.x,&wp.ptMaxPosition.y,

&wp.rcNormalPosition.left,&wp.rcNormalPosition.top, &wp.rcNormalPosition.right,&wp.rcNormalPosition.bottom); if (nRead!=10) return FALSE; wp.length=sizeof wp;//结构大小 *pwp=wp; //结构指针 return TRUE; }

static void PASCAL NEAR WriteWindowPlacement( LPWINDOWPLACEMENT pwp)

{ //窗口位置状态写入函数,写到INI文件

TCHAR szBuffer[sizeof(\ wsprintf(szBuffer,szFormat,//将参数值转换为字符串 pwp->flags,pwp->showCmd,

pwp->ptMinPosition.x,pwp->ptMinPosition.y, pwp->ptMaxPosition.x,pwp->ptMaxPosition.y,

pwp->rcNormalPosition.left,pwp->rcNormalPosition.top, pwp->rcNormalPosition.right,pwp->rcNormalPosition.bottom); AfxGetApp()->WriteProfileString(szSection,szWindowPos,szBuffer); }

(4)在应用程序建立函数OnCreate()中增加状态读取和设置功能 WINDOWPLACEMENT wp;//保存主窗口及工具条窗口位置状态 if (ReadWindowPlacement(&wp))//读取位置状态信息 SetWindowPlacement(&wp); //设置位置状态信息 (5)在应用程序建立函数OnCreate()中增加工具条状态恢复功能 m_wndDockToolBar.SetColumns(AfxGetApp()->GetProfileInt( _T(\恢复列格式,默认为3 m_wndDockNextBar.SetColumns(AfxGetApp()->GetProfileInt( _T(\

LoadBarState(_T(\恢复保存的状态和位置 (6)在应用程序关闭函数OnClose()中完善状态保存功能 void CMainFrame::OnClose() { //保存工具条等的状态

SaveBarState(_T(\保存工具条状态

AfxGetApp()->WriteProfileInt(_T(\写入列数 _T(\ AfxGetApp()->WriteProfileInt(_T(\ _T(\写入提示功能 WINDOWPLACEMENT wp; wp.length=sizeof wp;

if (GetWindowPlacement(&wp)){ wp.flags=0;

if (IsZoomed()) wp.flags|=WPF_RESTORETOMAXIMIZED; //如果窗口被放大,则保存为最大化状态 WriteWindowPlacement(&wp); }

CFrameWnd::OnClose(); }

虽然SaveBarState()和LoadBarState()函数保存和恢复了工具条的所有默认位置状态,但在实际自己实现的功能参数部分并不能被保存,所以应单独编写这些参数的保存代码,如工具栏的排列格式列参数值、颜色状态标志和是否存在动态提示功能标志等,在实际编程时一定要注意。 3、工具条的平面特性

工具条的平面特性给人耳目一新之感,很多大型应用程序中的工具条都采用这一特性,并取得了巨大成功。利用VC++5中的COMCTL32.DLL动态链接库可以实现平面式工具条,其主要解决问题包括:由于MFC使用风格控制位来控制工具条的外观,所以在建立工具条时不能直接设置这种风格,必须在建立后利用SetFlatLookStyle()函数来修改;工具条控制本身也不在各级按钮之间绘制分隔线,其另一个任务就是截取WM_PAINT消息,并在相应的位置处增加分隔线;工具条控制也不绘

制左边的把手(gripper) ,最后的任务就是调整客户区域并绘制并绘制相应的gripper。 显然,实际工作中需要动态链接库COMCTL32.DLL支持的上述方法很不方便。尽管最简便的方法是利用VC++ 5中的未公开工具栏风格TBSTYLE_FLAT,可以得到工具条的平面特性,只需在工具条建立后简单地增加一条代码\,但笔者经试验发现这种方法存在两个严重错误:其一是所建立的平面工具条在移动时,不能自动清除移动前的按钮图标,使工具条画面杂乱无章;其二是当建立的平面工具条具有浮动特性时,只要鼠标指针移动到浮动工具条上,整个应用程序窗口就会自动消失。所以第二种方法根本不可行。实现平面工具条的最好方法是在派生类中自己来完成,虽然这一过程比较复杂普通用户很难做到,但如果存在一个完美的平面工具条控制类,在自己的应用程序中增加相应控制类就是一件很容易的事了。下面是笔者实现完美平面工具条派生类的步骤:

(1)首先利用类向导ClassWizard为工具条控制类派生一个新类CTESTTOOLBAR ,并设置相应的派生类实现文件名。由于新类的基类无法直接选择CTOOLBAR,所以在选择新类的基类时先选择CTOOLBARCTRL为基类,当派生类生成后再将实现文件中的所有CTOOLBARCTRL类名修改为CTOOLBAR控制类,并利用ClassWizard 为新类增加消息WM_PAINT、WM_NCPAINT、WM_MOUSEMOVE、WM_LBUTTONDOWN和WM_LBUTTONUP消息处理功能函数,以便实现新类中平面工具条的各种特性。同时,要在MainFrm.cpp中增加包含文件TestToolBar.h。 (2)完善派生类实现文件TestToolBar.h内容 class CTestToolBar : public CToolBar {......//其它代码 public:

CTestToolBar(); //新类构造函数

UINT GetColumns() { return m_nColumns;};//取得列数 void SetState(UINT nLeft,BOOL nStated);//设置列数和状态 void OnDrawBorder(int index,CDC &dc,int flag);//画边框 void OnEraseBorder(int index,CDC &dc);//删除边框 void OnDrawBorders();//画平面特性

void OnDrawSep(int index,CDC &dc);//画分隔线 void OnDrawGrapper();//画把手 ......//其它代码

#ifdef _DEBUG //增加插入控制

virtual void AssertValid() const;

virtual void Dump(CDumpContext& dc) const; #endif

protected: //增加成员变量

UINT m_nColumns; //工具栏按钮列数 UINT m_nFlags; //鼠标按键标志 int m_nIndex; //按下的按钮号

int m_nFlagl; //左键按下标志 UINT m_nStated; //工具栏状态 CRect rt; //关闭按钮矩形区域 ......//其它代码 }

(3)完善派生类实现文件TestToolBar.cpp内容 ......//其它代码 #define TOOLLEFT 18 #define LBUTTONDOWN 1 #define LBUTTONUP 2 ......//其它代码

CTestToolBar::CTestToolBar() { //在构造函数中初始化变量

m_nColumns=0; //工具栏按钮列数 m_cxLeftBorder=16; //左边界 m_cxRightBorder=3; //右边界 m_cyTopBorder=3; //顶边界 m_cyBottomBorder=3;//底边界

m_nFlags=0; //按键标志成员变量 m_nIndex=0xffff; //按下的按钮号 m_nFlagl=0; //左键按下标志 m_nStated=TRUE; //工具栏状态 }

......//其它代码

#ifdef _DEBUG//插入代码完善

void CTestToolBar::AssertValid() const { CToolBar::AssertValid(); }

void CTestToolBar::Dump(CDumpContext& dc) const { CToolBar::Dump(dc); } #endif //_DEBUG ......//其它代码

虽然需要实现的函数比较多,但总起来说不过是取得客户区域或窗口所有区域的文本设备、建立画笔和绘图函数的集合,所以这里只给出了画按钮凸凹边线的函数,其它函数可仿造实现。 void CTestToolBar::OnDrawBorder(int index,CDC &dc,int flag) { //画按钮边线flag=0凸=1凹 CRect rect;

GetItemRect(index,&rect);//取得客户区域

rect.right--;rect.bottom--; CPen *oldpen; UINT color1,color2;

if (flag==0){//两种状态的颜色处理

color1=COLOR_BTNHILIGHT;//按钮高度颜色 color2=COLOR_BTNSHADOW; //按钮阴影颜色 } else {

color1=COLOR_BTNSHADOW; color2=COLOR_BTNHILIGHT; }

CPen pen1(PS_SOLID,1,::GetSysColor(color1)); CPen pen2(PS_SOLID,1,::GetSysColor(color2)); dc.SelectStockObject(NULL_BRUSH); oldpen=dc.SelectObject(&pen1);

dc.MoveTo(rect.right,rect.top);//画按钮边亮线 dc.LineTo(rect.left,rect.top); dc.LineTo(rect.left,rect.bottom);

dc.SelectObject(&pen2); //画按钮边暗线 dc.MoveTo(rect.right,rect.top); dc.LineTo(rect.right,rect.bottom); dc.LineTo(rect.left,rect.bottom);

//dc.SelectStockObject(BLACK_PEN);//画按钮边黑线 //dc.MoveTo(rect.right+1,rect.top); //dc.LineTo(rect.right+1,rect.bottom+1); //dc.LineTo(rect.left,rect.bottom+1); dc.SelectObject(oldpen); DeleteObject(pen1); DeleteObject(pen2); }

void CTestToolBar::OnDrawBorders() { //实现平面工具条 CRect rect; CPoint pt;

GetCursorPos(&pt); //取得鼠标指针 ScreenToClient(&pt);//变成窗口坐标 int index;

int count=GetCount();//工具条按钮总数


MFC通用控件使用详解(8).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:二年级下册备课(含二次备课)

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: