如何修改我的EnumWindowNamesProc以使用Lazarus并使用List作为参数?

时间:2016-07-25 15:02:49

标签: delphi lazarus

概述

我试图枚举所有可见窗口名称的列表,然后填充作为参数传递的列表。

在Delphi中,我能够使用以下内容:

EnumWindows(@EnumWindowNamesProc, LPARAM(FWindowNames));

然后我可以这样称呼上述内容:

FWindowNames

注意:List: TStrings是在自定义类中创建的字符串列表。

问题

我也试图使该功能与Lazarus / FPC兼容,但它不会接受{$IFDEF FPC} function EnumWindowNamesProc(wHandle: HWND; Param: LPARAM): BOOL; stdcall; {$ELSE} function EnumWindowNamesProc(wHandle: HWND; List: TStrings): BOOL; stdcall; {$ENDIF} var Title: array[0..255] of Char; begin Result := False; GetWindowText(wHandle, Title, 255); if IsWindowVisible(wHandle) then begin if Title <> '' then begin {$IFDEF FPC} // List no longer available {$ELSE} List.Add(string(Title)); {$ENDIF} end; end; Result := True; end; 参数。

Lazarus中的编译器错误抱怨类型不匹配(我突出了重要部分):

  

错误:arg no的类型不兼容。 1:得到&#34; (地址)   函数( LongWord; TStrings ):LongBool; StdCall)&#34;,期望&#34; (程序   变量类型的函数( LongWord; LongInt ):LongBool; StdCall)&#34;

我可以通过改变函数声明来阻止编译器抱怨:

List

但后来我丢失了TStrings参数。

我知道我可以修改代码并直接在函数内部使用Listbox1,但我希望创建一个可重用的函数,不需要了解VCL / LCL控件,而是希望有一个更优雅的解决方案并简单地传递基于TStrings的参数并添加到此参数。

问题:

所以我的问题是,在Delphi中,我能够将基于EnumWindowNamesProc的参数传递给我的List: TStrings,但在Lazarus中它不会接受它。是否可能,如果可以,我如何修改代码以便Lazarus接受{{1}}参数?

1 个答案:

答案 0 :(得分:5)

你可以。您不必丢失List 只需使用正确的参数和类型转换

function EnumWindowNamesProc(wHandle: HWND; List: LPARAM): BOOL; stdcall;
var
  Title: array[0..255] of Char;
begin
  Result := False;

  GetWindowText(wHandle, Title, 255);
  if IsWindowVisible(wHandle) then
  begin
    if Title <> '' then
    begin
      TStringList(List).Add(string(Title));
    end;
  end;
  Result := True;
end;

EnumWindows(@EnumWindowNamesProc, LPARAM(list));

完成我的回答。还有一个选项 - 用指针自己定义函数(比如在Delphi中)。然后你可以用同样的方式使用它。

function EnumWindows(lpEnumFunc:Pointer; lParam:LPARAM):WINBOOL; external 'user32' name 'EnumWindows';