using System;
using System.Drawing;
using System.Runtime.InteropServices;
using TaskbarLib.Interop;
namespace TaskbarLib.DesktopIntegration
{
///
/// The primary coordinator of the Windows 7 taskbar-related activities.
/// For additional functionality, see the JumpListManager
/// and ThumbButtonManager classes.
///
public static class Windows7Taskbar
{
#region Infrastructure
///
/// The WM_TaskbarButtonCreated message number.
///
public static uint TaskbarButtonCreatedMessage
{
get { return UnsafeNativeMethods.WM_TaskbarButtonCreated; }
}
// Use thread static to work around COM threading issues.
[ThreadStatic]
private static ITaskbarList3 _taskbarList;
internal static ITaskbarList3 TaskbarList
{
get
{
if (_taskbarList == null)
{
_taskbarList = (ITaskbarList3)new CTaskbarList();
_taskbarList.HrInit();
}
return _taskbarList;
}
}
private static IPropertyStore InternalGetWindowPropertyStore(IntPtr hwnd)
{
IPropertyStore propStore;
int rc = UnsafeNativeMethods.SHGetPropertyStoreForWindow(hwnd, ref SafeNativeMethods.IID_IPropertyStore, out propStore);
if (rc != 0)
throw Marshal.GetExceptionForHR(rc);
return propStore;
}
private static void InternalEnableCustomWindowPreview(IntPtr hwnd, bool enable)
{
int t = enable ? 1 : 0;
int rc;
rc = UnsafeNativeMethods.DwmSetWindowAttribute(hwnd, SafeNativeMethods.DWMWA_HAS_ICONIC_BITMAP, ref t, 4);
if (rc != 0)
throw Marshal.GetExceptionForHR(rc);
rc = UnsafeNativeMethods.DwmSetWindowAttribute(hwnd, SafeNativeMethods.DWMWA_FORCE_ICONIC_REPRESENTATION, ref t, 4);
if (rc != 0)
throw Marshal.GetExceptionForHR(rc);
}
#endregion
#region Application Id
///
/// Gets a window's application id by its window handle.
///
/// The window handle.
/// The application id of that window.
public static string GetWindowAppId(IntPtr hwnd)
{
IPropertyStore propStore = InternalGetWindowPropertyStore(hwnd);
PropVariant pv;
propStore.GetValue(ref PropertyKey.PKEY_AppUserModel_ID, out pv);
Marshal.ReleaseComObject(propStore);
return pv.GetValue();
}
///
/// Sets the window's application id by its window handle.
///
/// The window handle.
/// The application id.
public static void SetWindowAppId(IntPtr hwnd, string appId)
{
IPropertyStore propStore = InternalGetWindowPropertyStore(hwnd);
PropVariant pv = new PropVariant();
pv.SetValue(appId);
propStore.SetValue(ref PropertyKey.PKEY_AppUserModel_ID, ref pv);
Marshal.ReleaseComObject(propStore);
}
///
/// Sets the current process' explicit application user model id.
///
/// The application id.
public static void SetCurrentProcessAppId(string appId)
{
UnsafeNativeMethods.SetCurrentProcessExplicitAppUserModelID(appId);
}
///
/// Gets the current process' explicit application user model id.
///
/// The application id.
public static string GetCurrentProcessAppId()
{
string appId;
UnsafeNativeMethods.GetCurrentProcessExplicitAppUserModelID(out appId);
return appId;
}
#endregion
#region DWM Iconic Thumbnail and Peek Bitmap
///
/// Indicates that the specified window requests the DWM
/// to demand live preview (thumbnail and peek) mode when necessary
/// instead of relying on default preview.
///
/// The window handle.
public static void EnableCustomWindowPreview(IntPtr hwnd)
{
InternalEnableCustomWindowPreview(hwnd, true);
}
///
/// Indicates that the specified window does not require the DWM
/// to demand live preview (thumbnail and peek) mode when necessary,
/// i.e. this window relies on default preview.
///
/// The window handle.
public static void DisableCustomWindowPreview(IntPtr hwnd)
{
InternalEnableCustomWindowPreview(hwnd, false);
}
///
/// Sets the specified iconic thumbnail for the specified window.
/// This is typically done in response to a DWM message.
///
/// The window handle.
/// The thumbnail bitmap.
public static void SetIconicThumbnail(IntPtr hwnd, Bitmap bitmap)
{
int rc = UnsafeNativeMethods.DwmSetIconicThumbnail(hwnd, bitmap.GetHbitmap(), SafeNativeMethods.DWM_SIT_DISPLAYFRAME);
if (rc != 0)
throw Marshal.GetExceptionForHR(rc);
}
///
/// Sets the specified peek (live preview) bitmap for the specified
/// window. This is typically done in response to a DWM message.
///
/// The window handle.
/// The thumbnail bitmap.
/// Whether to display a standard window
/// frame around the bitmap.
public static void SetPeekBitmap(IntPtr hwnd, Bitmap bitmap, bool displayFrame)
{
int rc = UnsafeNativeMethods.DwmSetIconicLivePreviewBitmap(hwnd, bitmap.GetHbitmap(), IntPtr.Zero, displayFrame ? SafeNativeMethods.DWM_SIT_DISPLAYFRAME : (uint)0);
if (rc != 0)
throw Marshal.GetExceptionForHR(rc);
}
///
/// Sets the specified peek (live preview) bitmap for the specified
/// window. This is typically done in response to a DWM message.
///
/// The window handle.
/// The thumbnail bitmap.
/// The client area offset at which to display
/// the specified bitmap. The rest of the parent window will be
/// displayed as "remembered" by the DWM.
/// Whether to display a standard window
/// frame around the bitmap.
public static void SetPeekBitmap(IntPtr hwnd, Bitmap bitmap, Point offset, bool displayFrame)
{
var nativePoint = new POINT(offset.X, offset.Y);
int rc = UnsafeNativeMethods.DwmSetIconicLivePreviewBitmap(hwnd, bitmap.GetHbitmap(), ref nativePoint, displayFrame ? SafeNativeMethods.DWM_SIT_DISPLAYFRAME : (uint)0);
if (rc != 0)
throw Marshal.GetExceptionForHR(rc);
}
#endregion
#region Taskbar Overlay Icon
///
/// Draws the specified overlay icon on the specified window's
/// taskbar button.
///
/// The window handle.
/// The overlay icon.
/// The overlay icon description.
public static void SetTaskbarOverlayIcon(IntPtr hwnd, Icon icon, string description)
{
TaskbarList.SetOverlayIcon(
hwnd,
icon == null ? IntPtr.Zero : icon.Handle,
description);
}
#endregion
#region Taskbar Progress Bar
///
/// Represents the thumbnail progress bar state.
///
public enum ThumbnailProgressState
{
///
/// No progress is displayed.
///
NoProgress = 0,
///
/// The progress is indeterminate (marquee).
///
Indeterminate = 0x1,
///
/// Normal progress is displayed.
///
Normal = 0x2,
///
/// An error occurred (red).
///
Error = 0x4,
///
/// The operation is paused (yellow).
///
Paused = 0x8
}
///
/// Sets the progress state of the specified window's
/// taskbar button.
///
/// The window handle.
/// The progress state.
public static void SetProgressState(IntPtr hwnd, ThumbnailProgressState state)
{
TaskbarList.SetProgressState(hwnd, (TBPFLAG)state);
}
///
/// Sets the progress value of the specified window's
/// taskbar button.
///
/// The window handle.
/// The current value.
/// The maximum value.
public static void SetProgressValue(IntPtr hwnd, ulong current, ulong maximum)
{
TaskbarList.SetProgressValue(hwnd, current, maximum);
}
#endregion
#region Taskbar Thumbnails
///
/// Specifies that only a portion of the window's client area
/// should be used in the window's thumbnail.
///
/// The window.
/// The rectangle that specifies the clipped region.
public static void SetThumbnailClip(IntPtr hwnd, Rectangle clipRect)
{
RECT rect = new RECT(clipRect.Left, clipRect.Top, clipRect.Right, clipRect.Bottom);
TaskbarList.SetThumbnailClip(hwnd, ref rect);
}
///
/// Sets the specified window's thumbnail tooltip.
///
/// The window.
/// The tooltip text.
public static void SetThumbnailTooltip(IntPtr hwnd, string tooltip)
{
TaskbarList.SetThumbnailTooltip(hwnd, tooltip);
}
#endregion
#region Miscellaneous
///
/// Specifies that the taskbar- and DWM-related windows messages should
/// pass through the Windows UIPI mechanism even if the process is
/// running elevated. Calling this method is not required unless the
/// process is running elevated.
///
public static void AllowTaskbarWindowMessagesThroughUipi()
{
UnsafeNativeMethods.ChangeWindowMessageFilter(UnsafeNativeMethods.WM_TaskbarButtonCreated, SafeNativeMethods.MSGFLT_ADD);
UnsafeNativeMethods.ChangeWindowMessageFilter(SafeNativeMethods.WM_DWMSENDICONICTHUMBNAIL, SafeNativeMethods.MSGFLT_ADD);
UnsafeNativeMethods.ChangeWindowMessageFilter(SafeNativeMethods.WM_DWMSENDICONICLIVEPREVIEWBITMAP, SafeNativeMethods.MSGFLT_ADD);
UnsafeNativeMethods.ChangeWindowMessageFilter(SafeNativeMethods.WM_COMMAND, SafeNativeMethods.MSGFLT_ADD);
UnsafeNativeMethods.ChangeWindowMessageFilter(SafeNativeMethods.WM_SYSCOMMAND, SafeNativeMethods.MSGFLT_ADD);
UnsafeNativeMethods.ChangeWindowMessageFilter(SafeNativeMethods.WM_ACTIVATE, SafeNativeMethods.MSGFLT_ADD);
}
#endregion
}
}