如何在非 Delphi 应用程序中显示 Delphi DLL 进度条到任务栏

4
我有一个混合的CBuilder/Delphi dll,我从非VCL主机应用程序中加载它。我正在使用RAD Studio XE2。在加载dll时,我将应用程序句柄设置为主机的主窗体,这样就可以使我的表单和对话框不出现在任务栏上。但是,我想在任务栏上显示进度条,并使其与主机应用程序堆叠。我已经进行了广泛的搜索,但找不到类似的内容。
Dr. Bob在这里写了一个关于任务栏各种功能的不错的教程,从中我得到了一个进度条显示在主应用程序的任务栏按钮上,但我真正想要创建第二个“堆叠”的图标来表示进度条,这是许多应用程序所做的。Dr. Bob的示例假设您是主应用程序的一部分,并使用此代码添加选项卡:
if not Application.MainFormOnTaskBar then
  FormHandle := Application.Handle
else FormHandle := Application.MainForm.Handle;
TaskbarList.AddTab(FormHandle);

在我的情况下没有任何作用。我已经尝试过

FormHandle := FindWindow('TfmProg', NIL);
TaskbarList.addTab(FormHandle);

但这并不改变任何事情。
我已经将应用程序作为所有者和NIL创建了表单。我已经将其创建为fsNormal或fsStayOnTop。坦白地说,我已经触及了我能够接触到的每个参数,但似乎没有任何作用。

1
如果“AddTab”无法添加选项卡,则应返回一个HResult,告诉您原因。在这种情况下,它会告诉您什么? - Rob Kennedy
你好 @RobKennedy,返回的值是0,或者我认为是s_ok。我怀疑选项卡被正确创建但是父级关系可能有误,也许是隐藏表单? - marcp
1个回答

2
您正确地将Application.Handle设置为主机应用程序的主窗体句柄。这将使主机应用程序的主窗口成为您窗口的所有者。但是,正如您所观察到的那样,这也会使您的顶级窗口不出现在任务栏中。这是因为拥有的顶级窗口不会出现在任务栏中。
要将拥有的顶级窗口放置在任务栏上,您应该包含WS_EX_APPWINDOW扩展窗口样式。在您的窗体的CreateParams过程中添加此样式。
procedure CreateParams(var Params: TCreateParams); override;
....
procedure TMyForm.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
end;

然后,您可以使用ITaskbarList3.SetProgressStateITaskbarList3.SetProgressValue,传递您的表单句柄,为您的表单任务栏按钮显示任务栏进度。
我必须承认,我觉得你的代码很奇怪:
FormHandle := FindWindow('TfmProg', NIL);
TaskbarList.addTab(FormHandle);

由于代码在您的 DLL 中运行,同时也创建了表单,因此您不应该使用FindWindow来获取句柄。您可以使用Form.Handle,其中Form是对您的表单实例的引用。话虽如此,我仍然更喜欢上面概述的方法,使用WS_EX_APPWINDOW,因为它能够适应窗口句柄的重新创建,并且对我来说更简单些。

谢谢@DavidHeffernan。这就解决了问题。我之前尝试过类似的东西,但可能语法有误。我可能忘记了覆盖。例子是个好东西。干杯。 - marcp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接