gpt4 book ai didi

c# - 任务栏上的子组

转载 作者:太空宇宙 更新时间:2023-11-04 10:36:38 24 4
gpt4 key购买 nike

我有一个应用程序,它有一个主窗口,然后它会打开新的表单。整个应用程序就像一个具有多种子表单的文档阅读器。

例如,我打开了主窗口、3 个文档详细信息表单和 4 个其他内容的编辑器。

现在。由于所有子窗体都是主窗体的子窗体,它们都被分组在任务栏上的一个图标下,当您尝试在悬停时显示的列表中搜索某个窗口时,这可能会造成困惑。

是否可以告诉系统,特定形式的所有实例都必须在单独的图标中组合在一起?

像这样

Taskbar - grouped child forms

我通过了一些指南,但不幸的是,我还没有发现这个具体问题在任何地方都得到了解决。

虽然我在这里为我的应用程序设计和解决方案的简单预览寻找 C# 实现,但真正的应用程序可能会在 Delphi 中实现,所以真正的主要问题是操作系统是否支持这种行为,因为这是对正常行为的巨大覆盖——甚至可以在 Windows 中这样做吗?并且在 Linux(gnome、kde、xfce、unity)和 MacOS 上也可以做到吗?对于这些问题,我不需要知道 HOW-TO,只要有人已经解决了这个问题并且可以指出一些提到这个问题的文章的解决方案。

提前致谢。

最佳答案

我无法在其他平台(例如 Linux)上为您提供帮助,但这是 Windows 解决方案:

您可以使用 Windows 任务栏 API。对于 C#,.NET 以简洁的方式提供了它。您必须引用程序集 System.XamlMicrosoft.WindowsAPICodePack.Shell,然后您可以使用此代码:

using Microsoft.WindowsAPICodePack.Taskbar;

/* ... */

// Put this code in myForm.OnLoad or so
TaskbarManager.Instance.SetApplicationIdForSpecificWindow(myForm.Handle, "MyInternalGroupID");

这将为您的窗口分配一个“App Model ID”。 Windows 会将具有相同应用模型 ID 的所有窗口组合在一起。因此,您必须为不同的组使用不同的名称而不是 MyInternalGroupID

请注意,这也适用于跨多个实例,因此属于同一组的窗口即使来自多个进程也会一起出现。如果您不希望这样,则必须在组名称中包含当前进程 ID。

进一步阅读:Taskbar API overview , The Old New Thing article (with C++ example)


对于 Delphi,我找到了一个解决方案 here , 感谢 Björn Ole:

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# 中调用 TaskbarManager.Instance.SetApplicationIdForSpecificWindow 那样调用 SetAppID

关于c# - 任务栏上的子组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37133319/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com