Getting Mouse Click Coordinates

Hi guys. I am working on a Project in c# and need to get Mouse Click Coordinates in textbox . Click can be made outside the Screen. I have a code in Internet found but cann't make coordinates bring out in textbox. Here is code.. I was trying to write "hookStruct.pt.x" in HookCallBack but it didn't work. Has any one Idea how to do that:

namespace Mouse_Hook
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook,
            LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
            IntPtr wParam, IntPtr lParam);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);

        private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);
        private static LowLevelMouseProc _proc = HookCallback;

        private const int WH_MOUSE_LL = 14;
        private static IntPtr _hookID = IntPtr.Zero;

        private static IntPtr HookCallback(
        int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0 &&
                MouseMessages.WM_LBUTTONDOWN == (MouseMessages)wParam)
            {
                MSLLHOOKSTRUCT hookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
                Console.WriteLine(hookStruct.pt.x + ", " + hookStruct.pt.y);
                Console.Read();
            }
            return CallNextHookEx(_hookID, nCode, wParam, lParam);
        }

        private static IntPtr SetHook(LowLevelMouseProc proc)
        {
            using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
            {
                return SetWindowsHookEx(WH_MOUSE_LL, proc,
                    GetModuleHandle(curModule.ModuleName), 0);
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct POINT
        {
            public int x;
            public int y;
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct MSLLHOOKSTRUCT
        {
            public POINT pt;
            public uint mouseData;
            public uint flags;
            public uint time;
            public IntPtr dwExtraInfo;
        }

        private enum MouseMessages
        {
            WM_LBUTTONDOWN = 0x0201,
            WM_LBUTTONUP = 0x0202,
            WM_MOUSEMOVE = 0x0200,
            WM_MOUSEWHEEL = 0x020A,
            WM_RBUTTONDOWN = 0x0204,
            WM_RBUTTONUP = 0x0205
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            _hookID = SetHook(_proc);
            Application.Run();
            UnhookWindowsHookEx(_hookID);
        }

    }
}[
Dave1993 BulacAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Mike TomlinsonHigh School Computer Science, Computer Applications, and Mathematics TeachersCommented:
In a nutshell....

Hook in the Load() event.  Unhook in the FormClosed() event.  What is Application.Run() doing in there?!

The callback and associated variables shouldn't be static.  If they aren't, then you can use the Form in the callback.  Definitely DO NOT BLOCK in the callback.  Here's a quick example with just the changed portions and the coordinate of the click being displayed in the titlebar of the Form:
    public partial class Form1 : Form
    {

        private IntPtr _hookID = IntPtr.Zero;
        private LowLevelMouseProc _proc = null;

        public Form1()
        {
            InitializeComponent();
            this.Load += Form1_Load;
            this.FormClosed += Form1_FormClosed;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            _proc = HookCallback;
            _hookID = SetHook(_proc);            
        }

        private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0 && MouseMessages.WM_LBUTTONDOWN == (MouseMessages)wParam)
            {
                MSLLHOOKSTRUCT hookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
                this.Text = hookStruct.pt.x.ToString() + ", " + hookStruct.pt.y.ToString();
            }
            return CallNextHookEx(_hookID, nCode, wParam, lParam);
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            UnhookWindowsHookEx(_hookID);
        }

    }

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
it_saigeDeveloperCommented:
See if this doesn't assist you:
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace EE_Q28714279
{
	class Program
	{
		static NativeMethods.LowLevelMouseProcDelegate fProcDelegate;
		static IntPtr fMouseHook;

		static void Main(string[] args)
		{
			Console.WriteLine(GetExecutingAssemblyDirectory());
			Hook();
			Application.Run();
			Unhook();
		}

		/// <summary>Get the name of the executing assembly.  ex : If this function currently executed in this library "C:\MyProgram\MyLibrary.dll",
		/// this function will return "MyLibrary.dll"</summary>
		/// <returns>Name of executing assembly</returns>
		public static string GetExecutingAssembly()
		{
			try
			{
				// Get current assembly with filename
				var currentAssembly = Assembly.GetEntryAssembly().Location;
				// Initialize length
				var nbCharToKeep = currentAssembly.Length;
				// Decrease length until an escape caracter is found
				while (currentAssembly[nbCharToKeep - 1] != '\\')
					nbCharToKeep -= 1;

				// Return the dir including the last escape
				return currentAssembly.Substring(nbCharToKeep, currentAssembly.Length - nbCharToKeep);
			}
			catch (Exception ex)
			{
				Debug.WriteLine(string.Format("{0}: Exception reported in {1} - {2} [{3}]", MethodBase.GetCurrentMethod().Name, ex.Source, ex, ex.Message));
				return string.Empty;
			}
		}

		/// <summary>Get the current path of the executing assembly.  ex : If this function currently executed in this library "C:\MyProgram\MyLibrary.dll",
		/// this function will return "C:\MyProgram\"</summary>
		/// <returns>Current path of the executing assembly</returns>
		public static string GetExecutingAssemblyDirectory()
		{
			string result = string.Empty;
			try
			{
				result = new FileInfo(Assembly.GetEntryAssembly().Location).DirectoryName;
				if (result[result.Length - 1] != '\\')
					result = string.Format(@"{0}\", result);
			}
			catch (Exception ex)
			{
				Debug.WriteLine(string.Format("{0}: Exception reported in {1} - {2} [{3}]", MethodBase.GetCurrentMethod().Name, ex.Source, ex, ex.Message));
				result = string.Empty;
			}
			return result;
		}

		private static void Hook()
		{
			if (fProcDelegate != null)
				throw new InvalidOperationException("Cannot hook more than once");

			using (Process current = Process.GetCurrentProcess())
			using (ProcessModule module = current.MainModule)
			{
				fProcDelegate = NativeMethods.LowLevelMouseProc;
				fMouseHook = NativeMethods.SetWindowsHookEx(NativeMethods.WH_MOUSE_LL, fProcDelegate, NativeMethods.GetModuleHandle(module.ModuleName), 0);
			}

			if (fMouseHook == IntPtr.Zero)
				throw new Win32Exception();
		}

		private static void Unhook()
		{
			if (fProcDelegate == null)
				return;

			bool ok = NativeMethods.UnhookWindowsHookEx(fMouseHook);
			if (!ok)
				throw new Win32Exception();

			fProcDelegate = null;
		}
	}

	static class NativeMethods
	{
		public const int WH_MOUSE_LL = 14;

		/// <summary>Retrieves a module handle for the specified module. The module must have been loaded by the calling process.</summary>
		/// <param name="lpModuleName">The name of the loaded module (either a .dll or .exe file). If the file name extension is omitted, the default library extension .dll is appended. The file name string can include a trailing point character (.) to indicate that the module name has no extension. The string does not have to specify a path. When specifying a path, be sure to use backslashes (\), not forward slashes (/). The name is compared (case independently) to the names of modules currently mapped into the address space of the calling process. If this parameter is NULL, GetModuleHandle returns a handle to the file used to create the calling process (.exe file).</param>
		/// <returns>If the function succeeds, the return value is a handle to the specified module. If the function fails, the return value is NULL. To get extended error information, call GetLastError.</returns>
		/// <remarks>The GetModuleHandle function does not retrieve handles for modules that were loaded using the LOAD_LIBRARY_AS_DATAFILE flag.</remarks>
		[DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)]
		public static extern IntPtr GetModuleHandle(string lpModuleName);

		/// <summary>Installs an application-defined hook procedure into a hook chain.</summary>
		/// <param name="idHook">The type of hook procedure to be installed.</param>
		/// <param name="lpfn">A pointer to the hook procedure. If the dwThreadId parameter is zero or specifies the identifier of a thread created by a different process, the lpfn parameter must point to a hook procedure in a DLL. Otherwise, lpfn can point to a hook procedure in the code associated with the current process.</param>
		/// <param name="hMod">A handle to the DLL containing the hook procedure pointed to by the lpfn parameter. The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by the current process and if the hook procedure is within the code associated with the current process.</param>
		/// <param name="dwThreadId">The identifier of the thread with which the hook procedure is to be associated. For desktop apps, if this parameter is zero, the hook procedure is associated with all existing threads running in the same desktop as the calling thread.</param>
		/// <returns>If the function succeeds, the return value is the handle to the hook procedure. If the function fails, the return value is NULL. To get extended error information, call GetLastError.</returns>
		/// <remarks>You would install a hook procedure to monitor the system for certain types of events. These events are associated either with a specific thread or with all threads in the same desktop as the calling thread.</remarks>
		[DllImport("user32", EntryPoint = "SetWindowsHookEx", SetLastError = true)]
		public static extern IntPtr SetWindowsHookEx(int idHook, LowLevelMouseProcDelegate lpfn, IntPtr hMod, uint dwThreadId);

		/// <summary>Removes a hook procedure installed in a hook chain by the SetWindowsHookEx function.</summary>
		/// <param name="hHook">A handle to the hook to be removed. This parameter is a hook handle obtained by a previous call to SetWindowsHookEx.</param>
		/// <returns>If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError.</returns>
		[DllImport("user32", EntryPoint = "UnhookWindowsHookEx", SetLastError = true)]
		[return: MarshalAs(UnmanagedType.Bool)]
		public static extern bool UnhookWindowsHookEx(IntPtr hHook);

		/// <summary>Passes the hook information to the next hook procedure in the current hook chain. A hook procedure can call this function either before or after processing the hook information.</summary>
		/// <param name="hHook">This parameter is ignored.</param>
		/// <param name="nCode">The hook code passed to the current hook procedure. The next hook procedure uses this code to determine how to process the hook information.</param>
		/// <param name="wParam">The wParam value passed to the current hook procedure. The meaning of this parameter depends on the type of hook associated with the current hook chain.</param>
		/// <param name="lParam">The lParam value passed to the current hook procedure. The meaning of this parameter depends on the type of hook associated with the current hook chain.</param>
		/// <returns>This value is returned by the next hook procedure in the chain. The current hook procedure must also return this value. The meaning of the return value depends on the hook type. For more information, see the descriptions of the individual hook procedures.</returns>
		[DllImport("user32", EntryPoint = "CallNextHookEx", SetLastError = true)]
		public static extern IntPtr CallNextHookEx(IntPtr hHook, int nCode, IntPtr wParam, IntPtr lParam);

		/// <summary>Application-defined callback function used with the SetWindowsHookEx function. The system calls this function every time a new mouse input event is about to be posted into a thread input queue. The mouse input can come from the local mouse driver or from calls to the mouse_event function. If the input comes from a call to mouse_event, the input was "injected".</summary>
		/// <param name="nCode">A code the hook procedure uses to determine how to process the message. If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.</param>
		/// <param name="wParam">The identifier of the mouse message.</param>
		/// <param name="lParam">A pointer to a MSLLHOOKSTRUCT structure.</param>
		/// <returns>If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx. If nCode is greater than or equal to zero, and the hook procedure did not process the message, it is highly recommended that you call CallNextHookEx and return the value it returns; otherwise, other applications that have installed WH_KEYBOARD_LL hooks will not receive hook notifications and may behave incorrectly as a result. If the hook procedure processed the message, it may return a nonzero value to prevent the system from passing the message to the rest of the hook chain or the target window procedure.</returns>
		public static IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam)
		{
			try
			{
				LowLevelMouseHookStructure structure = (LowLevelMouseHookStructure)Marshal.PtrToStructure(lParam, typeof(LowLevelMouseHookStructure));
				Console.WriteLine("Point = {0}; Flag = {1}; Message = {2}", structure.point, structure.flags, (LowLevelMouseMessageType)wParam);
			}
			catch (Exception) { /* Squelched */ ;}

			return CallNextHookEx(IntPtr.Zero, nCode, wParam, lParam);
		}

		/// <summary>Point Structure</summary>
		[StructLayout(LayoutKind.Sequential)]
		public struct POINT
		{
			/// <summary>The x</summary>
			public int X;
			/// <summary>The y</summary>
			public int Y;

			/// <summary>Initializes a new instance of the <see cref="POINT"/> struct.</summary>
			/// <param name="x">The x.</param>
			/// <param name="y">The y.</param>
			public POINT(int x, int y)
			{
				X = x;
				Y = y;
			}

			/// <summary>Initializes a new instance of the <see cref="POINT"/> struct.</summary>
			/// <param name="point">The point.</param>
			public POINT(Point point) : this(point.X, point.Y) { ;}

			/// <summary>Performs an implicit conversion from <see cref="POINT"/> to <see cref="Point"/>.</summary>
			/// <param name="point">The point.</param>
			/// <returns>The result of the conversion.</returns>
			public static implicit operator Point(POINT point)
			{
				return new Point(point.X, point.Y);
			}

			/// <summary>Performs an implicit conversion from <see cref="Point"/> to <see cref="POINT"/>.</summary>
			/// <param name="point">The point.</param>
			/// <returns>The result of the conversion.</returns>
			public static implicit operator POINT(Point point)
			{
				return new POINT(point.X, point.Y);
			}

			/// <summary>Returns a <see cref="System.String" /> that represents this instance.</summary>
			/// <returns>A <see cref="System.String" /> that represents this instance.</returns>
			public override string ToString()
			{
				return ((Point)this).ToString();
			}
		}

		/// <summary>Structure that contains information about a low-level mouse input event</summary>
		[StructLayout(LayoutKind.Sequential)]
		public struct LowLevelMouseHookStructure
		{
			/// <summary>The x- and y-coordinates of the cursor, in screen coordinates.</summary>
			public POINT point;
			/// <summary>The message for the event.</summary>
			/// <remarks>If the message is WM_MOUSEWHEEL, the high-order word of this member is the wheel delta. The low-order word is reserved. A positive value indicates that the wheel was rotated forward, away from the user; a negative value indicates that the wheel was rotated backward, toward the user. One wheel click is defined as WHEEL_DELTA, which is 120.  If the message is WM_XBUTTONDOWN, WM_XBUTTONUP, WM_XBUTTONDBLCLK, WM_NCXBUTTONDOWN, WM_NCXBUTTONUP, or WM_NCXBUTTONDBLCLK, the high-order word specifies which X button was pressed or released, and the low-order word is reserved. This value can be one or more of the following values. Otherwise, mouseData is not used.</remarks>
			[MarshalAs(UnmanagedType.U4)]
			public uint mouseData;
			[MarshalAs(UnmanagedType.U4)]
			public LowLevelMouseHookFlags flags;
			/// <summary>The time stamp for this message.</summary>
			[MarshalAs(UnmanagedType.U4)]
			public uint time;
			/// <summary>The additional information field</summary>
			public UIntPtr dwExtraInfo;
		}

		/// <summary>Enum that contains the low-level mouse flags</summary>
		[Flags]
		public enum LowLevelMouseHookFlags : uint
		{
			/// <summary>No flags set</summary>
			None = 0x00,
			/// <summary>Event-injected flag.</summary>
			Injected = 0x1,
			/// <summary>Event-injected from a process running at a lower integrity level flag.</summary>
			LowerLevelInjected = 0x2
		}

		/// <summary>Enum that contains the low-level mouse message types</summary>
		public enum LowLevelMouseMessageType : uint
		{
			MouseMove = 0x200,
			LeftButtonDown = 0x201,
			LeftButtonUp = 0x202,
			LeftButtonDoubleClick = 0x203,
			RightButtonDown = 0x204,
			RightButtonUp = 0x205,
			RightButtonDoubleClick = 0x206,
			MiddleButtonDown = 0x207,
			MiddleButtonUp = 0x208,
			MiddleButtonDoubleClick = 0x209,
			MouseWheel = 0x20A,
			XButtonDown = 0x20B,
			XButtonUp = 0x20C,
			XButtonDoubleClick = 0x20D,
			MouseHorizontalWheel = 0x20E
		}

		/// <summary>Delegate for the low level mouse hook</summary>
		/// <param name="nCode">A code the hook procedure uses to determine how to process the message. If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.</param>
		/// <param name="wParam">The identifier of the mouse message.</param>
		/// <param name="lParam">A pointer to a KBDLLHOOKSTRUCT structure.</param>
		/// <returns>If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx. If nCode is greater than or equal to zero, and the hook procedure did not process the message, it is highly recommended that you call CallNextHookEx and return the value it returns; otherwise, other applications that have installed WH_KEYBOARD_LL hooks will not receive hook notifications and may behave incorrectly as a result. If the hook procedure processed the message, it may return a nonzero value to prevent the system from passing the message to the rest of the hook chain or the target window procedure.</returns>
		public delegate IntPtr LowLevelMouseProcDelegate(int nCode, IntPtr wParam, [In] IntPtr lParam);
	}
}

Open in new window

Which produces the following output -Capture.JPG-saige-
Dave1993 BulacAuthor Commented:
Thank you very much.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.