我有一个应用程序,它有一个主窗口,然后它打开新的表单。 整个应用程序就像一个包含多种子表单的文档阅读器。
例如,我打开了主窗口,3个文档详细信息表单和4个其他内容的编辑器。
现在。由于所有子表单都是主表单的子表单,因此它们都被分组在任务栏上的一个图标下,当您尝试搜索悬停时显示的列表中的某个窗口时,这可能会弄得一团糟。
是否可以告诉系统,所有特定表单的实例必须在单独的图标中组合在一起?
喜欢这个
我通过了一些指南,但不幸的是,我还没有发现这个特定的问题在任何地方都解决了。
通过我在这里寻找C#实现我的应用程序设计和解决方案的简单预览,真正的应用程序可能会在Delphi中实现,所以真正的和主要的问题是关于操作系统是否支持这种行为,因为这是对正常行为的巨大反应 - 甚至可以在Windows中这样做吗?它也可以在Linux(gnome,kde,xfce,unity)和MacOS上完成吗?对于这些问题,我不需要知道HOW-TO,只要有人遇到问题并且可以指出我提到这个问题的文章的解决方案。
提前致谢。
答案 0 :(得分:1)
我无法帮助您使用其他平台,例如Linux,但这是Windows解决方案:
您可以使用Windows任务栏API。对于 C#,.NET使其以一种简洁的方式可用。您必须引用程序集System.Xaml
和Microsoft.WindowsAPICodePack.Shell
,然后才能使用此代码:
using Microsoft.WindowsAPICodePack.Taskbar;
/* ... */
// Put this code in myForm.OnLoad or so
TaskbarManager.Instance.SetApplicationIdForSpecificWindow(myForm.Handle, "MyInternalGroupID");
这将为您的窗口分配“应用程序模型ID”。 Windows将所有具有相同应用程序型号ID的窗口组合在一起。因此,您必须为不同的组使用不同的名称而不是MyInternalGroupID
。
请注意,这也可以在多个实例中 ,因此属于同一组的窗口即使来自多个进程也会一起显示。如果您不想这样,则必须在组名中包含当前进程ID。
进一步阅读:Taskbar API overview,The Old New Thing article (with C++ example)
对于 Delphi ,我找到了一个解决方案here,归功于BjörnOle:
unit uAppID; interface uses Windows, ActiveX, PropSys, PropKey; function GetAppID(AHandle: THandle): string; function SetAppID(AHandle: THandle; const AAppID: string): boolean; implementation function SHGetPropertyStoreForWindow(hwnd: hwnd; const riid: TGUID; out ppv: IPropertyStore) : HRESULT; stdcall; external 'shell32.dll'; function GetAppID(AHandle: THandle): string; var hr: HRESULT; pps: IPropertyStore; v: TPropVariant; begin hr := SHGetPropertyStoreForWindow(AHandle, IID_IPropertyStore, pps); if Succeeded(hr) then begin pps.GetValue(PKEY_AppUserModel_ID, v); result := v.bstrVal; end else result := ''; end; function SetAppID(AHandle: THandle; const AAppID: string): boolean; var hr: HRESULT; pps: IPropertyStore; v: TPropVariant; begin hr := SHGetPropertyStoreForWindow(AHandle, IID_IPropertyStore, pps); if Succeeded(hr) then begin v.vt := VT_BSTR; v.bstrVal := SysAllocString(PChar(AAppID)); result := pps.SetValue(PKEY_AppUserModel_ID, v) = S_OK; end else result := false; end; end.
您需要以C#中SetAppID
的方式呼叫TaskbarManager.Instance.SetApplicationIdForSpecificWindow
,基本上。