VB: How to monitor opened windows and programs

Source: Internet
Author: User
This problem was raised by csdn netizen matthgh (before dawn). There are actually many solutions to this problem. Here I use the wh_shell hook to solve this problem, and the wh_shell Hook can get a lot of information, for example, window creation, window destruction, window activation, and the title bar of the window are re-painted. However, the information is based on the window, And matthgh wants to obtain the corresponding program at the same time. Then, how can we obtain the corresponding program path based on the handle of the window handle? Of course, this can be obtained by enumerating all processes. However, the speed will be slower, I used another method in the program. Although this method is common, I guess some of my friends may not know it yet. So I will explain it in a simple way:

'Obtain the corresponding program path based on the window handle, only applicable to the NT Platform
Public Function getexefromhandle (optional byval nhwnd as long = 0) as string
Dim nprocid as long
Dim nresult as long
Dim ntemp as long
Dim lmodules (1 to 200) as long
Dim sfile as string
Dim hprocess as long'
If nhwnd = 0 then nhwnd = getforegroundwindow ()
'Obtain the processid of the window.
If getwindowthreadprocessid (nhwnd, nprocid) <> 0 then
'Open process and obtain the process handle corresponding to the window.
Hprocess = OpenProcess (process_query_information or _
Process_vm_read, 0, nprocid)
If hprocess <> 0 then
'Obtain the module corresponding to the window
Nresult = enumprocessmodules (hprocess, lmodules (1 ),_
200, ntemp)
If nresult <> 0 then
'Get the program name
Sfile = space $ (260)
Nresult = getmodulefilenameex (hprocess, 0, sfile, Len (sfile ))
Sfile = lcase $ (left $ (sfile, nresult ))
Getexefromhandle = sfile
End if
'Close Process
Closehandle hprocess
End if
End if
End Function

Note the comments at the beginning of the function. This method is only applicable to the NT platform, so friends who use Win9x are still honest enumeration processes. Such code can be easily found on the Internet, I won't be arrogant here.
The wh_shell hook is described as follows on msdn:
Wh_shell hook

A shell application can use the wh_shell hook to receive important notifications. the system calla wh_shell hook procedure when the shell application is about to be activated and when a top-level window is created or destroyed.

Note that custom shell applications do not receive wh_shell messages. therefore, any application that registers itself as the default shell must call the systemparametersinfo function with spi_setminimizedmetrics before it (or any other application) can receive wh_shell messages.

The description of shellproc function can be viewed here: http://msdn.microsoft.com/library/en-us/winui/winui/windowsuserinterface/windowing/hooks/hookreference/hookfunctions/shellproc.asp? Frame = true
Some friends may think that an additional DLL is required to hook messages of other programs. Here I explicitly say that no additional DLL is needed. In fact, there is an API function numbered 181 in shell32.dll, which provides strong support for us to solve this problem. This function is usually declared in VB:
Declare function registershellhook lib "shell32" alias "#181" (byval hwnd as long, byval naction as long) as long
Hwnd is the window handle, while naction is usually the constant below:
Const rsh_deregister = 0
Const rsh_register = 1
Const rsh_register_progman = 2
Const rsh_register_taskman = 3

By using this API function, you can receive messages such as window creation and window destruction of other programs in your program. Note that by default, your program cannot receive these messages. If your program wants to receive these messages, you must register a message named "shellhook" using the registerwindowmessage function.
However, my program uses another API function: registershellhookwindow. This function serves the same purpose as the previously declared registershellhook function, but it only has one parameter, it looks more comfortable, the Message description about this function can be viewed here: http://msdn.microsoft.com/library/en-us/winui/winui/windowsuserinterface/windowing/hooks/hookreference/hookfunctions/registershellhookwindow.asp? Frame = true
According to the msdn instructions, this function can work in more than 2000 systems. I cannot find 2000 for the moment. I can say for sure that it works well in my XP SP2, if it cannot work well in 2000, use registershellhook instead of registershellhookwindow in the program. If it is good, let's talk about it here. The following code is provided:
A module and a form (the form name is form1, and the form has a ListBox (list1 ):

Module code:
Option explicit
Private declare function callwindowproc lib "USER32" alias "callwindowproca "(_
Byval lpprevwndfunc as long, byval hwnd as long ,_
Byval MSG as long, byval wparam as long ,_
Byval lparam as long) as long
Declare function getprocaddress lib "Kernel32" (byval hmodule as long, byval lpprocname as string) as long
Declare function loadlibrary lib "Kernel32" alias "loadlibrarya" (byval lplibfilename as string) as long
Private declare function getwindowtext lib "USER32" alias "getwindowtexta "(_
Byval hwnd as long, byval lpstring as string ,_
Byval CCH as long) as long

Private declare function registerwindowmessage lib "USER32" alias _
"Registerwindowmessagea" (byval lpstring as string) as long


Private declare function setwindowlong lib "USER32" alias _
"Setwindowlonga" (byval hwnd as long, byval nindex as long ,_
Byval dwnewlong as long) as long

Private declare function getwindowlong lib "USER32" alias _
"Getwindowlonga" (byval hwnd as long, byval nindex as long) as long
Private declare function registershellhook lib "shell32" alias "#181 "_
(Byval hwnd as long, byval naction as long) as long

Private declare function registershellhookwindow lib "USER32 "_
(Byval hwnd as long) as long
Private declare function getforegroundwindow lib "USER32" () as long

Private declare function getwindowthreadprocessid lib "USER32 "(_
Byval hwnd as long ,_
Lpdwprocessid as long) as long

Private declare function OpenProcess lib "Kernel32 "(_
Byval dwdesiredaccess as long ,_
Byval binherithandle as long ,_
Byval dwprocessid as long) as long

Private declare function enumprocessmodules lib "psapi. dll "(_
Byval hprocess as long ,_
Byref lphmodule as long ,_
Byval CB as long ,_
Byref lpcbneeded as long) as long

Private declare function getmodulefilenameex lib "psapi. dll "_
Alias "getmodulefilenameexa "(_
Byval hprocess as long ,_
Byval hmodule as long ,_
Byval lpfilename as string ,_
Byval nsize as long) as long

Private declare sub closehandle lib "Kernel32" (byval hpass as long)

Private const process_query_information = 1024.
Private const process_vm_read = 16

Private const hshell_windowcreated = 1
Private const hshell_windowdestroyed = 2
Private const hshell_activateshellwindow = 3
Private const hshell_windowactivated = 4
Private const hshell_getminrect = 5
Private const hshell_redraw = 6
Private const hshell_taskman = 7
Private const hshell_language = 8

Private const wm_ncdestroy = & h82

Private const gwl_wndproc =-4

Private const wh_shell = 10
Private const wh_cbt as long = 5

Private const gw_owner = 4
Private const gwl_exstyle = (-20)
Private const ws_ex_toolwindow = & h80
Private const ws_ex_appwindow = & h40000

Private const rsh_deregister = 0
Private const rsh_register = 1
Private const rsh_register_progman = 2
Private const rsh_register_taskman = 3

Private lpprevwndproc as long
Public msgshellhook as long

Public sub unhook (hwnd as long)
'Call registershellhook (hwnd, rsh_deregister)
Setwindowlong hwnd, gwl_wndproc, lpprevwndproc
End sub

Public sub starthook (hwnd as long)
Msgshellhook = registerwindowmessage ("shellhook ")
Dim hlibshell as long

Registershellhookwindow hwnd
'Call registershellhook (hwnd, rsh_register or rsh_register_taskman or rsh_register_progman)
Lpprevwndproc = setwindowlong (hwnd, gwl_wndproc, addressof windowproc)
End sub

Private function windowproc (byval hwnd as long, byval umsg as long ,_
Byval wparam as long, byval lparam as long) as long
Select case umsg
Case wm_ncdestroy
Unhook hwnd
Case msgshellhook
Select case wparam
Case hshell_windowcreated
Addcreatedstr lparam
'Case hshell_windowdestroyed
'This is useless. If you want to use it, add your code.
'Case hshell_redraw
'This is useless. If you want to use it, add your code.
'Case hshell_windowactivated
'This is useless. If you want to use it, add your code.
'Case hshell_getminrect
'This is useless. If you want to use it, add your code.
'Case hshell_redraw
'This is useless. If you want to use it, add your code.
'Case hshell_taskman
'This is useless. If you want to use it, add your code.
'Case hshell_language
'This is useless. If you want to use it, add your code.
End select
End select
Windowproc = callwindowproc (lpprevwndproc, hwnd, umsg, wparam, lparam)
End Function

Private function getexefromhandle (optional byval nhwnd as long = 0) as string
Dim nprocid as long
Dim nresult as long
Dim ntemp as long
Dim lmodules (1 to 200) as long
Dim sfile as string
Dim hprocess as long'
If nhwnd = 0 then nhwnd = getforegroundwindow ()
If getwindowthreadprocessid (nhwnd, nprocid) <> 0 then
Hprocess = OpenProcess (process_query_information or _
Process_vm_read, 0, nprocid)
If hprocess <> 0 then
Nresult = enumprocessmodules (hprocess, lmodules (1 ),_
200, ntemp)
If nresult <> 0 then
Sfile = space $ (260)
Nresult = getmodulefilenameex (hprocess, 0, sfile, Len (sfile ))
Sfile = lcase $ (left $ (sfile, nresult ))
Getexefromhandle = sfile
End if
Closehandle hprocess
End if
End if
End Function

Private function getwindowcaption (byval hwnd as long) as string
Dim mystr as string
Mystr = string (256, CHR $(0 ))'
Getwindowtext hwnd, mystr, 256
Mystr = left $ (mystr, instr (mystr, CHR $ (0)-1)
Getwindowcaption = mystr

End Function

Private sub addcreatedstr (byval hwnd as long)
If hwnd = 0 Then exit sub
Dim s as string
S = format (now, "Mm DD, yyyy hh: mm: SS ")
Dim mcaption as string
Mcaption = getwindowcaption (hwnd)
Dim exename as string
Exename = getexefromhandle (hwnd)
If mcaption <> "" And exename <> "" then
S = S + "the window with the handle:" + CSTR (hwnd) + "is created and the title is" + mcaption + ". The corresponding program path is:" + exename
Elseif mcaption = "" And exename <> "then
S = S + "the window with the handle:" + CSTR (hwnd) + "is created, and the corresponding program path is:" + exename
Elseif mcaption <> "" And exename = "" then
S = S + "the window with the handle:" + CSTR (hwnd) + "is created with the title:" + mcaption
Elseif mcaption = "" And exename = "" then
S = S + "the window with the handle:" + CSTR (hwnd) + "is created"
End if
Form1.list1. additem s
End sub

Form code:
Option explicit

Private sub form_load ()
Starthook me. hwnd
End sub

Private sub form_unload (cancel as integer)
Unhook me. hwnd
End sub

Private sub form_resize ()
List1.move 0, 0, scalewidth, scaleheight
End sub

Private sub listmediaclick ()
Msgbox list1.text
End sub

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.