1
+ using System ;
2
+ using System . ComponentModel ;
3
+ using System . Drawing ;
4
+ using System . Runtime . InteropServices ;
5
+ using System . Windows . Forms ;
6
+
7
+ namespace TaskSchedulerConfig
8
+ {
9
+ internal class CommandLink : Button
10
+ {
11
+ private const int BCM_SETNOTE = 0x00001609 ;
12
+ private const int BCM_SETSHIELD = 0x0000160C ;
13
+ private const int BS_COMMANDLINK = 0x0000000E ;
14
+
15
+ private Color activeTextColor ;
16
+ private string description ;
17
+ private Label lblDescription ;
18
+ private Label lblText ;
19
+ private bool mActivated ;
20
+ private DisplayStyle mDisplayStyle = DisplayStyle . Arrow ;
21
+ private bool mMouseOver ;
22
+ private PictureBox picIcon ;
23
+ private string text ;
24
+ private Color textColor ;
25
+
26
+ public CommandLink ( )
27
+ {
28
+ if ( IsVistaOrLater )
29
+ {
30
+ FlatStyle = FlatStyle . System ;
31
+ }
32
+ else
33
+ {
34
+ BackColor = Parent ? . BackColor ?? Color . White ;
35
+ FlatStyle = FlatStyle . Standard ;
36
+ Size = new Size ( 400 , 72 ) ;
37
+ TabStop = false ;
38
+ UseVisualStyleBackColor = false ;
39
+
40
+ textColor = Color . FromArgb ( 21 , 28 , 85 ) ;
41
+ activeTextColor = Color . FromArgb ( 7 , 74 , 229 ) ;
42
+
43
+ lblText = new Label { AutoSize = true , BackColor = Color . Transparent , ForeColor = textColor , Location = new Point ( 27 , 10 ) , Name = "lblText" , Size = new Size ( 0 , 21 ) , TabIndex = 0 } ;
44
+ lblText . Font = new Font ( "Segoe UI" , 12f , System . Drawing . FontStyle . Regular , GraphicsUnit . Point , ( byte ) 0 ) ;
45
+ lblText . ForeColor = Color . FromArgb ( ( int ) ( byte ) 21 , ( int ) ( byte ) 28 , ( int ) ( byte ) 85 ) ;
46
+ lblText . Click += ( o , e ) => OnClick ( e ) ;
47
+ lblText . MouseLeave += CommandLink_MouseLeave ;
48
+ Controls . Add ( lblText ) ;
49
+
50
+ lblDescription = new Label { BackColor = Color . Transparent , ForeColor = textColor , Location = new Point ( 33 , 36 ) , Name = "lblDescription" , Size = new Size ( 364 , 32 ) , TabIndex = 1 , UseCompatibleTextRendering = true } ;
51
+ lblDescription . Font = new Font ( "Segoe UI" , 9f , System . Drawing . FontStyle . Regular , GraphicsUnit . Point , ( byte ) 0 ) ;
52
+ lblDescription . ForeColor = Color . FromArgb ( ( int ) ( byte ) 21 , ( int ) ( byte ) 28 , ( int ) ( byte ) 85 ) ;
53
+ lblDescription . Click += ( o , e ) => OnClick ( e ) ;
54
+ lblDescription . MouseLeave += CommandLink_MouseLeave ;
55
+ Controls . Add ( lblDescription ) ;
56
+
57
+ picIcon = new PictureBox { BackColor = Color . Transparent , Location = new Point ( 10 , 13 ) , Name = "picIcon" , Size = new Size ( 16 , 16 ) , TabIndex = 2 , TabStop = false } ;
58
+ picIcon . Image = Properties . Resources . restarrow ;
59
+ picIcon . Click += ( o , e ) => OnClick ( e ) ;
60
+ picIcon . MouseLeave += CommandLink_MouseLeave ;
61
+ Controls . Add ( picIcon ) ;
62
+
63
+ Click += ( o , e ) => Selected ? . Invoke ( this , EventArgs . Empty ) ;
64
+ MouseEnter += ( o , e ) => MouseOver = true ;
65
+ MouseLeave += CommandLink_MouseLeave ;
66
+
67
+ MouseOver = false ;
68
+ Activated = false ;
69
+ }
70
+ }
71
+
72
+ public CommandLink ( DisplayStyle style , string text = null , string description = null ) : this ( )
73
+ {
74
+ Style = style ;
75
+ Text = text ;
76
+ Description = description ;
77
+ }
78
+
79
+ public event EventHandler Selected ;
80
+
81
+ public enum DisplayStyle
82
+ {
83
+ Arrow ,
84
+ Shield ,
85
+ }
86
+
87
+ [ Bindable ( true ) ]
88
+ [ DefaultValue ( null ) ]
89
+ public string Description
90
+ {
91
+ get { return description ; }
92
+ set
93
+ {
94
+ if ( IsVistaOrLater )
95
+ SendMessage ( Handle , BCM_SETNOTE , IntPtr . Zero , value ) ;
96
+ else
97
+ lblDescription . Text = value ;
98
+ description = value ;
99
+ }
100
+ }
101
+
102
+ [ Bindable ( true ) ]
103
+ [ DefaultValue ( DisplayStyle . Arrow ) ]
104
+ public DisplayStyle Style
105
+ {
106
+ get { return mDisplayStyle ; }
107
+ set
108
+ {
109
+ bool bInv = false ;
110
+ if ( mDisplayStyle != value )
111
+ {
112
+ bInv = true ;
113
+ }
114
+ mDisplayStyle = value ;
115
+ if ( bInv )
116
+ {
117
+ if ( IsVistaOrLater )
118
+ {
119
+ if ( mDisplayStyle == DisplayStyle . Shield )
120
+ SendMessage ( Handle , BCM_SETSHIELD , 0 , 1 ) ;
121
+ }
122
+ else
123
+ {
124
+ base . FlatStyle = FlatStyle . Standard ;
125
+
126
+ switch ( mDisplayStyle )
127
+ {
128
+ case DisplayStyle . Arrow :
129
+ picIcon . Image = mMouseOver ? Properties . Resources . selarrow : Properties . Resources . restarrow ;
130
+ break ;
131
+
132
+ case DisplayStyle . Shield :
133
+ picIcon . Image = Properties . Resources . shield ;
134
+ break ;
135
+
136
+ default :
137
+ picIcon . Image = null ;
138
+ break ;
139
+ }
140
+ Invalidate ( ) ;
141
+ }
142
+ }
143
+ }
144
+ }
145
+
146
+ [ Bindable ( true ) ]
147
+ [ DefaultValue ( null ) ]
148
+ public override string Text
149
+ {
150
+ get { return text ; }
151
+ set
152
+ {
153
+ if ( IsVistaOrLater )
154
+ base . Text = value ;
155
+ else
156
+ lblText . Text = value ;
157
+ text = value ;
158
+ }
159
+ }
160
+
161
+ protected override CreateParams CreateParams
162
+ {
163
+ get
164
+ {
165
+ CreateParams cp = base . CreateParams ;
166
+ if ( IsVistaOrLater )
167
+ cp . Style |= BS_COMMANDLINK ;
168
+ return cp ;
169
+ }
170
+ }
171
+
172
+ private bool Activated
173
+ {
174
+ get { return mActivated ; }
175
+ set
176
+ {
177
+ bool bInv = false ;
178
+ if ( mActivated != value )
179
+ bInv = true ;
180
+ mActivated = value ;
181
+ if ( bInv )
182
+ Invalidate ( ) ;
183
+ }
184
+ }
185
+
186
+ private bool Default => ( object . ReferenceEquals ( FindForm ( ) . AcceptButton , this ) ) ;
187
+
188
+ private static bool IsVistaOrLater => System . Environment . OSVersion . Version . Major > 5 ;
189
+
190
+ private bool MouseOver
191
+ {
192
+ get { return mMouseOver ; }
193
+ set
194
+ {
195
+ bool bInv = false ;
196
+ if ( mMouseOver != value )
197
+ bInv = true ;
198
+ mMouseOver = value ;
199
+ if ( ! IsVistaOrLater && bInv )
200
+ {
201
+ if ( mMouseOver == true )
202
+ {
203
+ lblText . ForeColor = activeTextColor ;
204
+ lblDescription . ForeColor = activeTextColor ;
205
+ if ( Style == DisplayStyle . Arrow )
206
+ picIcon . Image = Properties . Resources . selarrow ;
207
+ }
208
+ else
209
+ {
210
+ lblText . ForeColor = textColor ;
211
+ lblDescription . ForeColor = textColor ;
212
+ if ( Style == DisplayStyle . Arrow )
213
+ {
214
+ picIcon . Image = Properties . Resources . restarrow ;
215
+ }
216
+ }
217
+ Invalidate ( ) ;
218
+ }
219
+ }
220
+ }
221
+
222
+ public void ActivateChanged ( bool activate )
223
+ {
224
+ Activated = activate ;
225
+ }
226
+
227
+ protected override void OnPaint ( System . Windows . Forms . PaintEventArgs e )
228
+ {
229
+ if ( IsVistaOrLater )
230
+ {
231
+ base . OnPaint ( e ) ;
232
+ }
233
+ else
234
+ {
235
+ if ( base . FlatStyle != FlatStyle . Standard )
236
+ base . FlatStyle = FlatStyle . Standard ;
237
+
238
+ Pen oPen = null ;
239
+ Rectangle r = ClientRectangle ;
240
+ Brush oBrush = null ;
241
+
242
+ r . Width -= 1 ;
243
+ r . Height -= 1 ;
244
+
245
+ if ( MouseOver )
246
+ {
247
+ //the mouse is over is, draw the hover border
248
+ oPen = new Pen ( Color . FromArgb ( 198 , 198 , 198 ) ) ;
249
+ oBrush = new System . Drawing . Drawing2D . LinearGradientBrush ( ClientRectangle , BackColor , Color . FromArgb ( 246 , 246 , 246 ) , System . Drawing . Drawing2D . LinearGradientMode . Vertical ) ;
250
+ }
251
+ else if ( Activated && Default )
252
+ {
253
+ //draw the blue border
254
+ oPen = new Pen ( Color . FromArgb ( 198 , 244 , 255 ) ) ;
255
+ r . Width -= 2 ;
256
+ r . Height -= 2 ;
257
+ r . X += 1 ;
258
+ r . Y += 1 ;
259
+ }
260
+
261
+ if ( oBrush == null )
262
+ {
263
+ e . Graphics . FillRectangle ( new SolidBrush ( BackColor ) , ClientRectangle ) ;
264
+ }
265
+ else
266
+ {
267
+ e . Graphics . FillRectangle ( oBrush , ClientRectangle ) ;
268
+ oBrush . Dispose ( ) ;
269
+ }
270
+ if ( oPen != null )
271
+ {
272
+ oPen . LineJoin = System . Drawing . Drawing2D . LineJoin . Round ;
273
+ e . Graphics . DrawLine ( oPen , r . X + 2 , r . Y , r . X + r . Width - 2 , r . Y ) ;
274
+ e . Graphics . DrawLine ( oPen , r . X + r . Width - 2 , r . Y , r . X + r . Width , r . Y + 2 ) ;
275
+ e . Graphics . DrawLine ( oPen , r . X + r . Width , r . Y + 2 , r . X + r . Width , r . Y + r . Height - 2 ) ;
276
+ e . Graphics . DrawLine ( oPen , r . X + r . Width , r . Y + r . Height - 2 , r . X + r . Width - 2 , r . Y + r . Height ) ;
277
+ e . Graphics . DrawLine ( oPen , r . X + r . Width - 2 , r . Y + r . Height , r . X + 2 , r . Y + r . Height ) ;
278
+ e . Graphics . DrawLine ( oPen , r . X + 2 , r . Y + r . Height , r . X , r . Y + r . Height - 2 ) ;
279
+ e . Graphics . DrawLine ( oPen , r . X , r . Y + r . Height - 2 , r . X , r . Y + 2 ) ;
280
+ e . Graphics . DrawLine ( oPen , r . X , r . Y + 2 , r . X + 2 , r . Y ) ;
281
+ oPen . Dispose ( ) ;
282
+ }
283
+ }
284
+ }
285
+
286
+ [ DllImport ( "user32.dll" , CharSet = CharSet . Unicode ) ]
287
+ private static extern int SendMessage ( IntPtr hWnd , UInt32 Msg , int wParam , int lParam ) ;
288
+
289
+ [ DllImport ( "user32" , CharSet = CharSet . Unicode ) ]
290
+ private static extern IntPtr SendMessage ( IntPtr hWnd , UInt32 Msg , IntPtr wParam , string lParam ) ;
291
+
292
+ private void CommandLink_MouseLeave ( object sender , System . EventArgs e )
293
+ {
294
+ MouseOver = ClientRectangle . Contains ( PointToClient ( Control . MousePosition ) ) ;
295
+ Invalidate ( ) ;
296
+ }
297
+ }
298
+ }
0 commit comments