6

私は、自分のコンピューターで実行中のすべてのプロセスを一覧表示しようとしています。

EnumWindowsProc()短いサンプルコードの呼び出しステートメントの何が問題になっていますか。私のコンパイラは、この行で次のように主張しています。

EnumWindows(@EnumWindowsProc, ListBox1);

関数呼び出し内に変数が必要であること。@EnumWindowsProcvarに変更するにはどうすればよいですか?

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

1 に答える 1

16

まず第一に、宣言は間違っています。である必要がありstdcall、を返しますBOOL

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

第二に、あなたの実装は戻り値を設定しません。列挙を停止するTrueには、列挙を続行するために戻ります。Falseあなたの場合、あなたは戻る必要がありますTrue

LPARAM最後に、を呼び出すときにリストボックスをキャストする必要がありますEnumWindows

EnumWindows(@EnumWindowsProc , LPARAM(ListBox1));

詳細については、ドキュメントを参照してください。

すべてをまとめると、次のようになります。

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;

EnumWindowsまた、実行中のすべてのプロセスを列挙しているわけではないことにも注意してください。それが行うことは、すべてのトップレベルウィンドウを列挙することです。まったく同じことに注意してください。実行中のすべてのプロセスを列挙するには、がありEnumProcessesます。ただし、ウィンドウのタイトルとウィンドウのクラス名を読み取っているので、おそらくを使用することをお勧めしますEnumWindows


以前にも何度も言ったように、Delphiヘッダー変換がパラメータにEnumWindows使用Pointerされるという事実を嫌いEnumWindowsProcます。つまり、型の安全性をチェックするためにコンパイラーに頼ることはできません。私はいつも自分のバージョンのを使用していEnumWindowsます。

type
  TFNWndEnumProc = function(hwnd: HWND; lParam: LPARAM): BOOL; stdcall;

function EnumWindows(lpEnumFunc: TFNWndEnumProc; lParam: LPARAM): BOOL;
  stdcall; external  user32;

そして、関数を呼び出すときは@演算子を使用しないので、コールバック関数が正しく宣言されていることをコンパイラーに確認させます。

EnumWindows(EnumWindowsProc, ...);
于 2012-12-09T10:36:42.653 に答える