Delphi 10.1 ShellExecute错误不兼容类型';HWND&x27;和';TWindowsHandle';
我对Delphi 10.1中的以下代码有问题:Delphi 10.1 ShellExecute错误不兼容类型';HWND&x27;和';TWindowsHandle';,delphi,shellexecute,Delphi,Shellexecute,我对Delphi 10.1中的以下代码有问题: ShellExecute(handle,'open',PChar(filename), '','',SW_SHOWNORMAL); 当我尝试运行代码时,会出现以下错误: 不兼容的类型:“HWND”和“TWindowHandle” TWindowHandle是FireMonkey类。HWND是一个Windows句柄。这些是完全不同的类型 对于VCL,可以将类似于TForm.Handle的东西传递到ShellExecute(),它是一个HWND。对于
ShellExecute(handle,'open',PChar(filename), '','',SW_SHOWNORMAL);
当我尝试运行代码时,会出现以下错误:
不兼容的类型:“HWND”和“TWindowHandle”
TWindowHandle是FireMonkey类。
HWND
是一个Windows句柄。这些是完全不同的类型
对于VCL,可以将类似于TForm.Handle
的东西传递到ShellExecute()
,它是一个HWND
。对于FireMonkey(FMX),它不是,因为它是一个TWindowHandle
改为从unitWinapi.Windows使用GetDesktopWindow()
:
ShellExecute(GetDesktopWindow, 'open', PChar(filename), '', '', SW_SHOWNORMAL);
TWindowHandle是FireMonkey类。HWND
是一个Windows句柄。这些是完全不同的类型
对于VCL,可以将类似于TForm.Handle
的东西传递到ShellExecute()
,它是一个HWND
。对于FireMonkey(FMX),它不是,因为它是一个TWindowHandle
改为从unitWinapi.Windows使用GetDesktopWindow()
:
ShellExecute(GetDesktopWindow, 'open', PChar(filename), '', '', SW_SHOWNORMAL);
在FireMonkey中,表单属性的类型为(单元中定义的类)。在Windows上,它实现为(单元中定义的TWindowHandle
的子类)
TWinWindowHandle
将HWND
句柄存储在其属性中
要获取实际的HWND
句柄,您需要使用:
这将TWindowHandle
强制转换为TWindowHandle
(使用),然后返回其Wnd
属性值
更新了(基于雷米的评论):
Remy指出,FmxHandleToHWND
被证明是不推荐使用的(从现在开始)。这似乎没有得到最新源代码的支持,在Delphi 10.1 Berlin RTM版本中,似乎删除了通常的不推荐的修饰符,但是为了安全起见,让我们听一下文档的话
建议您完全按照FmxHandleToHWND
所做的操作,而不是FmxHandleToHWND
调用WindowHandleToPlatform
并访问Wnd
属性,以便:
ShellExecute(WindowHandleToPlatform(Handle).Wnd, 'open', PChar(filename), '', '', SW_SHOWNORMAL);
不过,更好的选择是使用,它更直接地替代FmxHandleToHWND
,而不是WindowHandleToPlatform
(我们可能想知道,为什么文档没有向我们指出这个例程,尽管可能的答案是文档编写者搞错了):
在FireMonkey中,表单属性的类型为(单元中定义的类)。在Windows上,它实现为(单元中定义的TWindowHandle
的子类)
TWinWindowHandle
将HWND
句柄存储在其属性中
要获取实际的HWND
句柄,您需要使用:
这将TWindowHandle
强制转换为TWindowHandle
(使用),然后返回其Wnd
属性值
更新了(基于雷米的评论):
Remy指出,FmxHandleToHWND
被证明是不推荐使用的(从现在开始)。这似乎没有得到最新源代码的支持,在Delphi 10.1 Berlin RTM版本中,似乎删除了通常的不推荐的修饰符,但是为了安全起见,让我们听一下文档的话
建议您完全按照FmxHandleToHWND
所做的操作,而不是FmxHandleToHWND
调用WindowHandleToPlatform
并访问Wnd
属性,以便:
ShellExecute(WindowHandleToPlatform(Handle).Wnd, 'open', PChar(filename), '', '', SW_SHOWNORMAL);
不过,更好的选择是使用,它更直接地替代FmxHandleToHWND
,而不是WindowHandleToPlatform
(我们可能想知道,为什么文档没有向我们指出这个例程,尽管可能的答案是文档编写者搞错了):
尝试将handle
参数更改为0
。问问自己为什么要在那里传递handle
。我想这就是你应用程序中表单的FMX句柄。您知道ShellExecute
将如何处理该参数吗?你有什么理由不通过0
?是什么驱使你传递不同的值?如果你能理解的话,你能理解这个论点将如何被使用吗?如果您不太了解它,为什么还要调用该函数?不要使用ShellExecute
,因为它不会以有用的方式报告错误。使用ShellExecuteEx
,这样做。你在检查错误吗?是否要显式使用open
动词,还是确实要执行默认动词?filename
是可执行文件吗?如果是这样,那么您应该使用CreateProcess
创建一个新进程,而不是让shell来完成工作。尝试将handle
参数更改为0
。问问自己为什么要在那里传递handle
。我想这就是你应用程序中表单的FMX句柄。您知道ShellExecute
将如何处理该参数吗?你有什么理由不通过0
?是什么驱使你传递不同的值?如果你能理解的话,你能理解这个论点将如何被使用吗?如果您不太了解它,为什么还要调用该函数?不要使用ShellExecute
,因为它不会以有用的方式报告错误。使用ShellExecuteEx
,这样做。你在检查错误吗?是否要显式使用open
动词,还是确实要执行默认动词?filename
是可执行文件吗?如果是这样,那么您应该使用CreateProcess
创建一个新进程,而不是让shell来完成这项工作。永远不要将桌面窗口用作窗口所有者。通过0可能是最干净的。@David-Like-Jor