【问题标题】:How to pass a form handle to a DLL for use in Windows API?如何将表单句柄传递给 DLL 以在 Windows API 中使用?
【发布时间】:2011-11-21 22:13:18
【问题描述】:

首先,我对 DLL 不太满意。我以前也做过,但是知道的很少,总是有问题。

我正在构建的这个 DLL 需要将 Windows 窗体句柄 (HWND) 传递给 DLL 函数,并且 DLL 将使用该句柄调用 Windows API 函数。在尝试调用任何函数(从Win7InitTaskbar 开始)时,我不断遇到访问冲突——就好像它甚至未能调用该函数一样。这让我得出结论,一定是 HWND 参数导致它崩溃......我认为......

library Win7;

uses
  //Do I need ShareMem?
  //ShareMem,      //<---
  Windows,
  Forms,
  JDWin7,
  SysUtils,
  Classes;

{$R *.res}

function Win7InitTaskbar(const FormHandle: HWND): Bool; stdcall;
begin
  Result:= InitializeTaskbarAPI(FormHandle);
end;

function Win7InitForm(const FormHandle: HWND): Bool; stdcall;
begin

end;

function Win7SetTaskbarState(const AState: Cardinal): Bool; stdcall;
begin
  Result:= SetTaskbarProgressState(AState);
end;

function Win7SetTaskbarValue(const ACurrent: UInt64; const AMax: UInt64): Bool; stdcall;
begin                                        //is UInt64 Safe for DLL?
  Result:= SetTaskbarProgressValue(ACurrent, AMax);
end;

exports
  Win7InitTaskbar,
  Win7InitForm,
  Win7SetTaskbarState,
  Win7SetTaskbarValue;

begin
end.

DLL函数的实现:

function Win7InitTaskbar(const FormHandle: HWND): Bool;
  external W7DLL;
function Win7SetTaskbarState(const AState: Cardinal): Bool;
  external W7DLL;
function Win7SetTaskbarValue(const ACurrent: UInt64; const AMax: UInt64): Bool;
  external W7DLL;

无论我是否使用ShareMem,我都有这个问题(我也不想使用)。使用HWND 参数发布函数是否安全?我也尝试了 LongWord,但仍然没有运气。内部函数InitializeTaskbarAPI 实际上确实在 DLL 之外完美地工作,如果我要直接在应用程序内部使用它的话。但在这种情况下,我想将它们放在一个共享的 DLL 中。

另外,将UInt64 传递到 DLL 中是否安全?当我得到源代码时,其中一个函数已经发布了这个参数类型。

【问题讨论】:

  • 请记住,每当您在问题中键入“错误”、“异常”或“访问冲突”等词时,您应该添加的下一个内容是准确 您收到的错误消息(或错误的准确描述),包括任何错误代码或内存地址。在没有更多信息的情况下说“我不断遇到访问冲突”是毫无意义的。谢谢。 :)
  • 对不起,这些地址对我来说毫无意义,所以我总是忽略它们,我看不懂计算机语言:P 但无论如何问题都解决了。
  • 仅仅因为它们对你没有意义并不意味着它们对每个人都没有意义。如果他们没有任何意义,他们就不会犯错误。而且,由于您的问题现在已解决,并不意味着您不应在未来帖子中包含这些信息(或编辑此帖子以添加信息以供他人将来受益)。
  • 老实说,它是许多不同错误消息的组合,从访问冲突开始,还有“EExternalException” - 我明白你的意思,但我宁愿不重新破坏我的项目以便能够发布确切的详细信息。
  • UInt64 是一个无符号的 64 位整数(无符号意味着没有负值并且大约是正范围的两倍)。我不记得 D7 是否有 UInt64 可用;如果您的代码使用它编译,并且 DLL 也使用它,那么来回传递应该没问题。

标签: delphi winapi dll delphi-7 hwnd


【解决方案1】:

在我看来,您的问题与使用 Sharemem 或将 Form.Handle 传递给 HWND 参数无关。

这只是calling convention 不匹配。您导出为stdcall,然后导入为register。每当你这样做时,运行时错误肯定会随之而来。

你需要这样做:

function Win7InitTaskbar(const FormHandle: HWND): Bool; 
  stdcall; external W7DLL;
function Win7SetTaskbarState(const AState: Cardinal): Bool;
  stdcall; external W7DLL;
function Win7SetTaskbarValue(const ACurrent: UInt64; const AMax: UInt64): Bool;
  stdcall; external W7DLL;

对于它的价值,您在这里不需要 Sharemem。只有当您在一个模块中分配内存但在另一个模块中释放它时才需要它。并且将Form.Handle 传递给DLL 中的HWND 参数不是问题。当您调用 Windows API 函数时,您一直都在这样做。

【讨论】:

  • 不错的收获 - 比我快 40 秒到达那里。 :) @Jerry,在 D7 帮助文件中搜索 calling conventions 以了解不同之处。
  • 啊哈!我要为自己忘记那件小事打自己一巴掌,谢谢你的抓住......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多