What can I call EnumWindowsProc?

I am trying to list all running processes on my computer.

What is wrong with my call statement EnumWindowsProc() in my short sample code. My compiler claims that on this line:

 EnumWindows(@EnumWindowsProc, ListBox1); 

that there must be a variable inside the function call. How do I change @EnumWindowsProc to var?

 unit Unit_process_logger; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls; type TForm1 = class(TForm) ListBox1: TListBox; Timer1: TTimer; procedure Timer1Timer(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; function EnumWindowsProc(wHandle: HWND; lb: TListBox): Boolean; var Form1: TForm1; implementation {$R *.dfm} function EnumWindowsProc(wHandle: HWND; lb: TListBox): Boolean; var Title, ClassName: array[0..255] of Char; begin GetWindowText(wHandle, Title, 255); GetClassName(wHandle, ClassName, 255); if IsWindowVisible(wHandle) then lb.Items.Add(string(Title) + '-' + string(ClassName)); end; procedure TForm1.Timer1Timer(Sender: TObject); begin ListBox1.Items.Clear; EnumWindows(@EnumWindowsProc, ListBox1); end; end. 
+4
source share
1 answer

First of all, the announcement is incorrect. It should be stdcall and it returns BOOL .

 function EnumWindowsProc(wHandle: HWND; lb: TListBox): BOOL; stdcall; 

Secondly, your implementation does not set the return value. Return True to continue enumeration, False to stop enumeration. In your case, you need to return True .

Finally, you will need to display the LPARAM list box when you call EnumWindows .

 EnumWindows(@EnumWindowsProc , LPARAM(ListBox1)); 

See the documentation for more information.

Combining all this, you have the following:

 function EnumWindowsProc(wHandle: HWND; lb: TListBox): BOOL; stdcall; var Title, ClassName: array[0..255] of char; begin GetWindowText(wHandle, Title, 255); GetClassName(wHandle, ClassName, 255); if IsWindowVisible(wHandle) then lb.Items.Add(string(Title) + '-' + string(ClassName)); Result := True; end; procedure TForm1.Timer1Timer(Sender: TObject); begin ListBox1.Items.Clear; EnumWindows(@EnumWindowsProc, LPARAM(ListBox1)); end; 

Note that EnumWindows does not list all running processes. What he does is list all the top-level windows. Pay attention to the same. EnumProcesses exists to list all running processes. However, since you are reading window names and window class names, you probably want to use EnumWindows .


As I said many times, I do not agree that translating the Delphi header to EnumWindows uses the Pointer for the EnumWindowsProc parameter. This means that you cannot rely on the compiler to check type safety. I personally always use my own version of EnumWindows .

 type TFNWndEnumProc = function(hwnd: HWND; lParam: LPARAM): BOOL; stdcall; function EnumWindows(lpEnumFunc: TFNWndEnumProc; lParam: LPARAM): BOOL; stdcall; external user32; 

And then, when you call the function, you are not using the @ operator, so let the compiler check the validity of your callback function:

 EnumWindows(EnumWindowsProc, ...); 
+11
source

All Articles