特性时,只要鼠标指针移动到浮动工具条上,整个应用程序窗口就会自动消失。所以第二种方法根本不可行。实现平面工具条的最好方法是在派生类中自己来完成,虽然这一过程比较复杂普通用户很难做到,但如果存在一个完美的平面工具条控制类,在自己的应用程序中增加相应控制类就是一件很容易的事了。下面是笔者实现完美平面工具条派生类的步骤: (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();//工具条按钮总数 CClientDC dc(this); //窗口客户区域 TBBUTTON button; //按钮数据结构
CToolBarCtrl &ToolBarCtrl=GetToolBarCtrl(); OnDrawGrapper(); //画把手 for(index=0;index
GetItemRect(index,&rect);//取得按钮矩形区域 rect.left++;rect.top++;
ToolBarCtrl.GetButton(index,&button);//取得按钮信息 if(button.fsState&(TBSTATE_CHECKED|TBSTATE_HIDDEN)) continue;
if(button.fsStyle&TBSTYLE_SEP){//画分隔线 if(m_nNew!=0) OnDrawSep(index,dc); } else if ((m_nIndex==index)||
button.fsState&TBSTATE_PRESSED){//凹按钮 OnEraseBorder(index,dc);//删除按钮边界
if (rect.PtInRect(pt)) OnDrawBorder(index,dc,1);//绘下凹按钮 else OnDrawBorder(index,dc,0);//绘凸出按钮
} else if (!rect.PtInRect(pt)||m_nFlags==LBUTTONUP|| !(button.fsState&TBSTATE_ENABLED)){ OnEraseBorder(index,dc);//删除按钮边界 } else if (m_nFlags!=LBUTTONDOWN){//凸按钮 OnEraseBorder(index,dc);//删除按钮边界
if(m_nFlagl==0)//鼠标按下防止再次重新出现凸起 OnDrawBorder(index,dc,0);//绘按钮边界 }
m_nFlags=0;//按下后移动后不正常凸起
}
ReleaseDC(&dc); }
void CTestToolBar::OnPaint() { //完善重绘按钮功能 CToolBar::OnPaint();
OnDrawBorders();//处理所有按钮边界 }
void CTestToolBar::OnLButtonDown(UINT nFlags, CPoint point) { //完善鼠标左键按下功能
m_nFlags=LBUTTONDOWN;//设置鼠标按键标志 m_nFlagl=1;
CToolBar::OnLButtonDown(nFlags,point);//调原函数 int index;
int count=GetCount();//工具栏按钮总数 TBBUTTON button;
CToolBarCtrl &ToolBarCtrl=GetToolBarCtrl(); for(index=0;index
ToolBarCtrl.GetButton(index,&button);//取得按钮信息 if (button.fsState&TBSTATE_PRESSED){ //记录按下按钮号 m_nIndex=index; } } }
void CTestToolBar::OnLButtonUp(UINT nFlags, CPoint point) { //完善鼠标释放功能
m_nFlags=LBUTTONUP;//设置鼠标按键标志 m_nFlagl=0;
CToolBar::OnLButtonUp(nFlags, point);//调原函数 CRect rect; CPoint pt;
GetCursorPos(&pt);//取得光标位置 ScreenToClient(&pt);//变成窗口坐标 CClientDC dc(this);//窗口客户区域
if (m_nIndex!=0xffff){//判断按下按钮执行功能时仍下凹 GetItemRect(m_nIndex,&rect);//取得矩形区域 rect.left++;rect.top++;
OnEraseBorder(m_nIndex,dc);//删除按钮边界
if (rect.PtInRect(pt)) OnDrawBorder(m_nIndex,dc,1);//绘下凹按钮 }
m_nIndex=0xffff; }
void CTestToolBar::OnMouseMove(UINT nFlags, CPoint point) { //完善鼠标移动功能
CToolBar::OnMouseMove(nFlags, point); int index;
int count=GetCount();//工具栏按钮总数 CRect rect;
if (nFlags&MK_LBUTTON) m_nFlagl=1;//防止再次重新出现凸起 else m_nFlagl=0;
OnDrawBorders();//绘制所有按钮 for(index=0;index
GetItemRect(index,&rect); rect.left++;rect.top++;
if (rect.PtInRect(point)&&//取得移动过程中输入焦点 !(GetButtonStyle(index)&TBBS_SEPARATOR)){ SetCapture();//设置鼠标输入焦点 return; } }
if (nFlags&MK_LBUTTON){//防止移出而失去输入焦点 SetCapture();//设置鼠标输入焦点 m_nFlagl=1; return;
} else m_nFlagl=0; ReleaseCapture(); return; }
void CTestToolBar::OnNcPaint() { //背景重画函数
CToolBar::OnNcPaint(); OnDrawGrapper(); }
void CTestToolBar::SetState(UINT nLeft,BOOL nStated) { //状态设置函数
m_cxLeftBorder=nLeft;//左边界 m_nStated=nStated; //工具栏状态 }
(4)有关派生类函数几点说明
①画按钮凹凸边线函数OnDrawBorder()
正常工具条中的按钮具有黑色的边线,使按钮凹凸感更强烈,但在平面工具条中的这种按钮并不美观,所以应省略黑色边线部分,并且必须使用系统的API函数 GetSysColor函数来取得边线颜色,以便系统改变颜色时按钮边线也随之改变,同时由于凹凸按钮边线画法完全相同,只是颜色相反,所以两者完全可由这个函数来实现; ②画分隔线函数OnDrawSep() 画分隔线时应遍历每个按钮,来取得分隔线的位置,并且利用客户区域文本描述表就可实现,只需画亮暗两条线就可实现; ③画把手函数OnDrawGripper()
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库常用控件用法(7)在线全文阅读。
相关推荐: