namespace DevComponents.DotNetBar { using System; using System.Windows.Forms; using System.Drawing; using System.Drawing.Text; using System.Drawing.Drawing2D; /// /// Summary description for Tooltip. /// [System.ComponentModel.ToolboxItem(false),System.ComponentModel.DesignTimeVisible(false)] public class ToolTip : System.Windows.Forms.Control { const long WS_POPUP=0x80000000L; const long WS_CLIPSIBLINGS=0x04000000L; const long WS_CLIPCHILDREN=0x02000000L; const long WS_EX_TOOLWINDOW=0x00000080L; const long WS_EX_TOPMOST=0x00000008L; // When set to true tooltip will be shown Immediately without delay //static bool bShowToolTip; private string m_ToolTip; private TextMarkup.BodyElement m_TextMarkup = null; private eDotNetBarStyle m_Style = eDotNetBarStyle.Office2003; private PopupShadow m_DropShadow=null; private bool m_AntiAlias = false; /// /// Gets or sets the rectangle of the control or item tooltip is displayed for. /// public Rectangle ReferenceRectangle = Rectangle.Empty; public ToolTip() { m_ToolTip=""; this.SetStyle(ControlStyles.Selectable,false); this.SetStyle(ControlStyles.AllPaintingInWmPaint,true); this.SetStyle(ControlStyles.Opaque,true); this.SetStyle(ControlStyles.ResizeRedraw,true); this.Font = SystemFonts.DefaultFont; // System.Windows.Forms.SystemInformation.MenuFont.Clone() as Font; this.BackColor=SystemColors.Control; this.ForeColor=SystemColors.ControlText; } public new string Text { get { return m_ToolTip; } set { m_ToolTip=value; if (MarkupEnabled && TextMarkup.MarkupParser.IsMarkup(ref m_ToolTip)) m_TextMarkup = TextMarkup.MarkupParser.Parse(m_ToolTip); else m_TextMarkup = null; if (m_TextMarkup != null) AntiAlias = true; if (_TooltipShown) { UpdateSize(); } } } private static bool _MarkupEnabled = true; /// /// Gets or sets whether text-markup is enabled for the tooltips. /// public static bool MarkupEnabled { get { return _MarkupEnabled; } set { _MarkupEnabled = value; } } public bool AntiAlias { get { return m_AntiAlias; } set { m_AntiAlias = value; } } private int _ColorDepth = -1; protected override void OnPaint(PaintEventArgs e) { // Get the Color of ToolTip text Color textColor = SystemColors.InfoText; Color backColor = SystemColors.Info; Color backColor2=Color.Empty; Color borderColor = ColorScheme.GetColor("767676"); if (_ColorDepth == -1) { _ColorDepth = Screen.FromControl(this).BitsPerPixel; } if (_ColorDepth < 8) { backColor = Color.White; textColor = Color.Black; } else { if (StyleManager.IsMetro(m_Style)) { DevComponents.DotNetBar.Metro.ColorTables.MetroColorTable metroColors = DevComponents.DotNetBar.Metro.Rendering.MetroRender.GetColorTable(); backColor = metroColors.CanvasColor; textColor = metroColors.ForeColor; } else if (BarFunctions.IsOffice2007Style(m_Style) && this.BackColor == SystemColors.Control) { backColor = ColorScheme.GetColor("FFFFFF"); backColor2 = ColorScheme.GetColor("E4E4F0"); textColor = ColorScheme.GetColor("4C4C4C"); } else { textColor = GetToolTipColor(); if (this.BackColor != SystemColors.Control) backColor = this.BackColor; } } Graphics g=e.Graphics; Rectangle r=this.ClientRectangle; if (m_AntiAlias) { g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint; g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; } SmoothingMode sm = g.SmoothingMode; g.SmoothingMode = SmoothingMode.None; if (BarFunctions.IsOffice2007Style(m_Style)) { DisplayHelp.DrawRectangle(g, borderColor, r); } else { System.Windows.Forms.ControlPaint.DrawBorder3D(g, r, System.Windows.Forms.Border3DStyle.Raised, System.Windows.Forms.Border3DSide.All); } r.Inflate(-1,-1); if (backColor2.IsEmpty) DisplayHelp.FillRectangle(g, r, backColor); else DisplayHelp.FillRectangle(g, r, backColor, backColor2); r.Offset(1,0); g.SmoothingMode = sm; if (m_TextMarkup == null) TextDrawing.DrawString(g, GetDrawText(), this.Font, textColor, r, GetStringFormat()); else { TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, this.Font, textColor, (this.RightToLeft == RightToLeft.Yes), e.ClipRectangle, true); m_TextMarkup.Bounds = new Rectangle(r.Location, m_TextMarkup.Bounds.Size); m_TextMarkup.Render(d); } } private void UpdateSize() { // Calculate Size of the window using (Graphics g = this.CreateGraphics()) { if (m_AntiAlias) { g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint; g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; } Size size = GetTooltipSize(g); this.Size = size; g.SmoothingMode = SmoothingMode.Default; g.TextRenderingHint = TextRenderingHint.SystemDefault; } if (!_FixedLocation.IsEmpty) this.Location = _FixedLocation; this.Invalidate(); Rectangle r = this.Bounds; if (m_DropShadow != null) { NativeFunctions.SetWindowPos(m_DropShadow.Handle, this.Handle, r.Left + 5, r.Top + 5, r.Width - 2, r.Height - 2, NativeFunctions.SWP_SHOWWINDOW | NativeFunctions.SWP_NOACTIVATE); m_DropShadow.UpdateShadow(); } } private bool _TooltipShown = false; private Size GetTooltipSize(Graphics g) { Size sz = Size.Empty; if (m_TextMarkup == null) sz = TextDrawing.MeasureString(g, GetDrawText(), this.Font, Screen.PrimaryScreen.WorkingArea.Size, GetStringFormat()); else { TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, this.Font, SystemColors.Control, (this.RightToLeft == RightToLeft.Yes)); m_TextMarkup.Measure(Screen.PrimaryScreen.WorkingArea.Size, d); sz = m_TextMarkup.Bounds.Size; m_TextMarkup.Arrange(new Rectangle(Point.Empty, sz), d); } sz.Width += Dpi.Width4; sz.Height += Dpi.Height4; return sz; } public void ShowToolTip() { if (!this.IsHandleCreated) this.CreateControl(); // Calculate Size of the window Graphics g=this.CreateGraphics(); if (m_AntiAlias) { g.TextRenderingHint = DisplayHelp.AntiAliasTextRenderingHint; g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; } Size sz = Size.Empty; try { g.PageUnit = GraphicsUnit.Pixel; sz = GetTooltipSize(g); //if (m_TextMarkup == null) // sz = TextDrawing.MeasureString(g, GetDrawText(), this.Font, Screen.PrimaryScreen.WorkingArea.Size, GetStringFormat()); //else //{ // TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, this.Font, SystemColors.Control, (this.RightToLeft == RightToLeft.Yes)); // m_TextMarkup.Measure(Screen.PrimaryScreen.WorkingArea.Size, d); // sz = m_TextMarkup.Bounds.Size; // m_TextMarkup.Arrange(new Rectangle(Point.Empty, sz), d); //} } finally { g.SmoothingMode = SmoothingMode.Default; g.TextRenderingHint = TextRenderingHint.SystemDefault; g.Dispose(); } g=null; Point mousePosition=System.Windows.Forms.Control.MousePosition; Rectangle r=new Rectangle(System.Windows.Forms.Control.MousePosition.X,System.Windows.Forms.Control.MousePosition.Y,(int)sz.Width,(int)sz.Height); //r.Inflate(2,2); r.Offset(12,24); ScreenInformation screen=BarFunctions.ScreenFromPoint(mousePosition); if(screen!=null) { System.Drawing.Size layoutArea=screen.WorkingArea.Size; layoutArea.Width-=(int)(layoutArea.Width*.2f); if (r.Right > screen.WorkingArea.Right) { r.X = r.Left - (r.Right - screen.WorkingArea.Right); } if (r.Bottom > screen.Bounds.Bottom) { if (ReferenceRectangle.IsEmpty) r.Y = mousePosition.Y - r.Height; else { r.Y = ReferenceRectangle.Y - r.Height - 1; } } if(r.Contains(System.Windows.Forms.Control.MousePosition.X,System.Windows.Forms.Control.MousePosition.Y)) { // We have to move it out of mouse position if (r.Height + System.Windows.Forms.Control.MousePosition.Y + 1 <= screen.WorkingArea.Height && (ReferenceRectangle.IsEmpty || !ReferenceRectangle.IntersectsWith(new Rectangle(r.X, System.Windows.Forms.Control.MousePosition.Y + 1, r.Width, r.Height)))) r.Y=System.Windows.Forms.Control.MousePosition.Y+1; else r.Y=System.Windows.Forms.Control.MousePosition.Y-r.Height-1; } } if (!_FixedLocation.IsEmpty) r.Location = _FixedLocation; this.Location=r.Location; this.ClientSize=r.Size; if(NativeFunctions.ShowDropShadow && this.ShowDropShadow) { if(m_DropShadow==null) { m_DropShadow=new PopupShadow(NativeFunctions.AlphaBlendingSupported); m_DropShadow.CreateControl(); } //m_DropShadow.Location=new Point(r.Left+4,r.Top+4); //m_DropShadow.Size=r.Size; // TODO: Bug Cannot set size and location correctly using the Size and Location because Form caption is hidden m_DropShadow.Hide(); } NativeFunctions.SetWindowPos(this.Handle,new IntPtr(NativeFunctions.HWND_TOP),0,0,0,0,NativeFunctions.SWP_SHOWWINDOW | NativeFunctions.SWP_NOSIZE | NativeFunctions.SWP_NOACTIVATE | NativeFunctions.SWP_NOMOVE); if(m_DropShadow!=null) { NativeFunctions.SetWindowPos(m_DropShadow.Handle,this.Handle,r.Left+5,r.Top+5,r.Width-2,r.Height-2,NativeFunctions.SWP_SHOWWINDOW | NativeFunctions.SWP_NOACTIVATE); m_DropShadow.UpdateShadow(); } _TooltipShown = true; } private string GetDrawText() { string s = m_ToolTip.Replace(@"\\n", "{spec_nl}"); s = s.Replace(@"\n", Environment.NewLine); return s.Replace("{spec_nl}",@"\n"); } private eTextFormat GetStringFormat() { eTextFormat format = eTextFormat.Default | eTextFormat.WordBreak | eTextFormat.VerticalCenter; return format; } private Color GetToolTipColor() { if(this.ForeColor!=SystemColors.ControlText) return this.ForeColor; Color clrRet=SystemColors.WindowText; try { Microsoft.Win32.RegistryKey objReg=Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Control Panel\\Colors\\",false); string sColor=objReg.GetValue("InfoText").ToString(); objReg.Close(); objReg=null; if(sColor==null || sColor=="") return clrRet; Char [] separator = {' '}; string[] sArr=sColor.Split(separator,3); if(sArr.GetUpperBound(0)==2) clrRet=Color.FromArgb(System.Convert.ToInt16(sArr[0]),System.Convert.ToInt16(sArr[1]),System.Convert.ToInt16(sArr[2])); } catch(Exception) { } return clrRet; } protected override void OnLocationChanged(EventArgs e) { base.OnLocationChanged(e); if(m_DropShadow!=null) { NativeFunctions.SetWindowPos(m_DropShadow.Handle,new IntPtr(NativeFunctions.HWND_TOP),this.Left+5,this.Top+5,0,0,NativeFunctions.SWP_SHOWWINDOW | NativeFunctions.SWP_NOACTIVATE | NativeFunctions.SWP_NOSIZE); } } private Point _FixedLocation = Point.Empty; /// /// Specifies fixed location for tooltip window. /// public Point FixedLocation { get { return _FixedLocation; } set { _FixedLocation = value; } } protected override CreateParams CreateParams { get { CreateParams p=base.CreateParams; p.Style=unchecked((int)(WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN)); p.ExStyle=(int)(WS_EX_TOOLWINDOW | WS_EX_TOPMOST); p.Caption=""; return p; } } protected override void OnVisibleChanged(EventArgs e) { if(!this.Visible && m_DropShadow!=null) { m_DropShadow.Hide(); m_DropShadow.Dispose(); m_DropShadow=null; } base.OnVisibleChanged(e); } public eDotNetBarStyle Style { get { return m_Style; } set { m_Style = value; if (BarFunctions.IsOffice2007Style(m_Style)) this.AntiAlias = true; } } private bool _ShowDropShadow = true; public bool ShowDropShadow { get { return _ShowDropShadow; } set { _ShowDropShadow = value; } } } }