如何从句柄中获取TForm的实例?

时间:2011-11-18 23:03:40

标签: delphi winapi dll delphi-7

我正在将一些函数转换为与Windows 7功能相关的DLL。我不能通过DLL传递TForm,所以我需要传递它的句柄。除了,一旦我在另一边有这个句柄,我该如何将它重建回TForm实例?另外,通过Delphi DLL传递句柄(HWND)以与C#调用兼容的适当方法是什么?

如果不可能,那么我至少需要知道如何仅使用Windows API更改窗口的颜色,不参考TForm。目标是从这个DLL中,它需要以某种方式改变窗体的颜色。将句柄传递给DLL是没有问题的,但如何使用该句柄来处理句柄所代表的形式?

我正在做的是整理一个DLL,其中包含使Delphi7应用程序与Windows7兼容所需的一切,例如绘图玻璃,在任务栏中正确显示多个表单(并最小化表单),显示绿色任务栏图标的进度,以及可能涉及的任何其他内容。这种类型的工作虽然需要修改表单。我需要能够在DLL中进行这些修改。

3 个答案:

答案 0 :(得分:8)

通常,您可以使用HWND单元中的VCL TWinControl函数将FindControl()转换为VCL Controls派生的对象指针。然后,您可以使用TWinControl运算符检查TForm实际上是is

然而,正如其他人所说的那样,通常在DLL边界上传递VCL对象是危险的,并且如果EXE和DLL都没有使用完全相同的VCL版本,RTL版本,内存管理器等进行编译,则会导致问题。安全地在DLL边界上的VCL对象,将您的DLL项目更改为BPL包项目,并确保在EXE和BPL中都启用了动态RTL。

答案 1 :(得分:4)

你无法从句柄中获得TForm。在你的Delphi应用程序之外没有这样的东西,除非你正在使用包(正如大卫的回答所说)。

您可以直接在API调用中使用HandleHWND),但只能 进行API调用。

您可以将HWND直接传递给GetDC等API调用,以获取设备上下文(DC),然后将DC直接与{{1}一起使用相关函数,例如DrawThemeText或其他需要窗口DrawTheme的函数。您还可以将其传递给需要DC的其他API调用。

答案 2 :(得分:3)

您无法跨DLL边界传递Delphi对象。它根本不起作用。没有从DLL导出Delphi类的机制。

你知道这一点,但是跨越边界传递一个句柄并没有帮助。您希望在边界另一侧的TForm上操作。但是唯一有意义的TForm实例是创建句柄的唯一实例,并且该实例被模块边界捕获。

有些对象只能从句柄中重新创建。例如,位图和图标具有此属性。这是因为除了存储在GDI句柄中的状态之外,它们没有任何状态。更复杂的VCL对象确实具有这种状态,其中存在问题。

您的选择是:

  1. 使用套餐。这是一种享受,但您必须为所有模块使用相同的编译器版本。
  2. 使用接口或COM。这使您可以自由地混合编译器版本甚至不同的语言。