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, ...);