我正试图在我的计算机上列出所有正在运行的进程.
EnumWindowsProc()我的简短示例代码中的调用语句有什么问题.我的编译器声称,在这一行:
EnumWindows(@EnumWindowsProc, ListBox1);
Run Code Online (Sandbox Code Playgroud)
在函数调用中需要一个变量.我应该如何更改@EnumWindowsProc为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.
Run Code Online (Sandbox Code Playgroud)
Dav*_*nan 12
首先,声明是错误的.它需要stdcall,并返回BOOL.
function EnumWindowsProc(wHandle: HWND; lb: TListBox): BOOL; stdcall;
Run Code Online (Sandbox Code Playgroud)
其次,您的实现不会设置返回值.返回True继续枚举,False停止枚举.在你的情况下,你需要返回True.
最后,您需要LPARAM在打电话时将列表框强制转换EnumWindows.
EnumWindows(@EnumWindowsProc , LPARAM(ListBox1));
Run Code Online (Sandbox Code Playgroud)
有关完整详细信息,请参阅文档.
总而言之,你有这个:
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;
Run Code Online (Sandbox Code Playgroud)
另请注意,EnumWindows不会枚举所有正在运行的进程.它的作用是枚举所有顶级窗口.注意完全相同的事情.要枚举所有正在运行的进程EnumProcesses.但是,由于您正在读出窗口标题和窗口类名称,您可能确实想要使用EnumWindows.
正如我以前多次说过,我不愿意的事实,德尔福标题翻译EnumWindows使用Pointer的EnumWindowsProc参数.这意味着您不能依赖编译器来检查类型安全性.我个人总是使用我自己的版本EnumWindows.
type
TFNWndEnumProc = function(hwnd: HWND; lParam: LPARAM): BOOL; stdcall;
function EnumWindows(lpEnumFunc: TFNWndEnumProc; lParam: LPARAM): BOOL;
stdcall; external user32;
Run Code Online (Sandbox Code Playgroud)
然后当你调用函数时你不使用@运算符,所以让编译器检查你的回调函数是否被正确声明:
EnumWindows(EnumWindowsProc, ...);
Run Code Online (Sandbox Code Playgroud)