AS. 自结束相关问题以来——下文中增加了更多例子。
下面的简单法典(它找到了顶级Ie窗口,并列举了其儿童)是行之有效的。 配有32个视窗目标平台。 以前版本的德尔菲也没有问题:
procedure TForm1.Button1Click(Sender: TObject);
function EnumChildren(hwnd: HWND; lParam: LPARAM): BOOL; stdcall;
const
Server = Internet Explorer_Server ;
var
ClassName: array[0..24] of Char;
begin
Assert(IsWindow(hwnd)); // <- Assertion fails with 64-bit
GetClassName(hwnd, ClassName, Length(ClassName));
Result := ClassName <> Server;
if not Result then
PUINT_PTR(lParam)^ := hwnd;
end;
var
Wnd, WndChild: HWND;
begin
Wnd := FindWindow( IEFrame , nil); // top level IE
if Wnd <> 0 then begin
WndChild := 0;
EnumChildWindows(Wnd, @EnumChildren, UINT_PTR(@WndChild));
if WndChild <> 0 then
..
end;
I ve 插入Asert
,以表明其没有64-bitWindows目标平台。 如果Iun-nest,则该守则没有任何问题。 背书。
我不敢肯定,这些错误的数值是否与参数一致,是否只是垃圾,或者是由于某些错误的记忆地址(回顾公约?)造成的。 nes击是不是我首先应该做的事情吗? 或者,这只是我不得不面对的一个缺陷?
edit:
In response to David s answer, the same code having EnumChildWindows
declared with a typed callback. Works fine with 32-bit:
(edit: The below does not really test what David says since I still used the @ operator. It works fine with the operator, but if I remove it, it indeed does not compile unless I un-nest the callback)
type
TFNEnumChild = function(hwnd: HWND; lParam: LPARAM): Bool; stdcall;
function TypedEnumChildWindows(hWndParent: HWND; lpEnumFunc: TFNEnumChild;
lParam: LPARAM): BOOL; stdcall; external user32 name EnumChildWindows ;
procedure TForm1.Button1Click(Sender: TObject);
function EnumChildren(hwnd: HWND; lParam: LPARAM): BOOL; stdcall;
const
Server = Internet Explorer_Server ;
var
ClassName: array[0..24] of Char;
begin
Assert(IsWindow(hwnd)); // <- Assertion fails with 64-bit
GetClassName(hwnd, ClassName, Length(ClassName));
Result := ClassName <> Server;
if not Result then
PUINT_PTR(lParam)^ := hwnd;
end;
var
Wnd, WndChild: HWND;
begin
Wnd := FindWindow( IEFrame , nil); // top level IE
if Wnd <> 0 then begin
WndChild := 0;
TypedEnumChildWindows(Wnd, @EnumChildren, UINT_PTR(@WndChild));
if WndChild <> 0 then
..
end;
Actually this limitation is not specific to a Windows API callbacks, but the same problem happens when taking address of that function into a variable of procedural type
and passing it, for example, as a custom comparator to TList.Sort
.
http://docwiki.embarcadero.com/RADStudio/Rio/en/Procedural_Types
procedure TForm2.btn1Click(Sender: TObject);
var s : TStringList;
function compare(s : TStringList; i1, i2 : integer) : integer;
begin
result := CompareText(s[i1], s[i2]);
end;
begin
s := TStringList.Create;
try
s.add( s1 );
s.add( s2 );
s.add( s3 );
s.CustomSort(@compare);
finally
s.free;
end;
end;
在为Win64汇编成册时,它按预期运作,但未能使用<条码>。 <代码>compare,s = nil
和i2
= 某些随机值;
如果在<代码>btn1Click功能之外有一 extractcompare
功能,则即便是Win64目标,也按预期运作。