gpt4 book ai didi

Delphi XE2 EnumWindows 无法正常工作

转载 作者:行者123 更新时间:2023-12-03 14:57:38 24 4
gpt4 key购买 nike

在 Win7 64 位上使用 Delphi XE2 update 3 或 update 4。

调用 enumwindows 的工作方式与以前在 Delphi 6 中的工作方式不同。

在 Delphi 6 中,enumwindows 处理窗口,直到回调函数返回 False。这就是文档所说的应该做的事情:

“要继续枚举,回调函数必须返回 TRUE;要停止枚举,必须返回 FALSE。”

按如下方式调用 enumwindows:

procedure TForm1.Button1Click(Sender: TObject);
begin
EnumWindows(@FindMyWindow,0);
if GLBWindowHandle <> 0 then begin
ShowMessage('found');
end;
end;

这是回调函数:

function FindMyWindow(hWnd: HWND; lParam: LPARAM): boolean; stdcall;
var TheText : array[0..150] of char;
str : string;
begin
Result := True;
GLBWindowHandle := 0;
if (GetWindowText(hWnd, TheText, 150) <> 0) then
begin
str := TheText;
if str = 'Form1' then
begin
GLBWindowHandle := hWnd;
Result := False;
end
else
result := True;
end;
end;

需要明确的是,回调函数是在按钮单击事件之前的代码中定义的,因此编译器可以找到它,而无需在界面部分中定义。

如果使用 Delphi 6 运行,一旦返回 False 结果并且 GLBWindowHandle 不为零,窗口枚举就会停止

如果使用 Delphi XE2 运行,则返回 False 结果后枚举将继续,并且 GLBWindowHandle 始终为零。

什么鬼?有人知道为什么枚举没有像文档所述那样停止以及它在 Delphi 6 中的使用方式吗?

干杯!

最佳答案

此声明不正确:

function FindMyWindow(hWnd: HWND; lParam: LPARAM): boolean; stdcall;

应该是:

function FindMyWindow(hWnd: HWND; lParam: LPARAM): BOOL; stdcall;

您必须小心不要混淆 BooleanBOOL,因为它们不是同一件事。前者是单字节,后者是4字节。 EnumWindows 期望的内容与回调函数提供的内容之间的不匹配足以导致您观察到的行为。

<小时/>

此外,罗布·肯尼迪 (Rob Kennedy) 贡献了这一精彩评论:

The compiler can help find this error if you get out of the habit of using the @ operator before the function name when you call EnumWindows. If the function signature is compatible, the compiler will let you use it without @. Using @ turns it into a generic pointer, and that's compatible with everything, so the error is masked by unnecessary syntax. In short, using @ to create function pointers should be considered a code smell.

<小时/>

讨论

不幸的是,Windows.pas header 翻译以最无益的方式定义了 EnumWindows,如下所示:

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

现在,问题出在 TFNWndEnumProc 的定义中。其定义为:

TFarProc = Pointer;
TFNWndEnumProc = TFarProc;

这意味着您必须使用@运算符来创建通用指针,因为该函数需要通用指针。如果 TFNWndEnumProc 声明如下:

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

那么编译器就能够发现错误。

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

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

function FindMyWindow(hWnd: HWND; lParam: LPARAM): Boolean; stdcall;
begin
Result := False;
end;

....
EnumWindows(FindMyWindow, 0);

编译器拒绝对 EnumWindows 的调用,并出现以下错误:

[DCC Error] Unit1.pas(38): E2010 Incompatible types: 'LongBool' and 'Boolean'

我想我会控制这个问题,并尝试说服 Embarcadero 停止使用 TFarProc

关于Delphi XE2 EnumWindows 无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9522080/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com