2016-05-10 53 views
0

我有一個應用程序,它有一個主窗口,然後它打開新的窗體。 整個應用程序就像一個文檔閱讀器,有許多類型的子表單。任務欄上的子表單組

例如,我打開了主窗口,3個文檔詳細信息表單和4個其他內容的編輯器。

現在。由於所有子窗體都是主窗體的子窗體,它們都被分組在任務欄上的一個圖標下,當您嘗試搜索窗口時顯示的列表中的某個窗口時,可能會造成混亂。

是否可以告訴系統,特定表單的所有實例必須在單獨的圖標中組合在一起?

像這樣

Taskbar - grouped child forms

我通過一些導遊了,但不幸的是,我還沒有發現這一特定問題beeing解決任何地方呢。

而且我希望在這裏爲我的應用程序設計和解決方案的普通預覽尋找C#實現,真正的應用程序可能會在Delphi中實現,所以真正的和主要的問題是如果操作系統甚至支持這種行爲,因爲這是一個正常行爲的巨大覆蓋 - 是否有可能在Windows中這樣做?還有可能在Linux(gnome,kde,xfce,unity)和MacOS上做到這一點?對於這些問題,我不需要知道如何解決問題,只要有人遇到問題,可以指點我提及這個問題的文章解決方案。

在此先感謝。

回答

1

我不能幫你與其他平臺,如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"); 

這將指派一名「應用模式ID」到你的窗口。 Windows將把所有帶有相同應用程序模型ID的窗口組合在一起。所以你必須使用不同的名字,而不是MyInternalGroupID

請注意,這也將在多個實例之間工作,因此屬於同一組的窗口即使在來自多個進程時也會一起出現。如果你不想要,你必須在組名中包含當前的進程ID。

延伸閱讀:Taskbar API overviewThe Old New Thing article (with C++ example)


對於德爾福,我找到了解決辦法here,學分比約恩·奧萊

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. 

您需要致電SetAppID你在C#中調用TaskbarManager.Instance.SetApplicationIdForSpecificWindow的方式,基本上。

+0

for c#,完美的作品。此外,還有德爾福的解決方案,即使我不能說它是正確還是工作,但現在,很高興知道,這是可能的。非常感謝 :) – Zorak