context: //------------------------------------------------------------------
  // <summary>
  // A P/Invoke wrapper for TaskDialog. Usability was given preference to perf and size.
  // </summary>
  //
  // <remarks/>
  //------------------------------------------------------------------
  
  namespace ProcessHacker.Components
  {
      using System;
      using System.Drawing;
      using System.Windows.Forms;
  
      /// <summary>
      /// The active Task Dialog window. Provides several methods for acting on the active TaskDialog.
      /// You should not use this object after the TaskDialog Destroy notification callback. Doing so
      /// will result in undefined behavior and likely crash.
      /// </summary>
      public class ActiveTaskDialog : IWin32Window
      {
          /// <summary>
          /// The Task Dialog's window handle.
          /// </summary>
          private readonly IntPtr handle;
  
          /// <summary>
          /// Creates a ActiveTaskDialog.
          /// </summary>
          /// <param name="handle">The Task Dialog's window handle.</param>
          internal ActiveTaskDialog(IntPtr handle)
          {
              if (handle == IntPtr.Zero)
              {
                  throw new ArgumentNullException("handle");
              }
  
              this.handle = handle;
          }
  
          /// <summary>
          /// The Task Dialog's handle.
          /// We don't own this window.
          /// </summary>
          public IntPtr Handle
          {
              get { return this.handle; }
          }
  
          /// <summary>
          /// Refreshes the contents of the Task Dialog. 
          /// Clients may send this message to the task dialog to 
          /// dynamically change the task dialog contents at run time.
          /// </summary>
          public void NavigatePage()
          { 
              //TODO: complete TaskDialog Navigate Page
              //IntPtr* p = (IntPtr*)UnsafeNativeMethods.TASKDIALOGCONFIG();
              //UnsafeNativeMethods.SendMessage(
              //    this.Handle,
              //    (uint)UnsafeNativeMethods.TASKDIALOG_MESSAGES.TDM_NAVIGATE_PAGE,
              //    IntPtr.Zero,
              //    config); 
          }
  
          /// <summary>
          /// Simulate the action of a button click in the TaskDialog. This can be a DialogResult value 
          /// or the ButtonID set on a TasDialogButton set on TaskDialog.Buttons.
          /// </summary>
          /// <param name="buttonId">Indicates the button ID to be selected.</param>
          /// <returns>If the function succeeds the return value is true.</returns>
          public bool ClickButton(int buttonId)
          {
              // TDM_CLICK_BUTTON                    = WM_USER+102, // wParam = Button ID
              return UnsafeNativeMethods.SendMessage(
                  this.handle,
                  (uint)UnsafeNativeMethods.TASKDIALOG_MESSAGES.TDM_CLICK_BUTTON,
                  (IntPtr)buttonId,
                  IntPtr.Zero) != IntPtr.Zero;
          }
  
          /// <summary>
          /// Used to indicate whether the hosted progress bar should be displayed in marquee mode or not.
          /// </summary>
          /// <param name="marquee">Specifies whether the progress bar sbould be shown in Marquee mode.
          /// A value of true turns on Marquee mode.</param>
          /// <returns>If the function succeeds the return value is true.</returns>
          public bool SetMarqueeProgressBar(bool marquee)
          {
              // TDM_SET_MARQUEE_PROGRESS_BAR        = WM_USER+103, // wParam = 0 (nonMarque) wParam != 0 (Marquee)
              return UnsafeNativeMethods.SendMessage(
                  this.handle,
                  (uint)UnsafeNativeMethods.TASKDIALOG_MESSAGES.TDM_SET_MARQUEE_PROGRESS_BAR,
                  (marquee ? (IntPtr)1 : IntPtr.Zero),
                  IntPtr.Zero) != IntPtr.Zero;
  
              // Future: get more detailed error from and throw.
          }
  
          /// <summary>
          /// Sets the state of the progress bar.
          /// </summary>
          /// <param name="newState">The state to set the progress bar.</param>
          /// <returns>If the function succeeds the return value is true.</returns>
          public bool SetProgressBarState(ProgressBarState newState)
          {
              // TDM_SET_PROGRESS_BAR_STATE          = WM_USER+104, // wParam = new progress state
              return UnsafeNativeMethods.SendMessage(
                  this.handle,
                  (uint)UnsafeNativeMethods.TASKDIALOG_MESSAGES.TDM_SET_PROGRESS_BAR_STATE,
                  (IntPtr)newState,
                  IntPtr.Zero) != IntPtr.Zero;
  
              // Future: get more detailed error from and throw.
          }
  
          /// <summary>
          /// Set the minimum and maximum values for the hosted progress bar.
          /// </summary>
          /// <param name="minRange">Minimum range value. By default, the minimum value is zero.</param>
          /// <param name="maxRange">Maximum range value.  By default, the maximum value is 100.</param>
          /// <returns>If the function succeeds the return value is true.</returns>
          public bool SetProgressBarRange(Int16 minRange, Int16 maxRange)
          {
              // TDM_SET_PROGRESS_BAR_RANGE          = WM_USER+105, // lParam = MAKELPARAM(nMinRange, nMaxRange)
              // #define MAKELPARAM(l, h)      ((LPARAM)(DWORD)MAKELONG(l, h))
              // #define MAKELONG(a, b)      ((LONG)(((WORD)(((DWORD_PTR)(a)) & 0xffff)) | ((DWORD)((WORD)(((DWORD_PTR)(b)) & 0xffff))) << 16))
              IntPtr lparam = (IntPtr)((minRange & 0xffff) | ((maxRange & 0xffff) << 16));
              return UnsafeNativeMethods.SendMessage(
                  this.handle,
                  (uint)UnsafeNativeMethods.TASKDIALOG_MESSAGES.TDM_SET_PROGRESS_BAR_RANGE,
                  IntPtr.Zero,
                  lparam) != IntPtr.Zero;
  
              // Return value is actually prior range.
          }
  
          /// <summary>
          /// Set the current position for a progress bar.
          /// </summary>
          /// <param name="newPosition">The new position.</param>
          /// <returns>Returns the previous value if successful, or zero otherwise.</returns>
          public int SetProgressBarPosition(int newPosition)
          {
              // TDM_SET_PROGRESS_BAR_POS            = WM_USER+106, // wParam = new position
              return (int)UnsafeNativeMethods.SendMessage(
                  this.handle,
                  (uint)UnsafeNativeMethods.TASKDIALOG_MESSAGES.TDM_SET_PROGRESS_BAR_POS,
                  (IntPtr)newPosition,
                  IntPtr.Zero);
          }
  
          /// <summary>
          /// Sets the animation state of the Marquee Progress Bar.
          /// </summary>
          /// <param name="startMarquee">true starts the marquee animation and false stops it.</param>
          /// <param name="speed">The time in milliseconds between refreshes.</param>
          public void SetProgressBarMarquee(bool startMarquee, uint speed)
          {
              // TDM_SET_PROGRESS_BAR_MARQUEE        = WM_USER+107, // wParam = 0 (stop marquee), wParam != 0 (start marquee), lparam = speed (milliseconds between repaints)
              UnsafeNativeMethods.SendMessage(
                  this.handle,
                  (uint)UnsafeNativeMethods.TASKDIALOG_MESSAGES.TDM_SET_PROGRESS_BAR_MARQUEE,
                  (startMarquee ? new IntPtr(1) : IntPtr.Zero),
                  (IntPtr)speed);
          }
  
          /// <summary>
          /// Updates the content text.
          /// </summary>
          /// <param name="content">The new value.</param>
          /// <returns>If the function succeeds the return value is true.</returns>
          public bool SetContent(string content)
          {
              // TDE_CONTENT,
              // TDM_SET_ELEMENT_TEXT                = WM_USER+108  // wParam = element (TASKDIALOG_ELEMENTS), lParam = new element text (LPCWSTR)
              return UnsafeNativeMethods.SendMessageWithString(
                  this.handle,
                  (uint)UnsafeNativeMethods.TASKDIALOG_MESSAGES.TDM_SET_ELEMENT_TEXT,
                  (IntPtr)UnsafeNativeMethods.TASKDIALOG_ELEMENTS.TDE_CONTENT,
                  content) != IntPtr.Zero;
          }
  
          /// <summary>
          /// Updates the Expanded Information text.
          /// </summary>
          /// <param name="expandedInformation">The new value.</param>
          /// <returns>If the function succeeds the return value is true.</returns>
          public bool SetExpandedInformation(string expandedInformation)
          {
              // TDE_EXPANDED_INFORMATION,
              // TDM_SET_ELEMENT_TEXT                = WM_USER+108  // wParam = element (TASKDIALOG_ELEMENTS), lParam = new element text (LPCWSTR)
              return UnsafeNativeMethods.SendMessageWithString(
                  this.handle,
                  (uint)UnsafeNativeMethods.TASKDIALOG_MESSAGES.TDM_SET_ELEMENT_TEXT,
                  (IntPtr)UnsafeNativeMethods.TASKDIALOG_ELEMENTS.TDE_EXPANDED_INFORMATION,
                  expandedInformation) != IntPtr.Zero;
          }
  
          /// <summary>
          /// Updates the Footer text.
          /// </summary>
          /// <param name="footer">The new value.</param>
          /// <returns>If the function succeeds the return value is true.</returns>
          public bool SetFooter(string footer)
          {
              // TDE_FOOTER,
              // TDM_SET_ELEMENT_TEXT                = WM_USER+108  // wParam = element (TASKDIALOG_ELEMENTS), lParam = new element text (LPCWSTR)
              return UnsafeNativeMethods.SendMessageWithString(
                  this.handle,
                  (uint)UnsafeNativeMethods.TASKDIALOG_MESSAGES.TDM_SET_ELEMENT_TEXT,
                  (IntPtr)UnsafeNativeMethods.TASKDIALOG_ELEMENTS.TDE_FOOTER,
                  footer) != IntPtr.Zero;
          }
  
          /// <summary>
          /// Updates the Main Instruction.
          /// </summary>
          /// <param name="mainInstruction">The new value.</param>
          /// <returns>If the function succeeds the return value is true.</returns>
          public bool SetMainInstruction(string mainInstruction)
          {
              // TDE_MAIN_INSTRUCTION
              // TDM_SET_ELEMENT_TEXT                = WM_USER+108  // wParam = element (TASKDIALOG_ELEMENTS), lParam = new element text (LPCWSTR)
              return UnsafeNativeMethods.SendMessageWithString(
                  this.handle,
                  (uint)UnsafeNativeMethods.TASKDIALOG_MESSAGES.TDM_SET_ELEMENT_TEXT,
                  (IntPtr)UnsafeNativeMethods.TASKDIALOG_ELEMENTS.TDE_MAIN_INSTRUCTION,
                  mainInstruction) != IntPtr.Zero;
          }
  
          /// <summary>
          /// Simulate the action of a radio button click in the TaskDialog. 
          /// The passed buttonID is the ButtonID set on a TaskDialogButton set on TaskDialog.RadioButtons.
          /// </summary>
          /// <param name="buttonId">Indicates the button ID to be selected.</param>
          public void ClickRadioButton(int buttonId)
          {
              // TDM_CLICK_RADIO_BUTTON = WM_USER+110, // wParam = Radio Button ID
              UnsafeNativeMethods.SendMessage(
                  this.handle,
                  (uint)UnsafeNativeMethods.TASKDIALOG_MESSAGES.TDM_CLICK_RADIO_BUTTON,
                  (IntPtr)buttonId,
                  IntPtr.Zero);
          }
  
          /// <summary>
          /// Enable or disable a button in the TaskDialog. 
          /// The passed buttonID is the ButtonID set on a TaskDialogButton set on TaskDialog.Buttons
          /// or a common button ID.
          /// </summary>
          /// <param name="buttonId">Indicates the button ID to be enabled or diabled.</param>
          /// <param name="enable">Enambe the button if true. Disable the button if false.</param>
          public void EnableButton(int buttonId, bool enable)
          {
              // TDM_ENABLE_BUTTON = WM_USER+111, // lParam = 0 (disable), lParam != 0 (enable), wParam = Button ID
              UnsafeNativeMethods.SendMessage(
                  this.handle,
                  (uint)UnsafeNativeMethods.TASKDIALOG_MESSAGES.TDM_ENABLE_BUTTON,
                  (IntPtr)buttonId,
                  (IntPtr)(enable ? 1 : 0));
          }
  
          /// <summary>
          /// Enable or disable a radio button in the TaskDialog. 
          /// The passed buttonID is the ButtonID set on a TaskDialogButton set on TaskDialog.RadioButtons.
          /// </summary>
          /// <param name="buttonId">Indicates the button ID to be enabled or diabled.</param>
          /// <param name="enable">Enambe the button if true. Disable the button if false.</param>
          public void EnableRadioButton(int buttonId, bool enable)
          {
              // TDM_ENABLE_RADIO_BUTTON = WM_USER+112, // lParam = 0 (disable), lParam != 0 (enable), wParam = Radio Button ID
              UnsafeNativeMethods.SendMessage(
                  this.handle,
                  (uint)UnsafeNativeMethods.TASKDIALOG_MESSAGES.TDM_ENABLE_RADIO_BUTTON,
                  (IntPtr)buttonId,
                  (IntPtr)(enable ? 1 : 0));
          }
  
          /// <summary>
          /// Check or uncheck the verification checkbox in the TaskDialog. 
          /// </summary>
          /// <param name="checkedState">The checked state to set the verification checkbox.</param>
          /// <param name="setKeyboardFocusToCheckBox">True to set the keyboard focus to the checkbox, and fasle otherwise.</param>
          public void ClickVerification(bool checkedState, bool setKeyboardFocusToCheckBox)
          {
              // TDM_CLICK_VERIFICATION = WM_USER+113, // wParam = 0 (unchecked), 1 (checked), lParam = 1 (set key focus)
              UnsafeNativeMethods.SendMessage(
                  this.handle,
                  (uint)UnsafeNativeMethods.TASKDIALOG_MESSAGES.TDM_CLICK_VERIFICATION,
                  (checkedState ? new IntPtr(1) : IntPtr.Zero),
  
gt:                 (setKeyboardFocusToCheckBox ? new IntPtr(1) : IntPtr.Zero));