我有一个混合的CBuilder / Delphi dll,我从非VCL主机应用程序加载。我正在使用RAD Studio XE2。在加载dll后,我将Application句柄设置为主机的主窗体,这样可以保持我的窗体和对话框不受任务栏的影响。但是,我想在任务栏上显示进度条,并将其与主机应用程序堆叠。我已经广泛搜索和搜索,但找不到类似的东西。
博士。 Bob在任务栏的各种功能上写了一篇很好的教程here,并且我已经在主应用程序的任务栏按钮中显示了一个进度条,但是我真的想为它创建第二个“堆叠”图标。进度条,很多应用程序都有。 Bob博士的例子假设您是主应用程序的一部分,并使用此代码添加选项卡:
if not Application.MainFormOnTaskBar then
FormHandle := Application.Handle
else FormHandle := Application.MainForm.Handle;
TaskbarList.AddTab(FormHandle);
在我的情况下没有做任何事情。我试过了
FormHandle := FindWindow('TfmProg', NIL);
TaskbarList.addTab(FormHandle);
但这不会改变任何事情。
我已经使用Application作为所有者和NIL创建了表单。我创建了它fsNormal或fsStayOnTop。坦率地说,我触及了我能得到的每一个参数,但似乎没有任何效果。
答案 0 :(得分:2)
将Application.Handle
设置为主机应用程序主窗体的句柄是正确的。这将使主机应用程序的主窗口成为Windows的owner。但是,正如您所观察到的那样,这也会使您的顶级窗口远离任务栏。那是因为拥有的顶级窗口没有出现在任务栏中。
要将拥有的顶级窗口放在任务栏上,您应该包含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.SetProgressState
和ITaskbarList3.SetProgressValue
,传递表单的句柄,以显示表单任务栏按钮的任务栏进度。
我必须承认我发现你的代码很奇怪:
FormHandle := FindWindow('TfmProg', NIL);
TaskbarList.addTab(FormHandle);
由于代码在您的DLL中运行,而DLL也创建了表单,因此您不应该使用FindWindow
来获取句柄。您可以使用Form.Handle
,其中Form
是对表单实例的引用。也就是说,我仍然更喜欢上面概述的方法,使用WS_EX_APPWINDOW
,因为它对窗口句柄重新创建具有弹性,对我来说感觉相当简单。