0

I'm trying to display the active time of different windows apps. like if the user change the window from Notepad to browser then the Notepad Active time will be displayed. This is output right now but the time is not accurate. i got the output using stopwatch. Any suggesion?

    public AppInfo GetActiveWindowTitle()
    {
        var handle = GetForegroundWindow();

        string name = "";
        uint pid = 0;
        GetWindowThreadProcessId(handle, out pid);
        Process p = Process.GetProcessById((int)pid);
        var processname = p.ProcessName;
        AppInfo appInfo = new AppInfo();
        appInfo.appname = processname;
        name = GetTitle(handle);
        appInfo.apptitle = name;
        if (!st.Contains(appInfo.apptitle)) {
            if (!st.Contains(appInfo.appname))
            {
                stopWatch.Reset();
                st.Push(appInfo.apptitle);
                st.Push(appInfo.appname);
                ///appInfo.startappTime = DateTime.Now;
                stopWatch.Start();
            }
        }
        else
        {
            stopWatch.Stop();
           // appInfo.endappTime = DateTime.Now;
           // appInfo.finalAppTime = appInfo.endappTime.Subtract(appInfo.startappTime);
           finalAppTime = stopWatch.Elapsed;
            appInfo.AppTotalTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",finalAppTime.Hours, finalAppTime.Minutes, finalAppTime.Seconds,finalAppTime.Milliseconds / 10);
            string appTitle = Convert.ToString(st.Pop());
            string appName = Convert.ToString(st.Pop());
            richTextBox1.Text = richTextBox1.Text + "\nApp Title= " + appTitle + "-------App Name =" + appName + "-----------------App Time =" + appInfo.AppTotalTime;
            
        }
            return appInfo;}

AppInfo appinfo = GetActiveWindowTitle();
richTextBox1.Text = richTextBox1.Text + "\n" + appinfo.appname + "-------" + appinfo.apptitle + "-----------------" + appinfo.AppTotalTime ;

This is the output

大陸北方網友
  • 3,696
  • 3
  • 12
  • 37
Adeel Yousafzai
  • 47
  • 1
  • 10

1 Answers1

0

Maybe you can monitor the active window via delegate WinEventDelegate.

Here is a simple demo that get "active time".

WinEventDelegate dele = null;
Stopwatch watch = new Stopwatch();

public Form1()
{
    InitializeComponent();
    dele = new WinEventDelegate(WinEventProc);
    IntPtr m_hhook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, IntPtr.Zero, dele, 0, 0, WINEVENT_OUTOFCONTEXT);
}

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 uint WINEVENT_OUTOFCONTEXT = 0;
private const uint EVENT_SYSTEM_FOREGROUND = 3;

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

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

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

string prewindow = "";

public void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
    watch.Stop();

    TimeSpan timeTaken = watch.Elapsed;
    string time = "Time taken: " + timeTaken.ToString(@"m\:ss\.fff");

    if (prewindow != "")
    {
        richTextBox1.Text += prewindow + ", " + time + "\n";
    }

    prewindow = GetActiveWindowTitle();

    watch.Restart();
}
大陸北方網友
  • 3,696
  • 3
  • 12
  • 37