科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件MFC程序员的WTL指南之高级界面类

MFC程序员的WTL指南之高级界面类

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

本文将介绍一些新类实现高级界面特性新类:控件自画和自定外观控件

作者:lithe 来源:blog 2007年10月19日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
WTL的新控件

  WTL有几个新控件,它们要么是其他封装类的扩展(像 CTreeViewCtrlEx),要么是提供windows标准控件没有的新功能(像 CHyperLink)。

  CBitmapButton

  WTL的CBitmapButton类声明在atlctrlx.h中,它比MFC的同名类使用起来要简单的多。WTL的CBitmapButton类使用image list而不是单个的位图资源,你可以将多个按钮的图像放到一个位图文件中,减少GDI资源的占用。这对于使用很多图片并需要在Windows 9X系统上运行的程序很有好处,因为使用太多的单个位图将会很快耗尽GDI资源并导致系统崩溃。

  CBitmapButton是一个CWindowImpl派生类,它又很多特色:自动调整控件的大小,自动生成3D边框,支持hot-tracking,每个按钮可以使用多个图像分别表示按钮的不同状态。

  在ControlMania2中,我们对前面的例子创建的自画按钮使用CBitmapButton类。现在CMainDlg对话框类中添加CBitmapButton类型的变量m_wndBmpBtn,调用SubclassWindow()函数或使用DDX将其和控件联系起来,将位图装载到image list并告诉按钮使用这个image list,还要告诉按钮每个图像分别对应按钮的什么状态。下面是OnInitDialog()函数中建立和使用这个按钮的代码段:

// Set up the bitmap button
CImageList 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.SetImageList ( iml );
m_wndBmpBtn.SetImages ( 0, 1, 2, 3 );

  默认情况下,按钮只是引用image list,所以OnInitDialog()不能delete它所创建的image list。下面显示的是新按钮的一般状态,注意控件是如何根据图像的大小来调整自己的大小。


  因为CBitmapButton是一个非常有用的类,我想介绍一下它的公有方法。

  CBitmapButton methods

  CBitmapButtonImpl类包含了实现一个按钮的所有代码,除非你想重载某个方法或消息处理,你可以对控件直接使用CBitmapButton类。

CBitmapButtonImpl constructor
CBitmapButtonImpl(DWORD dwExtendedStyle = BMPBTN_AUTOSIZE,HIMAGELIST hImageList = NULL)

  构造函数可以指定按钮的扩展样式(这与窗口的样式不冲突)和图像列表,通常使用默认参数就足够了,因为可以使用其他的方法设定这些属性。

SubclassWindow()
BOOL SubclassWindow(HWND hWnd)

  SubclassWindow()是个重载函数,主要完成控件的子类化和初始化控件类保有的内部数据。

Bitmap button extended styles
DWORD GetBitmapButtonExtendedStyle()
DWORD SetBitmapButtonExtendedStyle(DWORD dwExtendedStyle, DWORD dwMask = 0)

  CBitmapButton支持一些扩展样式,这些扩展样式会对按钮的外观和操作方式产生影响:

  BMPBTN_HOVER

  使用hot-tracking,当鼠标移到按钮上时按钮被画成焦点状态。

  BMPBTN_AUTO3D_SINGLE, BMPBTN_AUTO3D_DOUBLE

  在按钮图像周围自动产生一个三维边框,当按钮拥有焦点时会显示一个表示焦点的虚线矩形框。另外如果你没有指定按钮按下状态的图像,将会自动生成一个。BMPBTN_AUTO3D_DOUBLE样式生成的边框稍微粗一些,其他特征和BMPBTN_AUTO3D_SINGLE一样。

  BMPBTN_AUTOSIZE

  按钮调整自己的大小以适应图像大小,这是默认样式。

  BMPBTN_SHAREIMAGELISTS

  如果指定这个样式,按钮不负责销毁按钮使用的image list,如果不使用这个样式,CBitmapButton的析构函数会销毁按钮使用的image list。

  BMPBTN_AUTOFIRE

  如果设置这个样式,在按钮上按住鼠标左键不放将会产生连续的WM_COMMAND消息。

  调用SetBitmapButtonExtendedStyle()时,dwMask参数控制着那个样式将被改变,默认值是0,意味着用新样式完全替换旧的样式。

Image list management
HIMAGELIST GetImageList()
HIMAGELIST SetImageList(HIMAGELIST hImageList)

  调用SetImageList()设置按钮使用的image list。

Tooltip management
int GetToolTipTextLength()
bool GetToolTipText(LPTSTR lpstrText, int nLength)
bool SetToolTipText(LPCTSTR lpstrText)

  CBitmapButton支持显示工具提示(tooltip),调用SetToolTipText()指定显示的文字。

Setting the images to use
void SetImages(int nNormal, int nPushed = -1,int nFocusOrHover = -1, int nDisabled = -1)

  调用SetImages()函数告诉按钮分别使用image list的拿一个图像表示那个状态。nNormal是必须的,其它是可选的,使用-1表示对应的状态没有图像。

  CCheckListViewCtrl

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

  下面是一个定义list view扩展样式属性的例子,加入了一个使用这个样式的新类。(注意,扩展属性必须包含LVS_EX_CHECKBOXES,否则会因起断言错误消息。)

typedef CCheckListViewCtrlImplTraits<
WS_CHILD | WS_VISIBLE | LVS_REPORT,
WS_EX_CLIENTEDGE,
LVS_EX_CHECKBOXES | LVS_EX_GRIDLINES | LVS_EX_UNDERLINEHOT |
LVS_EX_ONECLICKACTIVATE> CMyCheckListTraits;

class CMyCheckListCtrl :
public CCheckListViewCtrlImpl<CMyCheckListCtrl, CListViewCtrl,
CMyCheckListTraits>
{
 private:
  typedef CCheckListViewCtrlImpl<CMyCheckListCtrl, CListViewCtrl, CMyCheckListTraits> baseClass;
 public:
  BEGIN_MSG_MAP(CMyCheckListCtrl)
   CHAIN_MSG_MAP(baseClass)
  END_MSG_MAP()
};

  CCheckListViewCtrl methods SubclassWindow()

  当子类化一个已经存在的list view控件时,SubclassWindow()查看CCheckListViewCtrlImplTraits的扩展样式属性并将之应用到控件上。未用到前两个参数(窗口样式和扩展窗口样式)。

  SetCheckState() and GetCheckState()

  这些方法实际上是在CListViewCtrl中,SetCheckState()使用行的索引和一个布尔类型参数,该布尔参数的值表示是否check这一行。GetCheckState()以行索引未参数,返回改行的checked状态。

  CheckSelectedItems()

  这个方法使用item的索引作为参数,它翻转这个item的check状态,这个item必须是被选定的,同时还将其他所有被选择的item设置成相应状态(译者加:多选状态下)。你大概不会用到这个方法,因为CCheckListViewCtrl会在check box被单击或用户按下了空格键时设置相应的item的状态。

  下面是ControlMania2中的CCheckListViewCtrl的样子:

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章