DotNetBar ComboBoxEx
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 }