//------------------------------------------------------------------ // // A P/Invoke wrapper for TaskDialog. Usability was given preference to perf and size. // // // //------------------------------------------------------------------ namespace ProcessHacker.Components { using System; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; /// /// Class to hold native code interop declarations. /// [System.Security.SuppressUnmanagedCodeSecurity] internal static partial class UnsafeNativeMethods { /// /// WM_USER taken from WinUser.h /// internal const uint WM_USER = 0x0400; /// /// The signature of the callback that receives messages from the Task Dialog when various events occur. /// /// The window handle of the /// The message being passed. /// wParam which is interpreted differently depending on the message. /// wParam which is interpreted differently depending on the message. /// The refrence data that was set to TaskDialog.CallbackData. /// A HRESULT value. The return value is specific to the message being processed. internal delegate int TaskDialogCallback([In] IntPtr hwnd, [In] uint msg, [In] UIntPtr wParam, [In] IntPtr lParam, [In] IntPtr refData); /// /// TASKDIALOG_FLAGS taken from CommCtrl.h. /// [Flags] internal enum TASKDIALOG_FLAGS { /// /// Enable hyperlinks. /// TDF_ENABLE_HYPERLINKS = 0x0001, /// /// Use icon handle for main icon. /// TDF_USE_HICON_MAIN = 0x0002, /// /// Use icon handle for footer icon. /// TDF_USE_HICON_FOOTER = 0x0004, /// /// Allow dialog to be cancelled, even if there is no cancel button. /// TDF_ALLOW_DIALOG_CANCELLATION = 0x0008, /// /// Use command links rather than buttons. /// TDF_USE_COMMAND_LINKS = 0x0010, /// /// Use command links with no icons rather than buttons. /// TDF_USE_COMMAND_LINKS_NO_ICON = 0x0020, /// /// Show expanded info in the footer area. /// TDF_EXPAND_FOOTER_AREA = 0x0040, /// /// Expand by default. /// TDF_EXPANDED_BY_DEFAULT = 0x0080, /// /// Start with verification flag already checked. /// TDF_VERIFICATION_FLAG_CHECKED = 0x0100, /// /// Show a progress bar. /// TDF_SHOW_PROGRESS_BAR = 0x0200, /// /// Show a marquee progress bar. /// TDF_SHOW_MARQUEE_PROGRESS_BAR = 0x0400, /// /// Callback every 200 milliseconds. /// TDF_CALLBACK_TIMER = 0x0800, /// /// Center the dialog on the owner window rather than the monitor. /// TDF_POSITION_RELATIVE_TO_WINDOW = 0x1000, /// /// Right to Left Layout. /// TDF_RTL_LAYOUT = 0x2000, /// /// No default radio button. /// TDF_NO_DEFAULT_RADIO_BUTTON = 0x4000, /// /// Task Dialog can be minimized. /// TDF_CAN_BE_MINIMIZED = 0x8000 } /// /// TASKDIALOG_ELEMENTS taken from CommCtrl.h /// internal enum TASKDIALOG_ELEMENTS { /// /// The content element. /// TDE_CONTENT, /// /// Expanded Information. /// TDE_EXPANDED_INFORMATION, /// /// Footer. /// TDE_FOOTER, /// /// Main Instructions /// TDE_MAIN_INSTRUCTION } /// /// TASKDIALOG_ICON_ELEMENTS taken from CommCtrl.h /// internal enum TASKDIALOG_ICON_ELEMENTS { /// /// Main instruction icon. /// TDIE_ICON_MAIN, /// /// Footer icon. /// TDIE_ICON_FOOTER } /// /// TASKDIALOG_MESSAGES taken from CommCtrl.h. /// internal enum TASKDIALOG_MESSAGES : uint { // Spec is not clear on what this is for. ///// ///// Navigate page. ///// ////TDM_NAVIGATE_PAGE = WM_USER + 101, /// /// Click button. /// TDM_CLICK_BUTTON = WM_USER + 102, // wParam = Button ID /// /// Set Progress bar to be marquee mode. /// TDM_SET_MARQUEE_PROGRESS_BAR = WM_USER + 103, // wParam = 0 (nonMarque) wParam != 0 (Marquee) /// /// Set Progress bar state. /// TDM_SET_PROGRESS_BAR_STATE = WM_USER + 104, // wParam = new progress state /// /// Set progress bar range. /// TDM_SET_PROGRESS_BAR_RANGE = WM_USER + 105, // lParam = MAKELPARAM(nMinRange, nMaxRange) /// /// Set progress bar position. /// TDM_SET_PROGRESS_BAR_POS = WM_USER + 106, // wParam = new position /// /// Set progress bar marquee (animation). /// TDM_SET_PROGRESS_BAR_MARQUEE = WM_USER + 107, // wParam = 0 (stop marquee), wParam != 0 (start marquee), lparam = speed (milliseconds between repaints) /// /// Set a text element of the Task Dialog. /// TDM_SET_ELEMENT_TEXT = WM_USER + 108, // wParam = element (TASKDIALOG_ELEMENTS), lParam = new element text (LPCWSTR) /// /// Click a radio button. /// TDM_CLICK_RADIO_BUTTON = WM_USER + 110, // wParam = Radio Button ID /// /// Enable or disable a button. /// TDM_ENABLE_BUTTON = WM_USER + 111, // lParam = 0 (disable), lParam != 0 (enable), wParam = Button ID /// /// Enable or disable a radio button. /// TDM_ENABLE_RADIO_BUTTON = WM_USER + 112, // lParam = 0 (disable), lParam != 0 (enable), wParam = Radio Button ID /// /// Check or uncheck the verfication checkbox. /// TDM_CLICK_VERIFICATION = WM_USER + 113, // wParam = 0 (unchecked), 1 (checked), lParam = 1 (set key focus) /// /// Update the text of an element (no effect if origially set as null). /// TDM_UPDATE_ELEMENT_TEXT = WM_USER + 114, // wParam = element (TASKDIALOG_ELEMENTS), lParam = new element text (LPCWSTR) /// /// Designate whether a given Task Dialog button or command link should have a User Account Control (UAC) shield icon. /// TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE = WM_USER + 115, // wParam = Button ID, lParam = 0 (elevation not required), lParam != 0 (elevation required) /// /// Refreshes the icon of the task dialog. /// TDM_UPDATE_ICON = WM_USER + 116, // wParam = icon element (TASKDIALOG_ICON_ELEMENTS), lParam = new icon (hIcon if TDF_USE_HICON_* was set, PCWSTR otherwise) /// /// Refreshes the contents of the Task Dialog. /// TDM_NAVIGATE_PAGE = WM_USER+101 } ///// ///// TaskDialog taken from commctrl.h. ///// ///// Parent window. ///// Module instance to get resources from. ///// Title of the Task Dialog window. ///// The main instructions. ///// Common push buttons to show. ///// The main icon. ///// The push button pressed. ////[DllImport("ComCtl32", CharSet = CharSet.Unicode, PreserveSig = false)] ////public static extern void TaskDialog( //// [In] IntPtr hwndParent, //// [In] IntPtr hInstance, //// [In] String pszWindowTitle, //// [In] String pszMainInstruction, //// [In] TaskDialogCommonButtons dwCommonButtons, //// [In] IntPtr pszIcon, //// [Out] out int pnButton); /// /// TaskDialogIndirect taken from commctl.h /// /// All the parameters about the Task Dialog to Show. /// The push button pressed. /// The radio button that was selected. /// The state of the verification checkbox on dismiss of the Task Dialog. [DllImport("comctl32.dll", CharSet = CharSet.Unicode, PreserveSig = false)] internal static extern void TaskDialogIndirect( [In] ref TASKDIALOGCONFIG pTaskConfig, [Out] out int pnButton, [Out] out int pnRadioButton, [MarshalAs(UnmanagedType.Bool)] [Out] out bool pfVerificationFlagChecked); /// /// Win32 SendMessage. /// /// Window handle to send to. /// The windows message to send. /// Specifies additional message-specific information. /// Specifies additional message-specific information. /// The return value specifies the result of the message processing; it depends on the message sent. [DllImport("user32.dll")] internal static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); /// /// Win32 SendMessage. /// /// Window handle to send to. /// The windows message to send. /// Specifies additional message-specific information. /// Specifies additional message-specific information as a string. /// The return value specifies the result of the message processing; it depends on the message sent. [DllImport("user32.dll", EntryPoint="SendMessage")] internal static extern IntPtr SendMessageWithString(IntPtr hWnd, uint Msg, IntPtr wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam); /// /// TASKDIALOGCONFIG taken from commctl.h. /// [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 1)] internal struct TASKDIALOGCONFIG { /// /// Size of the structure in bytes. /// public uint cbSize; /// /// Parent window handle. /// public IntPtr hwndParent; /// /// Module instance handle for resources. /// public IntPtr hInstance; /// /// Flags. /// public TASKDIALOG_FLAGS dwFlags; // TASKDIALOG_FLAGS (TDF_XXX) flags /// /// Bit flags for commonly used buttons. /// public TaskDialogCommonButtons dwCommonButtons; // TASKDIALOG_COMMON_BUTTON (TDCBF_XXX) flags /// /// Window title. /// [MarshalAs(UnmanagedType.LPWStr)] public string pszWindowTitle; // string or MAKEINTRESOURCE() /// /// The Main icon. Overloaded member. Can be string, a handle, a special value or a resource ID. /// public IntPtr MainIcon; /// /// Main Instruction. /// [MarshalAs(UnmanagedType.LPWStr)] public string pszMainInstruction; /// /// Content. /// [MarshalAs(UnmanagedType.LPWStr)] public string pszContent; /// /// Count of custom Buttons. /// public uint cButtons; /// /// Array of custom buttons. /// public IntPtr pButtons; /// /// ID of default button. /// public int nDefaultButton; /// /// Count of radio Buttons. /// public uint cRadioButtons; /// /// Array of radio buttons. /// public IntPtr pRadioButtons; /// /// ID of default radio button. /// public int nDefaultRadioButton; /// /// Text for verification check box. often "Don't ask be again". /// [MarshalAs(UnmanagedType.LPWStr)] public string pszVerificationText; /// /// Expanded Information. /// [MarshalAs(UnmanagedType.LPWStr)] public string pszExpandedInformation; /// /// Text for expanded control. /// [MarshalAs(UnmanagedType.LPWStr)] public string pszExpandedControlText; /// /// Text for expanded control. /// [MarshalAs(UnmanagedType.LPWStr)] public string pszCollapsedControlText; /// /// Icon for the footer. An overloaded member link MainIcon. /// public IntPtr FooterIcon; /// /// Footer Text. /// [MarshalAs(UnmanagedType.LPWStr)] public string pszFooter; /// /// Function pointer for callback. /// public TaskDialogCallback pfCallback; /// /// Data that will be passed to the call back. /// public IntPtr lpCallbackData; /// /// Width of the Task Dialog's client area in DLU's. /// If 0, Task Dialog will calculate the ideal width. /// public uint cxWidth; } } }