I have created a simple control which acts as a ToolTip and i have implemented drawing the text and painting the background in the control as my wish. No issues in this control side.
and also i have developed a component for ToolTip which integrates the created ToolTip with the controls. here is the component class.
[ProvideProperty("ToolTip", typeof(Control))]
public class ToolTipController : Component, IExtenderProvider
{
public ToolTipController()
{
}
Dictionary<Component, ToolTip> toolTipInfo = new Dictionary<Component, ToolTip>();
Dictionary<Component, ToolTip> ToolTipInfo
{
get
{
return toolTipInfo;
}
set
{
toolTipInfo = value;
}
}
public bool CanExtend(object extendee)
{
if (!(extendee is ToolTipController))
return true;
return false;
}
/// <summary>
/// Provides value for the Extended property Tooltip for controls.
/// </summary>
/// <returns>Value of the extended property.</returns>
public ToolTip GetToolTip(Component component)
{
if (ToolTipInfo.ContainsKey(component))
return toolTipInfo[component];
return null;
}
public void SetToolTip(Control control, ToolTip toolTip)
{
if (toolTip == null)
return;
if (!ToolTipInfo.ContainsKey(control))
{
ToolTipInfo.Add(control, toolTip);
toolTip.AddControl(control);
}
else
toolTipInfo[control] = toolTip;
}
}
Here is the Control for ToolTip.
public class ToolTip : Control
{
#region Private Variables
RightToLeft rightToLeft = RightToLeft.No;
Dictionary<IntPtr, Component> components;
TOOLINFO toolInfo;
Color foreColor;
Color backColor;
private string tipText;
Dictionary<ContentAlignment, TextFormatFlags> formatFlags;
#endregion Private variables
public ToolTip()
{
toolInfo = new TOOLINFO();
components = new Dictionary<IntPtr, Component>();
formatFlags = new Dictionary<ContentAlignment, TextFormatFlags>();
formatFlags[ContentAlignment.TopLeft] = TextFormatFlags.Default;
formatFlags[ContentAlignment.TopCenter] = TextFormatFlags.Top | TextFormatFlags.HorizontalCenter;
formatFlags[ContentAlignment.TopRight] = TextFormatFlags.Top | TextFormatFlags.Right;
formatFlags[ContentAlignment.MiddleLeft] = TextFormatFlags.VerticalCenter | TextFormatFlags.Left;
formatFlags[ContentAlignment.MiddleCenter] = TextFormatFlags.VerticalCenter | TextFormatFlags.HorizontalCenter;
formatFlags[ContentAlignment.MiddleRight] = TextFormatFlags.VerticalCenter | TextFormatFlags.Right;
formatFlags[ContentAlignment.BottomLeft] = TextFormatFlags.Bottom | TextFormatFlags.Left;
formatFlags[ContentAlignment.BottomCenter] = TextFormatFlags.Bottom | TextFormatFlags.HorizontalCenter;
formatFlags[ContentAlignment.BottomRight] = TextFormatFlags.Bottom | TextFormatFlags.Right;
}
#region Properties
/// <summary>
/// Gets or sets the RightToLeft value of the ToolTip.
/// </summary>
public RightToLeft RightToLeft
{
get
{
return rightToLeft;
}
set
{
rightToLeft = value;
}
}
/// <summary>
/// Gets or sets the Text to be drawn in the ToolTip.
/// </summary>
public string TipText
{
get
{
return tipText;
}
set
{
tipText = value;
}
}
/// <summary>
/// Gets or sets the ForeColor of the ToolTip.
/// </summary>
public Color ForeColor
{
get
{
if (foreColor == null)
return base.ForeColor;
return foreColor;
}
set
{
foreColor = value;
}
}
/// <summary>
/// Gets or sets the BackColor of the ToolTip.
/// </summary>
public Color BackColor
{
get
{
if (backColor == null)
return base.BackColor;
return backColor;
}
set
{
backColor = value;
}
}
#endregion Properties
internal void AddControl(Component component)
{
if (component != null)
{
if (component is Control)
{
Control control = component as Control;
control.HandleCreated += new EventHandler(Control_HandleCreated);
control.HandleDestroyed += new EventHandler(Control_HandleDestroyed);
if (control.IsHandleCreated)
{
Control_HandleCreated(control, EventArgs.Empty);
}
}
}
}
void Control_HandleDestroyed(object sender, EventArgs e)
{
}
public const int TTF_IDISHWND = 0x0001;
public const int TTF_SUBCLASS = 0x0010;
public const int TTF_TRANSPARENT = 0x0100;
public const int LPSTR_TEXTCALLBACKW = -1;
private TOOLINFO GetTOOLINFO(Control ctl)
{
TOOLINFO toolinfo = new TOOLINFO();
toolinfo.cbSize = Marshal.SizeOf(typeof(TOOLINFO));
toolinfo.hwnd = this.Handle;
toolinfo.uFlags = TTF_TRANSPARENT | TTF_SUBCLASS | TTF_IDISHWND;
toolinfo.uId = ctl.Handle;
toolinfo.lpszText = LPSTR_TEXTCALLBACKW;
return toolinfo;
}
void Control_HandleCreated(object sender, EventArgs e)
{
Control control = sender as Control;
if (control != null)
{
components[control.Handle] = control;
toolInfo = this.GetTOOLINFO(control);
NativeTip.SendMessage(new HandleRef(this, this.Handle), 1074, 0, ref toolInfo);
}
}
#region Overrides
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
int style = NativeTip.GetWindowLong(this.Handle, (int)SetWindowLongOffsets.GWL_STYLE);
NativeTip.SetWindowLong(this.Handle, (int)SetWindowLongOffsets.GWL_STYLE, style & ~(int)WindowStyles.WS_BORDER);
}
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
LinearGradientBrush brush = new LinearGradientBrush(e.ClipRectangle, Color.Red, Color.Black, LinearGradientMode.Horizontal);
TextFormatFlags textFormatFlags = TXTFORMAT.COMMON;
textFormatFlags |= TextFormatFlags.RightToLeft;
TextRenderer.DrawText(e.Graphics, this.TipText, this.Font, e.ClipRectangle, this.ForeColor, textFormatFlags);
}
protected override void OnPaintBackground(PaintEventArgs e)
{
base.OnPaintBackground(e);
SolidBrush brush = new SolidBrush(this.BackColor);
e.Graphics.FillRectangle(brush, e.ClipRectangle);
}
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
}
#endregion Overrides
}
I have integrated the ToolTip with below code,
ToolTipController controller = new ToolTipController();
ToolTip toolTip = new ToolTip();
toolTip.TipText = "My test tip";
controller.SetToolTip(this.button1, toolTip);
But the created tooltip is not associated with the button.
Does anyone know how to show the created ToolTip control while hovering in other controls?
Regards,
Amal Raj
See Question&Answers more detail:
os