How do I call EnumWindowsProc?
delphi, delphi-xe2
Solution
First of all the declaration is wrong. It needs to be `stdcall`, and it returns `BOOL`.
function EnumWindowsProc(wHandle: HWND; lb: TListBox): BOOL; stdcall;
Secondly, your implementation doesn't set the return value. Return `True` to continue enumeration, `False` to stop enumeration. In your case you need to return `True`.
Finally, you'll need to cast the list box to be `LPARAM` when you call `EnumWindows`.
EnumWindows(@EnumWindowsProc , LPARAM(ListBox1));
Consult the documentation for the full details.
Putting it all together you have this:
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 also that `EnumWindows` does not enumerate all running processes. What it does is enumerate all top level windows. Note quite the same thing. To enumerate all running processes there is `EnumProcesses`. However, since you are reading out window titles and window class names, you probably do want to use `EnumWindows`.
As I've said many times before, I loath the fact that the Delphi header translation for `EnumWindows` uses `Pointer` for the `EnumWindowsProc` parameter. Which means that you can't 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 don't use the `@` operator and so let the compiler check that your callback function is declared correctly:
EnumWindows(EnumWindowsProc, ...);
Problem
I'm, trying to list all running processes on my computer. What is wrong with my `EnumWindowsProc()` calling statement in my short example code. My compiler claims that, in this line: ``` EnumWindows(@EnumWindowsProc, ListBox1); ``` that there needs to be a variable inside the function call. How should I change `@EnumWindowsProc` to a 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. ```