如。 因为关闭相关的问题 - 更多的例子如下补充说。
下面简单的代码(指找到顶级的IE窗口,并列举其子)工程确定与'32位Windows的目标平台。 有与早期版本的Delphi以及没有问题:
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;
我已经插入一个Assert
以指示失败了'64位Windows的目标平台。 还有的代码,如果我未窝回调没有问题。
我不知道如果与参数传递错误的值都只是垃圾或者是由于一些错误放置的内存地址(调用约定?)。 是嵌套回调INFACT东西,我不应该摆在首位呢? 或者这只是一个缺陷,我要住在一起?
编辑:
在回答大卫的回答,具有相同的代码EnumChildWindows
宣布与类型化的回调。 正常工作与32位:
(编辑:下面并没有真正检验一下,大卫说,因为我仍用“@”操作符它工作正常,与运营商,但如果我删除它,它确实不编译,除非我取消窝回调)
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;
其实这个限制是不特定于Windows API的回调,但服用时该函数的地址到的变量会发生同样的问题, procedural type
和传递,例如,作为一个自定义的比较来TList.Sort
。
http://docwiki.embarcadero.com/RADStudio/XE4/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;
它的工作原理,当32位编译如预期,但未能与Access Violation
编译为Win64的时候。 在功能64位版本的compare
, s = nil
和i2
=一些随机值;
它也可以作为预期甚至Win64的目标,如果提取物compare
之外的功能btn1Click
功能。