DRAWITEMSTRUCT\WM_DRAWITEM\DrawItem()

来源:互联网 发布:淘宝店铺怎样设置红包 编辑:程序博客网 时间:2024/05/17 23:23

DRAWITEMSTRUCT 为需要自绘的控件或者菜单项提供了必要的信息。在需要绘制的控件或者菜单项对应的WM_DRAWITEM消息函数中得到一个指向
该结构的指针。 DRAWITEMSTRUCT结构的定义如下:
 typedef struct tagDRAWITEMSTRUCT{
 UINT CtlType; 
 UINT CtlID; 
 UINT itemID; 
 UINT itemAction; 
 UINT itemState; 
 HWND hwndItem; 
 HDC  hDC; 
 RECT rcItem; 
 ULONG_PTR itemData; 
 }DRAWITEMSTRUCT;

 结构成员:
 CtlType:
  指定了控件的类型,其取值如下表所示。 
 取值      描述

 ODT_BUTTON     按钮控件
 ODT_COMBOBOX    组合框控件
 ODT_LISTBOX     列表框控件
 ODT_LISTVIEW    列表视图控件
 ODT_MENU     菜单项
 ODT_STATIC     静态文本控件
 ODT_TAB      Tab控件

 CtlID:
  指定了自绘控件的ID值,而对于菜单项则不需要使用该成员

 itemID:
  表示菜单项ID,也可以表示列表框或者组合框中某项的索引值。对于一个空的列表框或组合框,该成员的值为–1。
  这时应用程序只绘制焦点矩形(该矩形的坐标由rcItem 成员给出)虽然此时控件中没有需要显示的项,但是绘制焦点矩形还是很有必
  要的,因为这样做能够提示用户该控件是否具有输入焦点。当然也可以设置itemAction 成员为合适值,使得无需绘制焦点。

 itemAction:
  指定绘制行为,其取值可以为下表中所示值的一个或者多个的联合。

 取值       描述

 ODA_DRAWENTIRE  当整个控件都需要被绘制时,设置该值
 ODA_FOCUS   如果控件需要在获得或失去焦点时被绘制,则设置该值。此时应该检查itemState成员,以确定控件是否具有输入焦点。
 ODA_SELECT   如果控件需要在选中状态改变时被绘制,则设置该值。此时应该检查itemState 成员,以确定控件是否处于选中状态。

 itemState:
  指定了当前绘制操作完成后,所绘项的可见状态。例如,如果菜单项应该被灰色显示,则可以指定ODS_GRAYED状态标志。其取值可以为下表中所示值的一个或者多个的联合。

 取值       描述

 ODS_CHECKED   如果菜单项将被选中,则可设置该值。该值只对菜单项有用。
 ODS_COMBOBOXEDIT 在自绘组合框控件中只绘制选择区域。
 ODS_DEFAULT   默认值。
 ODS_DISABLED  如果控件将被禁止,则设置该值。
 ODS_FOCUS   如果控件需要输入焦点,则设置该值。
 ODS_GRAYED   如果控件需要被灰色显示,则设置该值。该值只在绘制菜单时使用。
 ODS_HOTLIGHT  Windows 98/Me, Windows 2000/XP: 如果鼠标指针位于控件之上,则设置该值,这时控件会显示高亮颜色。
 ODS_INACTIVE  Windows 98/Me, Windows 2000/XP: 表示没有激活的菜单项。
 ODS_NOACCEL   Windows 2000/XP: 控件是否有快速键盘。
 ODS_NOFOCUSRECT  Windows 2000/XP: 不绘制捕获焦点的效果。
 ODS_SELECTED  选中的菜单项。

 hwndItem:
  指定了组合框、列表框和按钮等自绘控件的窗口句柄;如果自绘的对象时菜单项,则表示包含该菜单项的菜单句柄。

 hDC:
  指定了绘制操作所使用的设备环境。

 rcItem:
  指定了将被绘制的矩形区域。这个矩形区域就是上面hDC的作用范围。系统会自动裁剪组合框、列表框或按钮等控件的自
  绘制区域以外的部分。也就是说rcItem中的坐标点(0,0)指的就是控件的左上角。但是系统不裁剪菜单项,所以在绘制菜单项的时
  候,必须先通过一定的换算得到该菜单项的位置,以保证绘制操作在我们希望的区域中进行。

 itemData:
  对于菜单项,该成员的取值可以是由CMenu::AppendMenu、CMenu::InsertMenu或者CMenu::ModifyMenu等函数传递给菜单的值。
  对于列表框或这组合框,该成员的值可以为由ComboBox::AddString、CComboBox::InsertString、CListBox::AddString或者CListBox::InsertString等传递给控件的值。
  
 如果ctlType 的取值是ODT_BUTTON或者ODT_STATIC, itemData的取值为0。

=======================================================================

WM_DRAWITEM消息

WM_DRAWITEM 
当按钮,组合框,列表框或菜单的可视外观正在被改变的时候发送消息WM_DRAWITEM到按钮,组合框,列表框或菜单的所有者窗体让所有者绘制

WM_DRAWITEM 
idCtl = (UINT) wParam;             // 控件的标识符
lpdis = (LPDRAWITEMSTRUCT) lParam; // 绘制项的信息

参数:
idCtl
    wParam值。那个发送WM_DRAWITEM消息的控件的标识符.如果这个消息是发送到菜单,这个参数就是0
lpdis
   lParam值.指向一个DRAWITEMSTRUCT结构包含是关于绘制条目的必需的画和类型信息(笔者注:绘制菜单或控件的一些参数)

返回值:
 如果应用程序处理这个消息.它应返回的是TRUE;

默认动作:
 DefWindowProc函数为所有者画列表框条目的焦点矩形.

备注:
 DRAWITEMSTRUCT结构体的itemAction成员指定在那个应用程序将要运行绘图的相关操作
 在来自处理这个消息的返回之前,应用程序应保证那个DRAWITEMSTRUCT中的设备上下文标识符hDC成员是默认状态.

=======================================================================

 

在学习中经常遇到要重写DrawItem()的情况,但又有一个WM_DRAWITEM消息,它们是什么样的关系呢。 
   如果我们要重写一个CButton取名为CMyButton,我们可以重写CMyButton的DrawItem()函数来实现我们的需求,但CMyButton::DrawItem()是在什么时候调用呢?它是在它的宿主类的OnDrawItem()中被调用,OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct )正是对WM_DRAWiTEM的相应函数。

    宿主类可以根据nIDCtl来判定是哪个子控件。其实我们可以在OnDrawItem函数里对子控件进行绘制,但是有很多的子控件看起来不好,所以我们应该在子类的DrawItem对子类绘制,例如CMyButton::DrawItem。所以可以这样理解,OnDrawItem是画窗口中的子控件的,因为它的入口参数LPDRAWITEMSTRUCT带入不同子控件的相关参数,而且,你得把字控件设置成“自画”类型,才会调用到OnDrawItem。

    在学习中还有一个消息也是由宿主类被调用的,它就是WM_CTRCOLOR。这个消息是在子控件将要绘画时,利用反射机制发送给其宿主类。OnCtlColor (CDC* pDC, CWnd* pWnd, UINT nCtlColor),pDC,pWnd都是于子类 相关的,在这里可以设置,前景颜色,背景颜色,画刷类型,字体等等,但不能改变元素的界面框架,这是DrawItem 所能干的。

   如果同时有DrawItem(子类),OnDrawItem(宿主类),OnCtlColor(宿主类),它们的调用顺序是: OnCtlColor,OnDrawItem,DrawItem。

    如果我们同时又相应的子类的WM_PAINT消息,子类不会向宿主类发送WM_DRAWITEM消息,你要完成子类的 全部绘制工作,如果子类是一个列表框,就很麻烦。这事调用顺序是OnCtlColor,OnPaint。

在发送一个WM_PAINT消息前,总会先发送一个WM_ERASEBACK消息,我们在这里在一个背景图片。

   对于我们平时对控件的绘制,上面介绍的差不多了,还有一个CView的问题,也就是OnPaint和Ondraw的关系, 其实这个很简单,CView::OnPaint()的源码如下:

void CView::OnPaint() 

     CPaintDC dc(this);        
     OnPrepareDC(&dc);        
     OnDraw(&dc) 

void CView::OnPaint() { CPaintDC dc(this); OnPrepareDC(&dc); OnDraw(&dc) }


从代码中可以清楚的看出他们的关系。


以上是我自己的个人理解,当然这是通过跟踪得出的结论,可能结论中有错误,如果有,请指出。不胜感激。(转载)



文章转自:http://blog.sina.com.cn/s/blog_6ab9a9dc0100r395.html

0 0
原创粉丝点击