如何修改我的 EnumWindowNamesProc 以与 Lazarus 一起使用并使用 List 作为参数?
How can I modify my EnumWindowNamesProc to work with Lazarus and use a List as a parameter?
概览
我正在尝试枚举所有可见 window 名称的列表,然后填充作为参数传递的列表。
在 Delphi 中,我能够将其与以下内容一起使用:
function EnumWindowNamesProc(wHandle: HWND; List: TStrings): 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
List.Add(string(Title));
end;
end;
Result := True;
end;
然后我可以这样调用上面的代码:
EnumWindows(@EnumWindowNamesProc, LPARAM(FWindowNames));
注意:FWindowNames
是在自定义 class 中创建的字符串列表。
问题
我也在尝试使函数与 Lazarus/FPC 兼容,但它不接受 List: TStrings
参数。
Lazarus 中的编译器错误抱怨类型不匹配(我已突出显示重要部分):
Error: Incompatible type for arg no. 1: Got " (address of
function(LongWord;TStrings):LongBool;StdCall) ", expected " (procedure
variable type of function(LongWord;LongInt):LongBool;StdCall) "
我可以通过像这样更改函数声明来阻止编译器抱怨:
{$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;
但后来我丢失了 List
参数。
我知道我可以修改代码并直接在函数内部使用 Listbox1,但我希望创建一个不需要了解 VCL/LCL 控件的可重用函数,相反我希望一个更优雅的解决方案,只需传递一个基于 TStrings
的参数并添加到此。
问题:
所以我的问题是,在 Delphi 中我可以将基于 TStrings
的参数传递给我的 EnumWindowNamesProc
但在 Lazarus 中它不会接受它。是否可能,如果可以,我该如何修改代码以便 Lazarus 接受 List: TStrings
参数?
可以。你不必失去你的 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';
概览
我正在尝试枚举所有可见 window 名称的列表,然后填充作为参数传递的列表。
在 Delphi 中,我能够将其与以下内容一起使用:
function EnumWindowNamesProc(wHandle: HWND; List: TStrings): 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
List.Add(string(Title));
end;
end;
Result := True;
end;
然后我可以这样调用上面的代码:
EnumWindows(@EnumWindowNamesProc, LPARAM(FWindowNames));
注意:FWindowNames
是在自定义 class 中创建的字符串列表。
问题
我也在尝试使函数与 Lazarus/FPC 兼容,但它不接受 List: TStrings
参数。
Lazarus 中的编译器错误抱怨类型不匹配(我已突出显示重要部分):
Error: Incompatible type for arg no. 1: Got " (address of function(LongWord;TStrings):LongBool;StdCall) ", expected " (procedure variable type of function(LongWord;LongInt):LongBool;StdCall) "
我可以通过像这样更改函数声明来阻止编译器抱怨:
{$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;
但后来我丢失了 List
参数。
我知道我可以修改代码并直接在函数内部使用 Listbox1,但我希望创建一个不需要了解 VCL/LCL 控件的可重用函数,相反我希望一个更优雅的解决方案,只需传递一个基于 TStrings
的参数并添加到此。
问题:
所以我的问题是,在 Delphi 中我可以将基于 TStrings
的参数传递给我的 EnumWindowNamesProc
但在 Lazarus 中它不会接受它。是否可能,如果可以,我该如何修改代码以便 Lazarus 接受 List: TStrings
参数?
可以。你不必失去你的 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';