在Visual C++中透明浮动按键的实现.docx_第1页
在Visual C++中透明浮动按键的实现.docx_第2页
在Visual C++中透明浮动按键的实现.docx_第3页
在Visual C++中透明浮动按键的实现.docx_第4页
在Visual C++中透明浮动按键的实现.docx_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

在Visual C+中透明浮动按键的实现 有一种按键,看起来是一幅完整的图片,当鼠标移到按键区域时,图片的一部分凸现,形成一个按键,当鼠标移走时又恢复原来状态。 最近,看了一些关于浮动按键的代码,其原理大致上跟CBitmapButton差不多,用数幅位图代表按键的各个状态,响应鼠标的各种消息来设置按键的状态,实现按键的浮动显示,但是这样的按键却不能和周围的背景混和成一幅图片。 为了实现“透明”按键,可以简单地做个试验:先在对话框中加入一个BUTTON,通过属性框选“Owner Draw”风格,再加入一个PICTURE,并加入图片,将BUTTON移到PICTURE上。运行结果发现,按键没有显示出来,但在按键区域按下鼠标时,该按键仍然能发出WM_COMMAND消息,这样一个纯透明的按键建立了。显然,这个按键是毫无使用意义的,必须让用户容易觉察到按键的位置,可以把这个按键改造一下: (首先从Cbutton派生出一个新类CDrawButton) 把按键的标题显示出来这个实现起来比较简单,我们可以重载Cbutton类的成员函数DrawItem(), void CDrawButton:DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) CDC dc; Crect rect=lpDrawItemStruct-rcItem;/得到按键区域 Cstring sCaption; dc.Attach(lpDrawItemStruct-hDC); /得到设备环境CDC VERIFY(lpDrawItemStruct-CtlType=ODT_BUTTON); GetWindowText(sCaption);/得到按键的标题 dc.SetBkMode(TRANSPARENT);/透明显示 Cfont* m_pOldFont=dc.SelectObject(m_pFont); dc.DrawText(sCaption,&rect,DT_CENTER|DT_VCENTER|DT_SINGLELINE); dc.SelectObject(m_pOldFont); 其中的m_pFont是成员变量,它保存了对话框的字体指针,为了按键的标题风格与对话框的字体风格一致,在初始化时调用对话框的成员函数GetFont()即可得到指向对话框字体的Cfont类指针。 使按键浮动显示 要通过自绘来表示按键的各种状态,可填写DRAWITEMSTRUCT来通知DrawItem()函数需要做什么,我们先了解一下DRAWITEMSTRUCT: typedef struct tagDRAWITEMSTRUCT UINT CtlType; / 控件类型 UINT CtlID;/ 控件的ID号 UNIT itemID;/菜单项的索引 UINT itemAction;/ 绘图操作 UINT itemState; / 状态 HWND hwndItem; / 控件的窗口句柄 HDC hDC; / 相关的设备环境 RECT rcItem;/控件的范围 DWORD itemData;/ 指定与菜单项相联系的应用程序定义的32位值 DRAWITEMSTRUCT; 利用这个结构先做一个按键状态设置函数: void CDrawButton:SetButtonMode(UINT action, UINT mode) / TODO: Add your message handler code here and/or call default DRAWITEMSTRUCT DIS; DIS.CtlType = ODT_BUTTON; DIS.CtlID = GetDlgCtrlID(); DIS.itemAction = action; DIS.itemState = mode; DIS.hwndItem = GetSafeHwnd(); DIS.hDC = GetDC()-GetSafeHdc(); GetClientRect(&(DIS.rcItem); SendMessage(WM_DRAWITEM,(WPARAM)GetSafeHwnd(),(LPARAM)&DIS); ReleaseDC(CDC:FromHandle(DIS.hDC); 这样,我们可以响应鼠标的各种消息来设置按键的各种状态: void CDrawButton:OnMouseMove(UINT nFlags, Cpoint point) / TODO: Add your message handler code here and/or call default Crect rect; GetClientRect(&rect); if(rect.PtInRect(point) if (mBtnStats=BTN_NORMAL) SetButtonMode(ODA_SELECT, ODS_FOCUS); SetCapture(); else /AutoLoad(GetDlgCtrlID(),GetParent(); SetButtonMode(ODA_DRAWENTIRE,ODS_DEFAULT); ReleaseCapture(); Cbutton:OnMouseMove(nFlags, point); 这里,mBtnStats是个UINT类型的成员变量,它可以有三种自定义状态: BTN_NORMAL 正常状态 BTN_UP 鼠标移入按键区域或释放鼠标 BTN_DOWN 按下鼠标 (可以再加一种DISABLE状态) 当在按键区域释放鼠标时,必须发送WM_COMMAND消息: void CDrawButton:OnLButtonUp(UINT nFlags, Cpoint point) / TODO: Add your message handler code here and/or call default Crect rect; GetClientRect(&rect); if(rect.PtInRect(point) if (mBtnStats=BTN_DOWN) GetParent()-SendMessage(WM_COMMAND, MAKELPARAM(GetDlgCtrlID(),BN_CLICKED), (LPARAM)GetSafeHwnd(); SetCapture(); else SetButtonMode(ODA_DRAWENTIRE,ODS_DEFAULT); ReleaseCapture(); Cbutton:OnLButtonUp(nFlags, point); 接着就是绘制按键的各种状态:由于按键必须“透明”,所以在按下和释放时只在按键区域的四周加上一个3D边框就行了。而在正常状态下,则必须去掉边框恢复背景。但如何恢复背景图象呢?我是这样做的:在按键初始化时,先把被按键覆盖了的区域保存在一个Cbitmap类中,以后需要重绘按键时就把这个Cbitmap画在按键上就行了。 void CDrawButton:DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) / TODO: Add your code to draw the specified item CDC dc; Crect rect=lpDrawItemStruct-rcItem; Cstring sCaption; dc.Attach(lpDrawItemStruct-hDC); /得到绘制的设备环境CDC VERIFY(lpDrawItemStruct-CtlType=ODT_BUTTON); if (lpDrawItemStruct-itemAction & ODA_DRAWENTIRE) /重绘控件(正常状态) mBtnStats=BTN_NORMAL; if (m_pBitmap!=0) CDC memDC; memDC.CreateCompatibleDC(&dc); memDC.SelectObject(m_pBitmap); dc.BitBlt(0, 0, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY); memDC.DeleteDC(); /显示按键标题 GetWindowText(sCaption); dc.SetBkMode(TRANSPARENT); if (m_pFont!=0) Cfont* m_pOldFont=dc.SelectObject(m_pFont); dc.DrawText(sCaption,&rect, DT_CENTER|DT_VCENTER|DT_SINGLELINE); dc.SelectObject(m_pOldFont); if (lpDrawItemStruct-itemState & ODS_SELECTED) & (lpDrawItemStruct-itemAction & ODA_SELECT) /按下鼠标 mBtnStats=BTN_DOWN; dc.Draw3dRect(&rect,RGB(128,128,128),RGB(192,192,192); rect.top=rect.top+1;rect.bottom=rect.bottom-1; rect.left=rect.left+1;rect.right=rect.right-1; dc.Draw3dRect(&rect,RGB(0,0,0),RGB(255,255,255); if(!(lpDrawItemStruct-itemState & ODS_SELECTED) & (lpDrawItemStruct-itemAction & ODA_SELECT) /释放鼠标或鼠标进入按键区域 mBtnStats=BTN_UP; dc.Draw3dRect(&rect,RGB(255,255,255),RGB(0,0,0); rect.top=rect.top+1;rect.bottom=rect.bottom-1; rect.left=rect.left+1;rect.right=rect.right-1; dc.Draw3dRect(&rect,RGB(192,192,192),RGB(128,128,128); dc.Detach(); 接着就必须一些初始化工作,其中最关键就是把被按键覆盖了的区域保存进Cbitmap类中,我们知道CDC:StretchBlt()函数可以把位图的指定区域从一个设备拷贝到另一个设备中,这样可以很方便地把窗口或对话框的某个区域保存,条件是获得其DC: void CDrawButton:LoadBack(CWnd *pParent) ASSERT(GetStyle() & BS_OWNERDRAW); if (m_pBitmap!=0) return; Crect rect; GetWindowRect(&rect); pParent-ScreenToClient(&rect);/获得按键区域 CPaintDC dc(pParent); if (m_pBitmap=0) m_pBitmap=new Cbitmap;/初始化位图 m_pBitmap-CreateCompatibleBitmap(&dc,rect.Width(),rect.Height(); CDC memDC; memDC.CreateCompatibleDC(&dc); memDC.SelectObject(m_pBitmap); memDC.StretchBlt(0, 0, rect.Width(),rect.Height(), &dc, rect.left, rect.top, rect.Width(),rect.Height(), SRCCOPY);/保存 memDC.DeleteDC(); m_pFont=pParent-GetFont();/获得窗口或对话框的字体 ModifyStyle(0,WS_VISIBLE);/显示按键 SetBitmapMode(ODA_DRAWENTIRE,0);/绘制按键 而使这个类和对话框上的按键产生联系还必须调用一下SubclassDlgItem(): BOOL CDrawButton:AutoLoad(UINT nID, CWnd *pParent) / first attach the CDrawButton to the dialog control if (m_pBitmap!=0) return FALSE; if (!SubclassDlgItem(nID, pParent) return FALSE; LoadBack(pParent); return TRUE; 这个类还必须具有三个成员变量: Cfont* m_pFont; Cbitmap* m_pBitmap; UINT mBtnStats; 在构造函数中初始化这些变量 m_pBitmap=0; m_pFont=0; /赋予0是可以的 mBtnStats=BTN_NORMAL; 在折构函数中拆除位图 if(m_pBitmap!=0) delete m_pBitmap; 这样,一个透明的浮动式按键类就做好了,具体实现方法以下: 1.接管对话框的BUTTON,首先在对话框上画一个BUTTON,再加一

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论