How to get TForm instance from Handle?

I am converting some functions to DLLs that relate to the functionality of Windows 7. I cannot pass TForm through a DLL, so I need to pass its handle. Also, as soon as I have this descriptor on the other hand, how can I restore it back to the TForm instance? Also, what is the way to pass a descriptor (HWND) through a Delphi DLL for compatibility with a C # call, for example?

If this is not possible, at least I need to know how to change the window color only using the window API, not referring to TForm. The goal is that inside this DLL you need to somehow change the color of the form. Passing a DLL descriptor is not a problem, but how to use this descriptor to work with the form that the descriptor represents?

What I’m doing on purpose is to put together a single DLL that contains everything necessary for a Delphi7 application to be compatible with Windows7, for example, draw glass by correctly displaying several forms on the taskbar (and minimizing forms), showing green progress in the taskbar icon and everything that can be involved. This type of work requires modification of the form. I need to be able to make these changes from a DLL.

+6
source share
3 answers

You cannot get TForm from a descriptor. There is no such thing outside your Delphi application unless you use packages (as David said).

You can use Handle ( HWND ) directly in API calls, but only for API calls.

You can pass this HWND directly to API calls such as GetDC to get the device context ( DC ), and then use the DC directly with DrawTheme related functions such as DrawThemeText or whatever else that requires DC windows. You can also pass it to other API calls that require HWND .

+4
source

In general, you can convert HWND to a VCL TWinControl object pointer using the VCL FindControl() function in the Controls module. Then you can check if TWinControl a TForm using the is statement.

However, as others have argued, passing VCL objects across the DLL boundary is generally dangerous and can cause problems if both the EXE and the DLL are not compiled with the same version of VCL, RTL, memory manager, etc. To go VCL over the DLL boundary, change the DLL project to the BPL package project and make sure that Dynamic RTL is included in both the EXE and the BPL.

+7
source

You cannot pass Delphi objects across DLL boundaries. It just doesn't work. There is no mechanism for exporting a Delphi class from a DLL.

You know about this, but passing the handle across the border does not help. You want to work with TForm on the other side of the border. But the only TForm instance that might make sense is the only one that created the handle, and this instance falls into the trap of the module boundary.

There are several objects that can only be recreated from a descriptor. For example, bitmaps and icons have this property. This is because they do not have a state other than that stored in the GDI descriptor. More complex VCL objects have this state, and that is the problem.

Your options:

  • Use packages. This works, but you must use the same compiler version for all modules.
  • Use interfaces or COM. This gives you the freedom to mix compiler versions and even different languages.
+3
source

Source: https://habr.com/ru/post/901857/


All Articles