I have a problem with the following code in Delphi 10.1:
ShellExecute(handle,'open',PChar(filename), '','',SW_SHOWNORMAL);
When I try to run the code it gives me this error:
Incompatible Types: 'HWND' and 'TWindowHandle'
I have a problem with the following code in Delphi 10.1:
ShellExecute(handle,'open',PChar(filename), '','',SW_SHOWNORMAL);
When I try to run the code it gives me this error:
Incompatible Types: 'HWND' and 'TWindowHandle'
In FireMonkey, a Form's Handle
property is of type TWindowHandle
(a class defined in the FMX.Types unit). On Windows, it is implemented as TWinWindowHandle
(a subclass of TWindowHandle
defined in the FMX.Platform.Win unit).
TWinWindowHandle
stores the HWND
handle in its Wnd
property.
To get the actual HWND
handle, you would need to use FmxHandleToHWND()
:
ShellExecute(FmxHandleToHWND(Handle), 'open', PChar(filename), '', '', SW_SHOWNORMAL);
This casts the TWindowHandle
to TWinWindowHandle
(using WindowHandleToPlatform
) and then returns its Wnd
property value.
Updated (based on Remy's comments):
Remy points out that the FmxHandleToHWND
is documented to be deprecated (from XE4 onwards). This doesn't appear to be backed up by the latest source code, which seems in the case of Delphi 10.1 Berlin RTM version to have dropped the usual deprecated
modifier, but let's take the documentation's word for it just to be safe.
Instead of FmxHandleToHWND
you are advised to do exactly what FmxHandleToHWND
does, which is to call WindowHandleToPlatform
and access the Wnd
property, so:
ShellExecute(WindowHandleToPlatform(Handle).Wnd, 'open', PChar(filename), '', '', SW_SHOWNORMAL);
A better option, though, would be to use FormToHWND
, which is more a direct replacement for FmxHandleToHWND
than WindowHandleToPlatform
(and we can wonder why the docs don't point us at this routine, though the likely answer is the docs writer just got it wrong):
ShellExecute(FormToHWND(Handle), 'open', PChar(filename), '', '', SW_SHOWNORMAL);
A TWindowHandle
is a FireMonkey class. A HWND
is a Windows handle. These are completely different types.
For the VCL, it is fine to pass something like TForm.Handle
, which is a HWND
, to ShellExecute()
. For FireMonkey (FMX), it isn't, since that is a TWindowHandle
.
Use GetDesktopWindow()
from unit Winapi.Windows
instead:
ShellExecute(GetDesktopWindow, 'open', PChar(filename), '', '', SW_SHOWNORMAL);