Your Ad Here
首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 编程语言 > .NET > VB.NET > 剖析Net 精简版中Treeview控件Treenode的自描绘处理
【标  题】:剖析Net 精简版中Treeview控件Treenode的自描绘处理
【关键字】:Net,Treeview,Treenode
【来  源】:http://www.cnblogs.com/DreamlikeAttic/archive/2006/08/05/468876.html

剖析Net 精简版中Treeview控件Treenode的自描绘处理

Your Ad Here 连日暴雨倾盘,我养的小猫整日卷缩在阳台的角落象只死老鼠般一动不动,而我则在数据仓库的十多个表的联系独立分析中迷惘,枯燥无味的数据绑定使用程序失去了所有的生趣。我却定做一些其它的事情来放松绷紧的猫脑。

Treeview控件是我的老伙伴了,但直到前几天,一个希望设定treenode背景色的问题才令我发现,我一直没有深入到它的核心。不过一切都会好转,我决定重新复习windows的基础控件的内部动作。有部电影的对白令我记忆深刻:面包会有的,牛奶会有的。一个能自描绘TreenodeTreeview也会有的8)

 根据网上得到的部分代码资料及MSDN的帮助,我先在完整版中继承了一个Treeview对象,并试图处理TreeViewOCM_NOTIFY消息,所有的一切令人愉快,我轻易地截获了TreeNode对象在重绘前发出OCM_NOTIFY消息,消息中的lParam参数代表的NMTVCUSTOMDRAW结构的子结构NMTVCUSTOMDRAW中包含的dwDrawStage成员代表CDDS_ITEMPREPAINT/CDDS_ITEMPOSTPAINT标志,而且这个结构还包含有Treenode重绘时的DC,这意意味着我可以在Treenode的重绘前/后处理这个消息,并不再使用默认的Treeview消息处理过程而达到自描绘的效果。代码片段如下:

Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)

    Select Case m.Msg

      Case OCM_NOTIFY

        Dim NMTVCD As NMTVCUSTOMDRAW

 

        NMTVCD = Marshal.PtrToStructure(m.LParam, GetType(NMTVCUSTOMDRAW))

 

        Select Case NMTVCD.NMCD.hdr.code

          Case NM_CUSTOMDRAW

            Select Case NMTVCD.NMCD.dwDrawStage

              Case CDDS_PREPAINT

                ' 我要得到Treenode中绘图处理前后的通知

                m.Result = CDRF_NOTIFYITEMDRAW

 

              Case CDDS_ITEMPREPAINT //这个通知将在Treenode绘图处理前收到

   

                Dim ptr As New IntPtr

                Dim rcItem As New Rectangle

                Dim g As Graphics = Graphics.FromHdc(NMTVCD.NMCD.hdc)

                Dim b As New SolidBrush(Color.Blue)

 

                rcItem.X = NMTVCD.NMCD.dwItemSpec

               SendMessageItemRect(m.HWnd, TVM_GETITEMRECT, 1, rcItem)

                                    

                                     //你可以利用Graphics对象g来进行TreeNode的绘图,例如:

                g.FillRectangle(New SolidBrush(Color.Yellow), New RectangleF(rcItem.X, rcItem.Y, rcItem.Width, rcItem.Height))

 

 

                g.Dispose()

                b.Dispose()

 

                m.Result = CDRF_SKIPDEFAULT //这个返回值将通知Treeview控件不需再进行这个Treenode的绘图操作

 

              Case CDDS_ITEMPOSTPAINT ////这个通知将在Treenode处理后收到

                                      //和你可以以这儿进行和CDDS_ITEMPREPAINT过程相似的绘图操作

//这代表在Treeview进行treenode描绘后你还可以为treenode再多画一些东西8)

//代码略

                 m.Result = CDRF_SKIPDEFAULT

            End Select

 

        End Select

      Case Else

        MyBase.WndProc(m)

    End Select

 End Sub

 但在精简版中,我挂接了TreeView控件的消息处理过程,却始终无法收到OCM_NOTIFY消息,查阅了PPC2003SDK也没有发现该消息的说明,讨厌的WinCE系统没有提供这个通知。然后我在文档中迷醉了7~80分钟才发现,系统提供的Treeview只向父窗体发送WM_NOTIFY消息,消息的lParam代表的意义和OCM_NOTIFY通知完全一致。与是我不再继承,而是采取了使用一个自定义控件上放一个Treeview的方法。然后我在这个自定义控件中截到了WM_NOTIFY通知消息,接下来的Treenode绘图处理就和上面的示例大同小异了。

   //本控件的消息处理过程

    private int ThisWindowProc(IntPtr hwnd, uint uMsg, uint wParam, uint lParam)

    {

      bool tblnUseOldWinProc = true;

      int tintFuncReturn = 0;

 

      switch (uMsg)

      {

        case WM_NOTIFY:

          tagNMHDR tudtNMHDR;

          tagNMCUSTOMDRAWINFO tudtTreeViewCustomDrawInfo;

          tagNMTVCUSTOMDRAW tudtTreeViewCustomDraw;

 

 

          tudtNMHDR = (tagNMHDR)Marshal.PtrToStructure(new IntPtr(lParam), typeof(tagNMHDR));

          if (tudtNMHDR.hwndFrom == treMain.Handle)

          {

            switch (tudtNMHDR.code)

            {

              case NM_CUSTOMDRAW:

                tudtTreeViewCustomDraw = (tagNMTVCUSTOMDRAW)Marshal.PtrToStructure((IntPtr)lParam,

                  typeof(tagNMTVCUSTOMDRAW));

 

                tudtTreeViewCustomDrawInfo = tudtTreeViewCustomDraw.nmcd;

 

                switch (tudtTreeViewCustomDrawInfo.dwDrawStage)

                {

                  case CDDS_PREPAINT:

                    //本控件在Item重画前后都将获得Treeview控件的 NM_CUSTOMDRAW消息

                    tintFuncReturn = (int)CDRF_NOTIFYITEMDRAW;

                    tblnUseOldWinProc = false;//不再使用原始窗体的消息处理过程

                    break;

 

                  case CDDS_ITEMPREPAINT:

                    {

 

                      tintFuncReturn = fnCDDS_ITEMPREPAINT_NotifyMessage(hwnd, uMsg, wParam, lParam,

                        ref tudtTreeViewCustomDraw, ref tblnUseOldWinProc);

                      Marshal.StructureToPtr(tudtTreeViewCustomDraw, (IntPtr)lParam, false);//这是重绘TreeNode的处理过程

 

                      break;

                    }

                  default:

                    break;

 

                }//end switch

 

                break;

 

            }//end switch

          }//end if

 

 

          break;

 

 

        default:

          //对不处理的消息使用treeview的默认消息处理过程

          break;

      }//end switch

       if (tblnUseOldWinProc == true)

        return clsCECoreAPI.CallWindowProc(m_intThisPreviousWinProc, hwnd, uMsg, wParam, lParam);

      else

        return tintFuncReturn;

      //end if

 

}//end function

 

得到的运行效果如下:


移动设备开发感兴趣可以加入以下群24123368

入群需知:

1、不是编程开发人员请勿加入。

2、没时间讨论问题或喜欢潜水的请勿加入。

3、只想获得源程序的请勿加入

 

blog文档,未经作者同意,谢绝转载。谢谢你对我的blog的访问.

联系方式: missilecat@163.com QQ:85403578


关于缓存数据的应用:【上一篇】
工作项跟踪管理系统基本完成:【下一篇】
【相关文章】
  • PleacPerl——Internet Services
  • ACE based ftp/telnet library
  • Netcat-端口扫描
  • 提供一个基于.NET的加密/解密算法
  • CIFS:Common Internet File System
  • asp.net 2.0下一个标准GRIDVIEW功能的实现(不用datasource控件)
  • netscreen恢复默认方法
  • Jre 的安装 http://blog.chinaunix.net/u/16189/showart.
  • ASP.NET页面下载程序
  • 日志记录组件[Log4net]详细介绍
  • 【随机文章】
  • AIX System Security:4.Logging
  • qt中的信号和槽机制
  • some trouble current
  • 项目中文档组织的之不良习惯
  • 用Eclipse RCP & ECF 实现 Google Talk客户端
  • unix与nt开发平台比较(六)--字节对齐
  • delphi线程同步问题
  • java简单的获取windows系统网卡mac地址
  • js脚本中有中文字时,可能导致脚本错误的解决办法
  • 光传送网的智能化管理
  • 【相关评论】
    没有相关评论
    【发表评论】
    姓名:
    邮件:
    随机码*
    评论*
          
    |  首 页  |  版权声明  |  联系我们   |  网站地图  |
    CopyRight © 2004-2007 bbb软讯网络 All Rigths Reserved.