• 0

[C#] attach event to window exit


Question

I launch an application through another application. I can get the window handle of the application, and I want to add an event to it when it is closed.

When it is closed, I want to do something in my applcation... so I'm looking to attach to a window I guess, and when its Exited, throw an event and do something.

Any ideas?

Link to comment
https://www.neowin.net/forum/topic/616922-c-attach-event-to-window-exit/
Share on other sites

7 answers to this question

Recommended Posts

  • 0

Something along the lines of this?

using System.Windows.Forms;

class ClassName : Form
{
	//some class variables, methods, delegates, etc. ?
	ClassName ()
	{
		//some other things?
		this.FormClosing += new FormClosingEventHandler(formClosing);
	}

	void formClosing (object sender, FormClosingEventArgs)
	{
		//If you are using multithreaded programming, make sure to notify the threads that the app is
		//	closing somehow. Otherwise, you'll get exceptions (in the console if compiled as a console app)

		// THROW YOUR EVENT SOMEWHERE IN HERE
	}

	public static void Main (string[] args)
	{
		Application.Run(new ClassName());
	}
}

  • 0

My title and post are unclear...

I basically only have the Window handle, an IntPtr of the application of which I want to attach events to. Whenever this external window is closed, I want an event to be called in my application.

I understand events and the simplicity... .Exited or whatever, but I ONLY have the IntPtr handle to the window.

  • 0

You'll want to hook into Windows and monitor the WM_Close (WM_CLOSE = 0x0010) event and check the handle you have against the handle of the window being closed. You do this by overriding the WndProc event. Or you can set up a system wide hook The following is what I use to set this up. Just copy this into a .cs file (ex. Hook.cs) and create a reference to this in your form.

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;

namespace Hook
{
	public delegate void OnForegroundWindowChangedDelegate(IntPtr hWnd);
	public delegate void OnWindowMinimizeStartDelegate(IntPtr hWnd);
	public delegate void OnWindowMinimizeEndDelegate(IntPtr hWnd);
	public delegate void OnWindowDestroyDelegate(IntPtr hWnd);

	public sealed class Hooks
	{
		#region Windows API

		private enum SystemEvents : uint
		{
			EVENT_SYSTEM_DESTROY = 0x8001,
			EVENT_SYSTEM_MINIMIZESTART = 0x0016,
			EVENT_SYSTEM_MINIMIZEEND = 0x0017,
			EVENT_SYSTEM_FOREGROUND = 0x0003
		}

		private const uint WINEVENT_OUTOFCONTEXT = 0x0000;

		private delegate void WinEventDelegate(
			IntPtr hWinEventHook,
			uint eventType,
			IntPtr hWnd,
			int idObject,
			int idChild,
			uint dwEventThread,
			uint dwmsEventTime);

		[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
			);

		#endregion

		private WinEventDelegate dEvent;
		private IntPtr pHook;
		public OnForegroundWindowChangedDelegate OnForegroundWindowChanged;
		public OnWindowMinimizeStartDelegate OnWindowMinimizeStart;
		public OnWindowMinimizeEndDelegate OnWindowMinimizeEnd;
		public OnWindowDestroyDelegate OnWindowDestroy;

		public Hooks()
		{
			dEvent = this.WinEvent;
			pHook = SetWinEventHook(
				(uint)SystemEvents.EVENT_SYSTEM_DESTROY ,
				(uint)SystemEvents.EVENT_SYSTEM_DESTROY ,
				IntPtr.Zero,
				dEvent,
				0,
				0,
				WINEVENT_OUTOFCONTEXT
				);

			if (IntPtr.Zero.Equals(pHook)) throw new Win32Exception();

			GC.KeepAlive(dEvent);
		}

		private void WinEvent(IntPtr hWinEventHook, uint eventType, IntPtr hWnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
		{
			switch (eventType)
			{
				case (uint)SystemEvents.EVENT_SYSTEM_DESTROY:
					if (OnWindowDestroy != null) OnWindowDestroy(hWnd);
					break;

				//extend here when required
			}
		}

		~Hooks()
		{
			if (!IntPtr.Zero.Equals(pHook)) UnhookWinEvent(pHook);
			pHook = IntPtr.Zero;
			dEvent = null;

			OnWindowDestroy = null;
		}
	}
}

Then to use this, insert this into your form:

Hook hook = new Hook();

And then in your form's loading event insert this to set up an event for the hook:

hook.OnWindowDestroy += OnWindowDestroyDelegate(window_Destroyed);

private void window_Destroyed(IntPtr hWnd)
{
	 if (hWnd == {the handle you're looking for})
	 {
		  //Do whatever you need here!
	 }
}

Hope it helps.

  • 0

This is great... one problem... (I'm awful with delegates, I really need a book).

The hook setup gives me an error:

hook.OnWindowDestroy += OnWindowDestroyDelegate(window_Destroyed);

project.OnWindowDestroyDelegate' is a 'type' but is used like a 'variable'

I copied your code exactly, but just changed the namespace to my project.. I think that's correct...

  • 0
  zackiv31 said:
This is great... one problem... (I'm awful with delegates, I really need a book).

The hook setup gives me an error:

hook.OnWindowDestroy += OnWindowDestroyDelegate(window_Destroyed);

project.OnWindowDestroyDelegate' is a 'type' but is used like a 'variable'

I copied your code exactly, but just changed the namespace to my project.. I think that's correct...

Sorry, I forgot to type 'new' in there. The correct line should be:

hook.OnWindowDestroy += new OnWindowDestroyDelegate(window_Destroyed);

  • 0
  zackiv31 said:
This is great... one problem... (I'm awful with delegates, I really need a book).

The hook setup gives me an error:

hook.OnWindowDestroy += OnWindowDestroyDelegate(window_Destroyed);

project.OnWindowDestroyDelegate' is a 'type' but is used like a 'variable'

I copied your code exactly, but just changed the namespace to my project.. I think that's correct...

This is really very helpful post.

One question: I want to handle other message, like WM_PAINT, WM_MOVE, etc. in this case how can I get the message codes?

I tried declaring EVENT_SYSTEM_PAINT = 0x000F but this is not working.

Kindly suggest.

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • I happen to try it today not knowing about the update and was happily surprised; it is great.
    • Hello, Hardware Support Applications are a special kind of Microsoft Store app and have to go through additional checks and certifications because they can communicate directly with their driver, which means that a vulnerability in one of them could allow an attacker access to kernel space memory through the HSA ←→ device driver interface.  In other words, a BYOVD (bring your won vulnerable driver) attack, but with the HSA being used as an extra step. Remember, the Microsoft Store is strategic to Microsoft's long-term goals: they see it as the means to get the same 30% of every application sale that Apple and Google get through their stores, which is why it has been a fixture of Windows since Windows 8 was introduced in 2012 despite a low adoption rate.  Microsoft cannot afford to have anyone get an app through their store which causes a security issue for their end users.  Even if the app was written by and uploaded to the Microsoft Store by a partner, it is Microsoft's name on the store, and they are the ones that will have reputational/brand damage if they allow something malicious into their store. Regards, Aryeh Goretsky  
    • This is more from my childhood, when nickelodeon just launched and had to license shows to have something to air. Left a big an impact, but probably more emotion positive / childhood thing. Europe got the follow up season's decade's latter with the animation studio that did Air Bender but never licenses for the US. I miss the day's of longer intro's. Nier (PS3) Intro is epic, and was very unexpected.  PS1 Xengears was also epic and an amazing game.  
    • Sayan Sen, do you think one day an image of the Windows Vista desktop or the wallpaper could be used in the primary image of an article? (When I think of CDs and DVDs I think of that release of Windows and of earlier releases; it is the one that debuted IMAPI 2.0 and other features.)
  • Recent Achievements

    • Week One Done
      Ricky Chan earned a badge
      Week One Done
    • Week One Done
      maimutza earned a badge
      Week One Done
    • Week One Done
      abortretryfail earned a badge
      Week One Done
    • First Post
      Mr bot earned a badge
      First Post
    • First Post
      Bkl211 earned a badge
      First Post
  • Popular Contributors

    1. 1
      +primortal
      484
    2. 2
      +FloatingFatMan
      263
    3. 3
      snowy owl
      240
    4. 4
      ATLien_0
      227
    5. 5
      Edouard
      188
  • Tell a friend

    Love Neowin? Tell a friend!