1 using System;
2 using System.ComponentModel;
3 using System.Drawing;
4 using System.Runtime.InteropServices;
5 using System.Windows.Forms;
6 using Endv.DotNetBar.Rendering;
7 using Endv.DotNetBar.TextMarkup;
8 using Endv.Editors;
9
10 namespace Endv.DotNetBar.Controls
11 {
12 /// <summary>
13 /// Represents enhanced Windows combo box control.
14 /// </summary>
15 [ToolboxBitmap(typeof(ComboBoxEx), "Controls.ComboBoxEx.ico"), ToolboxItem(true), Designer(typeof(Design.ComboBoxExDesigner))]
16 public class ComboBoxEx : System.Windows.Forms.ComboBox, ICommandSource
17 {
18 /// <summary>
19 /// Represents the method that will handle the DropDownChange event.
20 /// </summary>
21 public delegate void OnDropDownChangeEventHandler(object sender, bool Expanded);
22 /// <summary>
23 /// Occurs when drop down portion of combo box is shown or hidden.
24 /// </summary>
25 public event OnDropDownChangeEventHandler DropDownChange;
26
27 private eDotNetBarStyle m_Style=eDotNetBarStyle.Office2007;
28 private bool m_DefaultStyle=false; // Disables our drawing in WndProc
29 private bool m_MouseOver=false;
30 private bool m_MouseOverThumb=false;
31 private bool m_DroppedDown=false;
32 //private System.Windows.Forms.Timer m_Timer;
33 private bool m_WindowsXPAware=false;
34 private bool m_DisableInternalDrawing=false;
35 private ImageList m_ImageList=null;
36 private int m_DropDownHeight=0;
37 private IntPtr m_LastFocusWindow;
38 private IntPtr m_DropDownHandle=IntPtr.Zero;
39 private ComboTextBoxMsgHandler m_TextWindowMsgHandler=null;
40 //private ComboListBoxMsgHandler m_ListBoxMsgHandler = null;
41
42 [DllImport("user32")]
43 private static extern bool ValidateRect(IntPtr hWnd,ref NativeFunctions.RECT pRect);
44
45 [DllImport("user32",SetLastError=true, CharSet=CharSet.Auto)]
46 private static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);
47 private const uint GW_CHILD=5;
48
49 private bool m_PreventEnterBeep=false;
50
51 private string m_WatermarkText = "";
52 private bool m_Focused = false;
53 private Font m_WatermarkFont = null;
54 private Color m_WatermarkColor = SystemColors.GrayText;
55 private bool m_IsStandalone = true;
56 private Timer m_MouseOverTimer = null;
57 private Rectangle m_ThumbRect = Rectangle.Empty;
58 private bool _FocusHighlightEnabled = false;
59 private static Color _DefaultHighlightColor = Color.FromArgb(0xFF, 0xFF, 0x88);
60 private Color _FocusHighlightColor = _DefaultHighlightColor;
61
62 /// <summary>
63 /// Creates new instance of ComboBoxEx.
64 /// </summary>
65 public ComboBoxEx():base()
66 {
67 if(!ColorFunctions.ColorsLoaded)
68 {
69 NativeFunctions.RefreshSettings();
70 NativeFunctions.OnDisplayChange();
71 ColorFunctions.LoadColors();
72 }
73 m_MouseOverTimer = new Timer();
74 m_MouseOverTimer.Interval = 10;
75 m_MouseOverTimer.Enabled = false;
76 m_MouseOverTimer.Tick += new EventHandler(MouseOverTimerTick);
77 #if FRAMEWORK20
78 this.FlatStyle = FlatStyle.Flat;
79 #endif
80 }
81
82 private bool _FocusCuesEnabled = true;
83 /// <summary>
84 /// Gets or sets whether control displays focus cues when focused.
85 /// </summary>
86 [DefaultValue(true), Category("Behavior"), Description("Indicates whether control displays focus cues when focused.")]
87 public virtual bool FocusCuesEnabled
88 {
89 get { return _FocusCuesEnabled; }
90 set
91 {
92 _FocusCuesEnabled = value;
93 if (this.Focused) this.Invalidate();
94 }
95 }
96
97 /// <summary>
98 /// Gets or sets whether control is stand-alone control. Stand-alone flag affects the appearance of the control in Office 2007 style.
99 /// </summary>
100 [Browsable(true), DefaultValue(true), Category("Appearance"), Description("Indicates the appearance of the control.")]
101 public bool IsStandalone
102 {
103 get { return m_IsStandalone; }
104 set
105 {
106 m_IsStandalone = value;
107 }
108 }
109
110 private bool _WatermarkEnabled = true;
111 /// <summary>
112 /// Gets or sets whether watermark text is displayed when control is empty. Default value is true.
113 /// </summary>
114 [DefaultValue(true), Description("Indicates whether watermark text is displayed when control is empty.")]
115 public virtual bool WatermarkEnabled
116 {
117 get { return _WatermarkEnabled; }
118 set { _WatermarkEnabled = value; this.Invalidate(); }
119 }
120
121 /// <summary>
122 /// Gets or sets the watermark (tip) text displayed inside of the control when Text is not set and control does not have input focus. This property supports text-markup.
123 /// Note that WatermarkText is not compatible with the auto-complete feature of .NET Framework 2.0.
124 /// </summary>
125 [Browsable(true), DefaultValue(""), Localizable(true), Category("Appearance"), Description("Indicates watermark text displayed inside of the control when Text is not set and control does not have input focus."), Editor(typeof(Design.TextMarkupUIEditor), typeof(System.Drawing.Design.UITypeEditor))]
126 public string WatermarkText
127 {
128 get { return m_WatermarkText; }
129 set
130 {
131 if (value == null) value = "";
132 m_WatermarkText = value;
133 MarkupTextChanged();
134 this.Invalidate();
135 }
136 }
137
138 private eWatermarkBehavior _WatermarkBehavior = eWatermarkBehavior.HideOnFocus;
139 /// <summary>
140 /// Gets or sets the watermark hiding behaviour. Default value indicates that watermark is hidden when control receives input focus.
141 /// </summary>
142 [DefaultValue(eWatermarkBehavior.HideOnFocus), Category("Behavior"), Description("Indicates watermark hiding behaviour.")]
143 public eWatermarkBehavior WatermarkBehavior
144 {
145 get { return _WatermarkBehavior; }
146 set { _WatermarkBehavior = value; this.Invalidate(); }
147 }
148
149 private TextMarkup.BodyElement m_TextMarkup = null;
150 private void MarkupTextChanged()
151 {
152 m_TextMarkup = null;
153
154 if (!TextMarkup.MarkupParser.IsMarkup(ref m_WatermarkText))
155 return;
156
157 m_TextMarkup = TextMarkup.MarkupParser.Parse(m_WatermarkText);
158 ResizeMarkup();
159 }
160
161 private void ResizeMarkup()
162 {
163 if (m_TextMarkup != null)
164 {
165 using (Graphics g = this.CreateGraphics())
166 {
167 MarkupDrawContext dc = GetMarkupDrawContext(g);
168 m_TextMarkup.Measure(GetWatermarkBounds().Size, dc);
169 Size sz = m_TextMarkup.Bounds.Size;
170 m_TextMarkup.Arrange(new Rectangle(GetWatermarkBounds().Location, sz), dc);
171 }
172 }
173 }
174 private MarkupDrawContext GetMarkupDrawContext(Graphics g)
175 {
176 return new MarkupDrawContext(g, (m_WatermarkFont == null ? this.Font : m_WatermarkFont), m_WatermarkColor, this.RightToLeft == RightToLeft.Yes);
177 }
178
179 /// <summary>
180 /// Gets or sets the watermark font.
181 /// </summary>
182 [Browsable(true), Category("Appearance"), Description("Indicates watermark font."), DefaultValue(null)]
183 public Font WatermarkFont
184 {
185 get { return m_WatermarkFont; }
186 set { m_WatermarkFont = value; this.Invalidate(true); }
187 }
188
189 /// <summary>
190 /// Gets or sets the watermark text color.
191 /// </summary>
192 [Browsable(true), Category("Appearance"), Description("Indicates watermark text color.")]
193 public Color WatermarkColor
194 {
195 get { return m_WatermarkColor; }
196 set { m_WatermarkColor = value; this.Invalidate(true); }
197 }
198 /// <summary>
199 /// Indicates whether property should be serialized by Windows Forms designer.
200 /// </summary>
201 [EditorBrowsable(EditorBrowsableState.Never)]
202 public bool ShouldSerializeWatermarkColor()
203 {
204 return m_WatermarkColor != SystemColors.GrayText;
205 }
206 /// <summary>
207 /// Resets the property to default value.
208 /// </summary>
209 [EditorBrowsable(EditorBrowsableState.Never)]
210 public void ResetWatermarkColor()
211 {
212 this.WatermarkColor = SystemColors.GrayText;
213 }
214
215 /// <summary>
216 /// Gets or sets the combo box background color. Note that in Office 2007 style back color of the control is automatically managed.
217 /// </summary>
218 [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
219 public override Color BackColor
220 {
221 get
222 {
223 return base.BackColor;
224 }
225 set
226 {
227 base.BackColor = value;
228 }
229 }
230
231 private bool m_UseCustomBackColor=false;
232 /// <summary>
233 /// Gets or sets whether the BackColor value you set is used instead of the style back color automatically provided by the control. Default
234 /// value is false which indicates that BackColor property is automatically managed. Set this property to true and then set BackColor property
235 /// to make control use your custom back color.
236 /// </summary>
237 [Browsable(false), DefaultValue(false)]
238 public bool UseCustomBackColor
239 {
240 get { return m_UseCustomBackColor; }
241 set { m_UseCustomBackColor = value; }
242 }
243
244 /// <summary>
245 /// Gets or sets value indicating whether system combo box appearance is used. Default value is false.
246 /// </summary>
247 [Browsable(false),Category("Behavior"),Description("Makes Combo box appear the same as built-in Combo box."),DefaultValue(false)]
248 public bool DefaultStyle
249 {
250 get
251 {
252 return m_DefaultStyle;
253 }
254 set
255 {
256 if(m_DefaultStyle!=value)
257 {
258 m_DefaultStyle=value;
259 this.Invalidate(true);
260 }
261 }
262 }
263
264 /// <summary>
265 /// Gets or sets value indicating whether the combo box is draw using the Windows XP Theme manager when running on Windows XP or theme aware OS.
266 /// </summary>
267 [Browsable(false),Category("Behavior"),Description("When running on WindowsXP draws control using the Windows XP Themes if theme manager is enabled."),DefaultValue(false)]
268 public bool ThemeAware
269 {
270 get
271 {
272 return m_WindowsXPAware;
273 }
274 set
275 {
276 if(m_WindowsXPAware!=value)
277 {
278 m_WindowsXPAware=value;
279 if(!m_WindowsXPAware)
280 m_DefaultStyle=false;
281 else if (m_WindowsXPAware && BarFunctions.ThemedOS)
282 {
283 m_DefaultStyle = true;
284 #if FRAMEWORK20
285 this.FlatStyle = FlatStyle.Standard;
286 #endif
287 }
288 }
289 }
290 }
291
292 /// <summary>
293 /// Disables internal drawing support for the List-box portion of Combo-box. Default value is false which means that internal drawing code is used. If
294 /// you plan to provide your own drawing for combo box items you must set this property to True.
295 /// </summary>
296 [Browsable(true),Category("Behavior"),Description("Disables internal drawing support for the List-box portion of Combo-box."), DefaultValue(false)]
297 public bool DisableInternalDrawing
298 {
299 get
300 {
301 return m_DisableInternalDrawing;
302 }
303 set
304 {
305 if(m_DisableInternalDrawing!=value)
306 m_DisableInternalDrawing=value;
307 }
308 }
309
310 /// <summary>
311 /// Gets or sets whether combo box generates the audible alert when Enter key is pressed.
312 /// </summary>
313 [System.ComponentModel.Browsable(true),DevCoBrowsable(true),System.ComponentModel.Category("Behavior"),System.ComponentModel.Description("Indicates whether combo box generates the audible alert when Enter key is pressed."),System.ComponentModel.DefaultValue(false)]
314 public bool PreventEnterBeep
315 {
316 get
317 {
318 return m_PreventEnterBeep;
319 }
320 set
321 {
322 m_PreventEnterBeep=value;
323 }
324 }
325
326 /// <summary>
327 /// The ImageList control used by Combo box to draw images.
328 /// </summary>
329 [Browsable(true),Category("Behavior"),Description("The ImageList control used by Combo box to draw images."), DefaultValue(null)]
330 public System.Windows.Forms.ImageList Images
331 {
332 get
333 {
334 return m_ImageList;
335 }
336 set
337 {
338 m_ImageList=value;
339 }
340 }
341
342 /// <summary>
343 /// Determines the visual style applied to the combo box when shown. Default style is Office 2007.
344 /// </summary>
345 [Browsable(true),Category("Appearance"), DefaultValue(eDotNetBarStyle.Office2007) ,Description("Determines the display of the item when shown.")]
346 public eDotNetBarStyle Style
347 {
348 get
349 {
350 return m_Style;
351 }
352 set
353 {
354 m_Style=value;
355 UpdateBackColor();
356 this.Invalidate(true);
357 }
358 }
359
360 protected override void OnHandleCreated(EventArgs e)
361 {
362 base.OnHandleCreated(e);
363 UpdateBackColor();
364 SetupTextBoxMessageHandler();
365 RemoveTheme(this.Handle);
366 }
367
368 /*protected override void OnHandleDestroyed(EventArgs e)
369 {
370 if(m_Timer!=null)
371 m_Timer.Enabled=false;
372 base.OnHandleDestroyed(e);
373 }*/
374
375 protected override void OnResize(EventArgs e)
376 {
377 ResizeMarkup();
378 this.Invalidate();
379 base.OnResize(e);
380 }
381
382 private void MouseOverTimerTick(object sender, EventArgs e)
383 {
384 bool over = false;
385
386 if (this.IsHandleCreated && this.Visible)
387 {
388 WinApi.RECT rw = new WinApi.RECT();
389 WinApi.GetWindowRect(this.Handle, ref rw);
390 Rectangle r = rw.ToRectangle();
391 if (r.Contains(Control.MousePosition))
392 over = true;
393 Point p=this.PointToClient(Control.MousePosition);
394 if (m_ThumbRect.Contains(p))
395 MouseOverThumb = true;
396 else
397 MouseOverThumb = false;
398 }
399
400 if (!over)
401 {
402 SetMouseOverTimerEnabled(false);
403 m_MouseOver = false;
404 UpdateBackColor();
405 this.Invalidate();
406 if (this.ParentItem != null) this.ParentItem.HideToolTip();
407 }
408 }
409 internal BaseItem ParentItem = null;
410
411 private bool MouseOverThumb
412 {
413 get { return m_MouseOverThumb; }
414 set
415 {
416 if (m_MouseOverThumb != value)
417 {
418 m_MouseOverThumb = value;
419 this.Invalidate();
420 }
421 }
422 }
423
424 protected override void OnGotFocus(EventArgs e)
425 {
426 base.OnGotFocus(e);
427 if (!m_MouseOver)
428 m_MouseOver = true;
429 UpdateBackColor();
430 this.Invalidate(true);
431 }
432
433 protected override void OnLostFocus(EventArgs e)
434 {
435 //if(!this.ClientRectangle.Contains(this.PointToClient(Control.MousePosition)))
436 //m_MouseOver=false;
437 SetMouseOverTimerEnabled(true);
438 //Color c = GetComboColors().Background;
439 //if (this.BackColor != c)
440 //this.BackColor = c;
441 //if(!m_MouseOver)
442 // this.Refresh();
443 m_LastFocusWindow=IntPtr.Zero;
444 base.OnLostFocus(e);
445 }
446
447 private Timer m_DropDownTrackTimer = null;
448 private void StartDropDownTrackTimer()
449 {
450 if (m_DropDownTrackTimer == null)
451 {
452 m_DropDownTrackTimer = new Timer();
453 m_DropDownTrackTimer.Tick += new EventHandler(DropDownTrackTimerTick);
454 m_DropDownTrackTimer.Interval = 200;
455 }
456 m_DropDownTrackTimer.Start();
457 }
458 private void StopDropDownTrackTimer()
459 {
460 Timer t = m_DropDownTrackTimer;
461 m_DropDownTrackTimer = null;
462 if (t != null)
463 {
464 t.Stop();
465 t.Dispose();
466 }
467 }
468
469 private void DropDownTrackTimerTick(object sender, EventArgs e)
470 {
471 DroppedDownInternal = (WinApi.SendMessage(this.Handle, (int)WinApi.WindowsMessages.CB_GETDROPPEDSTATE, IntPtr.Zero, IntPtr.Zero) != 0);
472 }
473
474 private bool DroppedDownInternal
475 {
476 get
477 {
478 return m_DroppedDown;
479 }
480 set
481 {
482 if (m_DroppedDown != value)
483 {
484 StopDropDownTrackTimer();
485 m_DroppedDown = value;
486 this.Invalidate();
487
488 if (DropDownChange != null)
489 DropDownChange(this, m_DroppedDown);
490 #if !FRAMEWORK20
491 if(m_DroppedDown)
492 {
493 StartDropDownTrackTimer();
494 }
495 #endif
496 }
497 }
498 }
499
500 #if FRAMEWORK20
501 protected override void OnDropDownClosed(EventArgs e)
502 {
503 DroppedDownInternal = false;
504 m_SelectedIndexInternal = this.SelectedIndex;
505 base.OnDropDownClosed(e);
506 }
507 #endif
508
509 protected override void OnDropDown(EventArgs e)
510 {
511 base.OnDropDown(e);
512 if(DropDownChange!=null)
513 this.DropDownChange(this,true);
514 DroppedDownInternal=true;
515 }
516
517 [DllImport("user32", CharSet = CharSet.Unicode)]
518 private static extern int SetWindowTheme(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)] String pszSubAppName, [MarshalAs(UnmanagedType.LPWStr)] String pszSubIdList);
519
520 private void RemoveTheme(IntPtr handle)
521 {
522 bool isXp = false;
523 if (System.Environment.Version.Major > 5)
524 isXp = true;
525 else if ((System.Environment.Version.Major == 5) &&
526 (System.Environment.Version.Minor >= 1))
527 isXp = true;
528 if (isXp)
529 SetWindowTheme(handle, " ", " ");
530 }
531
532 #region Internal Combo Colors
533 private class InternalComboColors
534 {
535 public Color Background = SystemColors.Window;
536 public Color Border = SystemColors.Window;
537 public LinearGradientColorTable ThumbBackground = null;
538 public Color ThumbText = SystemColors.ControlText;
539 public LinearGradientColorTable ThumbBorderOuter = null;
540 public LinearGradientColorTable ThumbBorderInner = null;
541 }
542
543 private InternalComboColors GetComboColors()
544 {
545 InternalComboColors c = new InternalComboColors();
546
547 bool bFocus = (m_MouseOverThumb || this.Focused || this.DroppedDownInternal && this.DropDownStyle != ComboBoxStyle.Simple);
548 if (bFocus && !this.Enabled)
549 bFocus = false;
550
551 if (BarFunctions.IsOffice2007Style(this.Style) && GlobalManager.Renderer is Office2007Renderer)
552 {
553 Office2007ComboBoxColorTable colorTable = ((Office2007Renderer)GlobalManager.Renderer).ColorTable.ComboBox;
554 Office2007ComboBoxStateColorTable stateColors = (IsToolbarStyle && !m_MouseOver ? colorTable.Default : colorTable.DefaultStandalone);
555 if (bFocus)
556 {
557 if (this.DroppedDown)
558 stateColors = colorTable.DroppedDown;
559 else if(bFocus)
560 stateColors = colorTable.MouseOver;
561 }
562
563 c.Background = stateColors.Background;
564 c.Border = stateColors.Border;
565 c.ThumbBackground = stateColors.ExpandBackground;
566 c.ThumbText = stateColors.ExpandText;
567 c.ThumbBorderOuter = stateColors.ExpandBorderOuter;
568 c.ThumbBorderInner = stateColors.ExpandBorderInner;
569 }
570 else
571 {
572 ColorScheme cs = new ColorScheme(this.Style);
573 if (bFocus)
574 {
575 if (DroppedDownInternal)
576 {
577 c.ThumbBackground = new LinearGradientColorTable(cs.ItemPressedBackground, cs.ItemPressedBackground2, cs.ItemPressedBackgroundGradientAngle);
578 c.Border = cs.ItemPressedBorder;
579 c.ThumbText = cs.ItemPressedText;
580 }
581 else
582 {
583 if (m_MouseOverThumb)
584 c.ThumbBackground = new LinearGradientColorTable(cs.ItemHotBackground, cs.ItemHotBackground2, cs.ItemHotBackgroundGradientAngle);
585 else
586 c.ThumbBackground = new LinearGradientColorTable(cs.BarBackground, cs.BarBackground2, cs.BarBackgroundGradientAngle);
587 c.Border = cs.ItemHotBorder;
588 c.ThumbText = cs.ItemHotText;
589 }
590 }
591 else
592 {
593 c.ThumbBackground = new LinearGradientColorTable(cs.BarBackground, cs.BarBackground2, cs.BarBackgroundGradientAngle);
594 if (m_MouseOver || !IsToolbarStyle)
595 {
596 c.Border = cs.ItemHotBorder;
597 }
598 }
599 }
600
601 if (_FocusHighlightEnabled && this.Enabled && this.Focused)
602 c.Background = _FocusHighlightColor;
603 else if (!this.Enabled)
604 {
605 c.Background = _DisabledBackColor.IsEmpty ? SystemColors.Control : _DisabledBackColor;
606 c.ThumbText = _DisabledForeColor.IsEmpty ? SystemColors.ControlDark : _DisabledForeColor; ;
607 }
608
609 return c;
610 }
611 #endregion
612
613 protected override void WndProc(ref Message m)
614 {
615 const int WM_PAINT = 0xF;
616 const int WM_PRINTCLIENT = 0x0318;
617 const int WM_CTLCOLORLISTBOX = 0x0134;
618 const int CB_ADDSTRING = 0x143;
619 const int CB_INSERTSTRING = 0x14A;
620 const int CB_DELETESTRING = 0x0144;
621
622 WinApi.RECT rect = new WinApi.RECT();
623
624 if (m.Msg == WM_CTLCOLORLISTBOX)
625 {
626 m_DropDownHandle = m.LParam;
627 if (m_DropDownHeight > 0)
628 {
629 WinApi.GetWindowRect(m.LParam, ref rect);
630 NativeFunctions.SetWindowPos(m.LParam, 0, rect.Left, rect.Top, rect.Right - rect.Left, m_DropDownHeight, NativeFunctions.SWP_NOACTIVATE | NativeFunctions.SWP_NOMOVE);
631 }
632 }
633 else if (m.Msg == (int)WinApi.WindowsMessages.CB_GETDROPPEDSTATE)
634 {
635 base.WndProc(ref m);
636 if (m.Result == IntPtr.Zero)
637 {
638 if (DroppedDownInternal)
639 {
640 DroppedDownInternal = false;
641 }
642 }
643 return;
644 }
645 else if (m.Msg == NativeFunctions.WM_SETFOCUS)
646 {
647 if (m.WParam != this.Handle)
648 m_LastFocusWindow = m.WParam;
649 }
650 else if (m.Msg == CB_ADDSTRING)
651 {
652 if (this.Items.Count > 0)
653 {
654 ComboItem cb = this.Items[this.Items.Count - 1] as ComboItem;
655 if (cb != null)
656 cb.m_ComboBox = this;
657 }
658 }
659 else if (m.Msg == CB_INSERTSTRING)
660 {
661 int index = m.WParam.ToInt32();
662 if (index >= 0 && index < this.Items.Count)
663 {
664 ComboItem cb = this.Items[index] as ComboItem;
665 if (cb != null)
666 cb.m_ComboBox = this;
667 }
668 m_SelectedIndexInternal = -1;
669 }
670 else if (m.Msg == CB_DELETESTRING)
671 {
672 m_SelectedIndexInternal = -1;
673 }
674 else if (m.Msg == NativeFunctions.WM_USER + 7)
675 {
676 if (this.DropDownStyle == ComboBoxStyle.DropDown && !m_Focused) this.SelectionLength = 0;
677 this.Invalidate(true);
678 return;
679 }
680
681 if (m_DefaultStyle)
682 {
683 base.WndProc(ref m);
684 return;
685 }
686
687 if ((m.Msg == WM_PAINT || m.Msg == WM_PRINTCLIENT) && this.DrawMode != DrawMode.Normal)
688 {
689 WinApi.GetWindowRect(m.HWnd, ref rect);
690 System.Drawing.Size controlSize = new Size(rect.Width, rect.Height);
691
692 WinApi.PAINTSTRUCT ps = new WinApi.PAINTSTRUCT();
693 IntPtr hdc = WinApi.BeginPaint(m.HWnd, ref ps);
694 try
695 {
696 Graphics g = Graphics.FromHdc(hdc);
697 try
698 {
699 PaintComboBox(g, controlSize);
700 }
701 finally
702 {
703 g.Dispose();
704 }
705 }
706 finally
707 {
708 WinApi.EndPaint(m.HWnd, ref ps);
709 }
710
711 if (this.Parent is ItemControl)
712 ((ItemControl)this.Parent).UpdateKeyTipsCanvas();
713 }
714 else
715 base.WndProc(ref m);
716 }
717
718 private void PaintComboBox(Graphics targetGraphics, System.Drawing.Size controlSize)
719 {
720 InternalComboColors colors = GetComboColors();
721 Rectangle r = new Rectangle(Point.Empty, controlSize);
722
723 BufferedBitmap bmp = new BufferedBitmap(targetGraphics, new Rectangle(0, 0, this.Width, this.Height));
724 try
725 {
726 Graphics g = bmp.Graphics;
727
728 PaintComboBackground(g, r, colors);
729 PaintComboBorder(g, r, colors);
730 Rectangle contentRect = PaintComboThumb(g, r, colors);
731 int selectedIndex = this.SelectedIndex == -1 ? -1 : m_SelectedIndexInternal;
732 if (m_SelectedIndexInternal == -1 && this.SelectedIndex >= 0) selectedIndex = this.SelectedIndex;
733 if (DropDownStyle == ComboBoxStyle.DropDownList && selectedIndex >= 0 && this.Items.Count > 0 && selectedIndex < this.Items.Count)
734 {
735 DrawItemState state = DrawItemState.ComboBoxEdit;
736 if (Focused)
737 state |= (DrawItemState.Focus | DrawItemState.Selected);
738
739 if (!Enabled) state = DrawItemState.Disabled | DrawItemState.ComboBoxEdit;
740 contentRect.Inflate(-1, -1);
741 this.OnDrawItem(new DrawItemEventArgs(g, this.Font, contentRect,
742 selectedIndex, state, this.ForeColor, this.BackColor));
743 }
744 if (this.ShouldDrawWatermark() && this.DropDownStyle == ComboBoxStyle.DropDownList)
745 DrawWatermark(g);
746
747 bmp.Render(targetGraphics);
748 }
749 finally
750 {
751 bmp.Dispose();
752 }
753 }
754
755 private Rectangle PaintComboThumb(Graphics g, Rectangle r, InternalComboColors colors)
756 {
757 Rectangle contentRect = r;
758 contentRect.Inflate(-2, -2);
759
760 if (this.DropDownStyle == ComboBoxStyle.Simple) return contentRect;
761
762 int thumbWidth = SystemInformation.HorizontalScrollBarThumbWidth;
763 Rectangle thumbRect = new Rectangle(r.Width - thumbWidth, r.Y, thumbWidth, r.Height);
764 if (RightToLeft == RightToLeft.Yes)
765 thumbRect = new Rectangle(r.X + 1, r.Y + 1, thumbWidth, r.Height - 2);
766 if (!this.IsToolbarStyle)
767 {
768 thumbRect.Y += 2;
769 thumbRect.Height -= 4;
770 thumbRect.Width -= 2; ;
771 if (RightToLeft == RightToLeft.Yes)
772 thumbRect.X += 2;
773 }
774 else if (!BarFunctions.IsOffice2007Style(this.Style))
775 thumbRect.Inflate(-1, -1);
776
777 if (RightToLeft == RightToLeft.Yes)
778 {
779 int diff = thumbRect.Right - contentRect.X + 2;
780 contentRect.Width -= diff;
781 contentRect.X += diff;
782 }
783 else
784 {
785 int diff = contentRect.Right - thumbRect.X + 2;
786 contentRect.Width -= diff;
787 }
788 //contentRect.Y++;
789 //contentRect.Height--;
790
791 if (!this.IsToolbarStyle && BarFunctions.IsOffice2007Style(this.Style))
792 {
793 Office2007ButtonItemPainter.PaintBackground(g, GetOffice2007StateColorTable(), thumbRect, RoundRectangleShapeDescriptor.RectangleShape);
794 }
795 else
796 {
797 if (colors.ThumbBackground != null)
798 DisplayHelp.FillRectangle(g, thumbRect, colors.ThumbBackground);
799 if (colors.ThumbBorderOuter != null)
800 DisplayHelp.DrawGradientRectangle(g, thumbRect, colors.ThumbBorderOuter, 1);
801 Rectangle innerBorder = thumbRect;
802 innerBorder.Inflate(-1, -1);
803 if (colors.ThumbBorderInner != null)
804 DisplayHelp.DrawGradientRectangle(g, innerBorder, colors.ThumbBorderInner, 1);
805 }
806
807 using(SolidBrush brush=new SolidBrush(colors.ThumbText))
808 DrawArrow(thumbRect, g, brush);
809
810 m_ThumbRect = thumbRect;
811 return contentRect;
812 }
813
814 [Browsable(false)]
815 public bool IsToolbarStyle
816 {
817 get { return !m_IsStandalone; }
818 }
819
820 protected Office2007ButtonItemStateColorTable GetOffice2007StateColorTable()
821 {
822 bool bFocus = (m_MouseOverThumb || this.DroppedDownInternal && this.DropDownStyle != ComboBoxStyle.Simple);
823
824 if (GlobalManager.Renderer is Office2007Renderer)
825 {
826 Office2007ColorTable ct = ((Office2007Renderer)GlobalManager.Renderer).ColorTable;
827 Office2007ButtonItemColorTable buttonColorTable = ct.ButtonItemColors[Enum.GetName(typeof(eButtonColor), eButtonColor.OrangeWithBackground)];
828 if (!this.Enabled)
829 return buttonColorTable.Disabled;
830 else if (this.DroppedDownInternal)
831 return buttonColorTable.Checked;
832 else if (bFocus)
833 return buttonColorTable.MouseOver;
834 else
835 return buttonColorTable.Default;
836 }
837
838 return null;
839 }
840
841 private void PaintComboBorder(Graphics g, Rectangle controlBounds, InternalComboColors colors)
842 {
843 DisplayHelp.DrawRectangle(g, colors.Border, controlBounds);
844 }
845
846 private void PaintComboBackground(Graphics g, Rectangle controlBounds, InternalComboColors colors)
847 {
848 DisplayHelp.FillRectangle(g, controlBounds, colors.Background);
849 }
850
851 private bool ShouldDrawWatermark()
852 {
853 if (_WatermarkEnabled && this.Enabled && (!this.Focused || _WatermarkBehavior== eWatermarkBehavior.HideNonEmpty) && this.Text == "" && this.SelectedIndex == -1)
854 return true;
855 return false;
856 }
857
858 private void DrawWatermark(Graphics g)
859 {
860 if (m_TextMarkup != null)
861 {
862 MarkupDrawContext dc = GetMarkupDrawContext(g);
863 m_TextMarkup.Render(dc);
864 }
865 else
866 {
867 eTextFormat tf = eTextFormat.Left | eTextFormat.VerticalCenter;
868
869 if (this.RightToLeft == RightToLeft.Yes) tf |= eTextFormat.RightToLeft;
870 //if (this.TextAlign == HorizontalAlignment.Left)
871 // tf |= eTextFormat.Left;
872 //else if (this.TextAlign == HorizontalAlignment.Right)
873 // tf |= eTextFormat.Right;
874 //else if (this.TextAlign == HorizontalAlignment.Center)
875 // tf |= eTextFormat.HorizontalCenter;
876 tf |= eTextFormat.EndEllipsis;
877 tf |= eTextFormat.WordBreak;
878 TextDrawing.DrawString(g, m_WatermarkText, (m_WatermarkFont == null ? this.Font : m_WatermarkFont),
879 m_WatermarkColor, GetWatermarkBounds(), tf);
880 }
881 }
882
883 private Rectangle GetWatermarkBounds()
884 {
885 if (this.DropDownStyle != ComboBoxStyle.DropDownList && m_TextWindowMsgHandler!=null)
886 {
887 WinApi.RECT rect = new WinApi.RECT();
888 WinApi.GetWindowRect(m_TextWindowMsgHandler.Handle, ref rect);
889 return new Rectangle(0, 0, rect.Width, rect.Height);
890 }
891
892 Rectangle r = new Rectangle(2, 0, this.Width - 2, this.Height);
893 r.Inflate(-2, -1);
894 int thumbSize = SystemInformation.HorizontalScrollBarThumbWidth;
895 r.Width -= thumbSize;
896 if (this.RightToLeft == RightToLeft.Yes)
897 r.X += thumbSize;
898
899 return r;
900 }
901
902 //private void CreateListBoxMsgHandler(IntPtr m_DropDownHandle)
903 //{
904 // DisposeListBoxMsgHandler();
905 // m_ListBoxMsgHandler = new ComboListBoxMsgHandler();
906 // m_ListBoxMsgHandler.AssignHandle(m_DropDownHandle);
907 //}
908
909 //private void DisposeListBoxMsgHandler()
910 //{
911 // if (m_ListBoxMsgHandler != null)
912 // {
913 // m_ListBoxMsgHandler.ReleaseHandle();
914 // m_ListBoxMsgHandler = null;
915 // }
916 //}
917
918 private void DrawArrow(Rectangle r, Graphics g, Brush b)
919 {
920 Point[] p=new Point[3];
921 p[0].X=r.Left+(r.Width-4)/2;
922 p[0].Y=r.Top+(r.Height-3)/2 + 1;
923 p[1].X=p[0].X+5;
924 p[1].Y=p[0].Y;
925 p[2].X=p[0].X+2;
926 p[2].Y=p[0].Y+3;
927 g.FillPolygon(b,p);
928 }
929
930 /*private void OnTimer(object sender, EventArgs e)
931 {
932 bool bRefresh=false;
933
934 if(m_DroppedDown && !this.DroppedDown)
935 {
936 m_DroppedDown=false;
937
938 if(DropDownChange!=null)
939 this.DropDownChange(this,false);
940
941 m_DropDownHandle=IntPtr.Zero;
942 bRefresh=true;
943 }
944
945 Point mousePos=this.PointToClient(Control.MousePosition);
946 if(!this.ClientRectangle.Contains(mousePos))
947 {
948 if(m_MouseOver && !m_DroppedDown)
949 {
950 m_MouseOver=false;
951 bRefresh=true;
952 }
953 }
954 else if(!m_MouseOver)
955 {
956 m_MouseOver=true;
957 bRefresh=true;
958 }
959
960 if(bRefresh)
961 this.Refresh();
962 }*/
963
964 protected override void OnVisibleChanged(EventArgs e)
965 {
966 base.OnVisibleChanged(e);
967 m_MouseOver=false;
968 if (this.DropDownStyle == ComboBoxStyle.DropDown && this.Items.Count > 0 && this.Items[0] is ComboItem && this.DisplayMember!="")
969 {
970 string s = this.DisplayMember;
971 this.DisplayMember = "";
972 this.DisplayMember = s;
973 }
974 if (this.IsHandleCreated && !this.IsDisposed)
975 {
976 UpdateBackColor();
977 }
978 }
979
980 private int m_SelectedIndexInternal = -1;
981
982 protected override void OnSelectedIndexChanged(EventArgs e)
983 {
984 m_SelectedIndexInternal = this.SelectedIndex;
985
986 if(!this.DroppedDownInternal)
987 {
988 if(DroppedDownInternal)
989 {
990 DroppedDownInternal=false;
991 }
992 if(!m_MouseOver)
993 this.Invalidate(true);
994 }
995 if (this.SelectedIndex == -1 && _WatermarkBehavior == eWatermarkBehavior.HideNonEmpty && m_WatermarkText.Length > 0 && this.Text == "")
996 this.Invalidate(true);
997 else if (this.DropDownStyle == ComboBoxStyle.DropDownList)
998 this.Invalidate();
999
1000 base.OnSelectedIndexChanged(e);
1001
1002 ExecuteCommand();
1003 }
1004
1005 protected override void OnTextChanged(EventArgs e)
1006 {
1007 if (this.SelectedIndex == -1 && _WatermarkBehavior == eWatermarkBehavior.HideNonEmpty && m_WatermarkText.Length > 0 && this.Text == "")
1008 this.Invalidate(true);
1009 base.OnTextChanged(e);
1010 }
1011
1012 /*protected override void OnEnabledChanged(EventArgs e)
1013 {
1014 base.OnEnabledChanged(e);
1015 SyncTimerEnabled();
1016 }*/
1017
1018 /*private void SyncTimerEnabled()
1019 {
1020 if(this.Visible)
1021 {
1022 if(!m_Timer.Enabled && this.Enabled && !this.DesignMode)
1023 m_Timer.Enabled=true;
1024 }
1025 else
1026 {
1027 if(m_Timer.Enabled)
1028 m_Timer.Enabled=false;
1029 }
1030 }*/
1031
1032 /// <summary>
1033 /// Clean up any resources being used.
1034 /// </summary>
1035 protected override void Dispose( bool disposing )
1036 {
1037 /*if(m_Timer!=null)
1038 {
1039 if(m_Timer.Enabled)
1040 m_Timer.Enabled=false;
1041 m_Timer.Dispose();
1042 m_Timer=null;
1043 }*/
1044 if (m_MouseOverTimer != null)
1045 {
1046 m_MouseOverTimer.Enabled = false;
1047 m_MouseOverTimer.Dispose();
1048 m_MouseOverTimer = null;
1049 }
1050 m_DisableInternalDrawing=true;
1051 if(m_TextWindowMsgHandler!=null)
1052 {
1053 m_TextWindowMsgHandler.ReleaseHandle();
1054 m_TextWindowMsgHandler=null;
1055 }
1056 base.Dispose( disposing );
1057 }
1058
1059 protected override void OnFontChanged(EventArgs e)
1060 {
1061 base.OnFontChanged(e);
1062 if(this.Disposing || this.IsDisposed)
1063 return;
1064 if(!m_DisableInternalDrawing && this.DrawMode==DrawMode.OwnerDrawFixed)
1065 {
1066 if(this.IsHandleCreated && this.Parent!=null && !this.Parent.IsDisposed)
1067 this.ItemHeight=this.FontHeight + 1;
1068 }
1069 }
1070
1071 internal int GetFontHeight()
1072 {
1073 return this.FontHeight;
1074 }
1075
1076 protected override void OnMeasureItem(MeasureItemEventArgs e)
1077 {
1078 base.OnMeasureItem(e);
1079 if(!m_DisableInternalDrawing)
1080 {
1081 if(this.DrawMode==DrawMode.OwnerDrawFixed)
1082 {
1083 e.ItemHeight = this.ItemHeight - 2;
1084 }
1085 else
1086 {
1087 object o=this.Items[e.Index];
1088 if(o is ComboItem)
1089 {
1090 if(((ComboItem)o).IsFontItem)
1091 MeasureFontItem(e);
1092 else
1093 {
1094 Size sz=GetComboItemSize(o as ComboItem);
1095 e.ItemHeight=sz.Height;
1096 e.ItemWidth=sz.Width;
1097 if (BarFunctions.IsOffice2007Style(m_Style))
1098 {
1099 e.ItemHeight += 6;
1100 e.ItemWidth += 6;
1101 }
1102 }
1103 }
1104 }
1105 }
1106 }
1107
1108 protected override void OnDrawItem(DrawItemEventArgs e)
1109 {
1110 base.OnDrawItem(e);
1111 InternalDrawItem(e);
1112 }
1113
1114 private void InternalDrawItem(DrawItemEventArgs e)
1115 {
1116 if(!m_DisableInternalDrawing && e.Index>=0)
1117 {
1118 object o=this.Items[e.Index];
1119 if(o is ComboItem)
1120 DrawComboItem(e);
1121 else
1122 DrawObjectItem(e);
1123 }
1124 }
1125
1126 protected virtual Size GetComboItemSize(ComboItem item)
1127 {
1128 Size size=Size.Empty;
1129 if(BarFunctions.IsHandleValid(this))
1130 {
1131 Graphics g=this.CreateGraphics();
1132 try
1133 {
1134 size=GetComboItemSize(item, g);
1135 }
1136 finally
1137 {
1138 g.Dispose();
1139 }
1140 }
1141 return size;
1142 }
1143
1144 protected virtual void DrawObjectItem(DrawItemEventArgs e)
1145 {
1146 Graphics g=e.Graphics;
1147 string text=GetItemText(this.Items[e.Index]);
1148 Color textColor = Color.Empty;
1149 Office2007ButtonItemStateColorTable ct = null;
1150
1151 if (BarFunctions.IsOffice2007Style(m_Style))
1152 {
1153 Office2007ButtonItemColorTable bct = ((Office2007Renderer)GlobalManager.Renderer).ColorTable.ButtonItemColors[0];
1154 if ((e.State & DrawItemState.Selected) != 0 || (e.State & DrawItemState.HotLight) != 0)
1155 ct = bct.MouseOver;
1156 else if ((e.State & DrawItemState.Disabled) != 0 || !this.Enabled)
1157 ct = bct.Disabled;
1158 else
1159 ct = bct.Default;
1160
1161 //if (ct != null)
1162 // textColor = ct.Text;
1163 if ((e.State & DrawItemState.Disabled) != 0 || !this.Enabled)
1164 textColor = _DisabledForeColor.IsEmpty ? SystemColors.ControlDark : _DisabledForeColor;
1165 else
1166 textColor = this.ForeColor;
1167
1168 if ((e.State & DrawItemState.HotLight) != 0 || (e.State & DrawItemState.Selected) != 0)
1169 {
1170 Rectangle r = e.Bounds;
1171 r.Width--;
1172 r.Height--;
1173 Office2007ButtonItemPainter.PaintBackground(g, ct, r, RoundRectangleShapeDescriptor.RoundCorner2);
1174 }
1175 else
1176 e.DrawBackground();
1177 }
1178 else
1179 {
1180 e.DrawBackground();
1181
1182 if ((e.State & DrawItemState.HotLight) != 0 || (e.State & DrawItemState.Selected) != 0)
1183 {
1184 g.FillRectangle(SystemBrushes.Highlight, e.Bounds);
1185 textColor = SystemColors.HighlightText;
1186 }
1187 else if ((e.State & DrawItemState.Disabled) != 0 || (e.State & DrawItemState.Grayed) != 0)
1188 textColor = _DisabledForeColor.IsEmpty ? SystemColors.ControlDark : _DisabledForeColor;
1189 else
1190 textColor = SystemColors.ControlText;
1191 }
1192
1193 if((e.State & DrawItemState.Focus)!=0)
1194 DrawFocusRectangle(e);
1195 Rectangle rText = e.Bounds;
1196
1197 if ((e.State & DrawItemState.ComboBoxEdit) == DrawItemState.ComboBoxEdit)
1198 {
1199 //rText.Inflate(-1, 0);
1200
1201 }
1202 else if (BarFunctions.IsOffice2007Style(m_Style))
1203 rText.Inflate(-3, 0);
1204 else
1205 rText.Inflate(-2, 0);
1206
1207 TextDrawing.DrawString(g,text,this.Font,textColor,rText,eTextFormat.Default | eTextFormat.NoClipping | eTextFormat.NoPrefix);
1208 }
1209
1210 private void DrawFocusRectangle(DrawItemEventArgs e)
1211 {
1212 if (_FocusCuesEnabled && ((e.State & DrawItemState.Focus) == DrawItemState.Focus) && ((e.State & DrawItemState.NoFocusRect) != DrawItemState.NoFocusRect))
1213 {
1214 Rectangle r = e.Bounds;
1215 //r.Width--;
1216 //r.Height--;
1217 ControlPaint.DrawFocusRectangle(e.Graphics, r, e.ForeColor, e.BackColor);
1218 }
1219 }
1220
1221 private Color _DisabledForeColor = Color.Empty;
1222 /// <summary>
1223 /// Gets or sets the text color for the text in combo-box when control Enabled property is set to false.
1224 /// Setting this property is effective only for DropDownList ComboBox style.
1225 /// </summary>
1226 [Category("Appearance"), Description("Indicates text color for the text in combo-box when control Enabled property is set to false. Setting this property is effective only for DropDownList ComboBox style.")]
1227 public Color DisabledForeColor
1228 {
1229 get { return _DisabledForeColor; }
1230 set
1231 {
1232 _DisabledForeColor = value;
1233 if (!this.Enabled)
1234 this.Invalidate();
1235 }
1236 }
1237 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
1238 public bool ShouldSerializeDisabledForeColor()
1239 {
1240 return !_DisabledForeColor.IsEmpty;
1241 }
1242 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
1243 public void ResetDisabledForeColor()
1244 {
1245 DisabledForeColor = Color.Empty;
1246 }
1247
1248 private Color _DisabledBackColor = Color.Empty;
1249 /// <summary>
1250 /// Gets or sets the control background color when control is disabled. Default value is an empty color which indicates that system background color is used when control is disabled.
1251 /// </summary>
1252 [Description("Indicates control background color when control is disabled"), Category("Appearance")]
1253 public Color DisabledBackColor
1254 {
1255 get { return _DisabledBackColor; }
1256 set
1257 {
1258 if (_DisabledBackColor != value)
1259 {
1260 _DisabledBackColor = value;
1261 if (!this.Enabled) this.Invalidate();
1262 }
1263 }
1264 }
1265 [EditorBrowsable(EditorBrowsableState.Never)]
1266 public bool ShouldSerializeDisabledBackColor()
1267 {
1268 return !_DisabledBackColor.IsEmpty;
1269 }
1270 [EditorBrowsable(EditorBrowsableState.Never)]
1271 public void ResetDisabledBackColor()
1272 {
1273 DisabledBackColor = Color.Empty;
1274 }
1275
1276 protected virtual void DrawComboItem(DrawItemEventArgs e)
1277 {
1278 ComboItem item=this.Items[e.Index] as ComboItem;
1279 if(item.IsFontItem)
1280 {
1281 this.DrawFontItem(e);
1282 return;
1283 }
1284
1285 Graphics g=e.Graphics;
1286 Image img=null;
1287 Color clr;
1288 Color textColor = item.ForeColor;
1289 if (textColor.IsEmpty || (e.State & DrawItemState.Selected) != 0 || (e.State & DrawItemState.HotLight) != 0)
1290 textColor = this.ForeColor;
1291
1292 if (item.ImageIndex >= 0 && m_ImageList != null && m_ImageList.Images.Count > item.ImageIndex)
1293 img = m_ImageList.Images[item.ImageIndex];
1294 else if (item.Image != null)
1295 img = item.Image;
1296
1297 Office2007ButtonItemStateColorTable ct = null;
1298 if (BarFunctions.IsOffice2007Style(m_Style))
1299 {
1300 Office2007ButtonItemColorTable bct = ((Office2007Renderer)GlobalManager.Renderer).ColorTable.ButtonItemColors[0];
1301 if ((e.State & DrawItemState.Selected) != 0 || (e.State & DrawItemState.HotLight) != 0)
1302 ct = bct.MouseOver;
1303 else if ((e.State & DrawItemState.Disabled) != 0 || !this.Enabled)
1304 ct = bct.Disabled;
1305 else
1306 ct = bct.Default;
1307 //if (ct == null)
1308 if (!this.Enabled)
1309 textColor = _DisabledForeColor.IsEmpty ? SystemColors.ControlDark : _DisabledForeColor;
1310 //else
1311 // textColor = SystemColors.ControlText;
1312 //else
1313 // textColor = ct.Text;
1314 }
1315
1316 int contWidth=this.DropDownWidth;
1317 if(item.ImagePosition!=HorizontalAlignment.Center && img!=null)
1318 {
1319 contWidth-=img.Width;
1320 if(contWidth<=0)
1321 contWidth=this.DropDownWidth;
1322 }
1323
1324 // Back Color
1325 if((e.State & DrawItemState.Selected)!=0 || (e.State & DrawItemState.HotLight)!=0)
1326 {
1327 if (BarFunctions.IsOffice2007Style(m_Style))
1328 Office2007ButtonItemPainter.PaintBackground(g, ct, e.Bounds, RoundRectangleShapeDescriptor.RoundCorner2);
1329 else
1330 e.DrawBackground();
1331 DrawFocusRectangle(e);
1332 }
1333 else
1334 {
1335 clr=item.BackColor;
1336 if(item.BackColor.IsEmpty)
1337 clr=e.BackColor;
1338 g.FillRectangle(new SolidBrush(clr),e.Bounds);
1339 }
1340
1341 // Draw Image
1342 Rectangle rImg=e.Bounds;
1343 Rectangle rText=e.Bounds;
1344 //if (e.State != DrawItemState.ComboBoxEdit)
1345 {
1346 if ((e.State & DrawItemState.ComboBoxEdit) == DrawItemState.ComboBoxEdit)
1347 {
1348 if (img != null)
1349 {
1350 rText.X += 3;
1351 rText.Width -= 3;
1352 }
1353 //rText.Inflate(-1, 0);
1354 //rText.Y++;
1355 //rText.Height--;
1356 }
1357 else if (BarFunctions.IsOffice2007Style(m_Style))
1358 rText.Inflate(-3, 0);
1359 else
1360 rText.Inflate(-2, 0);
1361 }
1362 if(img!=null)
1363 {
1364 rImg.Width=img.Width;
1365 rImg.Height=img.Height;
1366 if(item.ImagePosition==HorizontalAlignment.Left)
1367 {
1368 // Left
1369 if(e.Bounds.Height>img.Height)
1370 rImg.Y+=(e.Bounds.Height-img.Height)/2;
1371 rText.Width-=rImg.Width;
1372 rText.X+=rImg.Width;
1373 }
1374 else if(item.ImagePosition==HorizontalAlignment.Right)
1375 {
1376 // Right
1377 if(e.Bounds.Height>img.Height)
1378 rImg.Y+=(e.Bounds.Height-img.Height)/2;
1379 rImg.X=e.Bounds.Right-img.Width;
1380 rText.Width-=rImg.Width;
1381 }
1382 else
1383 {
1384 // Center
1385 rImg.X+=(e.Bounds.Width-img.Width)/2;
1386 rText.Y=rImg.Bottom;
1387 }
1388 g.DrawImage(img,rImg);
1389 }
1390
1391 // Draw Text
1392 if(item.Text!="")
1393 {
1394 System.Drawing.Font f=e.Font;
1395 bool bDisposeFont=false;
1396 try
1397 {
1398 if(item.FontName!="")
1399 {
1400 f=new Font(item.FontName,item.FontSize,item.FontStyle);
1401 bDisposeFont=true;
1402 }
1403 else if(item.FontStyle!=f.Style)
1404 {
1405 f = new Font(f, item.FontStyle);
1406 bDisposeFont=true;
1407 }
1408 }
1409 catch
1410 {
1411 f=e.Font;
1412 if(f==null)
1413 {
1414 f=System.Windows.Forms.SystemInformation.MenuFont.Clone() as Font;
1415 bDisposeFont=true;
1416 }
1417 }
1418
1419 eTextFormat format = eTextFormat.Default | eTextFormat.NoClipping | eTextFormat.NoPrefix;
1420 if (item.TextFormat.Alignment == StringAlignment.Center)
1421 format = eTextFormat.HorizontalCenter;
1422 else if (item.TextFormat.Alignment == StringAlignment.Far)
1423 format = eTextFormat.Right;
1424 if (item.TextLineAlignment == StringAlignment.Center)
1425 format |= eTextFormat.VerticalCenter;
1426 else if (item.TextLineAlignment == StringAlignment.Far)
1427 format |= eTextFormat.Bottom;
1428 TextDrawing.DrawString(g, item.Text, f, textColor, rText, format);
1429
1430 if(bDisposeFont)
1431 f.Dispose();
1432 }
1433
1434 }
1435
1436 protected virtual Size GetComboItemSize(ComboItem item, Graphics g)
1437 {
1438 if(this.DrawMode==DrawMode.OwnerDrawFixed)
1439 return new Size(this.DropDownWidth,this.ItemHeight);
1440
1441 Size sz=Size.Empty;
1442 Size textSize=Size.Empty;
1443 Image img=null;
1444 if(item.ImageIndex>=0)
1445 img=m_ImageList.Images[item.ImageIndex];
1446 else if(item.Image!=null)
1447 img=item.Image;
1448
1449 int contWidth=this.DropDownWidth;
1450 if(item.ImagePosition!=HorizontalAlignment.Center && img!=null)
1451 {
1452 contWidth-=img.Width;
1453 if(contWidth<=0)
1454 contWidth=this.DropDownWidth;
1455 }
1456
1457 Font font=this.Font;
1458 if(item.FontName!="")
1459 {
1460 try
1461 {
1462 font=new Font(item.FontName,item.FontSize,item.FontStyle);
1463 }
1464 catch
1465 {
1466 font=this.Font;
1467 }
1468 }
1469
1470 eTextFormat format = eTextFormat.Default;
1471 if (item.TextFormat.Alignment == StringAlignment.Center)
1472 format = eTextFormat.HorizontalCenter;
1473 else if (item.TextFormat.Alignment == StringAlignment.Far)
1474 format = eTextFormat.Right;
1475 if (item.TextLineAlignment == StringAlignment.Center)
1476 format |= eTextFormat.VerticalCenter;
1477 else if (item.TextLineAlignment == StringAlignment.Far)
1478 format |= eTextFormat.Bottom;
1479
1480 textSize=TextDrawing.MeasureString(g,item.Text,font,this.DropDownWidth,format);
1481 textSize.Width += 2;
1482 sz.Width=textSize.Width;
1483 sz.Height=textSize.Height;
1484 if(sz.Width<this.DropDownWidth)
1485 sz.Width=this.DropDownWidth;
1486
1487 if(item.ImagePosition==HorizontalAlignment.Center && img!=null)
1488 sz.Height+=img.Height;
1489 else if(img!=null && img.Height>sz.Height)
1490 sz.Height=img.Height;
1491
1492 return sz;
1493 }
1494
1495 /// <summary>
1496 /// Loads all fonts available on system into the combo box.
1497 /// </summary>
1498 public void LoadFonts()
1499 {
1500 this.Items.Clear();
1501
1502 System.Drawing.Text.InstalledFontCollection colInstalledFonts = new System.Drawing.Text.InstalledFontCollection();
1503 FontFamily[] aFamilies = colInstalledFonts.Families;
1504 foreach(FontFamily ff in aFamilies)
1505 {
1506 ComboItem item=new ComboItem();
1507 item.IsFontItem=true;
1508 item.FontName=ff.GetName(0);
1509 item.FontSize=this.Font.Size;
1510 item.Text=ff.GetName(0);
1511 this.Items.Add(item);
1512 }
1513 this.DropDownWidth=this.Width*2;
1514 }
1515
1516 private void DrawFontItem(DrawItemEventArgs e)
1517 {
1518 FontStyle[] styles=new FontStyle[4]{FontStyle.Regular,FontStyle.Bold,FontStyle.Italic,FontStyle.Bold | FontStyle.Italic};
1519 if (!BarFunctions.IsOffice2007Style(m_Style))
1520 e.DrawBackground();
1521 string fontname = this.Items[e.Index].ToString();
1522 FontFamily family = new FontFamily(fontname);
1523
1524 int iWidth = this.DropDownWidth/2-4;
1525 if(iWidth<=0)
1526 iWidth=this.Width;
1527 foreach(FontStyle style in styles)
1528 {
1529 if(family.IsStyleAvailable(style))
1530 {
1531 eTextFormat format = eTextFormat.Default | eTextFormat.NoPrefix;
1532 Color textColor = (e.State & DrawItemState.Selected) != 0 ? SystemColors.HighlightText : SystemColors.ControlText;
1533
1534 Office2007ButtonItemStateColorTable ct = null;
1535 if (BarFunctions.IsOffice2007Style(m_Style))
1536 {
1537 Office2007ButtonItemColorTable bct = ((Office2007Renderer)GlobalManager.Renderer).ColorTable.ButtonItemColors[0];
1538 if ((e.State & DrawItemState.Selected) != 0 || (e.State & DrawItemState.HotLight) != 0)
1539 ct = bct.MouseOver;
1540 else if ((e.State & DrawItemState.Disabled) != 0 || !this.Enabled)
1541 ct = bct.Disabled;
1542 else
1543 ct = bct.Default;
1544 //if (ct == null)
1545 if (!this.Enabled)
1546 textColor = _DisabledForeColor.IsEmpty ? SystemColors.ControlDark : _DisabledForeColor;
1547 else
1548 textColor = SystemColors.ControlText;
1549
1550 if ((e.State & DrawItemState.Selected) != 0 || (e.State & DrawItemState.HotLight) != 0)
1551 Office2007ButtonItemPainter.PaintBackground(e.Graphics, ct, e.Bounds, RoundRectangleShapeDescriptor.RoundCorner2);
1552 else
1553 {
1554 e.DrawBackground();
1555 }
1556 }
1557
1558 if ((e.State & DrawItemState.ComboBoxEdit) == DrawItemState.ComboBoxEdit)
1559 {
1560 Rectangle rt = e.Bounds;
1561 //rt.Y += 1;
1562 //rt.Height -= 1;
1563 TextDrawing.DrawString(e.Graphics, fontname, this.Font, textColor, rt, format);
1564 }
1565 else
1566 {
1567 Size szFont = TextDrawing.MeasureString(e.Graphics, fontname, this.Font);
1568 int iDiff = (int)((e.Bounds.Height - szFont.Height) / 2);
1569 Rectangle rFontName = new Rectangle(e.Bounds.X, e.Bounds.Y + iDiff,
1570 ((e.State & DrawItemState.Disabled)==DrawItemState.Disabled?e.Bounds.Width: Math.Max(e.Bounds.Width - 100, 32)), e.Bounds.Height - iDiff);
1571 TextDrawing.DrawString(e.Graphics, fontname, this.Font, textColor, rFontName, format);
1572 Rectangle rRemainder = new Rectangle(e.Bounds.X + iWidth + 4, e.Bounds.Y, e.Bounds.Width + 100, e.Bounds.Height);
1573 Font f = new Font(family, (float)e.Bounds.Height - 8, style);
1574 TextDrawing.DrawString(e.Graphics, fontname, f, textColor, rRemainder, format);
1575 }
1576 break;
1577 }
1578 }
1579 }
1580
1581 private void MeasureFontItem(MeasureItemEventArgs e)
1582 {
1583 e.ItemHeight = 18;
1584 }
1585
1586 #if !FRAMEWORK20
1587 /// <summary>
1588 /// Specifies the height of the drop-down portion of combo box.
1589 /// </summary>
1590 [Browsable(true),Category("Behavior"),Description("The height, in pixels, of drop down box in a combo box."), DefaultValue(0)]
1591 public int DropDownHeight
1592 {
1593 get
1594 {
1595 return m_DropDownHeight;
1596 }
1597 set
1598 {
1599 m_DropDownHeight=value;
1600 }
1601 }
1602 #endif
1603
1604 /// <summary>
1605 /// Releases the focus from combo box. The control that last had focus will receive focus back when this method is called.
1606 /// </summary>
1607 public void ReleaseFocus()
1608 {
1609 if(this.Focused && m_LastFocusWindow!=IntPtr.Zero)
1610 {
1611 Control ctrl=Control.FromChildHandle(new System.IntPtr(m_LastFocusWindow.ToInt32()));
1612 if(ctrl!=this)
1613 {
1614 if(ctrl!=null)
1615 ctrl.Focus();
1616 else
1617 {
1618 NativeFunctions.SetFocus(m_LastFocusWindow.ToInt32());
1619 }
1620 this.OnLostFocus(new System.EventArgs());
1621 }
1622 m_LastFocusWindow=IntPtr.Zero;
1623
1624 }
1625 }
1626
1627 protected override bool ProcessCmdKey(ref Message msg,Keys keyData)
1628 {
1629 if(keyData==Keys.Enter && m_PreventEnterBeep)
1630 {
1631 this.OnKeyPress(new KeyPressEventArgs((char)13));
1632 return true;
1633 }
1634 return base.ProcessCmdKey(ref msg, keyData);
1635 }
1636
1637 protected override void OnKeyDown(KeyEventArgs e)
1638 {
1639 if (!IsStandalone)
1640 {
1641 if (e.KeyCode == Keys.Enter)
1642 ReleaseFocus();
1643 else if (e.KeyCode == Keys.Escape)
1644 {
1645 ReleaseFocus();
1646 }
1647 }
1648
1649 base.OnKeyDown(e);
1650 }
1651
1652 /// <summary>
1653 /// Gets the window handle that the drop down list is bound to.
1654 /// </summary>
1655 [Browsable(false)]
1656 public IntPtr DropDownHandle
1657 {
1658 get
1659 {
1660 return m_DropDownHandle;
1661 }
1662 }
1663
1664 internal bool MouseOver
1665 {
1666 get
1667 {
1668 return m_MouseOver;
1669 }
1670 set
1671 {
1672 if(m_MouseOver!=value)
1673 {
1674 m_MouseOver=value;
1675 this.Invalidate(true);
1676 }
1677 }
1678 }
1679
1680 [System.ComponentModel.Editor(typeof(Endv.Editors.ComboItemsEditor), typeof(System.Drawing.Design.UITypeEditor)), Localizable(true)]
1681 public new ComboBox.ObjectCollection Items
1682 {
1683 get
1684 {
1685 return base.Items;
1686 }
1687 }
1688
1689 protected override void OnEnabledChanged(EventArgs e)
1690 {
1691 UpdateBackColor();
1692 base.OnEnabledChanged(e);
1693 }
1694
1695 private void UpdateBackColor()
1696 {
1697 if (!m_UseCustomBackColor)
1698 {
1699 Color c = GetComboColors().Background;
1700 if (this.BackColor != c)
1701 this.BackColor = c;
1702 }
1703 }
1704
1705 protected override void OnMouseEnter(EventArgs e)
1706 {
1707 if(!m_MouseOver)
1708 {
1709 m_MouseOver=true;
1710 UpdateBackColor();
1711 this.Invalidate(true);
1712 }
1713 SetMouseOverTimerEnabled(true);
1714 base.OnMouseEnter(e);
1715 }
1716 protected override void OnMouseLeave(EventArgs e)
1717 {
1718 //if(this.DroppedDown)
1719 //{
1720 // m_MouseOver=false;
1721 //}
1722 //else if(this.DropDownStyle!=ComboBoxStyle.DropDownList && m_MouseOver)
1723 //{
1724 // // Get the mouse position
1725 // Point p=this.PointToClient(Control.MousePosition);
1726 // if(!this.ClientRectangle.Contains(p))
1727 // {
1728 // m_MouseOver=false;
1729 // }
1730 //}
1731 //else if(m_MouseOver)
1732 //{
1733 // m_MouseOver=false;
1734 //}
1735 SetMouseOverTimerEnabled(true);
1736 //Color c = GetComboColors().Background;
1737 //if (this.BackColor != c)
1738 // this.BackColor = c;
1739 //this.Refresh();
1740 base.OnMouseLeave(e);
1741 }
1742
1743 protected override void OnMouseMove(MouseEventArgs e)
1744 {
1745 base.OnMouseMove(e);
1746 if (!m_MouseOver)
1747 {
1748 //if (!m_Focused)
1749 {
1750 m_MouseOver = true;
1751 this.Invalidate();
1752 SetMouseOverTimerEnabled(true);
1753 }
1754 }
1755 }
1756
1757 private void SetMouseOverTimerEnabled(bool value)
1758 {
1759 if (m_MouseOverTimer != null) m_MouseOverTimer.Enabled = value;
1760 }
1761
1762 private void SetupTextBoxMessageHandler()
1763 {
1764 #if FRAMEWORK20
1765 if (this.DropDownStyle != ComboBoxStyle.DropDownList && this.AutoCompleteMode == AutoCompleteMode.None)
1766 #else
1767 if (this.DropDownStyle != ComboBoxStyle.DropDownList)
1768 #endif
1769 {
1770 if (m_TextWindowMsgHandler == null)
1771 {
1772 // Get hold of the text box
1773 IntPtr hwnd = GetWindow(this.Handle, GW_CHILD);
1774 // Subclass so we can track messages
1775 if (hwnd != IntPtr.Zero)
1776 {
1777 m_TextWindowMsgHandler = new ComboTextBoxMsgHandler();
1778 m_TextWindowMsgHandler.MouseLeave += new EventHandler(this.TextBoxMouseLeave);
1779 m_TextWindowMsgHandler.Paint += new PaintEventHandler(TextBoxPaint);
1780 m_TextWindowMsgHandler.AssignHandle(hwnd);
1781 }
1782 }
1783 }
1784 else if (m_TextWindowMsgHandler != null)
1785 {
1786 m_TextWindowMsgHandler.ReleaseHandle();
1787 m_TextWindowMsgHandler = null;
1788 }
1789 }
1790
1791 protected override void OnDropDownStyleChanged(EventArgs e)
1792 {
1793 SetupTextBoxMessageHandler();
1794 base.OnDropDownStyleChanged(e);
1795 }
1796
1797 private void TextBoxPaint(object sender, PaintEventArgs e)
1798 {
1799 if (ShouldDrawWatermark())
1800 DrawWatermark(e.Graphics);
1801 }
1802
1803 private void TextBoxMouseLeave(object sender, EventArgs e)
1804 {
1805 if(!m_MouseOver)
1806 return;
1807 SetMouseOverTimerEnabled(true);
1808 }
1809
1810 /// <summary>
1811 /// Gets or sets whether FocusHighlightColor is used as background color to highlight text box when it has input focus. Default value is false.
1812 /// </summary>
1813 [DefaultValue(false), Browsable(true), Category("Appearance"), Description("Indicates whether FocusHighlightColor is used as background color to highlight text box when it has input focus.")]
1814 public virtual bool FocusHighlightEnabled
1815 {
1816 get { return _FocusHighlightEnabled; }
1817 set
1818 {
1819 if (_FocusHighlightEnabled != value)
1820 {
1821 _FocusHighlightEnabled = value;
1822 if (this.Focused)
1823 this.Invalidate();
1824 }
1825 }
1826 }
1827
1828 /// <summary>
1829 /// Gets or sets the color used as background color to highlight text box when it has input focus and focus highlight is enabled.
1830 /// </summary>
1831 [Browsable(true), Category("Appearance"), Description("Indicates color used as background color to highlight text box when it has input focus and focus highlight is enabled.")]
1832 public virtual Color FocusHighlightColor
1833 {
1834 get { return _FocusHighlightColor; }
1835 set
1836 {
1837 if (_FocusHighlightColor != value)
1838 {
1839 _FocusHighlightColor = value;
1840 if (this.Focused)
1841 this.Invalidate();
1842 }
1843 }
1844 }
1845
1846 [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
1847 public bool ShouldSerializeFocusHighlightColor()
1848 {
1849 return !_FocusHighlightColor.Equals(_DefaultHighlightColor);
1850 }
1851
1852 [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
1853 public void ResetFocusHighlightColor()
1854 {
1855 FocusHighlightColor = _DefaultHighlightColor;
1856 }
1857
1858 #region ICommandSource Members
1859 protected virtual void ExecuteCommand()
1860 {
1861 if (_Command == null) return;
1862 CommandManager.ExecuteCommand(this);
1863 }
1864
1865 /// <summary>
1866 /// Gets or sets the command assigned to the item. Default value is null.
1867 /// <remarks>Note that if this property is set to null Enabled property will be set to false automatically to disable the item.</remarks>
1868 /// </summary>
1869 [DefaultValue(null), Category("Commands"), Description("Indicates the command assigned to the item.")]
1870 public Command Command
1871 {
1872 get { return (Command)((ICommandSource)this).Command; }
1873 set
1874 {
1875 ((ICommandSource)this).Command = value;
1876 }
1877 }
1878
1879 private ICommand _Command = null;
1880 //[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
1881 ICommand ICommandSource.Command
1882 {
1883 get
1884 {
1885 return _Command;
1886 }
1887 set
1888 {
1889 bool changed = false;
1890 if (_Command != value)
1891 changed = true;
1892
1893 if (_Command != null)
1894 CommandManager.UnRegisterCommandSource(this, _Command);
1895 _Command = value;
1896 if (value != null)
1897 CommandManager.RegisterCommand(this, value);
1898 if (changed)
1899 OnCommandChanged();
1900 }
1901 }
1902
1903 /// <summary>
1904 /// Called when Command property value changes.
1905 /// </summary>
1906 protected virtual void OnCommandChanged()
1907 {
1908 }
1909
1910 private object _CommandParameter = null;
1911 /// <summary>
1912 /// Gets or sets user defined data value that can be passed to the command when it is executed.
1913 /// </summary>
1914 [Browsable(true), DefaultValue(null), Category("Commands"), Description("Indicates user defined data value that can be passed to the command when it is executed."), System.ComponentModel.TypeConverter(typeof(System.ComponentModel.StringConverter)), System.ComponentModel.Localizable(true)]
1915 public object CommandParameter
1916 {
1917 get
1918 {
1919 return _CommandParameter;
1920 }
1921 set
1922 {
1923 _CommandParameter = value;
1924 }
1925 }
1926
1927 #endregion
1928
1929
1930 private class ComboTextBoxMsgHandler:NativeWindow
1931 {
1932 private const int WM_MOUSELEAVE=0x02A3;
1933 private const int WM_MOUSEMOVE=0x0200;
1934 private const int TME_LEAVE=0x02;
1935 [DllImport("user32",SetLastError=true, CharSet=CharSet.Auto)]
1936 private static extern bool TrackMouseEvent(ref TRACKMOUSEEVENT lpEventTrack);
1937
1938 public event EventHandler MouseLeave;
1939 public event PaintEventHandler Paint;
1940
1941 private struct TRACKMOUSEEVENT
1942 {
1943 public int cbSize;
1944 public int dwFlags;
1945 public int hwndTrack;
1946 public int dwHoverTime;
1947 }
1948
1949 private bool m_MouseTracking=false;
1950
1951 protected override void WndProc(ref Message m)
1952 {
1953 const int WM_PAINT = 0xF;
1954 if(m.Msg==WM_MOUSEMOVE && !m_MouseTracking)
1955 {
1956 m_MouseTracking = true;
1957 TRACKMOUSEEVENT tme = new TRACKMOUSEEVENT();
1958 tme.dwFlags = TME_LEAVE;
1959 tme.cbSize = Marshal.SizeOf(tme);
1960 tme.hwndTrack = this.Handle.ToInt32();
1961 tme.dwHoverTime = 0;
1962 m_MouseTracking = TrackMouseEvent(ref tme);
1963 }
1964 else if(m.Msg==WM_MOUSELEAVE)
1965 {
1966 if(MouseLeave!=null)
1967 MouseLeave(this,new EventArgs());
1968 m_MouseTracking=false;
1969 }
1970 else if (m.Msg == WM_PAINT)
1971 {
1972 base.WndProc(ref m);
1973 if (Paint != null)
1974 {
1975 using (Graphics g = Graphics.FromHwnd(m.HWnd))
1976 Paint(this, new PaintEventArgs(g, Rectangle.Empty));
1977 }
1978 return;
1979 }
1980 base.WndProc(ref m);
1981 }
1982 }
1983 }
1984 }