Lately I am busy working on developing a small shell extension. There is a functionality in my shell extension, that user opens the .NET windows form by right clicking on a file (context menu). The user then decides to close the parent explorer window (instead of closing the windows form opened). Now, in such a case I would like to close the windows form too. So, to achieve this I had to subscribe to the close event of the windows explorer. The below code shows the how to achieve the same. Although I am monitoring window close (destroy event), this can done for any process in Windows for which you have the handler (For ex: Notepad). Read more at link provided in “References” section.

So we are going to do it by performing following steps:

  • Find out the handle of the window we are interested in
  • Hook the Destroy event
  • When the event is raised, perform the desired operation

Find out the handle of the window we are interested in

public static IntPtr Find(string moduleName, string mainWindowTitle) { //Search the window using Module and Title IntPtr WndToFind = NativeMethods.FindWindow(moduleName, mainWindowTitle); if (WndToFind.Equals(IntPtr.Zero)) { if (!string.IsNullOrEmpty(mainWindowTitle)) { //Search window using Title only. WndToFind = NativeMethods.FindWindowByCaption(WndToFind, mainWindowTitle); if (WndToFind.Equals(IntPtr.Zero)) return new IntPtr(0); } } return WndToFind; }

We call the Find method as below. P.S: In my shell extension this window handler is automatically given by the library to me, so I do not use Find method.

string ModuleName = "explorer.exe"; string MainWindowTitle = "Libraries"; var targetWnd = Find(ModuleName, MainWindowTitle);

Hook the Destroy event

Put the below code in your constructor or initialization method.

public MainWindow() { InitializeComponent(); Dictionary<AccessibleEvents, NativeMethods.WinEventProc> events = InitializeWinEventToHandlerMap(); //Hook window close event - close our HoverContorl on Target window close. NativeMethods.WinEventProc eventHandler = new NativeMethods.WinEventProc(events[AccessibleEvents.Destroy].Invoke); GCHandle gch = GCHandle.Alloc(eventHandler); _garbageHook = NativeMethods.SetWinEventHook(AccessibleEvents.Destroy, AccessibleEvents.Destroy, IntPtr.Zero, eventHandler , 0, 0, NativeMethods.SetWinEventHookParameter.WINEVENT_OUTOFCONTEXT); } private Dictionary<AccessibleEvents, NativeMethods.WinEventProc> InitializeWinEventToHandlerMap() { Dictionary<AccessibleEvents, NativeMethods.WinEventProc> dictionary = new Dictionary<AccessibleEvents, NativeMethods.WinEventProc>(); //You can add more events like ValueChanged - for more info please read - //http://msdn.microsoft.com/en-us/library/system.windows.forms.accessibleevents.aspx dictionary.Add(AccessibleEvents.Destroy, new NativeMethods.WinEventProc(this.DestroyCallback)); return dictionary; }

When the event is raised, perform the desired operation

private void DestroyCallback(IntPtr winEventHookHandle, AccessibleEvents accEvent, IntPtr windowHandle, int objectId, int childId, uint eventThreadId, uint eventTimeInMilliseconds) { //Make sure AccessibleEvents equals to LocationChange and the current window is the Target Window. if (accEvent == AccessibleEvents.Destroy && windowHandle.ToInt32() == _targetWindowHandler.ToInt32()) { //Queues a method for execution. The method executes when a thread pool thread becomes available. ThreadPool.QueueUserWorkItem(new WaitCallback(this.DestroyHelper)); } } private void DestroyHelper(object state) { MessageBox.Show("Good bye!"); //Removes an event hook function created by a previous call to NativeMethods.UnhookWinEvent(_garbageHook); }

This demo application can be downloaded from below provided link, where in I am opening the explorer window and listening to close event. On close I am showing a simple message box.

Download Code

References

Add your control on top of another application – By Shai Raiten


About author
Utkarsh Shigihalli
Utkarsh Shigihalli
Utkarsh is passionate about software development and has experience in the areas of Azure, Azure DevOps, C# and TypeScript. Over the years he has worked as an architect, independent consultant and manager in many countries including India, United States, Netherlands and United Kingdom. He is a Microsoft MVP and has developed numerous extensions for Visual Studio, Visual Studio Code and Azure DevOps.
We Are
  • onlyutkarsh
    Utkarsh Shigihalli
    Microsoft MVP, Technologist & DevOps Coach


  • arora_tarun
    Tarun Arora
    Microsoft MVP, Author & DevOps Coach at Avanade

Do you like our posts? Subscribe to our newsletter!
Our Book