Vanara/PInvoke/ComCtl32/CommCtrl.PropSheet.cs

946 lines
44 KiB
C#

using System;
using System.Runtime.InteropServices;
using Vanara.Extensions;
using static Vanara.PInvoke.Kernel32;
using static Vanara.PInvoke.Macros;
using static Vanara.PInvoke.User32;
namespace Vanara.PInvoke
{
public static partial class ComCtl32
{
/// <summary>
/// Specifies an application-defined callback function that a property sheet extension uses to add a page to a property sheet.
/// </summary>
/// <param name="hpage">
/// <para>Type: <c>HPROPSHEETPAGE</c></para>
/// <para>Handle to a property sheet page.</para>
/// </param>
/// <param name="lParam">
/// <para>Type: <c><c>LPARAM</c></c></para>
/// <para>Application-defined 32-bit value.</para>
/// </param>
/// <returns>
/// <para>Type: <c><c>BOOL</c></c></para>
/// <para>Returns <c>TRUE</c> if successful, or <c>FALSE</c> otherwise.</para>
/// </returns>
// BOOL CALLBACK AddPropSheetPageProc( HPROPSHEETPAGE hpage, LPARAM lParam); https://msdn.microsoft.com/en-us/library/windows/desktop/bb760805(v=vs.85).aspx
[PInvokeData("Prsht.h", MSDNShortId = "bb760805")]
[UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
public delegate bool AddPropSheetPageProc(IntPtr hpage, IntPtr lParam);
/// <summary>
/// Specifies an application-defined callback function that a property sheet calls when a page is created and when it is about to be
/// destroyed. An application can use this function to perform initialization and cleanup operations for the page.
/// </summary>
/// <param name="hwnd">Reserved; must be NULL.</param>
/// <param name="uMsg">Action flag.</param>
/// <param name="ppsp">
/// Pointer to a PROPSHEETPAGE structure that defines the page being created or destroyed. See the Remarks section for further discussion.
/// </param>
/// <returns>The return value depends on the value of the uMsg parameter.</returns>
[PInvokeData("Commctrl.h", MSDNShortId = "bb760813")]
[UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
public delegate uint PropSheetPageProc(HWND hwnd, PropSheetPageCallbackAction uMsg, PROPSHEETPAGE ppsp);
/// <summary>An application-defined callback function that the system calls when the property sheet is being created and initialized.</summary>
/// <param name="hwndDlg">Handle to the property sheet dialog box.</param>
/// <param name="uMsg">
/// Message being received. This parameter is one of the following values.
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PSCB_BUTTONPRESSED</term>
/// <term>
/// Version 6.0 and later.Indicates the user pressed a button in the property sheet dialog box.To enable this, specify
/// PSH_USECALLBACK in PROPSHEETHEADER.dwFlags and specify the name of this callback function in PROPSHEETHEADER.pfnCallback. The
/// lParam value is one of the following. Note that only PSBTN_CANCEL is valid when you are using the Aero wizard style(PSH_AEROWIZARD).
/// <list type="table">
/// <listheader>
/// <term>Button pressed</term>
/// <term>lParam value</term>
/// </listheader>
/// <item>
/// <term>OK</term>
/// <term>PSBTN_OK</term>
/// </item>
/// <item>
/// <term>Cancel</term>
/// <term>PSBTN_CANCEL</term>
/// </item>
/// <item>
/// <term>Apply</term>
/// <term>PSBTN_APPLYNOW</term>
/// </item>
/// <item>
/// <term>Close</term>
/// <term>PSBTN_FINISH</term>
/// </item>
/// </list>
/// <para>
/// Note that Comctl32.dll versions 6 and later are not redistributable.To use these versions of Comctl32.dll, specify the
/// particular version in a manifest. For more information on manifests, see Enabling Visual Styles.
/// </para>
/// </term>
/// </item>
/// <item>
/// <term>PSCB_INITIALIZED</term>
/// <term>Indicates that the property sheet is being initialized. The lParam value is zero for this message.</term>
/// </item>
/// <item>
/// <term>PSCB_PRECREATE</term>
/// <term>
/// Indicates that the property sheet is about to be created. The hwndDlg parameter is NULL, and the lParam parameter is the address
/// of a dialog template in memory.This template is in the form of a DLGTEMPLATE or DLGTEMPLATEEX structure followed by one or more
/// DLGITEMTEMPLATE structures.This message is not applicable if you are using the Aero wizard style(PSH_AEROWIZARD).
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="lParam">
/// Additional information about the message. The meaning of this value depends on the uMsg parameter.
/// <para>If uMsg is PSCB_INITIALIZED or PSCB_BUTTONPRESSED, the value of lParam is zero.</para>
/// <para>
/// If uMsg is PSCB_PRECREATE, then lParam will be a pointer to either a DLGTEMPLATE or DLGTEMPLATEEX structure describing the
/// property sheet dialog box. Test the signature of the structure to determine the type. If signature is equal to 0xFFFF then the
/// structure is an extended dialog template, otherwise the structure is a standard dialog template.
/// </para>
/// </param>
/// <returns>Returns zero.</returns>
[PInvokeData("Commctrl.h", MSDNShortId = "bb760815")]
[UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)]
public delegate int PropSheetProc(HWND hwndDlg, PropSheetCallbackMessage uMsg, IntPtr lParam);
/// <summary>Message being received.This parameter is one of the following values.</summary>
[PInvokeData("Commctrl.h", MSDNShortId = "bb760815")]
public enum PropSheetCallbackMessage
{
/// <summary>
/// Version 6.0 and later.Indicates the user pressed a button in the property sheet dialog box.To enable this, specify
/// PSH_USECALLBACK in PROPSHEETHEADER.dwFlags and specify the name of this callback function in PROPSHEETHEADER.pfnCallback.
/// The lParam value is one of the following. Note that only PSBTN_CANCEL is valid when you are using the Aero wizard style(PSH_AEROWIZARD).
/// <list type="table">
/// <listheader>
/// <term>Button pressed</term>
/// <term>lParam value</term>
/// </listheader>
/// <item>
/// <term>OK</term>
/// <term>PSBTN_OK</term>
/// </item>
/// <item>
/// <term>Cancel</term>
/// <term>PSBTN_CANCEL</term>
/// </item>
/// <item>
/// <term>Apply</term>
/// <term>PSBTN_APPLYNOW</term>
/// </item>
/// <item>
/// <term>Close</term>
/// <term>PSBTN_FINISH</term>
/// </item>
/// </list>
/// </summary>
PSCB_BUTTONPRESSED = 3,
/// <summary>Indicates that the property sheet is being initialized. The lParam value is zero for this message.</summary>
PSCB_INITIALIZED = 1,
/// <summary>
/// Indicates that the property sheet is about to be created. The hwndDlg parameter is NULL, and the lParam parameter is the
/// address of a dialog template in memory. This template is in the form of a DLGTEMPLATE or DLGTEMPLATEEX structure followed by
/// one or more DLGITEMTEMPLATE structures. This message is not applicable if you are using the Aero wizard style (PSH_AEROWIZARD).
/// </summary>
PSCB_PRECREATE = 2
}
/// <summary>Flags used by the <see cref="PROPSHEETPAGE.dwFlags"/> field.</summary>
[PInvokeData("Commctrl.h", MSDNShortId = "bb774548")]
[Flags]
public enum PropSheetFlags : uint
{
/// <summary>
/// Uses the default meaning for all structure members. This flag is not supported when using the Aero-style wizard (PSH_AEROWIZARD).
/// </summary>
PSP_DEFAULT = 0x0,
/// <summary>
/// Creates the page from the dialog box template in memory pointed to by the pResource member. The PropertySheet function
/// assumes that the template that is in memory is not write-protected. A read-only template will cause an exception in some
/// versions of Windows.
/// </summary>
PSP_DLGINDIRECT = 0x1,
/// <summary>
/// Enables the property sheet Help button when the page is active. This flag is not supported when using the Aero-style wizard (PSH_AEROWIZARD).
/// </summary>
PSP_HASHELP = 0x20,
/// <summary>
/// Version 5.80 and later. Causes the wizard property sheet to hide the header area when the page is selected. If a watermark
/// has been provided, it will be painted on the left side of the page. This flag should be set for welcome and completion
/// pages, and omitted for interior pages. This flag is not supported when using the Aero-style wizard (PSH_AEROWIZARD).
/// </summary>
PSP_HIDEHEADER = 0x800,
/// <summary>
/// Version 4.71 or later. Causes the page to be created when the property sheet is created. If this flag is not specified, the
/// page will not be created until it is selected the first time. This flag is not supported when using the Aero-style wizard (PSH_AEROWIZARD).
/// </summary>
PSP_PREMATURE = 0x400,
/// <summary>
/// Reverses the direction in which pszTitle is displayed. Normal windows display all text, including pszTitle, left-to-right
/// (LTR). For languages such as Hebrew or Arabic that read right-to-left (RTL), a window can be mirrored and all text will be
/// displayed RTL. If PSP_RTLREADING is set, pszTitle will instead read RTL in a normal parent window, and LTR in a mirrored
/// parent window.
/// </summary>
PSP_RTLREADING = 0x10,
/// <summary>
/// Calls the function specified by the pfnCallback member when creating or destroying the property sheet page defined by this structure.
/// </summary>
PSP_USECALLBACK = 0x80,
/// <summary>
/// Version 6.0 and later. Use an activation context. To use an activation context, you must set this flag and assign the
/// activation context handle to hActCtx. See the Remarks.
/// </summary>
PSP_USEFUSIONCONTEXT = 0x4000,
/// <summary>
/// Version 5.80 or later. Displays the string pointed to by the pszHeaderSubTitle member as the subtitle of the header area of
/// a Wizard97 page. To use this flag, you must also set the PSH_WIZARD97 flag in the dwFlags member of the associated
/// PROPSHEETHEADER structure. The PSP_USEHEADERSUBTITLE flag is ignored if PSP_HIDEHEADER is set. In Aero-style wizards, the
/// title appears near the top of the client area.
/// </summary>
PSP_USEHEADERSUBTITLE = 0x2000,
/// <summary>
/// Version 5.80 or later. Displays the string pointed to by the pszHeaderTitle member as the title in the header of a Wizard97
/// interior page. You must also set the PSH_WIZARD97 flag in the dwFlags member of the associated PROPSHEETHEADER structure.
/// The PSP_USEHEADERTITLE flag is ignored if PSP_HIDEHEADER is set. This flag is not supported when using the Aero-style wizard (PSH_AEROWIZARD).
/// </summary>
PSP_USEHEADERTITLE = 0x1000,
/// <summary>
/// Uses hIcon as the small icon on the tab for the page. This flag is not supported when using the Aero-style wizard (PSH_AEROWIZARD).
/// </summary>
PSP_USEHICON = 0x2,
/// <summary>
/// Uses pszIcon as the name of the icon resource to load and use as the small icon on the tab for the page. This flag is not
/// supported when using the Aero-style wizard (PSH_AEROWIZARD).
/// </summary>
PSP_USEICONID = 0x4,
/// <summary>
/// Maintains the reference count specified by the pcRefParent member for the lifetime of the property sheet page created from
/// this structure.
/// </summary>
PSP_USEREFPARENT = 0x40,
/// <summary>
/// Uses the pszTitle member as the title of the property sheet dialog box instead of the title stored in the dialog box
/// template. This flag is not supported when using the Aero-style wizard (PSH_AEROWIZARD).
/// </summary>
PSP_USETITLE = 0x8,
}
/// <summary>Flags used by the <see cref="PROPSHEETHEADER.dwFlags"/> field.</summary>
[PInvokeData("Commctrl.h", MSDNShortId = "bb774546")]
[Flags]
public enum PropSheetHeaderFlags : uint
{
/// <summary>
/// Uses the default meaning for all structure members, and creates a normal property sheet. This flag has a value of zero and
/// is not combined with other flags.
/// </summary>
PSH_DEFAULT = 0x00000000,
/// <summary>
/// Version 6.00 and Windows Vista.. Creates a wizard property sheet that uses the newer Aero style. The PSH_WIZARD flag must
/// also be set. The single-threaded apartment (STA) model must be used.
/// </summary>
PSH_AEROWIZARD = 0x00004000,
/// <summary>
/// Permits property sheet pages to display a Help button. You must also set the PSP_HASHELP flag in the page's PROPSHEETPAGE
/// structure when the page is created. If any of the initial property sheet pages enable a Help button, PSH_HASHELP will be set
/// automatically. If none of the initial pages enable a Help button, you must explicitly set PSH_HASHELP if you want to have
/// Help buttons on any pages that might be added later. This flag is not supported in conjunction with PSH_AEROWIZARD.
/// </summary>
PSH_HASHELP = 0x00000200,
/// <summary>
/// Version 5.80 and later. Indicates that a header bitmap will be used with a Wizard97 wizard. You must also set the
/// PSH_WIZARD97 flag. The header bitmap is obtained from the pszbmHeader member, unless the PSH_USEHBMHEADER flag is also set.
/// In that case, the header bitmap is obtained from the hbmHeader member. This flag is not supported in conjunction with PSH_AEROWIZARD.
/// </summary>
PSH_HEADER = 0x00080000,
/// <summary>
/// Version 6.00 and Windows Vista..The pszbmHeader member specifies a bitmap that is displayed in the header area. Must be used
/// in combination with PSH_AEROWIZARD.
/// </summary>
PSH_HEADERBITMAP = 0x08000000,
/// <summary>
/// Causes the PropertySheet function to create the property sheet as a modeless dialog box instead of as a modal dialog box.
/// When this flag is set, PropertySheet returns immediately after the dialog box is created, and the return value from
/// PropertySheet is the window handle to the property sheet dialog box. This flag is not supported in conjunction with PSH_AEROWIZARD.
/// </summary>
PSH_MODELESS = 0x00000400,
/// <summary>Removes the Apply button. This flag is not supported in conjunction with PSH_AEROWIZARD.</summary>
PSH_NOAPPLYNOW = 0x00000080,
/// <summary>
/// Version 5.80 and later. Removes the context-sensitive Help button ("?"), which is usually present on the caption bar of
/// property sheets. This flag is not valid for wizards. See About Property Sheets for a discussion of how to remove the caption
/// bar Help button for earlier versions of the common controls. This flag is not supported in conjunction with PSH_AEROWIZARD.
/// </summary>
PSH_NOCONTEXTHELP = 0x02000000,
/// <summary>
/// Version 6.00 and Windows Vista.. Specifies that no margin is inserted between the page and the frame. Must be used in
/// combination with PSH_AEROWIZARD.
/// </summary>
PSH_NOMARGIN = 0x10000000,
/// <summary>Uses the ppsp member and ignores the phpage member when creating the pages for the property sheet.</summary>
PSH_PROPSHEETPAGE = 0x00000008,
/// <summary>
/// Displays a title in the title bar of the property sheet. The title takes the appropriate form for the Windows version. In
/// more recent versions of Windows, the title is the string specified by the pszCaption followed by the string "Properties". In
/// older versions of Windows, the title is the string "Properties for", followed by the string specified by the pszCaption
/// member. This flag is not supported for wizards.
/// </summary>
PSH_PROPTITLE = 0x00000001,
/// <summary>
/// Allows the wizard to be resized by the user. Maximize and minimize buttons appear in the wizard's frame and the frame is
/// sizable. To use this flag, you must also set PSH_AEROWIZARD.
/// </summary>
PSH_RESIZABLE = 0x04000000,
/// <summary>
/// Displays the title of the property sheet (pszCaption) using right-to-left (RTL) reading order for Hebrew or Arabic
/// languages. If this flag is not specified, the title is displayed in left-to-right (LTR) reading order.
/// </summary>
PSH_RTLREADING = 0x00000800,
/// <summary>
/// Stretches the watermark in Internet Explorer 4.0-compatible Wizard97-style wizards. This flag is not supported in
/// conjunction with PSH_AEROWIZARD. <note>This style flag is only included to provide backward compatibility for certain
/// applications. Its use is not recommended, and it is only supported by common controls versions 4.0 and 4.01. With common
/// controls version 5.80 and later, this flag is ignored.</note>
/// </summary>
PSH_STRETCHWATERMARK = 0x00040000,
/// <summary>
/// Calls the function specified by the pfnCallback member when initializing the property sheet defined by this structure.
/// </summary>
PSH_USECALLBACK = 0x00000100,
/// <summary>
/// Version 5.80 or later. Obtains the header bitmap from the hbmHeader member instead of the pszbmHeader member. You must also
/// set either the PSH_AEROWIZARD flag or the PSH_WIZARD97 flag together with the PSH_HEADER flag.
/// </summary>
PSH_USEHBMHEADER = 0x00100000,
/// <summary>
/// Version 5.80 or later. Obtains the watermark bitmap from the hbmWatermark member instead of the pszbmWatermark member. You
/// must also set PSH_WIZARD97 and PSH_WATERMARK. This flag is not supported in conjunction with PSH_AEROWIZARD.
/// </summary>
PSH_USEHBMWATERMARK = 0x00010000,
/// <summary>Uses hIcon as the small icon in the title bar of the property sheet dialog box.</summary>
PSH_USEHICON = 0x00000002,
/// <summary>
/// Version 5.80 or later. Uses the HPALETTE structure pointed to by the hplWatermark member instead of the default palette to
/// draw the watermark bitmap and/or header bitmap for a Wizard97 wizard. You must also set PSH_WIZARD97, and PSH_WATERMARK or
/// PSH_HEADER. This flag is not supported in conjunction with PSH_AEROWIZARD.
/// </summary>
PSH_USEHPLWATERMARK = 0x00020000,
/// <summary>
/// Uses pszIcon as the name of the icon resource to load and use as the small icon in the title bar of the property sheet
/// dialog box.
/// </summary>
PSH_USEICONID = 0x00000004,
/// <summary>
/// Version 5.80 or later. Specifies that the language for the property sheet will be taken from the first page's resource. That
/// page must be specified by resource identifier.
/// </summary>
PSH_USEPAGELANG = 0x00200000,
/// <summary>
/// Uses the pStartPage member instead of the nStartPage member when displaying the initial page of the property sheet.
/// </summary>
PSH_USEPSTARTPAGE = 0x00000040,
/// <summary>
/// Version 5.80 or later. Specifies that a watermark bitmap will be used with a Wizard97 wizard on pages that have the
/// PSP_HIDEHEADER style. You must also set the PSH_WIZARD97 flag. The watermark bitmap is obtained from the pszbmWatermark
/// member, unless PSH_USEHBMWATERMARK is set. In that case, the header bitmap is obtained from the hbmWatermark member. This
/// flag is not supported in conjunction with PSH_AEROWIZARD.
/// </summary>
PSH_WATERMARK = 0x00008000,
/// <summary>Creates a wizard property sheet. When using PSH_AEROWIZARD, you must also set this flag.</summary>
PSH_WIZARD = 0x00000020,
/// <summary>
/// Version 5.80 or later. Creates a Wizard97-style property sheet, which supports bitmaps in the header of interior pages and
/// on the left side of exterior pages. This flag is not supported in conjunction with PSH_AEROWIZARD.
/// </summary>
PSH_WIZARD97 = 0x00002000,
/// <summary>
/// Adds a context-sensitive Help button ("?"), which is usually absent from the caption bar of a wizard. This flag is not valid
/// for regular property sheets. This flag is not supported in conjunction with PSH_AEROWIZARD.
/// </summary>
PSH_WIZARDCONTEXTHELP = 0x00001000,
/// <summary>Always displays the Finish button on the wizard. You must also set either PSH_WIZARD, PSH_WIZARD97, or PSH_AEROWIZARD.</summary>
PSH_WIZARDHASFINISH = 0x00000010,
/// <summary>
/// Version 5.80 or later. Uses the Wizard-lite style. This style is similar in appearance to PSH_WIZARD97, but it is
/// implemented much like PSH_WIZARD. There are few restrictions on how the pages are formatted. For instance, there are no
/// enforced borders, and the PSH_WIZARD_LITE style does not paint the watermark and header bitmaps for you the way Wizard97
/// does. This flag is not supported in conjunction with PSH_AEROWIZARD.
/// </summary>
PSH_WIZARD_LITE = 0x00400000,
}
/// <summary>Action flag.</summary>
[PInvokeData("Commctrl.h", MSDNShortId = "bb760813")]
public enum PropSheetPageCallbackAction
{
/// <summary>Version 5.80 or later. A page is being created. The return value is not used.</summary>
PSPCB_ADDREF = 0x0,
/// <summary>A page is being destroyed. The return value is ignored.</summary>
PSPCB_RELEASE = 0x1,
/// <summary>A dialog box for a page is being created. Return nonzero to allow it to be created, or zero to prevent it.</summary>
PSPCB_CREATE = 0x2,
}
/// <summary>Creates a new page for a property sheet.</summary>
/// <param name="lppsp">
/// <para>Type: <c>LPCPROPSHEETPAGE</c></para>
/// <para>Pointer to a <c>PROPSHEETPAGE</c> structure that defines a page to be included in a property sheet.</para>
/// </param>
/// <returns>
/// <para>Type: <c>HPROPSHEETPAGE</c></para>
/// <para>Returns the handle to the new property page if successful, or <c>NULL</c> otherwise.</para>
/// </returns>
// HPROPSHEETPAGE CreatePropertySheetPage( LPCPROPSHEETPAGE lppsp); https://msdn.microsoft.com/en-us/library/windows/desktop/bb760807(v=vs.85).aspx
[DllImport(Lib.ComCtl32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("Prsht.h", MSDNShortId = "bb760807")]
public static extern SafeHPROPSHEETPAGE CreatePropertySheetPage(PROPSHEETPAGE lppsp);
/// <summary>
/// Destroys a property sheet page. An application must call this function for pages that have not been passed to the
/// <c>PropertySheet</c> function.
/// </summary>
/// <param name="hPSPage">
/// <para>Type: <c>HPROPSHEETPAGE</c></para>
/// <para>Handle to the property sheet page to delete.</para>
/// </param>
/// <returns>
/// <para>Type: <c><c>BOOL</c></c></para>
/// <para>Returns nonzero if successful, or zero otherwise.</para>
/// </returns>
// BOOL DestroyPropertySheetPage( HPROPSHEETPAGE hPSPage); https://msdn.microsoft.com/en-us/library/windows/desktop/bb760809(v=vs.85).aspx
[DllImport(Lib.ComCtl32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("Prsht.h", MSDNShortId = "bb760809")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DestroyPropertySheetPage(HPROPSHEETPAGE hPSPage);
/// <summary>Creates a property sheet and adds the pages defined in the specified property sheet header structure.</summary>
/// <param name="lppsph">
/// <para>Type: <c>LPCPROPSHEETHEADER</c></para>
/// <para>Pointer to a <c>PROPSHEETHEADER</c> structure that defines the frame and pages of a property sheet.</para>
/// </param>
/// <returns>
/// <para>Type: <c><c>INT_PTR</c></c></para>
/// <para>For modal property sheets, the return value is as follows:</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>&amp;gt;=1</term>
/// <term>Changes were saved by the user.</term>
/// </listheader>
/// <item>
/// <term>0</term>
/// <term>No changes were saved by the user.</term>
/// </item>
/// <item>
/// <term>-1</term>
/// <term>An error occurred.</term>
/// </item>
/// </list>
/// </para>
/// <para>For modeless property sheets, the return value is the property sheet's window handle.</para>
/// <para>The following return values have a special meaning.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ID_PSREBOOTSYSTEM</term>
/// <term>
/// A page sent the PSM_REBOOTSYSTEM message to the property sheet. The computer must be restarted for the user's changes to take effect.
/// </term>
/// </item>
/// <item>
/// <term>ID_PSRESTARTWINDOWS</term>
/// <term>
/// A page sent the PSM_RESTARTWINDOWS message to the property sheet. Windows must be restarted for the user's changes to take effect.
/// </term>
/// </item>
/// </list>
/// </para>
/// </returns>
// INT_PTR PropertySheet( LPCPROPSHEETHEADER lppsph); https://msdn.microsoft.com/en-us/library/windows/desktop/bb760811(v=vs.85).aspx
[DllImport(Lib.ComCtl32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("Prsht.h", MSDNShortId = "bb760811")]
[return: MarshalAs(UnmanagedType.SysInt)]
public static extern IntPtr PropertySheet(ref PROPSHEETHEADER lppsph);
/// <summary>Defines the frame and pages of a property sheet.</summary>
[PInvokeData("Commctrl.h", MSDNShortId = "bb774546")]
[StructLayout(LayoutKind.Sequential)]
public struct PROPSHEETHEADER
{
/// <summary>
/// Size, in bytes, of this structure. The property sheet manager uses this member to determine which version of the
/// PROPSHEETHEADER structure you are using. For more information, see the Remarks.
/// </summary>
public uint dwSize;
/// <summary>Flags that indicate which options to use when creating the property sheet page.</summary>
public PropSheetHeaderFlags dwFlags;
/// <summary>Handle to the property sheet's owner window.</summary>
public HWND hwndParent;
/// <summary>
/// Handle to the instance from which to load the icon or title string resource. If the pszIcon or pszCaption member identifies
/// a resource to load, this member must be specified.
/// </summary>
public HINSTANCE hInstance;
/// <summary>
/// Handle to the icon to use as the small icon in the title bar of the property sheet dialog box. If the dwFlags member does
/// not include PSH_USEHICON, this member is ignored. This member is declared as a union with pszIcon.
/// <para><c>OR</c></para>
/// <para>
/// String icon resource to use as the small icon in the title bar of the property sheet dialog box. This member can specify
/// either the identifier of the icon resource or the address of the string that specifies the name of the icon resource. If the
/// dwFlags member does not include PSH_USEICONID, this member is ignored. This member is declared as a union with hIcon.
/// </para>
/// </summary>
public ResourceIdOrHandle<HICON> pIcon;
/// <summary>
/// Title of the property sheet dialog box. This member can specify either the identifier of a string resource or the address of
/// a string that specifies the title. If the dwFlags member includes PSH_PROPTITLE, the string "Properties for" is inserted at
/// the beginning of the title. This field is ignored for Wizard97 wizards. For Aero wizards, the string alone is used for the
/// caption, regardless of whether the PSH_PROPTITLE flag is set.
/// </summary>
public ResourceId pszCaption;
/// <summary>Number of elements in the phpage array.</summary>
public uint nPages;
/// <summary>
/// Zero-based index of the initial page that appears when the property sheet dialog box is created. This member is declared as
/// a union with pStartPage.
/// <para><c>OR</c></para>
/// <para>
/// Name of the initial page that appears when the property sheet dialog box is created. This member can specify either the
/// identifier of a string resource or the address of a string that specifies the name. This member is declared as a union with nStartPage.
/// </para>
/// </summary>
public ResourceId pStartPage;
/// <summary>
/// Pointer to an array of PROPSHEETPAGE structures that define the pages in the property sheet. If the dwFlags member does not
/// include PSH_PROPSHEETPAGE, this member is ignored. Note that the PROPSHEETPAGE structure is variable in size. Applications
/// that parse the array pointed to by ppsp must take the size of each page into account. This member is declared as a union
/// with phpage.
/// <para><c>OR</c></para>
/// <para>
/// Pointer to an array of handles to the property sheet pages. Each handle must have been created by a previous call to the
/// CreatePropertySheetPage function. If the dwFlags member includes PSH_PROPSHEETPAGE, phpage is ignored and should be set to
/// NULL. When the PropertySheet function returns, any HPROPSHEETPAGE handles in the phpage array will have been destroyed. This
/// member is declared as a union with ppsp.
/// </para>
/// </summary>
public IntPtr phpage;
/// <summary>
/// Pointer to an application-defined callback function that is called when the property sheet is initialized. For more
/// information about the callback function, see the description of the PropSheetProc function. If the dwFlags member does not
/// include PSH_USECALLBACK, this member is ignored.
/// </summary>
public PropSheetProc pfnCallback;
/// <summary>
/// Version 5.80 or later. Handle to the watermark bitmap. If the dwFlags member does not include PSH_USEHBMWATERMARK, this
/// member is ignored.
/// <para><c>OR</c></para>
/// <para>
/// Version 5.80 or later. Bitmap resource to use as the watermark. This member can specify either the identifier of the bitmap
/// resource or the address of the string that specifies the name of the bitmap resource. If the dwFlags member includes
/// PSH_USEHBMWATERMARK, this member is ignored.
/// </para>
/// </summary>
public ResourceIdOrHandle<HBITMAP> hbmWatermark;
/// <summary>
/// Version 5.80 or later. HPALETTE structure used for drawing the watermark bitmap and/or header bitmap. If the dwFlags member
/// does not include PSH_USEHPLWATERMARK, this member is ignored.
/// </summary>
public HPALETTE hplWatermark;
/// <summary>
/// Version 5.80 or later. Handle to the header bitmap. If the dwFlags member does not include PSH_USEHBMHEADER, this member is ignored.
/// <para><c>OR</c></para>
/// <para>
/// Version 5.80 or later. Bitmap resource to use as the header. This member can specify either the identifier of the bitmap
/// resource or the address of the string that specifies the name of the bitmap resource. If the dwFlags member includes
/// PSH_USEHBMHEADER, this member is ignored.
/// </para>
/// </summary>
public ResourceIdOrHandle<HBITMAP> hbmHeader;
}
/// <summary>Defines a page in a property sheet.</summary>
[PInvokeData("Commctrl.h", MSDNShortId = "bb774548")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class PROPSHEETPAGE : IDisposable
{
/// <summary>Size, in bytes, of this structure.</summary>
public uint dwSize;
/// <summary>Flags that indicate which options to use when creating the property sheet page.</summary>
public PropSheetFlags dwFlags;
/// <summary>
/// Handle to the instance from which to load an icon or string resource. If the pszIcon, pszTitle, pszHeaderTitle, or
/// pszHeaderSubTitle member identifies a resource to load, hInstance must be specified.
/// </summary>
public HINSTANCE hInstance;
/// <summary>
/// Dialog box template to use to create the page. This member can specify either the resource identifier of the template or the
/// address of a string that specifies the name of the template. If the PSP_DLGINDIRECT flag in the dwFlags member is set,
/// pszTemplate is ignored. This member is declared as a union with pResource.
/// </summary>
private IntPtr _pszTemplate;
/// <summary>
/// Handle to the icon to use as the icon in the tab of the page. If the dwFlags member does not include PSP_USEHICON, this
/// member is ignored. This member is declared as a union with pszIcon.
/// <para><c>OR</c></para>
/// <para>
/// Icon resource to use as the icon in the tab of the page. This member can specify either the identifier of the icon resource
/// or the address of the string that specifies the name of the icon resource. To use this member, you must set the
/// PSP_USEICONID flag in the dwFlags member. This member is declared as a union with hIcon.
/// </para>
/// </summary>
private IntPtr _hIcon;
/// <summary>
/// Title of the property sheet dialog box. This title overrides the title specified in the dialog box template. This member can
/// specify either the identifier of a string resource or the address of a string that specifies the title. To use this member,
/// you must set the PSP_USETITLE flag in the dwFlags member.
/// </summary>
private IntPtr _pszTitle;
/// <summary>
/// Pointer to the dialog box procedure for the page. Because the pages are created as modeless dialog boxes, the dialog box
/// procedure must not call the EndDialog function.
/// </summary>
public DialogProc pfnDlgProc;
/// <summary>
/// When the page is created, a copy of the page's PROPSHEETPAGE structure is passed to the dialog box procedure with a
/// WM_INITDIALOG message. The lParam member is provided to allow you to pass application-specific information to the dialog box
/// procedure. It has no effect on the page itself. For more information, see Property Sheet Creation.
/// </summary>
public IntPtr lParam;
/// <summary>
/// Pointer to an application-defined callback function that is called when the page is created and when it is about to be
/// destroyed. For more information about the callback function, see PropSheetPageProc. To use this member, you must set the
/// PSP_USECALLBACK flag in the dwFlags member.
/// </summary>
private PropSheetPageProc _pfnCallback;
/// <summary>
/// Pointer to the reference count value. To use this member, you must set the PSP_USEREFPARENT flag in the dwFlags member.
/// </summary>
private IntPtr _pcRefParent;
/// <summary>
/// Version 5.80 or later. Title of the header area. To use this member under the Wizard97-style wizard, you must also do the following:
/// <list type="bullet">
/// <item>
/// <term>Set the PSP_USEHEADERTITLE flag in the dwFlags member.</term>
/// </item>
/// <item>
/// <term>Set the PSH_WIZARD97 flag in the dwFlags member of the page's PROPSHEETHEADER structure.</term>
/// </item>
/// <item>
/// <term>Make sure that the PSP_HIDEHEADER flag in the dwFlags member is not set.</term>
/// </item>
/// </list>
/// </summary>
private IntPtr _pszHeaderTitle;
/// <summary>
/// Version 5.80 or later. Subtitle of the header area. To use this member, you must do the following:
/// <list type="bullet">
/// <item>
/// <term>Set the PSP_USEHEADERSUBTITLE flag in the dwFlags member.</term>
/// </item>
/// <item>
/// <term>Set the PSH_WIZARD97 flag in the dwFlags member of the page's PROPSHEETHEADER structure.</term>
/// </item>
/// <item>
/// <term>Make sure that the PSP_HIDEHEADER flag in the dwFlags member is not set.</term>
/// </item>
/// </list>
/// <note>This member is ignored when using the Aero-style wizard (PSH_AEROWIZARD).</note>
/// </summary>
private IntPtr _pszHeaderSubTitle;
/// <summary>
/// Version 6.0 or later. An activation context handle. Set this member to the handle that is returned when you create the
/// activation context with CreateActCtx. The system will activate this context before creating the dialog box. You do not need
/// to use this member if you use a global manifest.
/// </summary>
public HACTCTX hActCtx;
/// <summary>Initializes a new instance of the <see cref="PROPSHEETPAGE"/> class and sets the value of <see cref="dwSize"/>.</summary>
public PROPSHEETPAGE() => dwSize = (uint)Marshal.SizeOf(this);
/// <summary>
/// Dialog box template to use to create the page. This member can specify either the resource identifier of the template or the
/// address of a string that specifies the name of the template. If the PSP_DLGINDIRECT flag in the dwFlags member is set,
/// pszTemplate is ignored.
/// </summary>
public SafeResourceId pszTemplate
{
get => dwFlags.IsFlagSet(PropSheetFlags.PSP_DLGINDIRECT) ? SafeResourceId.Null : new SafeResourceId(_pszTemplate);
set
{
if (!dwFlags.IsFlagSet(PropSheetFlags.PSP_DLGINDIRECT)) FreeResource(ref _pszTemplate);
dwFlags = dwFlags.SetFlags(PropSheetFlags.PSP_DLGINDIRECT, false);
_pszTemplate = GetClonedHandle(value);
}
}
/// <summary>
/// A pointer to a dialog box template in memory. The PropertySheet function assumes that the template is in writeable memory; a
/// read-only template will cause an exception on some versions of Windows. If dwFlags does not include the PSP_DLGINDIRECT
/// value, this member is ignored.
/// </summary>
public IntPtr pResource
{
get => _pszTemplate;
set
{
if (!dwFlags.IsFlagSet(PropSheetFlags.PSP_DLGINDIRECT)) FreeResource(ref _pszTemplate);
_pszTemplate = value;
dwFlags = dwFlags.SetFlags(PropSheetFlags.PSP_DLGINDIRECT, true);
}
}
/// <summary>
/// A handle to the icon to use as the small icon in the tab for the page. If dwFlags does not include the PSP_USEHICON value,
/// this member is ignored.
/// </summary>
public HICON hIcon
{
get => dwFlags.IsFlagSet(PropSheetFlags.PSP_USEHICON) ? _hIcon : IntPtr.Zero;
set
{
if (dwFlags.IsFlagSet(PropSheetFlags.PSP_USEICONID)) FreeResource(ref _pszTemplate);
_hIcon = (IntPtr)value;
dwFlags = dwFlags.SetFlags(PropSheetFlags.PSP_USEICONID, false) | PropSheetFlags.PSP_USEHICON;
}
}
/// <summary>
/// Icon resource to use as the small icon in the tab for the page. This member can specify either the identifier of the icon
/// resource or the pointer to the string that specifies the name of the icon resource. If dwFlags does not include the
/// PSP_USEICONID value, this member is ignored.
/// </summary>
public SafeResourceId pszIcon
{
get => dwFlags.IsFlagSet(PropSheetFlags.PSP_USEICONID) ? new SafeResourceId(_hIcon) : SafeResourceId.Null;
set
{
if (dwFlags.IsFlagSet(PropSheetFlags.PSP_USEICONID)) FreeResource(ref _hIcon);
dwFlags = dwFlags.SetFlags(PropSheetFlags.PSP_USEHICON, false) | PropSheetFlags.PSP_USEICONID;
_hIcon = GetClonedHandle(value);
}
}
/// <summary>
/// Title of the property sheet dialog box. This title overrides the title specified in the dialog box template. This member can
/// specify either the identifier of a string resource or the pointer to a string that specifies the title. If dwFlags does not
/// include the PSP_USETITLE value, this member is ignored.
/// </summary>
public SafeResourceId pszTitle
{
get => dwFlags.IsFlagSet(PropSheetFlags.PSP_USETITLE) ? new SafeResourceId(_pszTitle) : SafeResourceId.Null;
set
{
if (dwFlags.IsFlagSet(PropSheetFlags.PSP_USETITLE)) FreeResource(ref _pszTitle);
dwFlags = dwFlags.SetFlags(PropSheetFlags.PSP_USETITLE, !value.IsInvalid);
_pszTitle = GetClonedHandle(value);
}
}
/// <summary>
/// Version 5.80 or later. Title of the header area. To use this member under the Wizard97-style wizard, you must also do the following:
/// <list type="bullet">
/// <item>
/// <term>Set the PSP_USEHEADERTITLE flag in the dwFlags member.</term>
/// </item>
/// <item>
/// <term>Set the PSH_WIZARD97 flag in the dwFlags member of the page's PROPSHEETHEADER structure.</term>
/// </item>
/// <item>
/// <term>Make sure that the PSP_HIDEHEADER flag in the dwFlags member is not set.</term>
/// </item>
/// </list>
/// </summary>
public SafeResourceId pszHeaderTitle
{
get => dwFlags.IsFlagSet(PropSheetFlags.PSP_USEHEADERTITLE) ? new SafeResourceId(_pszHeaderTitle) : SafeResourceId.Null;
set
{
if (dwFlags.IsFlagSet(PropSheetFlags.PSP_USEHEADERTITLE)) FreeResource(ref _pszHeaderTitle);
dwFlags = dwFlags.SetFlags(PropSheetFlags.PSP_USEHEADERTITLE, !value.IsInvalid);
_pszHeaderTitle = GetClonedHandle(value);
}
}
/// <summary>
/// Version 5.80 or later. Subtitle of the header area. To use this member, you must do the following:
/// <list type="bullet">
/// <item>
/// <term>Set the PSP_USEHEADERSUBTITLE flag in the dwFlags member.</term>
/// </item>
/// <item>
/// <term>Set the PSH_WIZARD97 flag in the dwFlags member of the page's PROPSHEETHEADER structure.</term>
/// </item>
/// <item>
/// <term>Make sure that the PSP_HIDEHEADER flag in the dwFlags member is not set.</term>
/// </item>
/// </list>
/// <note>This member is ignored when using the Aero-style wizard (PSH_AEROWIZARD).</note>
/// </summary>
public SafeResourceId pszHeaderSubTitle
{
get => dwFlags.IsFlagSet(PropSheetFlags.PSP_USEHEADERSUBTITLE) ? new SafeResourceId(_pszHeaderSubTitle) : SafeResourceId.Null;
set
{
if (dwFlags.IsFlagSet(PropSheetFlags.PSP_USEHEADERSUBTITLE)) FreeResource(ref _pszHeaderSubTitle);
dwFlags = dwFlags.SetFlags(PropSheetFlags.PSP_USEHEADERSUBTITLE, !value.IsInvalid);
_pszHeaderSubTitle = GetClonedHandle(value);
}
}
/// <summary>
/// Pointer to an application-defined callback function that is called when the page is created and when it is about to be
/// destroyed. For more information about the callback function, see PropSheetPageProc. To use this member, you must set the
/// PSP_USECALLBACK flag in the dwFlags member.
/// </summary>
public PropSheetPageProc pfnCallback
{
get => _pfnCallback;
set
{
dwFlags = dwFlags.SetFlags(PropSheetFlags.PSP_USECALLBACK, value != null);
_pfnCallback = value;
}
}
/// <summary>
/// Pointer to the reference count value. To use this member, you must set the PSP_USEREFPARENT flag in the dwFlags member.
/// </summary>
public IntPtr pcRefParent
{
get => _pcRefParent;
set
{
dwFlags = dwFlags.SetFlags(PropSheetFlags.PSP_USEREFPARENT, value != IntPtr.Zero);
_pcRefParent = value;
}
}
/// <inheritdoc/>
void IDisposable.Dispose()
{
if (!dwFlags.IsFlagSet(PropSheetFlags.PSP_DLGINDIRECT)) FreeResource(ref _pszTemplate);
if (dwFlags.IsFlagSet(PropSheetFlags.PSP_USEICONID)) FreeResource(ref _hIcon);
FreeResource(ref _pszTitle);
FreeResource(ref _pszHeaderTitle);
FreeResource(ref _pszHeaderSubTitle);
}
private static IntPtr GetClonedHandle(SafeResourceId rid) => rid == null ? IntPtr.Zero : (rid.IsIntResource ? rid.DangerousGetHandle() : StringHelper.AllocString(rid.ToString()));
private static void FreeResource(ref IntPtr ptr)
{
if (IS_INTRESOURCE(ptr) || ptr == IntPtr.Zero) return;
StringHelper.FreeString(ptr);
ptr = IntPtr.Zero;
}
}
/// <summary>Provides a <see cref="SafeHandle"/> to a that releases a created HPROPSHEETPAGE instance at disposal using DestroyPropertySheetPage.</summary>
public class SafeHPROPSHEETPAGE : SafeHANDLE, IUserHandle
{
/// <summary>Initializes a new instance of the <see cref="HPROPSHEETPAGE"/> class and assigns an existing handle.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
public SafeHPROPSHEETPAGE(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
private SafeHPROPSHEETPAGE() : base()
{
}
/// <summary>Performs an implicit conversion from <see cref="SafeHPROPSHEETPAGE"/> to <see cref="HPROPSHEETPAGE"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HPROPSHEETPAGE(SafeHPROPSHEETPAGE h) => h.handle;
/// <inheritdoc/>
protected override bool InternalReleaseHandle() => DestroyPropertySheetPage(this);
}
}
}