IntelliTip.cs
上传用户:hbhltzc
上传日期:2022-06-04
资源大小:1925k
文件大小:7k
源码类别:

xml/soap/webservice

开发平台:

Visual C++

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Windows.Forms;
  5. using System.Drawing;
  6. using System.Runtime.InteropServices;
  7. namespace XmlNotepad {
  8.     public enum TipRequestType { Default, Hover };
  9.     public class IntelliTipEventArgs : EventArgs {
  10.         public TipRequestType Type;
  11.         public string ToolTip;
  12.         public Point Location;
  13.         public Control Focus;
  14.     }
  15.     public delegate void IntelliTipEventHandler(object sender, IntelliTipEventArgs args);
  16.     /// <summary>
  17.     /// This class provides a ToolTip at the cursor location based on mouse hover events
  18.     /// on the watched child views.  It is wraps the WinForms ToolTip class and provides
  19.     /// some added benefits, like being able to monitor multiple child views, and being
  20.     /// able to Start() the tip operation based on some other event, (like list box
  21.     /// selection changed) and word wrapping of the tooltip text string.
  22.     /// </summary>
  23.     public class IntelliTip {
  24.         private Control owner;
  25.         private ToolTip tip = new ToolTip();
  26.         const int HoverDelay = 300;
  27.         int tipTime;
  28.         List<Control> watch = new List<Control>();
  29.         bool tipVisible;
  30.         TipRequestType type;
  31.         Timer popupDelay;
  32.         bool resetpending;
  33.         Rectangle lastHover;
  34.         Control showing;
  35.         public event IntelliTipEventHandler ShowToolTip;
  36.         public IntelliTip(Control owner) {
  37.             this.owner = owner;
  38.             this.tip.Popup += new PopupEventHandler(OnTipPopup);
  39.             owner.MouseMove += new MouseEventHandler(OnWatchMouseMove);
  40.             popupDelay = new Timer();
  41.             popupDelay.Tick += new EventHandler(popupDelay_Tick);
  42.             popupDelay.Interval = 500;
  43.             this.tip.AutoPopDelay = 0;
  44.             this.tip.AutomaticDelay = 0;
  45.             this.tip.UseAnimation = false;
  46.             this.tip.UseFading = false;
  47.         }
  48.         public int PopupDelay {
  49.             get { return this.popupDelay.Interval; }
  50.             set { this.popupDelay.Interval = value; }
  51.         }
  52.         public void AddWatch(Control c) {
  53.             c.MouseHover += new EventHandler(OnWatchMouseHover);
  54.             c.MouseMove += new MouseEventHandler(OnWatchMouseMove);
  55.             c.KeyDown += new KeyEventHandler(OnWatchKeyDown);
  56.             watch.Add(c);
  57.         }
  58.         public bool Visible {
  59.             get { return this.tipVisible; }
  60.         }
  61.         public void Hide() {
  62.             if (showing != null) {
  63.                 this.tip.Hide(showing);
  64.             }
  65.             showing = null;
  66.             this.tip.RemoveAll();                    
  67.             this.tipVisible = false;
  68.         }
  69.         //=============================== Private methods ===============================
  70.         void popupDelay_Tick(object sender, EventArgs e) {
  71.             popupDelay.Stop();
  72.             this.owner.Invoke(new EventHandler(OnPopupDelay), new object[] { this, EventArgs.Empty });
  73.         }
  74.         void OnPopupDelay(object sender, EventArgs e) {
  75.             this.OnShowToolTip();
  76.         }
  77.         void OnTipPopup(object sender, PopupEventArgs e) {
  78.             this.tipVisible = true;
  79.         }
  80.         void OnWatchKeyDown(object sender, KeyEventArgs e) {
  81.             Hide();  
  82.         }
  83.         void OnWatchMouseHover(object sender, EventArgs e) {
  84.             this.type = TipRequestType.Hover;
  85.             Start();
  86.         }
  87.         void Start() {
  88.             this.popupDelay.Stop();
  89.             this.popupDelay.Start();
  90.         }
  91.         Control GetFocus() {
  92.             foreach (Control c in this.watch) {
  93.                 if (c.Focused) return c;
  94.             }
  95.             return this.owner;
  96.         }
  97.         internal void OnShowToolTip() {
  98.             this.type = TipRequestType.Default;
  99.             lastHover = new Rectangle(Cursor.Position, Size.Empty);
  100.             lastHover.Inflate(10, 10);
  101.             resetpending = true;       
  102.             if (ShowToolTip != null && !owner.Capture) {
  103.                 Control c = GetFocus();
  104.                 Point local = c.PointToClient(Cursor.Position);
  105.                 IntelliTipEventArgs args = new IntelliTipEventArgs();
  106.                 args.Type = this.type;
  107.                 args.Focus = c;
  108.                 args.Location = local;
  109.                 ShowToolTip(this, args);
  110.                 string toolTip = args.ToolTip;
  111.                 if (!string.IsNullOrEmpty(toolTip)) {
  112.                     this.tip.ShowAlways = true;
  113.                     this.tip.Active = true;
  114.                     Point p = args.Location;
  115.                     if (p.X == local.X && p.Y == local.Y) {
  116.                         p.Y += 10;
  117.                         p.Y += 10;
  118.                     }
  119.                     this.tipTime = Environment.TickCount;
  120.                     showing = c;
  121.                     this.tip.Show(WordWrap(toolTip), (IWin32Window)c, p);
  122.                     return;
  123.                 }
  124.             }
  125.             this.tip.Hide(owner);
  126.         }
  127.         void OnWatchMouseMove(object sender, MouseEventArgs e) {
  128.             bool outside = !lastHover.Contains(Cursor.Position);
  129.             if (this.tipVisible && outside) {
  130.                 Hide();
  131.             }
  132.             if (resetpending && outside) {
  133.                 resetpending = false;
  134.                 this.ResetHoverTracking(((Control)sender).Handle);
  135.             }
  136.         }
  137.         string WordWrap(string tip) {
  138.             Screen screen = Screen.FromControl(owner);
  139.             int width = screen.Bounds.Width / 2;
  140.             StringBuilder sb = new StringBuilder();
  141.             using (Graphics g = owner.CreateGraphics()) {
  142.                 Font f = owner.Font;
  143.                 int wrap = 0;
  144.                 foreach (string word in tip.Split(' ', 't', 'r', 'n')) {
  145.                     if (string.IsNullOrEmpty(word)) continue;
  146.                     SizeF size = g.MeasureString(word + " ", f);
  147.                     wrap += (int)size.Width;
  148.                     sb.Append(word);
  149.                     if (wrap > width) {
  150.                         sb.Append('n');
  151.                         wrap = 0;
  152.                     } else {
  153.                         sb.Append(' ');
  154.                     }
  155.                 }
  156.             }
  157.             return sb.ToString();
  158.         }
  159.         #region HoverTracking
  160.         [DllImport("user32.dll", SetLastError = true)]
  161.         private static extern bool TrackMouseEvent(TRACKMOUSEEVENT tme);
  162.         [StructLayout(LayoutKind.Sequential)]
  163.         public class TRACKMOUSEEVENT {
  164.             public int cbSize = Marshal.SizeOf(typeof(TRACKMOUSEEVENT));
  165.             public int dwFlags;
  166.             public IntPtr hwndTrack;
  167.             public int dwHoverTime = HoverDelay; // Never set this to field ZERO, or to HOVER_DEFAULT, ever!
  168.         }
  169.         TRACKMOUSEEVENT trackMouseEvent;
  170.         const int TME_HOVER = 0x00000001;
  171.         const int WM_MOUSEHOVER = 0x02A1;
  172.         internal void ResetHoverTracking(IntPtr handle) {
  173.             if (trackMouseEvent == null) {
  174.                 trackMouseEvent = new TRACKMOUSEEVENT();
  175.                 trackMouseEvent.dwFlags = TME_HOVER;
  176.                 trackMouseEvent.hwndTrack = handle;
  177.             }
  178.             TrackMouseEvent(trackMouseEvent);
  179.         }
  180.         #endregion 
  181.     }
  182. }