ImageVerifierCode 换一换
格式:DOCX , 页数:19 ,大小:90.67KB ,
资源ID:7930152      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/7930152.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Part V高级对话框用户界面类.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

Part V高级对话框用户界面类.docx

1、Part V 高级对话框用户界面类MFC程序员的WTL指南: Part V - 高级对话框用户界面类原作 :Michael Dunn 英文原文翻译 :Orbit(桔皮干了) 下载演示程序代码本章内容 第五章介绍 特别的自画和外观定制类 o COwnerDraw o CCustomDraw WTL的新控件 o CBitmapButton o CCheckListViewCtrl o CTreeViewCtrlEx 和 CTreeItem o CHyperLink 对话框中控件的UI Updating DDV o 处理DDV验证失败 改变对话框的大小 继续 参考 修改记录 第五章介绍 在上一篇文章

2、我们介绍了一些与对话框和控件有关的WTL的特性,它们和MFC的相应的类作用相同。本文将介绍一些新类实现高级界面特性新类:控件自画和自定外观控件,新的WTL控件,UI updating和对话框数据验证(DDV)。特别的自画和外观定制类 由于自画和定制外观控件在图形用户界面中是很常用的手段,所以WTL提供了几个嵌入类来完成这些令人厌烦的工作。我接着就会介绍它们,事实上我们在上一个例子工程ControlMania2的结尾部分已经这么做了。如果你正随着我的讲解用应用程序生成向导创建新工程,请不要忘了使用无模式对话框,为了使正常工作必须使用无模式对话框,我会在对话框中控件的UI Updating部分详细

3、解释为什么这样作。COwnerDraw 控件的自画需要响应四个消息:WM_MEASUREITEM, WM_DRAWITEM, WM_COMPAREITEM, 和WM_DELETEITEM,在atlframe.h头文件中定义的COwnerDraw类可以简化这些工作,使用这个类就不需要处理这四个消息,你只需将消息链入COwnerDraw,它会调用你的类中的重载函数。如何将消息链入COwnerDraw取决与你是否将消息反射给控件,两种方法有些不同。下面是COwnerDraw类的消息映射链,它使得两种方法的差别更加明显:template class COwnerDrawpublic: BEGIN_MS

4、G_MAP(COwnerDraw) MESSAGE_HANDLER(WM_DRAWITEM, OnDrawItem) MESSAGE_HANDLER(WM_MEASUREITEM, OnMeasureItem) MESSAGE_HANDLER(WM_COMPAREITEM, OnCompareItem) MESSAGE_HANDLER(WM_DELETEITEM, OnDeleteItem) ALT_MSG_MAP(1) MESSAGE_HANDLER(OCM_DRAWITEM, OnDrawItem) MESSAGE_HANDLER(OCM_MEASUREITEM, OnMeasureIte

5、m) MESSAGE_HANDLER(OCM_COMPAREITEM, OnCompareItem) MESSAGE_HANDLER(OCM_DELETEITEM, OnDeleteItem) END_MSG_MAP();注意,消息映射链的主要部分处理WM_*消息,而ATL部分处理反射的消息,OCM_*。自画的通知消息就像WM_NOTIFY消息一样,你可以在父窗口处理它们,也可以将它们反射会控件,如果你使用前一种方法,消息被直接链入COwnerDraw:class CSomeDlg : public COwnerDraw, . BEGIN_MSG_MAP(CSomeDlg) /. CHAIN_

6、MSG_MAP(COwnerDraw) END_MSG_MAP() void DrawItem ( LPDRAWITEMSTRUCT lpdis );当然,如果你想要控件自己处理这些消息,你需要使用CHAIN_MSG_MAP_ALT宏将消息链入ALT_MSG_MAP(1)部分:class CSomeButtonImpl : public COwnerDraw, . BEGIN_MSG_MAP(CSomeButtonImpl) /. CHAIN_MSG_MAP_ALT(COwnerDraw, 1) DEFAULT_REFLECTION_HANDLER() END_MSG_MAP() void D

7、rawItem ( LPDRAWITEMSTRUCT lpdis );COwnerDraw类将对消息传递的参数展开,然后调用你的类中的实现函数。上面的例子中,我们自己的类实现DrawItem()函数,当有WM_DRAWITEM或OCM_DRAWITEM消息被链入COwnerDraw时,这个函数就会被调用。你可以重载的方法有:void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);int CompareItem(LPCOMPAREITEMS

8、TRUCT lpCompareItemStruct);void DeleteItem(LPDELETEITEMSTRUCT lpDeleteItemStruct);如果你不想处理某个消息,你可以调用SetMsgHandled(false),消息会被传递给消息映射链中的其他响应者。SetMsgHandled()事实上是COwnerDraw类的成员函数,但是它的作用和在BEGIN_MSG_MAP_EX()中使用SetMsgHandled()一样。对于ControlMania2,它从ControlMania1中的树控件开始,添加了自画按钮处理反射的WM_DRAWITEM消息,下面是资源编辑器中的新按

9、钮:现在我们需要一个新类实现自画按钮:class CODButtonImpl : public CWindowImpl, public COwnerDrawpublic: BEGIN_MSG_MAP_EX(CODButtonImpl) CHAIN_MSG_MAP_ALT(COwnerDraw, 1) DEFAULT_REFLECTION_HANDLER() END_MSG_MAP() void DrawItem ( LPDRAWITEMSTRUCT lpdis );DrawItem()使用了像BitBlt()这样的GDI函数向按钮的表面画位图,代码应该很容易理解,因为WTL使用的类名和函数名都

10、和MFC类似。void CODButtonImpl:DrawItem ( LPDRAWITEMSTRUCT lpdis )/ NOTE: m_bmp is a CBitmap inited in the constructor.CDCHandle dc = lpdis-hDC;CDC dcMem; dcMem.CreateCompatibleDC ( dc ); dc.SaveDC(); dcMem.SaveDC(); / Draw the buttons background, red if it has the focus, blue if not. if ( lpdis-itemStat

11、e & ODS_FOCUS ) dc.FillSolidRect ( &lpdis-rcItem, RGB(255,0,0) ); else dc.FillSolidRect ( &lpdis-rcItem, RGB(0,0,255) ); / Draw the bitmap in the top-left, or offset by 1 pixel if the button / is clicked. dcMem.SelectBitmap ( m_bmp ); if ( lpdis-itemState & ODS_SELECTED ) dc.BitBlt ( 1, 1, 80, 80, d

12、cMem, 0, 0, SRCCOPY ); else dc.BitBlt ( 0, 0, 80, 80, dcMem, 0, 0, SRCCOPY ); dcMem.RestoreDC(-1); dc.RestoreDC(-1);我们的按钮看起来是这个样子:CCustomDraw CCustomDraw类使用和COwnerDraw类相同的方法处理NM_CUSTOMDRAW消息,对于自定绘制的每个阶段都有相应的重载函数:DWORD OnPrePaint(int idCtrl, LPNMCUSTOMDRAW lpNMCD);DWORD OnPostPaint(int idCtrl, LPNMCU

13、STOMDRAW lpNMCD);DWORD OnPreErase(int idCtrl, LPNMCUSTOMDRAW lpNMCD);DWORD OnPostErase(int idCtrl, LPNMCUSTOMDRAW lpNMCD); DWORD OnItemPrePaint(int idCtrl, LPNMCUSTOMDRAW lpNMCD);DWORD OnItemPostPaint(int idCtrl, LPNMCUSTOMDRAW lpNMCD);DWORD OnItemPreErase(int idCtrl, LPNMCUSTOMDRAW lpNMCD);DWORD On

14、ItemPostEraset(int idCtrl, LPNMCUSTOMDRAW lpNMCD); DWORD OnSubItemPrePaint(int idCtrl, LPNMCUSTOMDRAW lpNMCD);这些函数默认都是返回CDRF_DODEFAULT,如果想自画控件或返回一个不同的值,就需要重载这些函数:你可能注意到上面的屏幕截图将“道恩”(Dawn:女名)显示成绿色,这是因为CBuffyTreeCtrl将消息链入CCustomDraw并重载了OnPrePaint()和OnItemPrePaint()方法。向树控件中添加节点时,节点的item data字段被设置成1,OnIt

15、emPrePaint()检查这个值,然后改变文字的颜色。DWORD CBuffyTreeCtrl:OnPrePaint(int idCtrl, LPNMCUSTOMDRAW lpNMCD) return CDRF_NOTIFYITEMDRAW; DWORD CBuffyTreeCtrl:OnItemPrePaint(int idCtrl, LPNMCUSTOMDRAW lpNMCD) if ( 1 = lpNMCD-lItemlParam ) pnmtv-clrText = RGB(0,128,0); return CDRF_DODEFAULT;CCustomDraw类也有SetMsgHand

16、led()函数,你可以像在COwnerDraw类那样使用这个函数。WTL的新控件 WTL有几个新控件,它们要么是其他封装类的扩展(像 CTreeViewCtrlEx),要么是提供windows标准控件没有的新功能(像 CHyperLink)。CBitmapButton WTL的CBitmapButton类声明在atlctrlx.h中,它比MFC的同名类使用起来要简单的多。WTL的CBitmapButton类使用image list而不是单个的位图资源,你可以将多个按钮的图像放到一个位图文件中,减少GDI资源的占用。这对于使用很多图片并需要在Windows 9X系统上运行的程序很有好处,因为使用

17、太多的单个位图将会很快耗尽GDI资源并导致系统崩溃。CBitmapButton是一个CWindowImpl派生类,它又很多特色:自动调整控件的大小,自动生成3D边框,支持hot-tracking,每个按钮可以使用多个图像分别表示按钮的不同状态。在ControlMania2中,我们对前面的例子创建的自画按钮使用CBitmapButton类。现在CMainDlg对话框类中添加CBitmapButton类型的变量m_wndBmpBtn,调用SubclassWindow()函数或使用DDX将其和控件联系起来,将位图装载到image list并告诉按钮使用这个image list,还要告诉按钮每个图像分

18、别对应按钮的什么状态。下面是OnInitDialog()函数中建立和使用这个按钮的代码段: / Set up the bitmap buttonCImageList iml; iml.CreateFromImage ( IDB_ALYSON_IMGLIST, 81, 1, CLR_NONE, IMAGE_BITMAP, LR_CREATEDIBSECTION ); m_wndBmpBtn.SubclassWindow ( GetDlgItem(IDC_ALYSON_BMPBTN) ); m_wndBmpBtn.SetToolTipText ( _T(Alyson) ); m_wndBmpBtn

19、.SetImageList ( iml ); m_wndBmpBtn.SetImages ( 0, 1, 2, 3 );默认情况下,按钮只是引用image list,所以OnInitDialog()不能delete它所创建的image list。下面显示的是新按钮的一般状态,注意控件是如何根据图像的大小来调整自己的大小。因为CBitmapButton是一个非常有用的类,我想介绍一下它的公有方法。CBitmapButton methods CBitmapButtonImpl类包含了实现一个按钮的所有代码,除非你想重载某个方法或消息处理,你可以对控件直接使用CBitmapButton类。CBitm

20、apButtonImpl constructorCBitmapButtonImpl(DWORD dwExtendedStyle = BMPBTN_AUTOSIZE,HIMAGELIST hImageList = NULL)构造函数可以指定按钮的扩展样式(这与窗口的样式不冲突)和图像列表,通常使用默认参数就足够了,因为可以使用其他的方法设定这些属性。SubclassWindow()BOOL SubclassWindow(HWND hWnd)SubclassWindow()是个重载函数,主要完成控件的子类化和初始化控件类保有的内部数据。Bitmap button extended stylesDW

21、ORD GetBitmapButtonExtendedStyle()DWORD SetBitmapButtonExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0)CBitmapButton支持一些扩展样式,这些扩展样式会对按钮的外观和操作方式产生影响:BMPBTN_HOVER 使用hot-tracking,当鼠标移到按钮上时按钮被画成焦点状态。 BMPBTN_AUTO3D_SINGLE, BMPBTN_AUTO3D_DOUBLE 在按钮图像周围自动产生一个三维边框,当按钮拥有焦点时会显示一个表示焦点的虚线矩形框。另外如果你没有指定按钮按下

22、状态的图像,将会自动生成一个。BMPBTN_AUTO3D_DOUBLE样式生成的边框稍微粗一些,其他特征和BMPBTN_AUTO3D_SINGLE一样。 BMPBTN_AUTOSIZE 按钮调整自己的大小以适应图像大小,这是默认样式。 BMPBTN_SHAREIMAGELISTS 如果指定这个样式,按钮不负责销毁按钮使用的image list,如果不使用这个样式,CBitmapButton的析构函数会销毁按钮使用的image list。 BMPBTN_AUTOFIRE 如果设置这个样式,在按钮上按住鼠标左键不放将会产生连续的WM_COMMAND消息。 调用SetBitmapButtonExte

23、ndedStyle()时,dwMask参数控制着那个样式将被改变,默认值是0,意味着用新样式完全替换旧的样式。Image list managementHIMAGELIST GetImageList()HIMAGELIST SetImageList(HIMAGELIST hImageList)调用SetImageList()设置按钮使用的image list。Tooltip managementint GetToolTipTextLength()bool GetToolTipText(LPTSTR lpstrText, int nLength)bool SetToolTipText(LPCTS

24、TR lpstrText)CBitmapButton支持显示工具提示(tooltip),调用SetToolTipText()指定显示的文字。Setting the images to usevoid SetImages(int nNormal, int nPushed = -1,int nFocusOrHover = -1, int nDisabled = -1)调用SetImages()函数告诉按钮分别使用image list的拿一个图像表示那个状态。nNormal是必须的,其它是可选的,使用1表示对应的状态没有图像。CCheckListViewCtrl CCheckListViewCtrl

25、类在atlctrlx.h中定义,它是一个CWindowImpl派生类,实现了一个带检查框的list view控件。它和MFC的CCheckListBox不同,CCheckListBox只是一个list box,不是list view。CCheckListViewCtrl类非常简单,只添加了很少的函数,当然,它使用了一个新的辅助类CCheckListViewCtrlImplTraits,它和CWinTraits类的作用类似,只是第三个参数是list view控件的扩展样式属性,如果你没有定义自己的CCheckListViewCtrlImplTraits,它将使用没默认的样式:LVS_EX_CHE

26、CKBOXES | LVS_EX_FULLROWSELECT。下面是一个定义list view扩展样式属性的例子,加入了一个使用这个样式的新类。(注意,扩展属性必须包含LVS_EX_CHECKBOXES,否则会因起断言错误消息。)typedef CCheckListViewCtrlImplTraits CMyCheckListTraits; class CMyCheckListCtrl : public CCheckListViewCtrlImplprivate: typedef CCheckListViewCtrlImpl baseClass;public: BEGIN_MSG_MAP(CM

27、yCheckListCtrl) CHAIN_MSG_MAP(baseClass) END_MSG_MAP();CCheckListViewCtrl methods SubclassWindow() 当子类化一个已经存在的list view控件时,SubclassWindow()查看CCheckListViewCtrlImplTraits的扩展样式属性并将之应用到控件上。未用到前两个参数(窗口样式和扩展窗口样式)。SetCheckState() and GetCheckState() 这些方法实际上是在CListViewCtrl中,SetCheckState()使用行的索引和一个布尔类型参数,该

28、布尔参数的值表示是否check这一行。GetCheckState()以行索引未参数,返回改行的checked状态。CheckSelectedItems() 这个方法使用item的索引作为参数,它翻转这个item的check状态,这个item必须是被选定的,同时还将其他所有被选择的item设置成相应状态(译者加:多选状态下)。你大概不会用到这个方法,因为CCheckListViewCtrl会在check box被单击或用户按下了空格键时设置相应的item的状态。下面是ControlMania2中的CCheckListViewCtrl的样子:CTreeViewCtrlEx and CTreeIte

29、m 有两个类使得树控件的使用简化了很多:CTreeItem类封装了HTREEITEM,一个CTreeItem对象含有一个HTREEITEM和一个指向包含这个HTREEITEM的树控件的指针,使你不必每次调用都引用树控件;CTreeViewCtrlEx和CTreeViewCtrl一样,只是它的方法操作CTreeItem而不是HTREEITEM。例如,InsertItem()函数返回一个CTreeItem而不是HTREEITEM,你可以使用CTreeItem操作新添加的item。下面是一个例子:/ Using plain HTREEITEMs:HTREEITEM hti, hti2; hti =

30、m_wndTree.InsertItem ( foo, TVI_ROOT, TVI_LAST ); hti2 = m_wndTree.InsertItem ( bar, hti, TVI_LAST ); m_wndTree.SetItemData ( hti2, 100 ); / Using CTreeItems:CTreeItem ti, ti2; ti = m_wndTreeEx.InsertItem ( foo, TVI_ROOT, TVI_LAST ); ti2 = ti.AddTail ( bar, 0 ); ti2.SetData ( 100 );CTreeViewCtrl对HTREEITEM的每一个操作,CTreeItem都有与之

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1