Author: Tadas Budvytis
Under Outlook style I mean treeview with additional information like, how many
unread mails left in the folder. Such info usually is painted in different color.
e.g. blue.
To look standart TreeView like MS treeView We must to:
1. Handle events sent from TreeView to his parent e.g. panel or Form
2. Paint additional information.
in the demo project for such purposes are created two functions
1. void WndProc(ref Message m)
And
2. void TreeViewPaint(ref Message m)
In demo project both these functions are in Form class.
In real world TreeViewPaint shall be in subclassed TreeView control and WndProc in
his parent.
1
2 //Tadas Budvytis Demo project
3 // budvytis@takas.lt
4 using System;
5 using System.Drawing;
6 using System.Collections;
7 using System.ComponentModel;
8 using System.Windows.Forms;
9 using System.Data;
10
11 namespace TB
12 {
13 /// <summary>
14 /// Summary description for Form1.
15 /// </summary>
16 ///
17
18
19
20 public unsafe struct NMHDR
21 {
22 public uint hwndFrom;
23 public uint idFrom;
24 public uint code;
25 }
26
27
28 public unsafe struct NMLVCUSTOMDRAW
29 {
30 public NMCUSTOMDRAW hdr;
31 public uint clrText;
32 public uint clrTextBk;
33 public int iSubItem;
34 }
35
36
37 public unsafe struct NMCUSTOMDRAW
38 {
39 public NMHDR hdr;
40 public uint dwDrawStage;
41 public uint hdc;
42 public uint x1;
43 public uint y1;
44 public uint x2;
45 public uint y2;
46 public uint dwItemSpec;
47 public uint uItemState;
48 public uint lItemlParam;
49
50 }
51
52
53 public class Form1 : System.Windows.Forms.form
54 {
55 //Normaly shall be in some other place of course
56 private const uint WM_NOTIFY=78;
57 private const uint NM_CUSTOMDRAW =4294967284;
58 private const uint CDDS_ITEMPREPAINT=65537;
59 private const uint CDRF_NOTIFYSUBITEMDRAW =32;
60
61 private System.Windows.Forms.TreeView treeView1;
62 /// <summary>
63 /// Required designer variable.
64 /// </summary>
65 private System.ComponentModel.Container components = null;
66
67 public Form1()
68 {
69 //
70 // Required for Windows Form Designer support
71 //
72 InitializeComponent();
73
74 //
75 // TODO: Add any constructor code after InitializeComponent call
76 //
77 }
78
79 /// <summary>
80 /// Clean up any resources being used.
81 /// </summary>
82 protected override void Dispose( bool disposing )
83 {
84 if( disposing )
85 {
86 if (components != null)
87 {
88 components.Dispose();
89 }
90 }
91 base.Dispose( disposing );
92 }
93
94
95 unsafe protected override void WndProc(ref Message m)
96 {
97 IntPtr inp;
98 NMCUSTOMDRAW *lp2;
99 NMHDR *lp;
100
101 inp=IntPtr.Zero ;
102
103 //Handle Notify message
104 if (m.Msg ==WM_NOTIFY)
105 {
106 lp=null;
107 lp=(NMHDR*)m.LParam.ToPointer ();
108 {
109 //Message is NM_CUSTOMDRAW
110 if (lp->code ==NM_CUSTOMDRAW)
111 {
112 lp2=(NMCUSTOMDRAW*)m.LParam.ToPointer ();
113
114 //It is a message Paint Item. Here we shall do some painting
115 if (lp2->dwDrawStage==CDDS_ITEMPREPAINT) //CDDS_ITEMPREPAINT
116 {
117 base.WndProc(ref m);
118 TreeViewPaint (ref m);
119 m.Result =(IntPtr)(0);
120 return;
121 }
122 else
123 {
124 //We shall return this value to get messages about item painting
125 m.Result =(IntPtr)CDRF_NOTIFYSUBITEMDRAW; ;
126
127 }
128
129 }
130 }
131 }
132 base.WndProc(ref m);
133 }
134
135
136 // This function paints additional info.
137 unsafe public void TreeViewPaint(ref Message m)
138 {
139 NMCUSTOMDRAW *lp2;
140 System.Drawing.Graphics g;
141 System.Windows.Forms.TreeNode node;
142 string strText; //Text to draw
143 long x1,y1; //coordinates there we will paint
144
145 lp2=(NMCUSTOMDRAW*)m.LParam.ToPointer ();
146
147 //Paint only this control items
148 //Now we have only one treeview so this code is commented
149 //if ((uint)this.Handle !=lp2->hdr.hwndFrom )
150 //{return;}
151
152 //Get graphic device
153 g=System.Drawing.Graphics.FromHwnd (this.treeView1.Handle );
154
155
156 //Get node whish we are going to paint
157 node=this.treeView1.GetNodeAt((int)lp2->x1+1,(int)lp2->y1+1);
158
159
160 x1=lp2->x1+node.Bounds.X +node.Bounds.Width +5;
161 y1=lp2->y1;
162 strText="( " +node.Index.ToString() +" )";
163
164 //Paint addition informatinon at the end of item
165 g.DrawString
166 (strText,this.treeView1.Font,System.Drawing.Brushes.DarkBlue,x1,y1,System.Drawing.St
167 ringFormat.GenericTypographic);
168 //lp2->x3 =lp2->x3 +100;
169 return;
170
171 }
172
173 #region Windows Form Designer generated code
174 /// <summary>
175 /// Required method for Designer support - do not modify
176 /// the contents of this method with the code editor.
177 /// </summary>
178 private void InitializeComponent()
179 {
180 this.treeView1 = new System.Windows.Forms.TreeView();
181 this.SuspendLayout();
182 //
183 // treeView1
184 //
185 this.treeView1.Dock = System.Windows.Forms.DockStyle.Fill;
186 this.treeView1.ImageIndex = -1;
187 this.treeView1.Name = "treeView1";
188 this.treeView1.Nodes.AddRange(new System.Windows.Forms.TreeNode[] {
189 new System.Windows.Forms.TreeNode("My TreeView Today ", new
190 System.Windows.Forms.TreeNode[] {
191 new
192 System.Windows.Forms.TreeNode("Node1")}),
193 new System.Windows.Forms.TreeNode("Node2"),
194 new System.Windows.Forms.TreeNode("Node3"),
195 new System.Windows.Forms.TreeNode("Node4", new
196 System.Windows.Forms.TreeNode[] {
197 new
198 System.Windows.Forms.TreeNode("Node5", new System.Windows.Forms.TreeNode[] {
199 new
200 System.Windows.Forms.TreeNode("Node6", new System.Windows.Forms.TreeNode[] {
201
202 new System.Windows.Forms.TreeNode("Node7", new System.Windows.Forms.TreeNode[] {
203
204 new System.Windows.Forms.TreeNode("Node8")})})})})});
205 this.treeView1.SelectedImageIndex = -1;
206 this.treeView1.Size = new System.Drawing.Size(129, 226);
207 this.treeView1.TabIndex = 0;
208 //
209 // Form1
210 //
211 this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
212 this.ClientSize = new System.Drawing.Size(129, 226);
213 this.Controls.AddRange(new System.Windows.Forms.Control[] {
214 this.treeView1});
215 this.Name = "Form1";
216 this.Text = "frmTreeView";
217 this.ResumeLayout(false);
218
219 }
220 #endregion
221
222 /// <summary>
223 /// The main entry point for the application.
224 /// </summary>
225 [STAThread]
226 static void Main()
227 {
228 Application.Run(new Form1());
229 }
230
231
232 }
233 }
|