delphi - Delphi 嵌套类中的 EnumWindows

标签 delphi winapi

我在使用嵌套类中的回调函数的 EnumWindows 函数时遇到一些问题:

TProcessWatch = class(TObject)
private
  ...
  type
    TProcessInfo = class(TObject)
    private
    type
      PEnumCallbackParam = ^TEnumCallbackParam;
      TEnumCallbackParam = class
        A : Integer;
        ...
      end;
    private
      FOwner : TProcessWatch;
      function FEnumWindowsCallback(hWindow : HWND; lParam : LPARAM) : BOOL; export;
      procedure SomeProc;
      ...
    end;
private
  FProcesses : TProcessInfo;
  ...
public
  ...

SomeProc 中,有一个对 EnumWindows 的调用

EnumCallbackParam := TEnumCallbackParam.Create;
try
  EnumCallbackParam.A := 0;
  EnumWindows(@TProcessWatch.TProcessInfo.FEnumWindowsCallback, LongInt(@EnumCallbackParam));
  ...
finally
  EnumCallbackParam.Free;
end;

这是一个 FEnumWindowsCallback 函数列表:

function TProcessWatch.TProcessInfo.FEnumWindowsCallback(hWindow: HWND;
  lParam : LPARAM): BOOL; export;
var
  CallbackParam : PEnumCallbackParam;
begin
  CallbackParam := Pointer(lParam); // A is inaccessible
  Result := True;
  ...
end;

在运行时,当调用 EnumWindows 时,FEnumWindowsCallback 始终接收 hWindow = 0 并且 lParam 指向达到无法获得的值(value)。

如果回调函数在表单中声明为私有(private),那么所有这些都可以正常工作,但是当我尝试在嵌套类中将此函数设为私有(private)时,它就出错了。

为什么?以及如何使其发挥作用?目标是使 FEnumWindowsCallback 和所有其他涉及的函数在 TProcessWatch 中私有(private)化。

最佳答案

回调声明错误。应该是:

class function EnumWindowsCallback(hWindow: HWND; 
  lParam: LPARAM): BOOL; static; stdcall; 

您使用了错误的调用约定和实例方法。

其他评论:

  • EnumCallbackParam 已经是一个指针。您可以将其作为参数传递。
  • 转换为 LPARAM 而不是 LongInt,以便您的代码在编译为 64 位时也能正常工作。
  • export 关键字在 32 位或 64 位 Delphi 中没有任何意义。它被忽略,您不应该使用它,因为它会增加困惑并且可能会造成困惑。

关于delphi - Delphi 嵌套类中的 EnumWindows,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29615120/

相关文章:

multithreading - iTask - 如何使用变量作为任务过程的参数

c++ - 在 WPF、wxWidgets、Win32 API 和 MFC 之间进行选择

winapi - 如何从 SYSTEMTIME 获取本地化日期和时间

delphi - 如何在Delphi 10.2中设置FireMonkey表单图标运行时

delphi - Delphi 10.3 中带预览的文件打开对话框

当我尝试下载大文件时,Delphi XE2 DataSnap REST - "Out of memory"

Delphi:像工具栏中的渐变一样

c++ - 将光标定位在 RichEdit 控件中文本的末尾

c++ - 如何显示来自另一个进程的模态对话框窗口?

c++ - 如何制作不依赖 msvc dll 的 win32 应用程序?