   A time tracker - Visual Basic
  I haven't programmed in Visual Basic in a while and was doing this as a sort of side project for my teacher.  He asked if I was willing to attempt to make him a Visual Basic program that will check what window is the currently active window, see if it is a sub-window of an already logged window, and record how long the window is in use.The problem that I have hit however is that, when i have multiple windows open under the same program such as Firefox, it records each as a separate entry.  I was hoping to make it so that it will record how long an application such as Firefox is open total, not how long each window is separately opened.To get the currently opened windows I am using the API commands: -GetForegroundWindow to get the window's handle-GetWindowText to get the window's titleI have attempted to use the GetParent, GetAncestor, and GetWindow commands, but I am not making any progress.Any help with this would be greatly appreciated.  The project isn't for a grade, just for my own knowledge; however, I would still like to see this project through to the end. (I hate quitting halfway through)If you think seeing my current code will help, let me know and i will post it the next time i check the forum.Sorry for the wall of text ^_^Thanks,~John   
  The last time I had to tackle this I used a brute force approach.I would GetForegroundWindow(), then GetWindowThreadProcessId() and GetModuleFileNameEx() to get the image which loaded the process - which happens to be the executable.Other ways are possible, psapi has a lot of tools to query just about anything.I don't really know the "best" way to do everything, the above just served me well enough to track how much time I spent in any given application.   ;  Thank you Antheus.  I'll be outta town for the next couple days but when I get back I'll try your suggestions.  I'm sure i can find the rest of the info I'll need from MSDN.Once again I really thank you for your suggestions.~John[Edited by - RaiderIV on June 16, 2009 11:39:56 AM];Quote:Original post by AntheusThe last time I had to tackle this I used a brute force approach.I would GetForegroundWindow(), then GetWindowThreadProcessId() and GetModuleFileNameEx() to get the image which loaded the process - which happens to be the executable.Other ways are possible, psapi has a lot of tools to query just about anything.I don't really know the "best" way to do everything, the above just served me well enough to track how much time I spent in any given application.Okay, I have just got back in town and I was trying out the suggestions you gave me; however, I am having a problem somewhere along the line function.Not all but majority of my code:    'Windows API functions    Private Declare Function GetForegroundWindow Lib "user32" () As System.IntPtr    Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" ( _   ByVal hWnd As System.IntPtr, _   ByVal lpString As System.Text.StringBuilder, _   ByVal nMaxCount As Integer) As Integer    Private Declare Function GetWindowThreadProcessId Lib "user32.dll" ( _   ByVal hwnd As Long, _   ByVal lpdwProcessId As Long) As System.IntPtr    Private Declare Function GetModuleFileNameEx Lib "psapi" Alias "GetModuleFileNameExA" ( _   ByVal hProcess As Long, _   ByVal lpFilename As System.Text.StringBuilder, _   ByVal nSize As Long) As LongPrivate Sub t_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles t.Tick   ' To store the handle to a window.   Dim hWnd As System.IntPtr   Dim procID As Long, _  testProcID As Long   ' To store the text of the title bar of the window.   Dim lpString As New System.Text.StringBuilder(255), _  lpFileName As New System.Text.StringBuilder(255)   Dim tempStr As String   Dim tempInt As Integer, listCount As Integer   Dim addItem As Boolean = False   ' Recieves the handle of the foreground window   hWnd = GetForegroundWindow()   ' Gets title of the active window   GetWindowText(hWnd, lpString, lpString.Capacity)   procID = GetWindowThreadProcessId(hWnd, testProcID)   GetModuleFileNameEx(procID, lpFileName, lpFileName.Capacity)   tempStr = lpFileName.ToString()   lblTestLabel.Text = tempStrEnd SubWhen outputting various variables to lblTestLabel.Text they show up as:testProcID = 0procID = a large number that changes every time I run the programlpFileName = ""I know that GetModuleFileNameEx is suppose to get me the path of the .exe file, but when i try to output it to lblTestLabel, I get nothing.any ideas or suggestions?I've looked for a few examples or some help from google to no avail, so I figure the next best step would be to breakdown and ask other people for help.Thanks,~John;  I think:Private Declare Function GetWindowThreadProcessId Lib "user32.dll" ( _   ByVal hwnd As Long, _   ByVal lpdwProcessId As Long) As System.IntPtrshould be:Private Declare Function GetWindowThreadProcessId Lib "user32.dll" ( _   ByVal hwnd As Long, _   ByRef lpdwProcessId As Long) As System.IntPtrBut I'm not 100% with vb syntax. You want to pass in the address of the 2nd parameter. Lucky testProcID is set to 0 when it is declared or else you would most likely get a runtime error.   