Last active
November 28, 2018 14:16
-
-
Save xtu/c4a4c179261c4768e1eac8188448ac72 to your computer and use it in GitHub Desktop.
A class to monitor when a WinForm form is found
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Runtime.InteropServices; | |
using System.Windows.Forms; | |
namespace WindowsFormsApp11 | |
{ | |
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); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment