Hook minimize event of third party application - c#

I have following hook class:
public sealed class Hook : IDisposable
{
public delegate void Win32Event(IntPtr hWnd);
#region Windows API
private const uint WINEVENT_OUTOFCONTEXT = 0x0000;
[DllImport("User32.dll", SetLastError = true)]
private static extern IntPtr SetWinEventHook(
uint eventMin,
uint eventMax,
IntPtr hmodWinEventProc,
WinEventDelegate lpfnWinEventProc,
uint idProcess,
uint idThread,
uint dwFlags);
[DllImport("user32.dll")]
private static extern bool UnhookWinEvent(
IntPtr hWinEventHook
);
private enum SystemEvents : uint
{
EVENT_OBJECT_CREATE = 0x8000,
EVENT_OBJECT_DESTROY = 0x8001,
EVENT_SYSTEM_MINIMIZESTART = 0x0016,
EVENT_SYSTEM_MINIMIZEEND = 0x0017,
EVENT_SYSTEM_FOREGROUND = 0x0003
}
private delegate void WinEventDelegate(
IntPtr hWinEventHook,
uint eventType,
IntPtr hWnd,
int idObject,
int idChild,
uint dwEventThread,
uint dwmsEventTime);
#endregion
public Win32Event OnWindowCreate = delegate { };
public Win32Event OnWindowDestroy = delegate { };
public Win32Event OnWindowForegroundChanged = delegate { };
public Win32Event OnWindowMinimizeEnd = delegate { };
public Win32Event OnWindowMinimizeStart = delegate { };
private IntPtr pHook;
private bool _disposed;
public Hook(IntPtr hWnd)
{
pHook = SetWinEventHook((uint) SystemEvents.EVENT_SYSTEM_FOREGROUND,
(uint) SystemEvents.EVENT_OBJECT_DESTROY,
hWnd,
WinEvent,
0,
0,
WINEVENT_OUTOFCONTEXT
);
if (IntPtr.Zero.Equals(pHook))
throw new Win32Exception();
}
public void Dispose()
{
Dispose(true);
}
private void WinEvent(IntPtr hWinEventHook, uint eventType, IntPtr hWnd, int idObject, int idChild,
uint dwEventThread, uint dwmsEventTime)
{
switch ((SystemEvents) eventType)
{
case SystemEvents.EVENT_OBJECT_DESTROY:
OnWindowDestroy(hWnd);
break;
case SystemEvents.EVENT_SYSTEM_FOREGROUND:
OnWindowForegroundChanged(hWnd);
break;
case SystemEvents.EVENT_SYSTEM_MINIMIZESTART:
OnWindowMinimizeStart(hWnd);
break;
case SystemEvents.EVENT_SYSTEM_MINIMIZEEND:
OnWindowMinimizeEnd(hWnd);
break;
case SystemEvents.EVENT_OBJECT_CREATE:
OnWindowCreate(hWnd);
break;
}
}
~Hook()
{
Dispose(false);
}
private void Dispose(bool manual)
{
if (_disposed)
return;
if (!IntPtr.Zero.Equals(pHook))
UnhookWinEvent(pHook);
pHook = IntPtr.Zero;
OnWindowCreate = null;
OnWindowDestroy = null;
OnWindowForegroundChanged = null;
OnWindowMinimizeStart = null;
OnWindowMinimizeEnd = null;
_disposed = true;
if (manual)
{
GC.SuppressFinalize(this);
}
}
}
But when I use it nothing happens:
class Program
{
static void Main(string[] args)
{
var process = Process.GetProcessesByName("Notepad")[0];
var hook = new Hook(process.MainWindowHandle);
hook.OnWindowMinimizeStart += wnd => Console.WriteLine("Minimized at {0}", DateTime.Now.ToShortTimeString());
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
}
what am I doing wrong here? It seems that everything is OK.

Related

MouseHook stops sending input randomaly

I have a MouseHook class that I got, And I created an event with it, but it's randomly stopping sending input to the event for some reason, Its sending the location/buttons for a couple of seconds to minutes but for some reason it just stops randomly
I created and event like that
MouseHook mouse = new MouseHook();
mouse.OnMouseActivity += new System.Windows.Forms.MouseEventHandler(Mouse_OnMouseActivity);
mouse.Start();
And that's how I notice (For some reasong after couple of seconds-minutes it just stops sending input)
void Mouse_OnMouseActivity(object sender, System.Windows.Forms.MouseEventArgs e)
{
num++;
Console.WriteLine(num);
}
and that's the class:
public class MouseHook
{
private const int WM_MOUSEMOVE = 0x200;
private const int WM_LBUTTONDOWN = 0x201;
private const int WM_RBUTTONDOWN = 0x204;
private const int WM_MBUTTONDOWN = 0x207;
private const int WM_LBUTTONUP = 0x202;
private const int WM_RBUTTONUP = 0x205;
private const int WM_MBUTTONUP = 0x208;
private const int WM_LBUTTONDBLCLK = 0x203;
private const int WM_RBUTTONDBLCLK = 0x206;
private const int WM_MBUTTONDBLCLK = 0x209;
public event System.Windows.Forms.MouseEventHandler OnMouseActivity;
static int hMouseHook = 0;
public const int WH_MOUSE_LL = 14;
HookProc MouseHookProcedure;
[StructLayout(LayoutKind.Sequential)]
public class POINT
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
public class MouseHookStruct
{
public POINT pt;
public int hWnd;
public int wHitTestCode;
public int dwExtraInfo;
}
[DllImport("kernel32.dll")]
public static extern IntPtr GetModuleHandle(string name);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(int idHook);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);
public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
public MouseHook()
{
}
~MouseHook()
{
Stop();
}
public void Start()
{
if (hMouseHook == 0)
{
MouseHookProcedure = new HookProc(MouseHookProc);
//hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProcedure, Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]), 0);
hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProcedure, GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0);
if (hMouseHook == 0)
{
Stop();
throw new Exception("SetWindowsHookEx failed.");
}
}
}
public void Stop()
{
bool retMouse = true;
if (hMouseHook != 0)
{
retMouse = UnhookWindowsHookEx(hMouseHook);
hMouseHook = 0;
}
if (!(retMouse)) throw new Exception("UnhookWindowsHookEx failed.");
}
private int MouseHookProc(int nCode, Int32 wParam, IntPtr lParam)
{
if ((nCode >= 0) && (OnMouseActivity != null))
{
MouseButtons button = MouseButtons.None;
int clickCount = 0;
switch (wParam)
{
case WM_LBUTTONDOWN:
button = MouseButtons.Left;
clickCount = 1;
break;
case WM_LBUTTONUP:
button = MouseButtons.Left;
clickCount = 2;
break;
case WM_LBUTTONDBLCLK:
button = MouseButtons.Left;
clickCount = 3;
break;
case WM_RBUTTONDOWN:
button = MouseButtons.Right;
clickCount = 4;
break;
case WM_RBUTTONUP:
button = MouseButtons.Right;
clickCount = 5;
break;
case WM_RBUTTONDBLCLK:
button = MouseButtons.Right;
clickCount = 6;
break;
}
MouseHookStruct MyMouseHookStruct = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));
System.Windows.Forms.MouseEventArgs e = new System.Windows.Forms.MouseEventArgs(button, clickCount, MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y, 0);
OnMouseActivity(this, e);
}
return CallNextHookEx(hMouseHook, nCode, wParam, lParam);
}
}

CallbackOnCollectedDelegate was detected (after some calls of Process.GetProcessByID by WinEventProc)

I need your guidance masters.
Bellow follow my code. I'm capturing the title of the window when the event 3 or 8 occur and creating a counter when the event 9 occur.
My code is working great, but, when I try to get the name of the owner of windows' exe with my function GetProcessName, I'm receiving the error "CallbackOnCollectedDelegate was detected". I already did and tried all I knowed, but nothing resolve the error. The error occur after some time of start the use of the application.
When I not call my function GetProcessName, the error not happen.
delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime);
[DllImport("user32.dll")]
static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess, uint idThread, uint dwFlags);
[DllImport("user32.dll")]
public static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, out uint ProcessId);
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
private const uint EVENT_SYSTEM_FOREGROUND = 3;
private const uint EVENT_SYSTEM_CAPTUREEND = 9;
private const uint EVENT_SYSTEM_CAPTURESTART = 8;
int counter = 0;
public Form1()
{
InitializeComponent();
IntPtr handle = IntPtr.Zero;
SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_CAPTUREEND, IntPtr.Zero, new WinEventDelegate(WinEventProc), 0, 0, 0);
}
public void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
try
{
if (eventType == EVENT_SYSTEM_FOREGROUND || eventType == EVENT_SYSTEM_CAPTURESTART && idObject == 0)
{
aux1 = GetActiveWindowTitle(hwnd);//A function tha get a name of the title of the window
if (aux1 != aux2 && string.IsNullOrEmpty(aux1) == false)
{
GetWindowThreadProcessId(hwnd, out pid);
pnomelast = GetProcessName((int)pid);//This is the function!!
aux2 = aux1;
aux1 = "";
}
}
else if (eventType == EVENT_SYSTEM_CAPTUREEND)
{
counter = counter + 1;
}
}
catch (Exception e)
{
};
}
public static string GetProcessName(int processId)
{
try
{
return Process.GetProcessById(processId).MainModule.FileName.ToString().Split('\\').Last();
}
catch (Exception)
{
return "";
}
}
Thanks a lot.
Your issue is that SetWinEventHook is creating a new delegate on the fly which has no reference. Since it is orphaned, it will be destroyed on the next garbage collection.
First create a new WinEventDelegate
private static winEventDelegate = new WinEventDelegate(WinEventProc);
Then change:
SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_CAPTUREEND, IntPtr.Zero, new WinEventDelegate(WinEventProc), 0, 0, 0);
TO:
SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_CAPTUREEND, IntPtr.Zero, winEventDelegate, 0, 0, 0);
I made a complete and compact version of the code, that represents the problem, the error happen when the Process.GetProcessById is called. Thanks.
namespace stackoverflow1 {
public partial class Form1 : Form {
delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime);
[DllImport("user32.dll")]
static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess, uint idThread, uint dwFlags);
[DllImport("user32.dll")]
public static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, out uint ProcessId);
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
private const uint EVENT_SYSTEM_FOREGROUND = 3;
private const uint EVENT_SYSTEM_CAPTURESTART = 8;
uint pid = 0;
string pnamelast = "";
public Form1()
{
InitializeComponent();
WinEventDelegate dele = new WinEventDelegate(WinEventProc);
SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_CAPTURESTART, IntPtr.Zero, dele, 0, 0, 0);
}
private void Form1_Load(object sender, EventArgs e)
{
}
public void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
try
{
if (eventType == EVENT_SYSTEM_FOREGROUND || eventType == EVENT_SYSTEM_CAPTURESTART && idObject == 0)
{
GetWindowThreadProcessId(hwnd, out pid);
pnamelast = Process.GetProcessById((int)pid).MainModule.FileName.ToString().Split('\\').Last();
textBox1.AppendText(pnamelast + "\r\n");
}
}
catch
{
}
}
}
}

Winforms Static HandleCreated or OnLoad Event

Is there any static event that is triggered when a handle for a Winforms control is created or when it is loaded for the first time?
This is a contrived example:
using (Form f1 = new Form())
{
f1.HandleCreated += (sender, args) => { MessageBox.Show("hi"); };
f1.ShowDialog();
}
using (Form f2 = new Form())
{
f2.HandleCreated += (sender, args) => { MessageBox.Show("hi"); };
f2.ShowDialog();
}
And this is what I want:
Form.StaticHandleCreated += (sender, args) => { MessageBox.Show("hi"); };
using (Form f1 = new Form())
{
f1.ShowDialog();
}
using (Form f2 = new Form())
{
f2.ShowDialog();
}
(I want this because I have several hundred controls, and I need to customize the default behavior of a third party control, and the vendor does not provide a better way. They specifically say to handle the OnLoad event to do the customization, but this is a massive workload.)
Thanks to xtu, here is the working version that doesn't hold onto the forms longer than necessary, to avoid memory leaks.
public class WinFormMonitor : IDisposable
{
private readonly IntPtr _eventHook;
private List<Form> _detectedForms = new List<Form>();
public event Action<Form> NewFormDetected;
private WinEventDelegate _winEventDelegate;
public WinFormMonitor()
{
_winEventDelegate = WinEventProc;
_eventHook = SetWinEventHook(
EVENT_OBJECT_CREATE,
EVENT_OBJECT_CREATE,
IntPtr.Zero,
_winEventDelegate,
0,
0,
WINEVENT_OUTOFCONTEXT);
}
public void Dispose()
{
_detectedForms.Clear();
UnhookWinEvent(_eventHook);
}
private void WinEventProc(IntPtr hWinEventHook, uint eventType,
IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
if (idObject != 0 || idChild != 0) return;
var currentForms = Application.OpenForms.OfType<Form>().ToList();
var newForms = currentForms.Except(_detectedForms);
foreach (var f in newForms)
{
NewFormDetected?.Invoke(f);
}
_detectedForms = currentForms;
}
private const uint EVENT_OBJECT_CREATE = 0x8000;
private const uint WINEVENT_OUTOFCONTEXT = 0;
private delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType,
IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime);
[DllImport("user32.dll")]
private static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr
hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess,
uint idThread, uint dwFlags);
[DllImport("user32.dll")]
private static extern bool UnhookWinEvent(IntPtr hWinEventHook);
}
I was inspired by this answer and used SetWinEventHook API to create a new WinForm monitor. Basically, it monitors the EVENT_OBJECT_CREATE event and fires an event whenever a new window is found.
The usage is very simple. You create a new instance and then attach a handler to the NewFormCreated event. Here is an example:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
using (var monitor = new WinFormMonitor())
{
monitor.NewFormCreated += (sender, form) => { MessageBox.Show($"hi {form.Text}"); };
Application.Run(new Form1());
}
}
And here is the source of the WinFormMonitor:
public class WinFormMonitor : IDisposable
{
private readonly IntPtr _eventHook;
private readonly IList<int> _detectedFormHashes = new List<int>();
public event EventHandler<Form> NewFormCreated = (sender, form) => { };
public WinFormMonitor()
{
_eventHook = SetWinEventHook(
EVENT_OBJECT_CREATE,
EVENT_OBJECT_CREATE,
IntPtr.Zero,
WinEventProc,
0,
0,
WINEVENT_OUTOFCONTEXT);
}
public void Dispose()
{
_detectedFormHashes.Clear();
UnhookWinEvent(_eventHook);
}
private void WinEventProc(IntPtr hWinEventHook, uint eventType,
IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
// filter out non-HWND namechanges... (eg. items within a listbox)
if (idObject != 0 || idChild != 0) return;
if (!TryFindForm(hwnd, out var foundForm)) return;
RaiseIfNewFormFound(foundForm);
}
private void RaiseIfNewFormFound(Form foundForm)
{
var formHash = foundForm.GetHashCode();
if (_detectedFormHashes.Contains(formHash)) return;
NewFormCreated(this, foundForm);
_detectedFormHashes.Add(formHash);
}
private static bool TryFindForm(IntPtr handle, out Form foundForm)
{
foreach (Form openForm in Application.OpenForms)
{
if (openForm.Handle != handle) continue;
foundForm = openForm;
return true;
}
foundForm = null;
return false;
}
private const uint EVENT_OBJECT_CREATE = 0x8000;
private const uint WINEVENT_OUTOFCONTEXT = 0;
private delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType,
IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime);
[DllImport("user32.dll")]
private static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr
hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess,
uint idThread, uint dwFlags);
[DllImport("user32.dll")]
private static extern bool UnhookWinEvent(IntPtr hWinEventHook);
}

c# global system hook to detect change of active window

I have been using the following code to detect a change of active window with C# but on the odd occasion it simply doesn't register the change of an active window when it definitely occurs. In most instances it works absolutely fine. I've had a look into it but it seems to me that the only thing I can do is turn to C++ to get a reliable solution but before doing that I thought I would ask the question of the code below.
GlobalEventHook.Start();
GlobalEventHook.WinEventActive += new EventHandler(GlobalEventHook_WinEventActive); //set up the global hook events
private void GlobalEventHook_WinEventActive(object sender, EventArgs e)
{
// do whatever
}
using System;
using System.Collections;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace Pro
{
public static class GlobalEventHook
{
[DllImport("user32.dll")]
internal static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc,
WinEventDelegate lpfnWinEventProc, uint idProcess, uint idThread, uint dwFlags);
[DllImport("user32.dll")]
internal static extern bool UnhookWinEvent(IntPtr hWinEventHook);
public static event EventHandler WinEventActive = delegate { };
public static event EventHandler WinEventContentScrolled = delegate { };
public delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject,
int idChild, uint dwEventThread, uint dwmsEventTime);
private static WinEventDelegate dele = null;
private static IntPtr _hookID = IntPtr.Zero;
public static void Start()
{
dele = new WinEventDelegate(WinEventProc);
_hookID = SetWinEventHook(Win32API.EVENT_SYSTEM_FOREGROUND, Win32API.EVENT_SYSTEM_FOREGROUND, IntPtr.Zero, dele, 0, 0, Win32API.WINEVENT_OUTOFCONTEXT);
}
public static void stop()
{
UnhookWinEvent(_hookID);
}
public static void restart()
{
_hookID = SetWinEventHook(Win32API.EVENT_SYSTEM_FOREGROUND, Win32API.EVENT_SYSTEM_FOREGROUND, IntPtr.Zero, dele, 0, 0, Win32API.WINEVENT_OUTOFCONTEXT);
}
public static void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
try
{
if (eventType == Win32API.EVENT_SYSTEM_FOREGROUND)
{
if (hwnd == Win32API.GetForegroundWindow())
{
WinEventActive(null, new EventArgs());
}
}
}
catch (Exception exc)
{
}
}

How to get processes from mouse event using Intptr (USER32.dll) ???

I have a problem in last two days i want to get processes of users which he clicked. like if a user clicks Notepad my program should tell me that user clicked Notepad. Notepad is opened. And if user clicks Calculator my program also tell that user clicked Calculator. Calcultor process is runing.
For this purpose i used this code. Hook manager which gives me mouse click events but not giving me the process.
I am only getting mouse intptr event.
private static void WindowEventCallback(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
Console.WriteLine("Event {0}", hwnd);// it is giving me mouse event
/*uint pid;
GetWindowThreadProcessId(hwnd, out pid);// it gives me process id
Process p = Process.GetProcessById((int)pid);// now here exception occured not in vs studio but when i run its exe then its gives me access violation exception
if (!my.ContainsKey(p.MainWindowTitle.ToString()))
{
my.Add(p.MainWindowTitle.ToString(), p.Id.ToString());
Console.WriteLine("\r\n");
Console.WriteLine("Status = Running");
Console.WriteLine("\r\n Window Title:" + p.MainWindowTitle.ToString());
Console.WriteLine("\r\n Process Name:" + p.ProcessName.ToString());
Console.WriteLine("\r\n Process Starting Time:" + p.StartTime.ToString());
}*/
}
the full code is
static void Main(string[] args)
{
HookManager.SubscribeToWindowEvents();
EventLoop.Run();
}
public static class HookManager
{
[DllImport("user32.dll")]
public static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, out uint ProcessId);
public static void SubscribeToWindowEvents()
{
if (windowEventHook == IntPtr.Zero)
{
windowEventHook = SetWinEventHook(
EVENT_SYSTEM_FOREGROUND, // eventMin
EVENT_SYSTEM_FOREGROUND, // eventMax
IntPtr.Zero, // hmodWinEventProc
WindowEventCallback, // lpfnWinEventProc
0, // idProcess
0, // idThread
WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);
if (windowEventHook == IntPtr.Zero)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
}
static Dictionary<string, string> my = new Dictionary<string, string>();
private static void WindowEventCallback(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
Console.WriteLine("Event {0}", hwnd);
/*uint pid;
GetWindowThreadProcessId(hwnd, out pid);
Process p = Process.GetProcessById((int)pid);
if (!my.ContainsKey(p.MainWindowTitle.ToString()))
{
my.Add(p.MainWindowTitle.ToString(), p.Id.ToString());
Console.WriteLine("\r\n");
Console.WriteLine("Status = Running");
Console.WriteLine("\r\n Window Title:" + p.MainWindowTitle.ToString());
Console.WriteLine("\r\n Process Name:" + p.ProcessName.ToString());
Console.WriteLine("\r\n Process Starting Time:" + p.StartTime.ToString());
}*/
}
}
private static IntPtr windowEventHook;
private delegate void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime);
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr SetWinEventHook(int eventMin, int eventMax, IntPtr hmodWinEventProc, WinEventProc lpfnWinEventProc, int idProcess, int idThread, int dwflags);
[DllImport("user32.dll", SetLastError = true)]
private static extern int UnhookWinEvent(IntPtr hWinEventHook);
private const int WINEVENT_INCONTEXT = 4;
private const int WINEVENT_OUTOFCONTEXT = 0;
private const int WINEVENT_SKIPOWNPROCESS = 2;
private const int WINEVENT_SKIPOWNTHREAD = 1;
private const int EVENT_SYSTEM_FOREGROUND = 3;
public static class EventLoop
{
public static void Run()
{
MSG msg;
while (true)
{
if (PeekMessage(out msg, IntPtr.Zero, 0, 0, PM_REMOVE))
{
if (msg.Message == WM_QUIT)
break;
TranslateMessage(ref msg);
DispatchMessage(ref msg);
}
}
}
[StructLayout(LayoutKind.Sequential)]
private struct MSG
{
public IntPtr Hwnd;
public uint Message;
public IntPtr WParam;
public IntPtr LParam;
public uint Time;
}
const uint PM_NOREMOVE = 0;
const uint PM_REMOVE = 1;
const uint WM_QUIT = 0x0012;
[DllImport("user32.dll")]
private static extern bool PeekMessage(out MSG lpMsg, IntPtr hwnd, uint wMsgFilterMin, uint wMsgFilterMax, uint wRemoveMsg);
[DllImport("user32.dll")]
private static extern bool TranslateMessage(ref MSG lpMsg);
[DllImport("user32.dll")]
private static extern IntPtr DispatchMessage(ref MSG lpMsg);
}
}
If you want to put your logic inside the mouse click handler you can simply call GetActiveWindow to get window handle (if you dont already have it). Then you can use GetWindowThreadProcessId to get process id from window handle.
Doing this with every mouse click looks like an overkill, however. You should probably think about hooking to active window change. Check this for details: Is there Windows system event on active window changed?

Categories

Resources