0

How can I detect whether Windows are created for the first time and closed (not minimised)? I need to log the time a new window which belongs to a process is created and closed.

My current implementation is:

public partial class Form2 : Form
{

    WinEventDelegate dele2 = null;

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

    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 uint EVENT_SYSTEM_FOREGROUND = 3;
    private const uint EVENT_SYSTEM_DESTROY = 0x8001;
    private const uint EVENT_OBJECT_CREATE = 0x8000;

    [DllImport("user32.dll")]
    static extern IntPtr GetForegroundWindow();

    [DllImport("user32.dll")]
    static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);

    [DllImport("user32.dll")]
    public static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, out uint ProcessId);

    public Form2()
    {
        InitializeComponent();

        dele2 = new WinEventDelegate(WinEventProcDestory);
        SetWinEventHook(EVENT_OBJECT_CREATE, EVENT_SYSTEM_DESTROY, IntPtr.Zero, dele2, 0, 0, WINEVENT_OUTOFCONTEXT);
    }

    private string GetActiveWindowTitle()
    {
        const int nChars = 256;
        IntPtr handle = IntPtr.Zero;
        StringBuilder Buff = new StringBuilder(nChars);
        handle = GetForegroundWindow();

        if (GetWindowText(handle, Buff, nChars) > 0)
        {
            return Buff.ToString();
        }
        return null;
    }

    private String GetProcessName(IntPtr hwnd)
    {
        uint pid;
        IntPtr ptr = GetWindowThreadProcessId(hwnd, out pid);
        Process p = Process.GetProcessById((int)pid);

        return p.ProcessName;
    }

    public void WinEventProcDestory(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
    {
        String windowTitle = GetActiveWindowTitle();
        this.dataGridView2.Rows.Add(windowTitle, DateTime.Now, "-");
    }
}

As you can see in the implementation I'm logging each event to a datagrid and as soon as I start the application I get 10+ events for this or any other application I open. I expected just one.

Alternatively is there a better way to do is with Java (JNI)? Open to all solutions.

Thanks in advance!

User24231
  • 506
  • 1
  • 7
  • 20
  • [EVENT_OBJECT_CREATE and EVENT_OBJECT_DESTROY](https://msdn.microsoft.com/en-us/library/windows/desktop/dd318066.aspx) report the events when a window is created and destroyed, respectively. I don't know, what you mean by *open* and *close*. You will have to provide a succinct specification if you need a concise answer. It's also necessary to state, why you believe the aforementioned events are raised too often. From my experience, those events are raised precisely once per window. – IInspectable Dec 12 '15 at 16:22
  • Hi thanks for you reply. Apologies for the ambiguities in my question, I've just edited it. I'm not exactly sure on the correct Window State terminology but I hope you understand what I'm trying to achieve. – User24231 Dec 12 '15 at 19:40
  • `EVENT_OBJECT_CREATE` is raised for **every** window created. Applications usually consist of many windows, the 'main' application window, custom child windows, and controls, so I would expect to see multiple `EVENT_OBJECT_CREATE` events when launching a single application. Windows can also be created without being shown, which also raises this event. This is often done during startup to allocate resources required to display error messages. Maybe you need to explain why you need to know. – IInspectable Dec 12 '15 at 19:47
  • So I need to log the time a user opens an application and time a user closes the application. For example if a user opens Notepad, the time needs to be logged and then again only when Notepad is closed. I guess currently I'm logging the time for child windows, controls etc. Is there a way to filter these out and just care about the first event and when the main application is destroyed? – User24231 Dec 12 '15 at 20:10
  • You are going about this the wrong way. There is no 1:1 mapping between windows and applications. Any application can have zero or more windows. There is, however, a 1:1 mapping between processes and applications, so you need to monitor process creation and termination. See [How to detect win32 process creation/termination in c++](http://stackoverflow.com/q/3556048/1889329). – IInspectable Dec 12 '15 at 20:15
  • @IInspectable An application can use more than one process – David Heffernan Dec 12 '15 at 23:04

0 Answers0