QA@IT

C# MDIの子Windowをタスクバーに表示したい

3481 PV

お世話になっております。

C#でWindowsアプリの開発を行っているのですが、MS Office製品のように MDI Window内で開いている子Windowをタクスバーに表示したいのですが、方法がわかりません。

SetWindowLong で WS_EX_APPWINDOW を設定してみたりしたのですがダメでした。

色々と調べているとWindows7以降とそれ以前ではタスクバーの制御の方法が変わっているようですが、WindowsXP などの旧来のタスクバーで表示させる方法を探しています。

どなたかやり方を知っている方がいましたらご享受願えますでしょうか。

よろしくお願い致します。

  • VisualStudioのバージョンを教えてください -
  • 2012Expressになります。
    よろしくお願いします。
    -

回答

あまり細かく検証していないのですが、ITaskbarListを利用するのはどうでしょう。

以下のクラスファイルを追加します。名前空間は適宜変更してください。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace QaItMDITaskBar
{
    [ComImport,
    Guid("56fdf342-fd6d-11d0-958a-006097c9a090"),
    InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface ITaskbarList
    {
        /// <summary>
        /// Initializes the taskbar list object. This method must be called before any other ITaskbarList methods can be called.
        /// </summary>
        void HrInit();

        /// <summary>
        /// Adds an item to the taskbar.
        /// </summary>
        /// <param name="hWnd">A handle to the window to be added to the taskbar.</param>
        void AddTab([In] IntPtr hWnd);

        /// <summary>
        /// Deletes an item from the taskbar.
        /// </summary>
        /// <param name="hWnd">A handle to the window to be deleted from the taskbar.</param>
        void DeleteTab([In] IntPtr hWnd);

        /// <summary>
        /// Activates an item on the taskbar. The window is not actually activated; the window's item on the taskbar is merely displayed as active.
        /// </summary>
        /// <param name="hWnd">A handle to the window on the taskbar to be displayed as active.</param>
        void ActivateTab([In] IntPtr hWnd);

        /// <summary>
        /// Marks a taskbar item as active but does not visually activate it.
        /// </summary>
        /// <param name="hWnd">A handle to the window to be marked as active.</param>
        void SetActiveAlt([In] IntPtr hWnd);
    }

    [ComImport]
    [Guid("56fdf344-fd6d-11d0-958a-006097c9a090")]
    public class CoTaskbarList
    {
    }
}

これを使うには、たとえばプロジェクトにMDI親フォームを追加して、そのShowNewFormイベントハンドラを以下の様にします。

private void ShowNewForm(object sender, EventArgs e)
{
    Form childForm = new Form();
    childForm.MdiParent = this;
    childForm.Text = "ウィンドウ " + childFormNumber++;
    childForm.Show();


    IntPtr windowHandle = childForm.Handle;
    var taskbarList = (ITaskbarList)new CoTaskbarList();
    taskbarList.HrInit();
    taskbarList.AddTab(windowHandle);
    taskbarList.ActivateTab(windowHandle);
    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(taskbarList);

    childForm.FormClosed += (s,evt) =>
    {
        var list = (ITaskbarList)new CoTaskbarList();
        list.HrInit();
        list.DeleteTab(windowHandle);
        System.Runtime.InteropServices.Marshal.ReleaseComObject(list);

    };
}

ITaskbarListの生成やFormを閉じるときの処理などが雑ですが、サンプルということでご了承ください。

ITaskbarListの定義は http://www.pinvoke.net/default.aspx/shell32/ITaskbarList.html
を参考にしました。

編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。