Loading the module


First we must get the handle of the current module. If the user selects anything that causes a new process to become active, WinWatch will need to get a new module handle and update all the resources. Similarly, if the user selects a DLL or other module in the Modules list box, WinWatch must update the resources. Documentation for many of the Windows API resource functions say that these functions expect an instance handle. Ignore this. What they really want is a module handle (which is usually the same as the instance handle anyway).


Chapter 6 explained how to get a module handle with the ModFromProcID function. Unfortunately, this function only returns a valid module handle for the current program. If you get the module handle this way, you’ll only be able to view the resources of programs in your own address space. Under the surface, a module handle is actually a pointer, and a pointer from another program might as well be a pointer from another universe.


If you want to use the resources of a particular module, you’ll need to load that module into the current address space. You can do this with either the Load­Library or the LoadLibraryEx API function (we’ll use the Ex version). Normally, LoadLi­braryEx is used in other languages to load DLLs dynamically, but usually there’s no reason to do this with Visual Basic because DLLs are loaded automatically when you use API functions with the Declare syntax. Visual Basic can’t call function pointers retrieved with the GetProcAddress API function anyway. But you can load any EXE, DLL, or FON file into your address space and then use its resources.


That’s what the WinWatch UpdateDisplay procedure does in the following code block:

sModCur = ExePathFromProcID(idProcCur)
hMod = LoadLibraryEx(sModCur, 0, LOAD_LIBRARY_AS_DATAFILE)
’ Save process handle for FreeLibrary
hModFree = hMod

Notice that LoadLibraryEx has a flag that specifies that you need to use only resources. This is a little more efficient than loading all the procedure addresses that you couldn’t call anyway. When you’re done, call FreeLibrary to release the module:

‘ If process changed, update it
If idProc <> idProcCur Then
idProcCur = idProc
‘ Unload previous process
If hModFree Then Call FreeLibrary(hModFree)

The two preceding fragments are a tiny part of the complex UpdateDisplay procedure, which contains all the logic for figuring out what part of the Win­Watch display needs to change and how.