⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fmsmessagetip.cs

📁 一个很简单的考试系统。实用性很强啊!数据库在里面
💻 CS
字号:
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

/*
 * 
 *	NOTE 1 : This class and logic will work only and only if the
 *		following key in the registry is set
 *		HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\EnableToolTips\
 * 
 *	NOTE 2 : There needs to be a manifest file in the output location.
 *		This is in order for the close button to work properly.
 *
 *	NOTE 3 : Needs WinXP.
 * 
*/

namespace BalloonCS
{
	/*
	 * commented to avoid multiple declarations
	 * in project
	 * 
	 * public enum TooltipIcon : int
	{
		None,
		Info,
		Warning,
		Error
	}*/

	public enum BalloonAlignment 
	{
		TopLeft,
		TopMiddle,
		TopRight,
		LeftMiddle,
		RightMiddle,
		BottomLeft,
		BottomMiddle,
		BottomRight,
	}

	public enum BalloonPosition
	{
		/// <summary>
		/// Positions using the exact co-ordinates.
		/// So if the co-ordinates are outside the screen,
		/// tip wont be shown.
		/// </summary>
		Absolute,

		/// <summary>
		/// Positions using the co-ordinates as a reference.
		/// Regardless of the co-ordinates, the tip will 
		/// always be shown on the screen.
		/// </summary>
		Track
	}

	public delegate void DeActivateEventHandler();

	internal class MessageTool : NativeWindow
	{
		private const int WM_LBUTTONDOWN = 0x0201;
		public event DeActivateEventHandler DeActivate;
		
		protected override void WndProc(ref System.Windows.Forms.Message m)
		{
			if( m.Msg == WM_LBUTTONDOWN )
			{
				System.Diagnostics.Debug.WriteLine(m);
				// allow the balloon to close if clicked upon
				if(DeActivate!=null)
				{
					DeActivate();
				}
			}

			base.WndProc(ref m);
		}
	}
	/// <summary>
	/// A sample class to manipulate ballon tooltips.
	/// Windows XP balloon-tips if used properly can 
	/// be very helpful.
	/// This class creates a balloon tooltip in the form of a message.
	/// This becomes useful for showing important information 
	/// quickly to the user.
	/// For example in a data-entry form full of 
	/// controls if an error is made somewhere in entering data
	/// use this to point the bad control.
	/// This helps in a shorter learning cycle of the 
	/// application.
	/// NOTE: the difference between this and HoverBalloon class
	/// is that this can be shown on demand.
	/// </summary>
	public class MessageBalloon : IDisposable
	{
		private MessageTool m_tool = null;
		private Control m_parent;
		private TOOLINFO ti;

		private int m_maxWidth = 250;
		private string m_text = "FMS Balloon Tooltip Control Display Message";
		private string m_title = "FMS Balloon Tooltip Message";
		private TooltipIcon m_titleIcon = TooltipIcon.None;
		private BalloonAlignment m_align = BalloonAlignment.TopRight;
		private bool m_absPosn = false;
		private bool m_centerStem = false;

		private const string TOOLTIPS_CLASS = "tooltips_class32";
		private const int WS_POPUP = unchecked((int)0x80000000);
		private const int WM_USER = 0x0400;
		private readonly IntPtr HWND_TOPMOST = new IntPtr(-1);		
		private const int SWP_NOSIZE = 0x0001;
		private const int SWP_NOMOVE = 0x0002;
		private const int SWP_NOACTIVATE = 0x0010;
		private const int SWP_NOZORDER = 0x0004;
		
		[DllImport("User32", SetLastError=true)]
		private static extern int SetWindowPos(
			IntPtr hWnd,
			IntPtr hWndInsertAfter,
			int X,
			int Y,
			int cx,
			int cy,
			int uFlags);

		[DllImport("User32", SetLastError=true)]
		private static extern int GetClientRect(
			IntPtr hWnd,
			ref RECT lpRect);

		[DllImport("User32", SetLastError=true)]
		private static extern int ClientToScreen(
			IntPtr hWnd,
			ref RECT lpRect);

		[DllImport("User32", SetLastError=true)]
		private static extern int SendMessage(
			IntPtr hWnd,
			int Msg,
			int wParam,
			IntPtr lParam);

		[StructLayout(LayoutKind.Sequential)]
		private struct RECT
		{
			public int left;
			public int top;
			public int right;
			public int bottom;
		}

		private const int TTS_ALWAYSTIP = 0x01;
		private const int TTS_NOPREFIX = 0x02;
		private const int TTS_BALLOON = 0x40;
		private const int TTS_CLOSE = 0x80;
		
		private const int TTM_TRACKPOSITION = WM_USER + 18;
		private const int TTM_SETMAXTIPWIDTH = WM_USER + 24;
		private const int TTM_TRACKACTIVATE = WM_USER + 17;
		private const int TTM_ADDTOOL = WM_USER + 50;
		private const int TTM_SETTITLE = WM_USER + 33;

		private const int TTF_IDISHWND = 0x0001;
		private const int TTF_SUBCLASS = 0x0010;
		private const int TTF_TRACK = 0x0020;
		private const int TTF_ABSOLUTE = 0x0080;
		private const int TTF_TRANSPARENT = 0x0100;
		private const int TTF_CENTERTIP = 0x0002;
		private const int TTF_PARSELINKS = 0x1000;

		[StructLayout(LayoutKind.Sequential)]
		private struct TOOLINFO
		{
			public int cbSize;
			public int uFlags;
			public IntPtr hwnd;
			public IntPtr uId;
			public RECT rect;
			public IntPtr hinst;
			[MarshalAs(UnmanagedType.LPTStr)] 
			public string lpszText;
			public uint lParam;
		}
		
		/// <summary>
		/// Creates a new instance of the MessageBalloon.
		/// </summary>
		public MessageBalloon()
		{
			m_tool = new MessageTool();
			m_tool.DeActivate += new DeActivateEventHandler(this.Hide);
		}

		/// <summary>
		/// Creates a new instance of the MessageBalloon.
		/// </summary>
		/// <param name="parent">Set the parent control which will display.</param>
		public MessageBalloon(Control parent)
		{
			m_parent = parent;
			m_tool = new MessageTool();
			m_tool.DeActivate += new DeActivateEventHandler(this.Hide);

		}

		~MessageBalloon()
		{
			Dispose(false);
		}

		private bool disposed = false;
		public void Dispose()
		{
			Dispose(true);
			// Take yourself off the Finalization queue 
			// to prevent finalization code for this object
			// from executing a second time.
			GC.SuppressFinalize(this);
		}

		protected virtual void Dispose(bool disposing)
		{
			if(!this.disposed)
			{
				if(disposing)
				{
					// release managed resources if any
				}
				
				// release unmanaged resource
				Hide();

				// Note that this is not thread safe.
				// Another thread could start disposing the object
				// after the managed resources are disposed,
				// but before the disposed flag is set to true.
				// If thread safety is necessary, it must be
				// implemented by the client.
			}
			disposed = true;
		}

		private void CreateTool()
		{
			System.Diagnostics.Debug.Assert(
				m_parent.Handle!=IntPtr.Zero, 
				"parent hwnd is null", "SetToolTip");

			CreateParams cp = new CreateParams();
			cp.ClassName = TOOLTIPS_CLASS;
			cp.Style = 
				WS_POPUP | 
				TTS_BALLOON | 
				TTS_NOPREFIX |	
				TTS_ALWAYSTIP |
				TTS_CLOSE;

			// create the tool
			m_tool.CreateHandle(cp);

			// create and fill in the tool tip info
			ti = new TOOLINFO();
			ti.cbSize = Marshal.SizeOf(ti);

			ti.uFlags = TTF_TRACK |
				TTF_IDISHWND |
				TTF_TRANSPARENT | 
				TTF_SUBCLASS |
				TTF_PARSELINKS;

			// absolute is used tooltip maynot be shown 
			// if coords exceed the corners of the screen
			if(m_absPosn)
			{
				ti.uFlags |= TTF_ABSOLUTE;
			}

			if(m_centerStem)
			{
				ti.uFlags |= TTF_CENTERTIP;
			}

			ti.uId = m_tool.Handle;
			ti.lpszText = m_text;
			ti.hwnd = m_parent.Handle;

			GetClientRect(m_parent.Handle, ref ti.rect);
			ClientToScreen(m_parent.Handle, ref ti.rect);

			// make sure we make it the top level window
			SetWindowPos(
				m_tool.Handle, 
				HWND_TOPMOST, 
				0, 0, 0, 0,
				SWP_NOACTIVATE | 
				SWP_NOMOVE | 
				SWP_NOSIZE);

			// add the tool tip
			IntPtr ptrStruct = Marshal.AllocHGlobal(Marshal.SizeOf(ti));
			Marshal.StructureToPtr(ti, ptrStruct, true);

			SendMessage(
				m_tool.Handle, TTM_ADDTOOL, 0, ptrStruct);

			ti = (TOOLINFO)Marshal.PtrToStructure(ptrStruct, 
				typeof(TOOLINFO));

			SendMessage(
				m_tool.Handle, TTM_SETMAXTIPWIDTH, 
				0, new IntPtr(m_maxWidth));

			IntPtr ptrTitle = Marshal.StringToHGlobalAuto(m_title);

			SendMessage(
				m_tool.Handle, TTM_SETTITLE, 
				(int)m_titleIcon, ptrTitle);

			SetBalloonPosition(ti.rect);

			Marshal.FreeHGlobal(ptrStruct);
			Marshal.FreeHGlobal(ptrTitle);
		}
		
		private void SetBalloonPosition(RECT rect)
		{
			int x = 0, y = 0;

			// calculate cordinates depending upon aligment
			switch(m_align)
			{
				case BalloonAlignment.TopLeft:
					x = rect.left;
					y = rect.top;
					break;
				case BalloonAlignment.TopMiddle:
					x = rect.left + (rect.right / 2);
					y = rect.top;
					break;
				case BalloonAlignment.TopRight:
					x = rect.left + rect.right;
					y = rect.top;
					break;
				case BalloonAlignment.LeftMiddle:
					x = rect.left;
					y = rect.top + (rect.bottom / 2);
					break;
				case BalloonAlignment.RightMiddle:
					x = rect.left + rect.right;
					y = rect.top + (rect.bottom / 2);
					break;
				case BalloonAlignment.BottomLeft:
					x = rect.left;
					y = rect.top + rect.bottom;
					break;
				case BalloonAlignment.BottomMiddle:
					x = rect.left + (rect.right / 2);
					y = rect.top + rect.bottom;
					break;
				case BalloonAlignment.BottomRight:
					x = rect.left + rect.right;
					y = rect.top + rect.bottom;
					break;
				default:
					System.Diagnostics.Debug.Assert(false, "undefined enum", "default case reached");
					break;
			}

			//int pt = MAKELONG(ti.rect.left, ti.rect.top);
			int pt = MAKELONG(x, y);
			IntPtr ptr = new IntPtr(pt);

			SendMessage(
				m_tool.Handle, TTM_TRACKPOSITION,
				0, ptr);
				
		}

		/// <summary>
		/// Shows or hides the tool.
		/// </summary>
		/// <param name="show">0 to hide, -1 to show</param>
		private void Display(int show)
		{
			IntPtr ptrStruct = Marshal.AllocHGlobal(Marshal.SizeOf(ti));
			Marshal.StructureToPtr(ti, ptrStruct, true);

			SendMessage(
				m_tool.Handle, TTM_TRACKACTIVATE,
				show, ptrStruct);

			Marshal.FreeHGlobal(ptrStruct);
		}

		/// <summary>
		/// Hides the message if visible.
		/// </summary>
		public void Hide()
		{
			Display(0);
			m_tool.DestroyHandle();
		}

		private int MAKELONG(int loWord, int hiWord)
		{
			return (hiWord << 16) | (loWord & 0xffff);
		}

		/// <summary>
		/// Sets or gets the Title.
		/// </summary>
		public string Title
		{
			get
			{
				return m_title;
			}
			set
			{
				m_title = value;
			}
		}

		/// <summary>
		/// Sets or gets the display icon.
		/// </summary>
		public TooltipIcon TitleIcon
		{
			get
			{
				return m_titleIcon;
			}
			set
			{
				m_titleIcon = value;
			}
		}

		/// <summary>
		/// Sets or get the display text.
		/// </summary>
		public string Text
		{
			get
			{
				return m_text;
			}
			set
			{
				m_text = value;
			}
		}

		/// <summary>
		/// Sets or gets the parent.
		/// </summary>
		public Control Parent
		{
			get
			{
				return m_parent;
			}
			set
			{
				m_parent = value;
			}
		}

		/// <summary>
		/// Sets or gets the placement of the balloon.
		/// </summary>
		public BalloonAlignment Align
		{
			get
			{
				return m_align;
			}
			set
			{
				m_align = value;
			}
		}

		/// <summary>
		/// Sets or gets the positioning of the balloon.
		/// TRUE : Positions using the exact co-ordinates,
		/// if the co-ordinates are outside the screen, tip wont be shown.
		/// FALSE : Positions using the co-ordinates as a reference.
		/// Regardless of the co-ordinates, the tip will 
		/// always be shown on the screen.
		/// </summary>
		public bool UseAbsolutePositioning
		{
			get
			{
				return m_absPosn;
			}
			set
			{
				m_absPosn = value;
			}
		}

		/// <summary>
		/// Sets or gets the stem position 
		/// in the tip. 
		/// TRUE : The stem of the tip is set to center.
		/// An attempt is made to show the tip with the stem
		/// centered, if that would make the tip to be 
		/// hidden partly, stem is not centered.
		/// FALSE: Stem is not centered.
		/// </summary>
		public bool CenterStem
		{
			get
			{
				return m_centerStem;
			}
			set
			{
				m_centerStem = value;
			}
		}

		/// <summary>
		/// Show the Message in a balloon tooltip.
		/// </summary>
		public void Show()
		{
			// recreate window always
			Hide();

			CreateTool();
			Display(-1);
		}

	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -