2

I want to know whether there is any event triggered when a new window appears/comes on the desktop. I am open to using COM,WMI,WinApis, UIAutomation or any other method but the language of choice is C#.

The actual requirement: A process has 1 main window and many other windows. The class name of one of the windows is, say, X, (i got this info using pinvoke). Now this window pops up some times whenever there is some notification in the process. I do not want to show this window. I do not have code access to that process so that i can disable that window. So is there any way that i can get an event or any other mechanism which keeps track of the desktop and anytime a window with classname X comes/about to come it hides it.

Do tell if i am not clear with the question. Thanks

EDIT : Simon's answer is really good. I tried that and am able to get notification for all windows except notifications/toast windows such as that of lync's im toast notification or outlook new mail notification. I tried with different elements of Automation Element and Windows Pattern but still could not get those...Any ideas how i can get those...you may read comments in Simon's answer for more context/detail. Once again thanks to Simon for introducing to the great power of UIAUtomation...Loving it!

Why
  • 626
  • 11
  • 29
  • 1
    I think you can use the [UI Automation](http://msdn.microsoft.com/en-us/library/ms753107(v=vs.110).aspx) - it supports a [`WindowOpened`](http://msdn.microsoft.com/en-us/library/system.windows.automation.windowpattern.windowopenedevent(v=vs.110).aspx) event – Damien_The_Unbeliever Jun 26 '14 at 07:25

3 Answers3

10

As Damien said in his comment, you can use UI automation, like this in a C# sample console app:

class Program
{
    static void Main(string[] args)
    {
        Automation.AddAutomationEventHandler(WindowPattern.WindowOpenedEvent, AutomationElement.RootElement, TreeScope.Subtree, (sender, e) =>
            {
                AutomationElement src = sender as AutomationElement;
                if (src != null)
                {
                    Console.WriteLine("Class : " + src.Current.ClassName);
                    Console.WriteLine("Title : " + src.Current.Name);
                    Console.WriteLine("Handle: " + src.Current.NativeWindowHandle);
                }
            });

        Console.WriteLine("Press any key to quit...");
        Console.ReadKey(true);
    }
}
Simon Mourier
  • 132,049
  • 21
  • 248
  • 298
  • hey...thanks...i have one more question...can we also get information about windows such as notificatios, for example the ones that come when new mail in outlook, or new im in lync/skype etc... I tried the above code but it did not show for such kind of windows...Through other win apis i have found that , for ex, the window class of lync toast notification is different than the conversation window class. SO i was hoping that on getting the event here i would just hide that window – Why Jun 26 '14 at 11:25
  • The Windows tree is huge. The sample uses AutomationElement.RootElement (which is the Desktop window) as the parent, and it does not get all sub windows notifications. But you can use other elements as the start. You can get other elements using the AutomationElement.FromHandle, FromPoint methods, etc. – Simon Mourier Jun 26 '14 at 12:03
  • I'm using the .NET automation library on Windows 10. I added an event handler just like your example -- rooted at RootElement, scope Subtree. But the odd thing is we nearly always see two events each time a window opens. Occasionally, there may be just a single event, but >95% of the time there are two. The events are distinct objects but contain the same EventId and from same source. Any clues where to look? – Steve Robbins Feb 13 '20 at 22:00
  • @SteveRobbins - I've tested my answer's code today with Windows 10 and it works fine. Do you have a problem with my sample or other code? If it's another code you should ask another question. – Simon Mourier Feb 13 '20 at 22:05
  • @SimonMourier good question. I was using my own code previously, but today I compiled your code exactly as presented above. I do see the same behaviour -- but only a few applications (two so far) exhibit double open events. One of them is my company's application, but the other one is Adobe Acrobat Reader DC Version 2020.006.20034. So the mystery deepens. – Steve Robbins Feb 15 '20 at 20:42
  • @SteveRobbins - ok, I guess these apps create multiple windows for some reason, but as an end-user you only see one – Simon Mourier Feb 16 '20 at 08:01
  • @SimonMourier: I definitely only see one window, but it's not clear that two are created -- the two events have the same window handle, for example. The only thing that comes to mind is temporally filter them -- i.e. ignore a second event for the same handle if it occurs within X seconds of the first. – Steve Robbins Feb 16 '20 at 18:44
3

One option is RegisterShellHookWindow. You supply a window handle that can receive notification messages. The notifications that could be useful to you are HSHELL_WINDOWCREATED or HSHELL_WINDOWACTIVATED.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
0

Here MSDN has provided code for registering for windows notifications. But this is specific to Windows Sever 2008. I think similar you can find for your version of Window.

Nitin Joshi
  • 1,638
  • 1
  • 14
  • 17