Vanara/Windows.Shell.Common/TaskBar/TaskbarList.cs

323 lines
15 KiB
C#

using System;
using Vanara.InteropServices;
using Vanara.PInvoke;
using static Vanara.PInvoke.Ole32;
using static Vanara.PInvoke.PropSys;
using static Vanara.PInvoke.Shell32;
namespace Vanara.Windows.Shell
{
/// <summary>State of the progress shown on a taskbar button.</summary>
public enum TaskbarButtonProgressState
{
/// <summary>No progress is displayed.</summary>
None = TBPFLAG.TBPF_NOPROGRESS,
/// <summary>The progress is indeterminate (marquee).</summary>
Indeterminate = TBPFLAG.TBPF_INDETERMINATE,
/// <summary>Normal progress is displayed.</summary>
Normal = TBPFLAG.TBPF_NORMAL,
/// <summary>An error occurred (red).</summary>
Error = TBPFLAG.TBPF_ERROR,
/// <summary>The operation is paused (yellow).</summary>
Paused = TBPFLAG.TBPF_PAUSED
}
/// <summary>
/// Methods that control the Windows taskbar. It allows you to dynamically add, remove, and activate items on the taskbar. This wraps all
/// of the ITaskbarListX interfaces.
/// </summary>
public static class TaskbarList
{
private static readonly TaskbarListStaticFinalizer finalizer = new();
private static readonly Version Win7Ver = new(6, 1);
private static ITaskbarList2 taskbar2;
private static ITaskbarList4 taskbar4;
static TaskbarList()
{
taskbar2 = new ITaskbarList2();
taskbar2.HrInit();
taskbar4 = taskbar2 as ITaskbarList4;
}
/// <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">The window on the taskbar to be displayed as active.</param>
public static void ActivateTaskbarItem(HWND hwnd) => taskbar2?.ActivateTab(hwnd);
/// <summary>
/// Gets the explicit Application User Model ID (AppUserModelID) used to associate processes, files, and windows with a particular application.
/// </summary>
/// <param name="hwnd">The window whose thumbnail displays the tooltip. This window must belong to the calling process.</param>
/// <returns>The Application User Model ID.</returns>
public static string GetWindowAppId(HWND hwnd) => GetWindowProperty(hwnd, PROPERTYKEY.System.AppUserModel.ID);
/// <summary>Marks a window as full-screen.</summary>
/// <param name="hwnd">The window to be marked.</param>
/// <param name="fullscreen">A Boolean value marking the desired full-screen status of the window.</param>
/// <exception cref="ArgumentNullException">parent</exception>
public static void MarkFullscreenWindow(HWND hwnd, bool fullscreen) => taskbar2?.MarkFullscreenWindow(hwnd, fullscreen);
/// <summary>
/// Informs the taskbar that a new tab or document thumbnail has been provided for display in an application's taskbar group flyout.
/// </summary>
/// <param name="hwndTab">The tab or document window. This value is required and cannot be NULL.</param>
/// <param name="hwndMDI">
/// The application's main window. This value tells the taskbar which application's preview group to attach the new thumbnail to.
/// This value is required and cannot be NULL.
/// </param>
/// <remarks>
/// By itself, registering a tab thumbnail alone will not result in its being displayed. You must also call SetTabOrder to instruct
/// the group where to display it.
/// </remarks>
public static void RegisterTab(HWND hwndTab, HWND hwndMDI)
{
Validate7OrLater();
taskbar4?.RegisterTab(hwndTab, hwndMDI);
}
/// <summary>Marks a taskbar button as active but does not visually activate it.</summary>
/// <param name="hwnd">The window to be marked as active.</param>
/// <exception cref="ArgumentNullException">parent</exception>
public static void SetActiveAlt(HWND hwnd) => taskbar2?.SetActiveAlt(hwnd);
/// <summary>Applies an overlay to a taskbar button to indicate application status or a notification to the user.</summary>
/// <param name="hwnd">
/// The window whose associated taskbar button receives the overlay. This window must belong to a calling process associated with the
/// button's application.
/// </param>
/// <param name="icon">
/// The icon to use as the overlay. This should be a small icon, measuring 16x16 pixels at 96 dpi. If an overlay icon is already
/// applied to the taskbar button, that existing overlay is replaced.
/// <para>
/// This value can be <see langword="null"/>. How a <see langword="null"/> value is handled depends on whether the taskbar button
/// represents a single window or a group of windows.
/// </para>
/// <list type="bullet">
/// <item>
/// <term>If the taskbar button represents a single window, the overlay icon is removed from the display.</term>
/// </item>
/// <item>
/// <term>
/// If the taskbar button represents a group of windows and a previous overlay is still available (received earlier than the current
/// overlay, but not yet freed by a NULL value), then that previous overlay is displayed in place of the current overlay.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="description">
/// A string that provides an alt text version of the information conveyed by the overlay, for accessibility purposes.
/// </param>
/// <exception cref="ArgumentNullException">parent</exception>
public static void SetOverlayIcon(HWND hwnd, HICON icon, string description)
{
Validate7OrLater();
taskbar4?.SetOverlayIcon(hwnd, icon, description);
}
/// <summary>Sets the type and state of the progress indicator displayed on a taskbar button.</summary>
/// <param name="hwnd">
/// The window in which the progress of an operation is being shown. This window's associated taskbar button will display the
/// progress bar.
/// </param>
/// <param name="status">The current state of the progress button. Specify only one of the enum values.</param>
public static void SetProgressState(HWND hwnd, TaskbarButtonProgressState status)
{
Validate7OrLater();
taskbar4?.SetProgressState(hwnd, (TBPFLAG)status);
}
/// <summary>
/// Displays or updates a progress bar hosted in a taskbar button to show the specific percentage completed of the full operation.
/// </summary>
/// <param name="hwnd">The window whose associated taskbar button is being used as a progress indicator.</param>
/// <param name="completed">
/// An application-defined value that indicates the proportion of the operation that has been completed at the time the method is called.
/// </param>
/// <param name="total">An application-defined value that specifies the value ullCompleted will have when the operation is complete.</param>
public static void SetProgressValue(HWND hwnd, ulong completed, ulong total)
{
Validate7OrLater();
taskbar4?.SetProgressValue(hwnd, completed, total);
}
/// <summary>Informs the taskbar that a tab or document window has been made the active window.</summary>
/// <param name="hwndTab">
/// The active tab window. This window must already be registered through RegisterTab. This value can be NULL if no tab is active.
/// </param>
/// <param name="hwndMDI">
/// The application's main window. This value tells the taskbar which group the thumbnail is a member of. This value is required and
/// cannot be NULL.
/// </param>
public static void SetTabActive(HWND hwndTab, HWND hwndMDI)
{
Validate7OrLater();
taskbar4?.SetTabActive(hwndTab, hwndMDI, 0);
}
/// <summary>
/// Inserts a new thumbnail into a tabbed-document interface (TDI) or multiple-document interface (MDI) application's group flyout or
/// moves an existing thumbnail to a new position in the application's group.
/// </summary>
/// <param name="hwndTab">
/// The tab window whose thumbnail is being placed. This value is required, must already be registered through RegisterTab, and
/// cannot be NULL.
/// </param>
/// <param name="hwndInsertBefore">
/// The tab window whose thumbnail that hwndTab is inserted to the left of. This window must already be registered through
/// RegisterTab. If this value is NULL, the new thumbnail is added to the end of the list.
/// </param>
/// <remarks>This method must be called for the thumbnail to be shown in the group. Call it after you have called RegisterTab.</remarks>
public static void SetTabOrder(HWND hwndTab, HWND hwndInsertBefore = default)
{
Validate7OrLater();
taskbar4?.SetTabOrder(hwndTab, hwndInsertBefore);
}
/// <summary>
/// Allows a tab to specify whether the main application frame window or the tab window should be used as a thumbnail or in the peek
/// feature under certain circumstances.
/// </summary>
/// <param name="hwndTab">The tab window that is to have properties set. This windows must already be registered through RegisterTab.</param>
/// <param name="properties">
/// One or more members of the STPFLAG enumeration that specify the displayed thumbnail and peek image source of the tab thumbnail.
/// </param>
public static void SetTabProperties(HWND hwndTab, STPFLAG properties)
{
Validate7OrLater();
taskbar4?.SetTabProperties(hwndTab, properties);
}
/// <summary>Selects a portion of a window's client area to display as that window's thumbnail in the taskbar.</summary>
/// <param name="hwnd">The window represented in the taskbar.</param>
/// <param name="windowClipRect">
/// A <see cref="PRECT"/> that specifies a selection within the window's client area, relative to the upper-left corner of that
/// client area. To clear a clip that is already in place and return to the default display of the thumbnail, set this parameter to NULL.
/// </param>
public static void SetThumbnailClip(HWND hwnd, PRECT windowClipRect)
{
Validate7OrLater();
taskbar4?.SetThumbnailClip(hwnd, windowClipRect);
}
/// <summary>
/// Specifies or updates the text of the tooltip that is displayed when the mouse pointer rests on an individual preview thumbnail in
/// a taskbar button flyout.
/// </summary>
/// <param name="hwnd">The window whose thumbnail displays the tooltip. This window must belong to the calling process.</param>
/// <param name="tip">
/// The text to be displayed in the tooltip. This value can be NULL, in which case the title of the window is used as the tooltip.
/// </param>
public static void SetThumbnailTooltip(HWND hwnd, string tip)
{
Validate7OrLater();
taskbar4?.SetThumbnailTooltip(hwnd, tip);
}
/// <summary>
/// Sets the explicit Application User Model ID (AppUserModelID) used to associate processes, files, and windows with a particular application.
/// </summary>
/// <param name="hwnd">The window whose thumbnail displays the tooltip. This window must belong to the calling process.</param>
/// <param name="appId">The Application User Model ID.</param>
public static void SetWindowAppId(HWND hwnd, string appId) => SetWindowProperty(hwnd, PROPERTYKEY.System.AppUserModel.ID, appId);
/// <summary>Adds a thumbnail toolbar with a specified set of buttons to the thumbnail image of a window in a taskbar button flyout.</summary>
/// <param name="hwnd">
/// The window whose thumbnail representation will receive the toolbar. This window must belong to the calling process.
/// </param>
/// <param name="buttons">
/// An array of THUMBBUTTON structures. Each THUMBBUTTON defines an individual button to be added to the toolbar. Buttons cannot be
/// added or deleted later, so this must be the full defined set. Buttons also cannot be reordered, so their order in the array,
/// which is the order in which they are displayed left to right, will be their permanent order.
/// </param>
public static void ThumbBarAddButtons(HWND hwnd, THUMBBUTTON[] buttons)
{
Validate7OrLater();
taskbar4?.ThumbBarAddButtons(hwnd, (uint)buttons.Length, buttons);
}
/// <summary>
/// Specifies an image list that contains button images for a toolbar embedded in a thumbnail image of a window in a taskbar button flyout.
/// </summary>
/// <param name="hwnd">
/// The window whose thumbnail representation contains the toolbar to be updated. This window must belong to the calling process.
/// </param>
/// <param name="imageList">The image list that contains all button images to be used in the toolbar.</param>
public static void ThumbBarSetImageList(HWND hwnd, HIMAGELIST imageList)
{
Validate7OrLater();
taskbar4?.ThumbBarSetImageList(hwnd, imageList);
}
/// <summary>
/// Shows, enables, disables, or hides buttons in a thumbnail toolbar as required by the window's current state. A thumbnail toolbar
/// is a toolbar embedded in a thumbnail image of a window in a taskbar button flyout.
/// </summary>
/// <param name="hwnd">The window whose thumbnail representation contains the toolbar.</param>
/// <param name="buttons">
/// An array of THUMBBUTTON structures. Each THUMBBUTTON defines an individual button. If the button already exists (the iId value is
/// already defined), then that existing button is updated with the information provided in the structure.
/// </param>
public static void ThumbBarUpdateButtons(HWND hwnd, THUMBBUTTON[] buttons)
{
Validate7OrLater();
taskbar4?.ThumbBarUpdateButtons(hwnd, (uint)buttons.Length, buttons);
}
/// <summary>Removes a thumbnail from an application's preview group when that tab or document is closed in the application.</summary>
/// <param name="hwnd">
/// The tab window whose thumbnail is being removed. This is the same value with which the thumbnail was registered as part the group
/// through RegisterTab. This value is required and cannot be NULL.
/// </param>
public static void UnregisterTab(HWND hwnd)
{
Validate7OrLater();
taskbar4?.UnregisterTab(hwnd);
}
internal static string GetWindowProperty(HWND hwnd, PROPERTYKEY propkey)
{
// Get the IPropertyStore for the given window handle
using ComReleaser<IPropertyStore> pPropStore = ComReleaserFactory.Create(GetWindowPropertyStore(hwnd));
// Get the value
using PROPVARIANT pv = new PROPVARIANT();
pPropStore.Item.GetValue(propkey, pv);
return pv.Value.ToString();
}
internal static IPropertyStore GetWindowPropertyStore(HWND hwnd) => SHGetPropertyStoreForWindow<IPropertyStore>(hwnd);
internal static void SetWindowProperty(HWND hwnd, PROPERTYKEY propkey, string value)
{
// Get the IPropertyStore for the given window handle
using ComReleaser<IPropertyStore> pPropStore = ComReleaserFactory.Create(GetWindowPropertyStore(hwnd));
// Set the value
using PROPVARIANT pv = new PROPVARIANT(value);
pPropStore.Item.SetValue(propkey, pv);
}
private static void Validate7OrLater()
{
if (Environment.OSVersion.Version < Win7Ver)
{
throw new InvalidOperationException("This method is only available on Windows 7 and later.");
}
}
private sealed class TaskbarListStaticFinalizer
{
~TaskbarListStaticFinalizer()
{
taskbar2 = null;
taskbar4 = null;
}
}
}
}