Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1614093
  • 博文数量: 585
  • 博客积分: 14610
  • 博客等级: 上将
  • 技术积分: 7402
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-15 10:52
文章存档

2013年(5)

2012年(214)

2011年(56)

2010年(66)

2009年(44)

2008年(200)

分类: C/C++

2009-07-10 11:14:29

.font { font-size: 9pt; line-height: 12pt } .bfont { font-size: 11pt; line-height: 13pt } a:link { color: #0033cc; cursor: hand; font-style: normal; text-decoration: none } a:visited { color: #0033cc; font-style: normal; text-decoration: none } a:active { color: rgb(255,0,0); font-style: normal; text-decoration: none } a:hover { color: #408080; text-decoration: underline }

VC6工具栏的新特色


ToolBar是基于动态库comctl32.dll,该动态库随IE更新。


   绝大多数新特色将由在调用CreateEx() 和其它CToolBar成员函数时指定的新的风格标志来确定。下面是 commctrl.h的一部分,它定义了 TBSTYLE类标识符:

#define TBSTYLE_BUTTON 0x0000 #define TBSTYLE_SEP 0x0001 #define TBSTYLE_CHECK 0x0002 #define TBSTYLE_GROUP 0x0004 #define TBSTYLE_CHECKGROUP (TBSTYLE_GROUP | TBSTYLE_CHECK) #if (_WIN32_IE >= 0x0300) #define TBSTYLE_DROPDOWN 0x0008 #endif #if (_WIN32_IE >= 0x0400) #define TBSTYLE_AUTOSIZE 0x0010 #define TBSTYLE_NOPREFIX 0x0020 #endif #define TBSTYLE_TOOLTIPS 0x0100 #define TBSTYLE_WRAPABLE 0x0200 #define TBSTYLE_ALTDRAG 0x0400 #if (_WIN32_IE >= 0x0300) #define TBSTYLE_FLAT 0x0800 #define TBSTYLE_LIST 0x1000 #define TBSTYLE_CUSTOMERASE 0x2000 #endif #if (_WIN32_IE >= 0x0400) #define TBSTYLE_REGISTERDROP 0x4000 #define TBSTYLE_TRANSPARENT 0x8000 #define TBSTYLE_EX_DRAWDDARROWS 0x00000001 #endif

  注意:到其中的一些条件编译,

 _WIN32_IE 缺省指的是 IE 4.0(即取值为 0x0400)

             IE 3.0(即取值为 0x0300)


扁平钮和把手

   CToolBar类实现了对扁平钮、把手和其它新的视觉效果的支持。

    在预览版中,AppWizard FACE="System,黑体" LANG="ZH-CN">并不会自动包括这些新特色,但它们却很容易被加入。表 1显示了 AppWizard创建的主框架窗口的 OnCreate()函数,表 2显示了需要做哪些修改以获得具有扁平钮和把手的工具条。图 1显示了表 1创建出的工具条,而图 2显示出了表 2实现的工具条。

表1: CMainFrame::OnCreate as generated by AppWizard

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if(CMDIFrameWnd::OnCreate(lpCreateStruct) == -1) return -1; if(!m_wndToolBar.Create(this) || !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

图1


fig1.gif (5536 bytes)

表2: Adding flat buttons and the gripper

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if(CMDIFrameWnd::OnCreate(lpCreateStruct) == -1) return -1; if(!m_wndToolBar.CreateEx(this) || !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: Remove this if you don't want tool tips or a resizeable toolbar m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() | CBRS_GRIPPER | CBRS_BORDER_3D | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC); // TODO: Delete these three lines if you don't want the toolbar to // be dockable m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); DockControlBar(&m_wndToolBar); return 0; }

图2


    为了作出扁平按钮我必须使用CreateEx()来代替 Create()。这个新的函数在afxext.h中声明:

BOOL CreateEx ( CWnd* pParentWnd, // parent window DWORD dwCtrlStyle = TBSTYLE_FLAT,     // extended style DWORD dwStyle = // style WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP, CRect rcBorders = CRect(0,0,0,0),    // border rectangle UINT nID = AFX_IDW_TOOLBAR     // identifier );

    因为扩展风格缺省指的就是TBSTYLE_FLAT,只需要把创建Crate 改为 CreateEx()即可

    为了获得把手,我必须在调用SetBarStyle()函数时包含 CBRS_GRIPPER标志,参看表2。这是 CControlBar类的一个新风格,而CToolBar类是从它继承而来的。 请注意到我也加入了CBRS_BORDER_3D标志,这是为了修正一个未知的绘制问题,该问题将会在工具条的边缘绘制一些多余的点。这也许意味着预览版确实有这个问题,因为一旦我将 3D标志加入就立即解决了并且也似乎没有影响到别的什么。

    上面所作的两个简单的改变是使得一个已存程序获得酷界面的最省力的方法。在一个程序具有了扁平钮和把手的同时,它也不会发生不应有的其它改变。

文本标签

  MFC程序员通过SetButtonText()函数为每个按钮设置一个文本串来获得这种效果。

    表3显示了如何使用现有的文本提示作为按钮的标签,而且图 3和图4显示了将工具条分别定位在顶端和右边的效果。我仍然使得文本提示有效,但你可以通过在调用 SetBarStyle()时去掉CBRS_TOOLTIPS风格而使之无效。

3: Adding text labels
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if(CMDIFrameWnd::OnCreate(lpCreateStruct) == -1) return -1; if(!m_wndToolBar.CreateEx(this) || !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: Remove this if you don't want tool tips or a resizeable toolbar m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() | CBRS_GRIPPER | CBRS_BORDER_3D | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC); // Add text to each button for(int i = 0; i < m_wndToolBar.GetCount(); i++) {
    UINT id = m_wndToolBar.GetItemID(i);     CString s;
    if(!s.LoadString(id)) continue;    
    int j = s.Find(_T('\n'));     if(j < 0) continue;     s = s.Right(s.GetLength() - j - 1);
    m_wndToolBar.SetButtonText(i,s); }// Adjust sizes to include text
   CRect rect;    m_wndToolBar.GetItemRect(0,&rect);    m_wndToolBar.SetSizes(rect.Size(),CSize(16,15));// TODO: Delete these three lines if you don't want the toolbar to // be dockable m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); DockControlBar(&m_wndToolBar); return 0;}


图3


图4

    为了产生按钮标签,一个简单的for循环扫过所有的按钮并且从与之相连的帮助串中提取出提示文本。在设置完每个按钮的标签后,就调用工具条的 SetSizes()函数去重新计算工具条的外观以便使得标签可见。也许会有更好的方法去实现最后一步,但我还是从微软的 MFCIE范例程序中借用了这个过程,不为别的,只为它确实有效。

    从很多方面来说,MFCIE都是值得仔细学习的。从本质上来说,它实际上是 Internet Explorer的一个微型版本,并且它还阐述了如何使用版本 6的一些新特色。你将会惊讶于在你的MFC应用程序中添加 HTML浏览功能是如此之简单。

    在绝大多数情况下你会希望文本标签显示在按钮下面(这在最初的公用控件库中是唯一的选择)。 Internet Explorer 3.0版加入了TBSTYLE_LIST风格,该风格导致文本标签显示在按钮右边。对于在标签旁边显示一个下拉列表或者按钮被一个子窗口覆盖时,该风格是很有用的。

下拉列表

    在“工具条的变形”一文中,我演示了通过将一个组合框作为一个子窗口来在工具条上添加下拉列表的情形。该方法在版本 6中仍然有效,并且当你想在工具条上显示当前的可选择项时它仍然是有用的。然而,有时你希望工具条包含一个可以在鼠标点击时显示选择列表或菜单的按钮。该功能现在可以通过扩展风格 TBSTYLE_DROPDOWN和TBSTYLE_EX_DRAWDDARROWS实现了。

    例如,假设我希望对应于“文件”菜单下“新建”的按钮可以显示一个我的应用程序知道如何去创建的所有文件类型的列表。表 4 显示在前面的例子中如何加入该功能,而图 5显示该工具条。我抓取了鼠标停留在该按钮上时的屏幕,它显示出了按钮和下拉箭头之间的分隔线。

    为了加入一个下拉箭头,首先我必须在基本的工具条控件上调用SetExtendedStyle()函数,并且指定TBSTYLE_EX_DRAWDDARROWS风格。然后我必须在每一个我想要显示下拉箭头的按钮上指定TBSTYLE_DROPDOWN风格。

表 4: Converting the File menu New command to a drop-down button
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if(CMDIFrameWnd::OnCreate(lpCreateStruct) == -1) return -1; if(!m_wndToolBar.CreateEx(this) || !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: Remove this if you don't want tool tips or a resizeable toolbar m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() | CBRS_GRIPPER | CBRS_BORDER_3D | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC); // Add text to each button for(int i = 0; i < m_wndtoolbar.getcount(); i++) { UINT id = m_wndToolBar.GetItemID(i); CString s; if(!s.LoadString(id)) continue; int j="s.Find(_T('\n')); if(j < 0) continue; s=s.Right(s.GetLength(),j,1); m_wndToolBar.SetButtonText(i,s); } // Add drop-down arrow to File|New button m_wndToolBar.GetToolBarCtrl().SetExtendedStyle(TBSTYLE_EX_DRAWDDARROWS); i=m_wndToolBar.CommandToIndex(ID_FILE_NEW); UINT id,style; int image; m_wndToolBar.GetButtonInfo(i,id,style,image); m_wndToolBar.SetButtonInfo(i,ID_FILE_NEW,TBSTYLE_BUTTON | TBSTYLE_DROPDOWN,image); // Adjust sizes to include text CRect rect; m_wndToolBar.GetItemRect(0,&rect); m_wndToolBar.SetSizes(rect.Size(),CSize(16,15)); // TODO: Delete these three lines if you don't want the toolbar to // be dockable m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); DockControlBar(&m_wndToolBar); return 0; }

fig5.gif (5825 bytes)
图5

    当用户在New按钮上点击时,就象图 5所示一样,基本的按钮操作就发生了。在这个例子中命令消息导致调用CWinApp::OnFileNew()。然而,当用户点击下拉箭头时,工具条就发出TBN_DROPDOWN通知消息给工具条的父窗口。我可以通过重载OnNotify()函数或者通过在消息映射中加入一个ON_NOTIFY而获取这个消息。

表5

    显示了后者的实现技术。通常我显示一个弹出菜单或者一个列表框去响应这个通知消息。在绝大多数情况下没有必要提供一个结果值,因为缺省值( TBDDRET_DEFAULT)显示了我已获取了对这个事件的控制。其它可能的结果值是 TBDDRET_NODEFAULT和TBDDRET_TREATPRESSED。前者表示该事件没有受到控制,当出现后者时,工具条就表现得好像该按钮被点击一样。

表 5: Handling drop-down notifications
BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd) //{{AFX_MSG_MAP(CMainFrame) ON_WM_CREATE() //}}AFX_MSG_MAP ON_NOTIFY(TBN_DROPDOWN,AFX_IDW_TOOLBAR,OnDropDown) END_MESSAGE_MAP() void CMainFrame::OnDropDown(NMHDR* pNotifyStruct,LRESULT* result) { NMTOOLBAR* pInfo = (NMTOOLBAR*)pNotifyStruct; switch(pInfo->iItem) { case ID_FILE_NEW: TRACE0("ID_FILE_NEW drop down\n"); // TODO: Display popup menu or list box break; // TODO: Add cases for other drop-down buttons } }

热点图像

    运行Internet Explorer 4.0并且将鼠标在工具条上划过。就能注意到在平时每个按钮是平淡的颜色。而当鼠标触及到该按钮时,他会凸出来并且显现出鲜艳的颜色。这种视觉效果采用了工具条控件的被称作“热点图像”的功能。

    一般的AppWizard代码使用工具条资源来指定其上按键的外观和与每个按键相连接的一个命令ID。工具条资源实际上包含一个复合的位图,该位图在调用LoadToolBar()函数时将被转变成一个图像列表(参见表4)。要激活热点图像功能,我必须通过SetHotImageList()函数提供第二个图像列表,就象表6所示一样。

表 6: Using hot images
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if(CMDIFrameWnd::OnCreate(lpCreateStruct) == -1) return -1; if(!m_wndToolBar.CreateEx(this) || !m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) { TRACE0("Failed to create toolbar\n"); return -1; // fail to create } CImageList img; if(!img.Create(IDB_MAINFRAME,16,0,RGB(128,128,128))) { TRACE0("Failed to load hot images\n"); return -1; } m_wndToolBar.GetToolBarCtrl().SetHotImageList(&img); img.Detach(); 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: Remove this if you don't want tool tips or a resizeable toolbar m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() | CBRS_GRIPPER | CBRS_BORDER_3D | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC); // Add text to each button for(int i = 0; i < m_wndtoolbar.getcount(); i++) { UINT id= m_wndToolBar.GetItemID(i); CString s; if(!s.LoadString(id)) continue; int j="s.Find(_T('\n')); if(j < 0) continue; s=s.Right(s.GetLength(), j, 1); m_wndToolBar.SetButtonText(i,s); } // Add drop-down arrow to File|New button m_wndToolBar.GetToolBarCtrl().SetExtendedStyle(TBSTYLE_EX_DRAWDDARROWS); i = m_wndToolBar.CommandToIndex(ID_FILE_NEW); UINT id,style; int image; m_wndToolBar.GetButtonInfo(i,id,style,image); m_wndToolBar.SetButtonInfo(i,ID_FILE_NEW,TBSTYLE_BUTTON | TBSTYLE_DROPDOWN,image); // Adjust sizes to include text CRect rect; m_wndToolBar.GetItemRect(0,&rect); m_wndToolBar.SetSizes(rect.Size(),CSize(16,15)); // TODO: Delete these three lines if you don't want the toolbar to // be dockable m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); DockControlBar(&m_wndToolBar); return 0; }

fig6.gif (5986 bytes)
图6

    图6 显示了热点图像被激活的情形。鼠标正停留在 New按钮上,它就被显示成一个空文档的图形。其它的按钮是扁平的和淡颜色的。为了生成这个改进的工具条,我将 res子目录下的toolbar.bmp拷贝为 toolbar1.bmp,然后将其作为一个位图资源插入资源中,并取其 ID为IDR_MAINFRAME。 接下来我编辑 IDR_MAINFRAME 工具条,用很淡的颜色(例如淡灰色)来取代它原来的颜色。最后,我加入了如表 6所示的对函数SetHotImageList()的调用。

    这个例子演示了在一个已存的工具条中加入热点图像的捷径,但他不会改进工具条的外观。如果你想在这一点上取得更好的效果,MFCIE的例子包含了非常好的蚀刻位图,它演示了当你使用非常有艺术性的图像时它能达到何等地步的视觉效果。

其它特色

    前面的讲解演示了你怎样简单地改变现存的MFC程序,以获得扁平钮、把手、下拉列表和热点图像的功能。 Visual C++ 6.0还提供了几种其它令人感兴趣的工具条特色,包括自定义绘制、 OLE拖入目标和使用rebar(抱歉,不知道该单词指的是什么)容器等。这些特色将会是将来的栏目的主题。

阅读(723) | 评论(0) | 转发(0) |
0

上一篇:列表框 CListBox

下一篇:CRectTracker

给主人留下些什么吧!~~