using System; using System.Drawing; using System.Runtime.InteropServices; using System.Windows.Forms; using Vanara.PInvoke; using static Vanara.PInvoke.User32_Gdi; using static Vanara.PInvoke.Shell32; namespace Vanara.Windows.Shell { /// 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. public static class TaskbarList { static readonly Finalizer finalizer = new Finalizer(); static ITaskbarList2 taskbar2; static ITaskbarList4 taskbar4; static TaskbarList() { var tb = new CTaskbarList(); taskbar2 = (ITaskbarList2)tb; try { taskbar4 = (ITaskbarList4)tb; } catch { taskbar4 = null; } taskbar2?.HrInit(); } sealed class Finalizer { ~Finalizer() { if (taskbar2 != null) Marshal.ReleaseComObject(taskbar2); if (taskbar4 != null) Marshal.ReleaseComObject(taskbar4); } } /// Gets the taskbar button created MSG identifier. /// The taskbar button created MSG identifier. public static uint TaskbarButtonCreatedWinMsgId => RegisterWindowMessage("TaskbarButtonCreated"); /// Activates an item on the taskbar. The window is not actually activated; the window's item on the taskbar is merely displayed as active. /// The window on the taskbar to be displayed as active. /// parent public static void ActivateTaskbarItem(IWin32Window parent) { if (parent == null) throw new ArgumentNullException(nameof(parent)); taskbar2?.ActivateTab(parent.Handle); } /// Marks a window as full-screen. /// The window to be marked. /// A Boolean value marking the desired full-screen status of the window. /// parent public static void MarkFullscreenWindow(IWin32Window parent, bool fullscreen) { if (parent == null) throw new ArgumentNullException(nameof(parent)); taskbar2?.MarkFullscreenWindow(parent.Handle, fullscreen); } /// Marks a taskbar item as active but does not visually activate it. /// The window to be marked as active. /// parent public static void SetActiveAlt(IWin32Window parent) { if (parent == null) throw new ArgumentNullException(nameof(parent)); taskbar2?.SetActiveAlt(parent.Handle); } // Thumbnail Toolbars ============================================ /// Adds a thumbnail toolbar with a specified set of buttons to the thumbnail image of a window in a taskbar button flyout. /// The window whose thumbnail representation will receive the toolbar. This window must belong to the calling process. /// /// 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. /// public static void ThumbBarAddButtons(IWin32Window parent, THUMBBUTTON[] buttons) { Validate7OrLater(); if (parent == null) throw new ArgumentNullException(nameof(parent)); if (buttons == null) throw new ArgumentNullException(nameof(buttons)); taskbar4?.ThumbBarAddButtons(parent.Handle, (uint)buttons.Length, buttons); } /// Specifies an image list that contains button images for a toolbar embedded in a thumbnail image of a window in a taskbar button flyout. /// The window whose thumbnail representation contains the toolbar to be updated. This window must belong to the calling process. /// The image list that contains all button images to be used in the toolbar. public static void ThumbBarSetImageList(IWin32Window parent, ImageList imageList) { Validate7OrLater(); if (parent == null) throw new ArgumentNullException(nameof(parent)); if (imageList == null) throw new ArgumentNullException(nameof(imageList)); taskbar4?.ThumbBarSetImageList(parent.Handle, imageList.Handle); } /// /// 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. /// /// The window whose thumbnail representation contains the toolbar. /// /// 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. /// public static void ThumbBarUpdateButtons(IWin32Window parent, THUMBBUTTON[] buttons) { Validate7OrLater(); if (parent == null) throw new ArgumentNullException(nameof(parent)); if (buttons == null) throw new ArgumentNullException(nameof(buttons)); taskbar4?.ThumbBarUpdateButtons(parent.Handle, (uint)buttons.Length, buttons); } // Overlays ============================================ /// Applies an overlay to a taskbar button to indicate application status or a notification to the user. /// /// The window whose associated taskbar button receives the overlay. This window must belong to a calling process associated with the button's application. /// /// /// 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. /// /// This value can be . How a value is handled depends on whether the taskbar button represents a single /// window or a group of windows. /// /// /// If the taskbar button represents a single window, the overlay icon is removed from the display. /// 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. /// /// /// A string that provides an alt text version of the information conveyed by the overlay, for accessibility purposes. public static void SetOverlayIcon(IWin32Window parent, Icon icon, string description) { Validate7OrLater(); if (parent == null) throw new ArgumentNullException(nameof(parent)); taskbar4?.SetOverlayIcon(parent.Handle, icon == null ? IntPtr.Zero : icon.Handle, description); } // Progress Bars ============================================ /// Sets the type and state of the progress indicator displayed on a taskbar button. /// /// The window in which the progress of an operation is being shown. This window's associated taskbar button will display the progress bar. /// /// The current state of the progress button. Specify only one of the enum values. public static void SetProgressState(IWin32Window parent, TBPFLAG status) { Validate7OrLater(); if (parent == null) throw new ArgumentNullException(nameof(parent)); taskbar4?.SetProgressState(parent.Handle, status); } /// Displays or updates a progress bar hosted in a taskbar button to show the specific percentage completed of the full operation. /// The window whose associated taskbar button is being used as a progress indicator. /// /// An application-defined value that indicates the proportion of the operation that has been completed at the time the method is called. /// /// An application-defined value that specifies the value ullCompleted will have when the operation is complete. public static void SetProgressValue(IWin32Window parent, ulong completed, ulong total) { Validate7OrLater(); if (parent == null) throw new ArgumentNullException(nameof(parent)); taskbar4?.SetProgressValue(parent.Handle, completed, total); } // Thumbnails ============================================ /// Informs the taskbar that a new tab or document thumbnail has been provided for display in an application's taskbar group flyout. /// The tab or document window. This value is required and cannot be NULL. /// /// 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. /// /// /// 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. /// public static void RegisterTab(IWin32Window parent, IWin32Window childWindow) { Validate7OrLater(); if (childWindow == null) throw new ArgumentNullException(nameof(childWindow)); if (parent == null) throw new ArgumentNullException(nameof(parent)); taskbar4?.RegisterTab(childWindow.Handle, parent.Handle); } /// Informs the taskbar that a tab or document window has been made the active window. /// The active tab window. This window must already be registered through RegisterTab. This value can be NULL if no tab is active. /// /// 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. /// public static void SetTabActive(IWin32Window parent, IWin32Window childWindow) { Validate7OrLater(); if (childWindow == null) throw new ArgumentNullException(nameof(childWindow)); if (parent == null) throw new ArgumentNullException(nameof(parent)); taskbar4?.SetTabActive(childWindow.Handle, parent.Handle, 0); } /// /// 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. /// /// /// The tab window whose thumbnail is being placed. This value is required, must already be registered through RegisterTab, and cannot be NULL. /// /// /// 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. /// /// This method must be called for the thumbnail to be shown in the group. Call it after you have called RegisterTab. public static void SetTabOrder(IWin32Window childWindow, IWin32Window insertBeforeChildWindow = null) { Validate7OrLater(); if (childWindow == null) throw new ArgumentNullException(nameof(childWindow)); taskbar4?.SetTabOrder(childWindow.Handle, insertBeforeChildWindow?.Handle ?? IntPtr.Zero); } /// /// 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. /// /// The tab window that is to have properties set. This windows must already be registered through RegisterTab. /// One or more members of the STPFLAG enumeration that specify the displayed thumbnail and peek image source of the tab thumbnail. public static void SetTabProperties(IWin32Window childWindow, STPFLAG properties) { Validate7OrLater(); if (childWindow == null) throw new ArgumentNullException(nameof(childWindow)); taskbar4?.SetTabProperties(childWindow.Handle, properties); } /// Removes a thumbnail from an application's preview group when that tab or document is closed in the application. /// /// 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. /// public static void UnregisterTab(IWin32Window childWindow) { Validate7OrLater(); if (childWindow == null) throw new ArgumentNullException(nameof(childWindow)); taskbar4?.UnregisterTab(childWindow.Handle); } /// Selects a portion of a window's client area to display as that window's thumbnail in the taskbar. /// The window represented in the taskbar. /// /// A 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. /// public static void SetThumbnailClip(IWin32Window parent, Rectangle windowClipRect) { Validate7OrLater(); if (parent == null) throw new ArgumentNullException(nameof(parent)); RECT cr = windowClipRect; taskbar4?.SetThumbnailClip(parent.Handle, cr); } /// /// 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. /// /// The window whose thumbnail displays the tooltip. This window must belong to the calling process. /// 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. public static void SetThumbnailTooltip(IWin32Window parent, string tip) { Validate7OrLater(); if (parent == null) throw new ArgumentNullException(nameof(parent)); taskbar4?.SetThumbnailTooltip(parent.Handle, tip); } static readonly Version Win7Ver = new Version(6, 1); private static void Validate7OrLater() { if (Environment.OSVersion.Version < Win7Ver) throw new InvalidOperationException("This method is only available on Windows 7 and later."); } } }