From: "Valdas Bucinskas" valdas.bucinskas@ipsistemos.lt
Hello, I liked your example a lot. I was playing with it recently, and got some questions.
- Is there any documentation on what methods can be called from
user32.dll,
kernel32.dll, psapi.dll (the dlls I see in Win32Window instance methods)?
Documentation is a problem. You really need the documentation of (one of the newer) Windows SDK. Programmers that have connection time for free or at a very low rate can read this documentation in the internet. Programmers that have access to the IBM Smalltalk system can look into class OSCall and pool dictionary PlatformFunctions to see what is available for Windows 95 (To the best of my knowledge, the calls for many newer API functions are not provided in OSCall, but can easily be added by an user that needs them.)
- I tried to know some information about other process than Squeak.exe,
but
couldn't figure out how to do that ?
Newer Windows versions have the API function EnumProcesses (in psapi.dll) that let you da that. The function writes the IDs of all processes into an array. In squeak, you use a ByteArray as argument for the method call and some auxiliary protocol form ByteArray to convert the bytes into integers. Once you have the process IDs, you can collect all process-related information for the processes.
For autentic information, please read this page: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/perfmon/bas e/enumprocesses.asp
The attached changes set contains additional methods for these API functions: EnumProcesses OpenProcess CloseHandle LastError
With these you can evaluate this example (you find it also in the preambble of the change set. ):
| interface array uint cb x err handleArray i j upperIdx oc processHandle | interface := Win32Window new. array := ByteArray new: 8000. " sufficient for up to 2000 processes " uint := ByteArray new: 4. cb := 8000. x := interface apiEnumProcesses: array size: cb bytesReturned: uint . x ifFalse: [ err := interface getLastError. err]. handleArray := OrderedCollection new: 2000.
" convert the bytes into unsigned integers " upperIdx := uint unsignedLongAt: 1. j := i := 1.
[j < upperIdx] whileTrue: [ handleArray add: (array unsignedLongAt: j).
i := i + 1. j := j + 4.
].
" use the process IDs to open the processes and to query the amount of resources they use. " oc := OrderedCollection new. handleArray do: [:idx | processHandle := interface getProcessHandleWithAccessRights: 16r400 inherit: true processId: idx. processHandle notNil ifTrue: [ oc add: (Array with: idx with: (interface apiGetGuiResources: processHandle type: 0) with: (interface apiGetGuiResources: processHandle type: 1) ).
interface closeHandle: processHandle.] ]. oc inspect " It is a nice idea to compare this with the data that are shown in the Task Manager "
======================================
I also fixed a bug from the example that I posted yesterday:
The typeSIZE_T is an unsigned long integer (That is what I found in the file _stddef.h of the Borland c++ compiler). In my example from yesterday I interpreted these values as signed integers. This is wrong and should be changed. The subclasses of ExternalStructure understand the class method defineFields that creates the accessors for all items that are declared in the fields method.
You see that the use of FFI is not really difficult; what you have to do it to translate the specifications from the Microsoft Documentation into api calls.
Have success.
Gretings Boris