VC++界面编程之--实现工具栏自定义皮肤
来源:互联网 发布:php开发实例大全 pdf 编辑:程序博客网 时间:2024/05/18 02:56
工具栏的工作原理就是:首先在父窗口上创建一个子窗口,然后在一个子窗口上创建不同ID的按钮,当用户点击某个按钮时,就会以一个命令的方式通知父窗口:我被点击了。所以我沿着这个思路,制作了一个自定义皮肤的工具栏。
工具栏效果展现:
该工具栏包含了:①自定义背景图片、②自定义按钮图片、③自定义ToolTips、④动态增加按钮,等几个主要功能。当鼠标移动到某个工具栏按钮上上时,会动态切换按钮状态,并出现自定义的ToolTips。
实现步骤一(创建)
创建一个名为CCustomCommandBar的子窗口,指定窗口类型为:WS_CHILD | WS_VISIBLE即可。
class CCustomCommandBar: public CWindowImpl<CCustomCommandBar>创建函数:
// Create command bar.HWND Create(const HWND wndParent, const UINT nID){if (::IsWindow(wndParent) && nID > 0){m_wndParent = wndParent;CRect rc(0, 0, 1, 1);return CWindowImpl<CCustomCommandBar>::Create(wndParent, rc, _T(""), WS_CHILD | WS_VISIBLE, 0, nID);}ATLASSERT(FALSE);return NULL;}
实现步骤二(设置工具栏背景)
找一张PNG图片,然后用其来做工具栏的背景,我没有刻意的去指定背景图片尺寸,一定要精确的与预定的工具栏吻合。而是找了一张较大的图,进行部分裁切。这样既可以保证动态增加一些按钮后,图像不失真。
// Load background image.BOOL LoadBackgroundImage(const UINT nImageID){m_Lock.Lock();m_imgBack.Load_Image(nImageID, _T("PNG"));if (m_imgBack.m_pImage != NULL){m_Lock.Unlock();return TRUE;}m_Lock.Unlock();ATLASSERT(FALSE);return FALSE;}工具栏进行重绘只是进行简单的贴图,而工具栏尺寸,将由按钮的数量决定。
// Draw background image when got WM_PAINT message.void DoPaint(Graphics& g){m_Lock.Lock();if (m_imgBack.m_pImage != NULL){g.DrawImage(m_imgBack.m_pImage, 0, 0);}m_Lock.Unlock();}实现步骤三(添加按钮)
由于按钮是由工具栏动态创建的,所以只需传进按钮的ID、图片的ID并记录好创建的按钮顺序即可。当创建好按钮后,就重新计算每个按钮的位置,并重置工具栏的大小。
// Insert button.BOOL InsertButton(const UINT nButtonID, const UINT nImageID, const int nImageNum, const BUTTONIMAGEINDEX BtnImgIndex, const CString& strToolTip){if (IsWindow() && nButtonID > 0 && nImageID > 0 && nImageNum > 0){// First, create button.CCustomButton* pButton= new CCustomButton();HWND wndButton= pButton->Create(m_hWnd, nButtonID);ATLASSERT(::IsWindow(wndButton));pButton->LoadBitmap(nImageID, nImageNum);pButton->SetImages(BtnImgIndex.nNormal, BtnImgIndex.nSelected, BtnImgIndex.nHot, BtnImgIndex.nDisable);pButton->SetToolTipText(strToolTip);// Second, record created button info.BUTTONINFO* pBtnInfo= (BUTTONINFO*)malloc( sizeof(BUTTONINFO) );pBtnInfo->nID= nButtonID;pBtnInfo->pButton= pButton;m_szButtons.Add(pBtnInfo);// Lastly, move button and record button position.MoveButtons();return TRUE;}ATLASSERT(FALSE);return FALSE;}实现步骤四(计算工具栏尺寸并移动按钮)
根据每个按钮的间隔计图片宽度,计算工具栏的长度。然后根据按钮图片的高度,来计算工具栏的高度。计算完成后,先重置工具栏的尺寸,然后再依次移动按钮。
重置工具栏尺寸:
// Move and record all buttons to specified position.void MoveButtons(){// First, Calculate all buttons position.for (int nIndex = 0; nIndex < m_szButtons.GetSize(); ++nIndex){CRect rcPos;m_szButtons[nIndex]->pButton->GetClientRect(&rcPos);int X = 0;int Y = m_nVerSpace;// calculate first button.if (0 == nIndex){X = m_nHorSpace;}// calculate left button X position via previous button.else{X = m_szButtons[nIndex - 1]->rcPos.right + m_nBtnSpace;}rcPos.MoveToXY(X, Y);m_szButtons[nIndex]->rcPos = rcPos;}// Second, resize command bar window via all buttons position.ResizeCommandBar();// Lastly, move buttons.for (int nIndex = 0; nIndex < m_szButtons.GetSize(); ++nIndex){m_szButtons[nIndex]->pButton->MoveWindow(m_szButtons[nIndex]->rcPos, FALSE);}}移动按钮:
// Resize command bar via buttons' position.BOOL ResizeCommandBar(){int nHeight = m_nVerSpace * 2 + m_szButtons[0]->rcPos.Height();// Calculate width via last button's position.int nWidth= m_szButtons[m_szButtons.GetSize() - 1]->rcPos.right + m_nHorSpace;if (nHeight > 0 && nWidth > 0){ResizeClient(nWidth, nHeight);return TRUE;}ATLASSERT(FALSE);return FALSE;}实现步骤五(为父窗口设置点击消息反馈)
我们可以使用WM_COMMAND来通知父窗口:工具栏某个按钮被点击了。
BEGIN_MSG_MAP(CCustomCommandBar)MESSAGE_HANDLER(WM_COMMAND, OnCommand)REFLECT_NOTIFICATIONS()END_MSG_MAP()
LRESULT OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/){if( lParam != 0 && ::GetParent((HWND) lParam) == m_hWnd ) {::SendMessage(GetParent(), uMsg, wParam, lParam);}return 0;}小结:
类似工具栏这些控件,比如CReBar,都可以用子窗口的形式进行制作。这样做的好处就是:相对比较简单,不需要大费周章的去控制CToolBar原有的一些自绘方法。并且可以增加一些自定义元素在里面。
下载链接:
http://download.csdn.net/detail/renstarone/6973195
0 0
- VC++界面编程之--实现工具栏自定义皮肤
- VC++界面编程之--使用分层窗口实现界面皮肤
- VC++界面编程之--自定义进度条(CProgressBar)皮肤
- VC++界面编程之--自定义CButton(按钮)皮肤
- VC++界面编程之--自定义标签控件(CStatic)皮肤
- VC++界面编程之--自定义CEdit(编辑框)皮肤
- VC自定义工具栏
- VC 界面库 皮肤库
- VC 界面库 皮肤库
- VC 界面库 皮肤库
- VC 界面库皮肤库
- VC 界面库皮肤库
- VC 界面库 皮肤库
- VC 界面库 皮肤库
- VC 界面库 皮肤库
- VC 界面库皮肤库
- VC 界面库皮肤库
- VC 界面库皮肤库
- 计算机小型化以来简单介绍
- Discuz!DIY完全教程
- 001 - 翻译官方文档之前
- maven环境搭建 .
- 织梦更新后 如何去掉底部的 powered by dedecms
- VC++界面编程之--实现工具栏自定义皮肤
- MySQL的Innodb缓存相关优化
- Jquery中正则表达式的应用小示例
- 【Android】如何使用从Github上下载的开源项目
- 业务对数据的需求的四大层次
- JSON资料整理
- visual studio各版本号
- 基于TQ2440的u-boot 1.1.6移植(二)(支持nor flash nand flash )
- Android WebView相关属性