using System; using System.Drawing; using System.Runtime.InteropServices; using Vanara.Extensions; using Vanara.InteropServices; using static Vanara.PInvoke.User32; namespace Vanara.PInvoke { public static partial class ComCtl32 { /// Window Class Name for Header control. public const string WC_HEADER = "SysHeader"; private const int HDM_FIRST = 0x1200; private const int HDN_FIRST = -300; /// The variable that receives information about the results of a hit test. [Flags] public enum HeaderHitTestFlag : uint { /// The point is above the header control's bounding rectangle. HHT_ABOVE = 0x0100, /// The point is below the header control's bounding rectangle. HHT_BELOW = 0x0200, /// The point is inside the header control's bounding rectangle but is not over a header item. HHT_NOWHERE = 0x0001, /// The point is on the divider between two header items. HHT_ONDIVIDER = 0x0004, /// /// The point is on the divider of an item that has a width of zero. Dragging the divider reveals the item instead of resizing /// the item to the left of the divider. /// HHT_ONDIVOPEN = 0x0008, /// The point is within the split button of the item. The style HDF_SPLITBUTTON must be set on the item. HHT_ONDROPDOWN = 0x2000, /// The point is over the filter area. HHT_ONFILTER = 0x0010, /// The point is on the filter button. HHT_ONFILTERBUTTON = 0x0020, /// The point is to the left of the header control's bounding rectangle. HHT_ONHEADER = 0x0002, /// /// The point is within the state icon of the item. If style HDS_CHECKBOXES is specified, the point is within the checkbox of the item. /// HHT_ONITEMSTATEICON = 0x1000, /// /// The point is within the overflow button of the header control. The style HDS_OVERFLOW must be set on the header control. /// HHT_ONOVERFLOW = 0x4000, /// The point is to the left of the header control's bounding rectangle. HHT_TOLEFT = 0x0800, /// The point is to the right of the header control's bounding rectangle. HHT_TORIGHT = 0x0400, } /// The type of filter specified by . public enum HeaderItemFilterType { /// String data. HDFT_ISSTRING = 0, /// Numerical data. HDFT_ISNUMBER = 1, /// Date data. The pvFilter member is a pointer to a SYSTEMTIME structure. HDFT_ISDATE = 2, /// Ignore pvFilter. HDFT_HASNOVALUE = 0x8000 } /// Flags that specify an format. [Flags] public enum HeaderItemFormat : uint { /// The item's contents are left-aligned. HDF_LEFT = 0x0000, /// The item's contents are right-aligned. HDF_RIGHT = 0x0001, /// The item's contents are centered. HDF_CENTER = 0x0002, /// Isolate the bits corresponding to the three justification flags listed in the preceding table. HDF_JUSTIFYMASK = 0x0003, /// /// Typically, windows displays text left-to-right (LTR). Windows can be mirrored to display languages such as Hebrew or Arabic /// that read right-to-left (RTL). Usually, header text is read in the same direction as the text in its parent window. If /// HDF_RTLREADING is set, header text will read in the opposite direction from the text in the parent window. /// HDF_RTLREADING = 0x0004, /// /// The item displays a checkbox. The flag is only valid when the HDS_CHECKBOXES style is first set on the header control. /// HDF_CHECKBOX = 0x0040, /// The item displays a checked checkbox. The flag is only valid when HDF_CHECKBOX is also set. HDF_CHECKED = 0x0080, /// The width of the item cannot be modified by a user action to resize it. HDF_FIXEDWIDTH = 0x0100, /// The header control's owner draws the item. HDF_OWNERDRAW = 0x8000, /// The item displays a string. HDF_STRING = 0x4000, /// The item displays a bitmap. HDF_BITMAP = 0x2000, /// The bitmap appears to the right of text. HDF_BITMAP_ON_RIGHT = 0x1000, /// /// Display an image from an image list. Specify the image list by sending an HDM_SETIMAGELIST message. Specify the index of the /// image in the iImage member of this structure. /// HDF_IMAGE = 0x0800, /// /// Draws an up-arrow on this item. This is typically used to indicate that information in the current window is sorted on this /// column in ascending order. This flag cannot be combined with HDF_IMAGE or HDF_BITMAP. /// HDF_SORTUP = 0x0400, /// /// Draws a down-arrow on this item. This is typically used to indicate that information in the current window is sorted on this /// column in descending order. This flag cannot be combined with HDF_IMAGE or HDF_BITMAP. /// HDF_SORTDOWN = 0x0200, /// The item displays a split button. The HDN_DROPDOWN notification is sent when the split button is clicked. HDF_SPLITBUTTON = 0x1000000 } [Flags] public enum HeaderItemImageDisplay { None, Bitmap = 0x2000, ImageListItem = 0x0800, DownArrow = 0x0200, UpArrow = 0x0400, } /// Flags indicating which structure members contain valid data or must be filled in. [Flags] public enum HeaderItemMask : uint { /// The member is valid. HDI_BITMAP = 0x0010, /// /// While handling the message HDM_GETITEM, the header control may not have all the values needed to complete the request. In /// this case, the control must call the application back for the values via the HDN_GETDISPINFO notification. If HDI_DI_SETITEM /// has been passed in the HDM_GETITEM message, the control will cache any values returned from HDN_GETDISPINFO (otherwise the /// values remain unset.) /// HDI_DI_SETITEM = 0x0040, /// /// The and members are valid. This is used to filter out the values /// specified in the type member. /// HDI_FILTER = 0x0100, /// The member is valid. HDI_FORMAT = 0x0004, /// The same as HDI_WIDTH. HDI_HEIGHT = HDI_WIDTH, /// The member is valid and specifies the image to be displayed with the item. HDI_IMAGE = 0x0020, /// The member is valid. HDI_LPARAM = 0x0008, /// The member is valid and specifies the item's order value. HDI_ORDER = 0x0080, /// The member is valid. HDI_STATE = 0x0200, /// The and members are valid. HDI_TEXT = 0x0002, /// The member is valid and specifies the item's width. HDI_WIDTH = 0x0001, /// All members are valid. HDI_ALL = 0x03FF, } /// Valid entries for . public enum HeaderItemState { /// No state value. None = 0, /// The item has keyboard focus. HDIS_FOCUSED = 1 } public enum HeaderMessage { HDM_CLEARFILTER = HDM_FIRST + 24, // int, 0 HDM_CREATEDRAGIMAGE = HDM_FIRST + 16, // int, 0 HDM_DELETEITEM = HDM_FIRST + 2, // int, 0 HDM_EDITFILTER = HDM_FIRST + 23, // int, bool HDM_GETBITMAPMARGIN = HDM_FIRST + 21, // 0,0 HDM_GETFOCUSEDITEM = HDM_FIRST + 27, // 0,0 HDM_GETIMAGELIST = HDM_FIRST + 9, // 0, 0 HDM_GETITEM = HDM_FIRST + 11, // int, HDITEM HDM_GETITEMCOUNT = HDM_FIRST + 0, // 0, 0 HDM_GETITEMDROPDOWNRECT = HDM_FIRST + 25, // int, RECT HDM_GETITEMRECT = HDM_FIRST + 7, // int, RECT* HDM_GETORDERARRAY = HDM_FIRST + 17, // iCount, lpArray HDM_GETOVERFLOWRECT = HDM_FIRST + 26, // 0, RECT* HDM_GETUNICODEFORMAT = 0X2006, // CCM_GETUNICODEFORMAT, HDM_HITTEST = HDM_FIRST + 6, // 0, HDHITTEST HDM_INSERTITEM = HDM_FIRST + 10, // int, HDITEM HDM_LAYOUT = HDM_FIRST + 5, // 0, HDLAYOUT HDM_ORDERTOINDEX = HDM_FIRST + 15, // int, 0 HDM_SETBITMAPMARGIN = HDM_FIRST + 20,// iWidth, 0 HDM_SETFILTERCHANGETIMEOUT = HDM_FIRST + 22, // 0, int HDM_SETFOCUSEDITEM = HDM_FIRST + 28, // 0, int HDM_SETHOTDIVIDER = HDM_FIRST + 19, // bool, int HDM_SETIMAGELIST = HDM_FIRST + 8, // HDSIL_, hImageList HDM_SETITEM = HDM_FIRST + 12, // int, HDITEM HDM_SETORDERARRAY = HDM_FIRST + 18, // iCount, lpArray HDM_SETUNICODEFORMAT = 0X2005, // CCM_SETUNICODEFORMAT, } #pragma warning disable CS1572 // XML comment has a param tag, but there is no parameter by that name /// Header control notifications [PInvokeData("Commctrl.h", MSDNShortId = "ff485940")] public enum HeaderNotification { /// /// Sent by a header control when a drag operation has begun on one of its items. This notification code is sent only by header /// controls that are set to the HDS_DRAGDROP style. This notification code is sent in the form of a WM_NOTIFY message. /// /// /// A pointer to an NMHEADER structure containing information about the header item that is being dragged. /// /// /// To allow the header control to automatically manage drag-and-drop operations, return FALSE. If the owner of the /// control is manually performing drag-and-drop reordering, return TRUE. /// HDN_BEGINDRAG = HDN_FIRST - 10, /// /// Notifies a header control's parent window that a filter edit has begun. This notification code is sent in the form of a /// WM_NOTIFY message. /// /// /// A pointer to an NMHEADER structure that contains additional information about the filter that is being edited. /// /// No return value. HDN_BEGINFILTEREDIT = HDN_FIRST - 14, /// /// Notifies a header control's parent window that the user has begun dragging a divider in the control (that is, the user has /// pressed the left mouse button while the mouse cursor is on a divider in the header control). This notification code is sent /// in the form of a WM_NOTIFY message. /// /// /// A pointer to an NMHEADER structure that contains information about the header control and the item whose divider is to /// be dragged. /// /// Returns FALSE to allow tracking of the divider, or TRUE to prevent tracking. HDN_BEGINTRACK = HDN_FIRST - 26, /// /// Notifies a header control's parent window that the user double-clicked the divider area of the control. This notification /// code is sent in the form of a WM_NOTIFY message. /// /// /// A pointer to an NMHEADER structure that contains information about the header control and the item whose divider was double-clicked. /// /// No return value. HDN_DIVIDERDBLCLICK = HDN_FIRST - 25, /// /// Sent by a header control to its parent when the drop-down arrow on the header control is clicked. This notification code is /// sent in the form of a WM_NOTIFY message. /// /// A pointer to an NMHEADER structure that contains information on the header control. /// No return value. HDN_DROPDOWN = HDN_FIRST - 18, /// /// Sent by a header control when a drag operation has ended on one of its items. This notification code is sent as a /// WM_NOTIFY message. Only header controls that are set to the HDS_DRAGDROP style send this notification code. /// /// /// A pointer to an NMHEADER structure containing information about the header item that was being dragged. /// /// /// To allow the control to automatically place and reorder the item, return FALSE. To prevent the item from being placed, /// return TRUE. /// HDN_ENDDRAG = HDN_FIRST - 11, /// /// Notifies a header control's parent window that a filter edit has ended. This notification code is sent in the form of a /// WM_NOTIFY message. /// /// /// A pointer to an NMHEADER structure that contains additional information about the filter that is being edited. /// /// No return value. HDN_ENDFILTEREDIT = HDN_FIRST - 15, /// /// Notifies a header control's parent window that the user has finished dragging a divider. This notification code sent in the /// form of a WM_NOTIFY message. /// /// /// A pointer to an NMHEADER structure that contains information about the header control and the item whose divider was dragged. /// /// No return value. HDN_ENDTRACK = HDN_FIRST - 27, /// /// Notifies the header control's parent window when the filter button is clicked or in response to an HDM_SETITEM /// message. This notification code sent in the form of a WM_NOTIFY message. /// /// /// A pointer to an NMHDFILTERBTNCLICK structure that contains information about the header control and the header filter button. /// /// /// If you return TRUE, an HDN_FILTERCHANGE notification code will be sent to the header control's parent window. This /// notification code gives the parent window an opportunity to synchronize its user interface elements. Return FALSE if /// you do not want the notification sent. /// HDN_FILTERBTNCLICK = HDN_FIRST - 13, /// /// Notifies the header control's parent window that the attributes of a header control filter are being changed or edited. This /// notification code sent in the form of a WM_NOTIFY message. /// /// /// A pointer to an NMHEADER structure that contains information about the header control and the header item, including /// the attributes that are about to change. /// /// No return value. HDN_FILTERCHANGE = HDN_FIRST - 12, /// /// Sent to the owner of a header control when the control needs information about a callback header item. This notification code /// is sent as a WM_NOTIFY message. /// /// /// A pointer to an NMHDDISPINFO structure. On input, the fields of the structure specify what information is required and /// the item of interest. /// /// Returns an LRESULT. HDN_GETDISPINFO = HDN_FIRST - 29, /// /// Notifies a header control's parent window that the attributes of a header item have changed. This notification code is sent /// in the form of a WM_NOTIFY message. /// /// /// A pointer to an NMHEADER structure that contains information about the header control, including the attributes that /// have changed. /// /// No return value. HDN_ITEMCHANGED = HDN_FIRST - 21, /// /// Notifies a header control's parent window that the attributes of a header item are about to change. This notification code is /// sent in the form of a WM_NOTIFY message. /// /// /// A pointer to an NMHEADER structure that contains information about the header control and the header item, including /// the attributes that are about to change. /// /// Returns FALSE to allow the changes, or TRUE to prevent them. HDN_ITEMCHANGING = HDN_FIRST - 20, /// /// Notifies a header control's parent window that the user clicked the control. This notification code is sent in the form of a /// WM_NOTIFY message. /// /// /// A pointer to an NMHEADER structure that identifies the header control and specifies the index of the header item that /// was clicked and the mouse button used to click the item. The pItem member is set to NULL. /// /// No return value. HDN_ITEMCLICK = HDN_FIRST - 22, /// /// Notifies a header control's parent window that the user double-clicked the control. This notification code is sent in the /// form of a WM_NOTIFY message. Only header controls that are set to the HDS_BUTTONS style send this notification code. /// /// A pointer to an NMHEADER structure that contains information about this notification code. /// No return value. HDN_ITEMDBLCLICK = HDN_FIRST - 23, /// /// Notifies a header control's parent window that a key has been pressed with an item selected. This notification code is sent /// in the form of a WM_NOTIFY message. /// /// /// A pointer to an NMHEADER structure that contains additional information about the key that is being pressed. /// /// No return value. HDN_ITEMKEYDOWN = HDN_FIRST - 17, /// /// Notifies a header control's parent window that the user clicked an item's state icon. This notification code is sent in the /// form of a WM_NOTIFY message. /// /// /// A pointer to an NMHEADER structure that contains additional information about the state icon that was clicked on. /// /// No return value. HDN_ITEMSTATEICONCLICK = HDN_FIRST - 16, /// /// Sent by a header control to its parent when the header's overflow button is clicked. This notification code is sent in the /// form of an WM_NOTIFY message. /// /// /// /// A pointer to a NMHEADER structure that describes the notification code. The calling process is responsible for /// allocating this structure, including the contained NMHDR structure. Set the members of the NMHDR structure, /// including the code member that must be set to HDN_OVERFLOWCLICK. /// /// /// Set the iItem member of the NMHEADER structure to the index of the first header item that is not visible and /// thus should be displayed on an overflow. /// /// /// No return value. HDN_OVERFLOWCLICK = HDN_FIRST - 19, /// /// Notifies a header control's parent window that the user is dragging a divider in the header control. This notification code /// is sent in the form of a WM_NOTIFY message. /// /// /// A pointer to an NMHEADER structure that contains information about the header control and the item whose divider is /// being dragged. /// /// Returns FALSE to continue tracking the divider, or TRUE to end tracking. HDN_TRACK = HDN_FIRST - 28, } #pragma warning restore CS1572 // XML comment has a param tag, but there is no parameter by that name /// /// Header controls have a number of styles, described in this section, that determine the control's appearance and behavior. You set /// the initial styles when you create the header control. /// [PInvokeData("Commctrl.h", MSDNShortId = "bb775241")] [Flags] public enum HeaderStyle { /// /// Each item in the control looks and behaves like a push button. This style is useful if an application carries out a task when /// the user clicks an item in the header control. For example, an application could sort information in the columns differently /// depending on which item the user clicks. /// HDS_BUTTONS = 0x0002, /// Allows drag-and-drop reordering of header items. HDS_DRAGDROP = 0x0040, /// /// Include a filter bar as part of the standard header control. This bar allows users to conveniently apply a filter to the /// display. Calls to HDM_LAYOUT will yield a new size for the control and cause the list view to update. /// HDS_FILTERBAR = 0x0100, /// /// Version 6.0 and later. Causes the header control to be drawn flat when the operating system is running in classic mode. /// Comctl32.dll version 6 is not redistributable but it is included in Windows. To use Comctl32.dll version 6, specify it /// in a manifest. For more information on manifests, see Enabling Visual Styles. /// HDS_FLAT = 0x0200, /// Causes the header control to display column contents even while the user resizes a column. HDS_FULLDRAG = 0x0080, /// /// Indicates a header control that is intended to be hidden. This style does not hide the control. Instead, when you send the /// HDM_LAYOUT message to a header control with the HDS_HIDDEN style, the control returns zero in the cy member of the WINDOWPOS /// structure. You would then hide the control by setting its height to zero. This can be useful when you want to use the control /// as an information container instead of a visual control. /// HDS_HIDDEN = 0x0008, /// Creates a header control with a horizontal orientation. HDS_HORZ = 0x0000, /// Enables hot tracking. HDS_HOTTRACK = 0x0004, /// /// Version 6.00 and later. Allows the placing of checkboxes on header items. For more information, see the fmt member of HDITEM. /// HDS_CHECKBOXES = 0x0400, /// Version 6.00 and later. The user cannot drag the divider on the header control. HDS_NOSIZING = 0x0800, /// /// Version 6.00 and later. A button is displayed when not all items can be displayed within the header control's rectangle. When /// clicked, this button sends an HDN_OVERFLOWCLICK notification. /// HDS_OVERFLOW = 0x1000, } /// Contains information about header control text filters. [PInvokeData("Commctrl.h", MSDNShortId = "bb775251")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct HDTEXTFILTER { /// A pointer to the buffer containing the filter. public string pszText; /// A value specifying the maximum size, in characters, for an edit control buffer. public int cchTextMax; /// Initializes a new instance of the struct. /// The filter. public HDTEXTFILTER(string filter) { pszText = filter; cchTextMax = filter.Length; } /// Initializes a new instance of the struct. /// The length. public HDTEXTFILTER(int length) : this(new string('\0', length)) { } /// Returns a that represents this instance. /// A that represents this instance. public override string ToString() => pszText; } /// /// Contains information about a hit test. This structure is used with the HDM_HITTEST message and it supersedes the HD_HITTESTINFO structure. /// [PInvokeData("Commctrl.h", MSDNShortId = "bb775245")] [StructLayout(LayoutKind.Sequential)] public sealed class HDHITTESTINFO { /// A POINT structure that contains the point to be hit test, in client coordinates. public Point pt; /// /// The variable that receives information about the results of a hit test. Two of these values can be combined, such as when the /// position is above and to the left of the client area. /// public HeaderHitTestFlag flags; /// If the hit test is successful, contains the index of the item at the hit test point. public int iItem; } /// Contains information about an item in a header control. This structure supersedes the HD_ITEM structure. /// [PInvokeData("Commctrl.h", MSDNShortId = "bb775247")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public sealed class HDITEM : IDisposable { /// Flags indicating which other structure members contain valid data or must be filled in. public HeaderItemMask mask = 0; /// The width or height of the item. public int cxy; /// /// A pointer to an item string. If the text is being retrieved from the control, this member must be initialized to point to a /// character buffer. If this member is set to LPSTR_TEXTCALLBACK, the control will request text information for this item by /// sending an HDN_GETDISPINFO notification code. Note that although the header control allows a string of any length to be /// stored as item text, only the first 260 TCHARs are displayed. /// public StrPtrAuto pszText; /// A handle to the item bitmap. public HBITMAP hbm = IntPtr.Zero; /// /// The length of the item string, in TCHARs. If the text is being retrieved from the control, this member must contain the /// number of TCHARs at the address specified by pszText. /// public uint cchTextMax; /// Flags that specify the item's format. public HeaderItemFormat fmt = 0; /// Application-defined item data. public IntPtr lParam = IntPtr.Zero; /// /// The zero-based index of an image within the image list. The specified image will be displayed in the header item in addition /// to any image specified in the hbm field. If iImage is set to I_IMAGECALLBACK, the control requests text information for this /// item by using an HDN_GETDISPINFO notification code. To clear the image, set this value to I_IMAGENONE. /// public int iImage; /// /// The order in which the item appears within the header control, from left to right. That is, the value for the far left item /// is 0. The value for the next item to the right is 1, and so on. /// public int iOrder; /// The type of filter specified by pvFilter. public HeaderItemFilterType type; /// /// The address of an application-defined data item. The data filter type is determined by setting the flag value of the member. /// Use the HDFT_ISSTRING flag to indicate a string and HDFT_ISNUMBER to indicate an integer. When the HDFT_ISSTRING flag is used /// pvFilter is a pointer to a HDTEXTFILTER structure. /// public IntPtr pvFilter = IntPtr.Zero; /// The state. public HeaderItemState state; /// Initializes a new instance of the class. /// The mask. [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.LinkDemand, Flags = System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)] public HDITEM(HeaderItemMask mask = HeaderItemMask.HDI_ALL) { if (mask.IsFlagSet(HeaderItemMask.HDI_TEXT)) pszText = new StrPtrAuto(cchTextMax = 1024); } /// Initializes a new instance of the class. /// The text. public HDITEM(string text = null) => Text = text; /// Gets or sets the bitmap. Aligned to the field. public Bitmap Bitmap { get => hbm.IsNull ? null : Image.FromHbitmap((IntPtr)hbm); set { hbm = value?.GetHbitmap() ?? IntPtr.Zero; EnumExtensions.SetFlags(ref mask, HeaderItemMask.HDI_BITMAP); } } /// Gets or sets a value indicating whether this is checked. /// true if checked; otherwise, false. public bool Checked { get => fmt.IsFlagSet(HeaderItemFormat.HDF_CHECKED); set { EnumExtensions.SetFlags(ref fmt, HeaderItemFormat.HDF_CHECKED, value); EnumExtensions.SetFlags(ref mask, HeaderItemMask.HDI_FORMAT); } } /// Gets or sets the filter. This value must be a string, integer, DateTime or SYSTEMTIME. /// The filter. public object Filter { get { if (!mask.IsFlagSet(HeaderItemMask.HDI_FILTER)) return null; switch (type) { case HeaderItemFilterType.HDFT_ISSTRING: return pvFilter.ToStructure().ToString(); case HeaderItemFilterType.HDFT_ISNUMBER: return pvFilter.ToInt32(); case HeaderItemFilterType.HDFT_ISDATE: return pvFilter.ToStructure().ToDateTime(DateTimeKind.Unspecified); case HeaderItemFilterType.HDFT_HASNOVALUE: return null; default: throw new InvalidOperationException(); } } set { switch (value) { case null: type = HeaderItemFilterType.HDFT_HASNOVALUE; Marshal.FreeCoTaskMem(pvFilter); pvFilter = IntPtr.Zero; break; case DateTime dt: pvFilter = new SYSTEMTIME(dt).MarshalToPtr(Marshal.AllocCoTaskMem, out var _); type = HeaderItemFilterType.HDFT_ISDATE; break; case string str: pvFilter = new HDTEXTFILTER(str).MarshalToPtr(Marshal.AllocCoTaskMem, out var _); type = HeaderItemFilterType.HDFT_ISSTRING; break; case int i: pvFilter = new IntPtr(i); type = HeaderItemFilterType.HDFT_ISNUMBER; break; case SYSTEMTIME st: pvFilter = st.MarshalToPtr(Marshal.AllocCoTaskMem, out var _); type = HeaderItemFilterType.HDFT_ISDATE; break; default: throw new ArgumentException("Value must be a string, integer, DateTime or SYSTEMTIME"); } EnumExtensions.SetFlags(ref mask, HeaderItemMask.HDI_FILTER); } } /// Gets or sets a value indicating whether the header is fixed width. /// true if fixed width; otherwise, false. public bool FixedWidth { get => fmt.IsFlagSet(HeaderItemFormat.HDF_FIXEDWIDTH); set { EnumExtensions.SetFlags(ref fmt, HeaderItemFormat.HDF_FIXEDWIDTH, value); EnumExtensions.SetFlags(ref mask, HeaderItemMask.HDI_FORMAT); } } /// Gets or sets a value indicating whether this header is focused. /// true if focused; otherwise, false. public bool Focused { get => state == HeaderItemState.HDIS_FOCUSED; set { state = value ? HeaderItemState.HDIS_FOCUSED : HeaderItemState.None; EnumExtensions.SetFlags(ref mask, HeaderItemMask.HDI_STATE); } } /// Gets or sets the header format. /// The format. public HeaderItemFormat Format { get => fmt; set { fmt = value; EnumExtensions.SetFlags(ref mask, HeaderItemMask.HDI_FORMAT); } } /// Gets or sets a value indicating whether the bitmap is on the right. /// true if bitmap is on the right; otherwise, false. public bool BitmapRightToLeft { get => fmt.IsFlagSet(HeaderItemFormat.HDF_BITMAP_ON_RIGHT); set { EnumExtensions.SetFlags(ref fmt, HeaderItemFormat.HDF_BITMAP_ON_RIGHT, value); EnumExtensions.SetFlags(ref mask, HeaderItemMask.HDI_FORMAT); } } /// Gets or sets the how the image is displayed. /// How the image is displayed. public HeaderItemImageDisplay ImageDisplay { get { if (fmt.IsFlagSet(HeaderItemFormat.HDF_BITMAP)) return HeaderItemImageDisplay.Bitmap; if (fmt.IsFlagSet(HeaderItemFormat.HDF_IMAGE)) return HeaderItemImageDisplay.ImageListItem; if (fmt.IsFlagSet(HeaderItemFormat.HDF_SORTDOWN)) return HeaderItemImageDisplay.DownArrow; if (fmt.IsFlagSet(HeaderItemFormat.HDF_SORTUP)) return HeaderItemImageDisplay.UpArrow; return HeaderItemImageDisplay.None; } set { const HeaderItemFormat imgMask = HeaderItemFormat.HDF_BITMAP | HeaderItemFormat.HDF_IMAGE | HeaderItemFormat.HDF_SORTUP | HeaderItemFormat.HDF_SORTDOWN; EnumExtensions.SetFlags(ref fmt, imgMask, false); EnumExtensions.SetFlags(ref fmt, (HeaderItemFormat)value); EnumExtensions.SetFlags(ref mask, HeaderItemMask.HDI_FORMAT); } } /// Gets or sets the index of the image in the image list. /// The index of the image. public int ImageIndex { get => iImage; set { iImage = value; EnumExtensions.SetFlags(ref mask, HeaderItemMask.HDI_IMAGE); } } /// Gets or sets an application defined value. /// The parameter. public IntPtr LParam { get => lParam; set { lParam = value; EnumExtensions.SetFlags(ref mask, HeaderItemMask.HDI_LPARAM); } } /// Gets or sets the order in which the item appears in the header. /// The order. public int Order { get => iOrder; set { iOrder = value; EnumExtensions.SetFlags(ref mask, HeaderItemMask.HDI_ORDER); } } /// Gets or sets a value indicating whether the header item is owner drawn. /// true if owner drawn; otherwise, false. public bool OwnerDrawn { get => fmt.IsFlagSet(HeaderItemFormat.HDF_OWNERDRAW); set { EnumExtensions.SetFlags(ref fmt, HeaderItemFormat.HDF_OWNERDRAW, value); EnumExtensions.SetFlags(ref mask, HeaderItemMask.HDI_FORMAT); } } /// Gets or sets a value indicating whether header text is displayed right to left. /// true if right to left; otherwise, false. public bool RightToLeft { get => fmt.IsFlagSet(HeaderItemFormat.HDF_RTLREADING); set { EnumExtensions.SetFlags(ref fmt, HeaderItemFormat.HDF_RTLREADING, value); EnumExtensions.SetFlags(ref mask, HeaderItemMask.HDI_FORMAT); } } /// Gets or sets a value indicating whether to show a checkbox. /// true if shows checkbox; otherwise, false. public bool ShowCheckbox { get => fmt.IsFlagSet(HeaderItemFormat.HDF_CHECKBOX); set { EnumExtensions.SetFlags(ref fmt, HeaderItemFormat.HDF_CHECKBOX, value); EnumExtensions.SetFlags(ref mask, HeaderItemMask.HDI_FORMAT); } } /// Gets or sets a value indicating whether to show a split button. /// true if showing a split button; otherwise, false. public bool ShowSplitButton { get => fmt.IsFlagSet(HeaderItemFormat.HDF_SPLITBUTTON); set { EnumExtensions.SetFlags(ref fmt, HeaderItemFormat.HDF_SPLITBUTTON, value); EnumExtensions.SetFlags(ref mask, HeaderItemMask.HDI_FORMAT); } } /// Gets or sets a value indicating whether to show text. /// true if showing text; otherwise, false. public bool ShowText { get => fmt.IsFlagSet(HeaderItemFormat.HDF_STRING); set { EnumExtensions.SetFlags(ref fmt, HeaderItemFormat.HDF_STRING, value); EnumExtensions.SetFlags(ref mask, HeaderItemMask.HDI_FORMAT); } } /// Gets or sets the text. /// The text. /// Text - A header control will only display the first 260 characters. public string Text { get => mask.IsFlagSet(HeaderItemMask.HDI_TEXT) ? pszText.ToString() : null; set { if (value != null && value.Length > Kernel32.MAX_PATH) throw new ArgumentOutOfRangeException(nameof(Text), @"A header control will only display the first 260 characters."); EnumExtensions.SetFlags(ref mask, HeaderItemMask.HDI_TEXT, pszText.Assign(value, out cchTextMax)); } } /// Gets or sets the text alignment. /// The text alignment. public HeaderItemFormat TextAlignment { get => fmt & HeaderItemFormat.HDF_JUSTIFYMASK; set { value = value & HeaderItemFormat.HDF_JUSTIFYMASK; EnumExtensions.SetFlags(ref fmt, HeaderItemFormat.HDF_JUSTIFYMASK, false); EnumExtensions.SetFlags(ref fmt, value); EnumExtensions.SetFlags(ref mask, HeaderItemMask.HDI_FORMAT); } } /// /// Gets or sets a value indicating whether this header requests a callback message to retrieve the text. Setting this /// value to either true or false will remove any previously set value for the property or field. /// /// true if using text callback; otherwise, false. public bool UseTextCallback { get => mask.IsFlagSet(HeaderItemMask.HDI_TEXT) && (IntPtr)pszText == LPSTR_TEXTCALLBACK; set { EnumExtensions.SetFlags(ref mask, HeaderItemMask.HDI_TEXT, value); pszText.AssignConstant(value ? -1 : 0); } } /// Gets or sets the width. /// The width. public int Width { get => cxy; set { cxy = value; EnumExtensions.SetFlags(ref mask, HeaderItemMask.HDI_WIDTH); } } /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. public void Dispose() { pszText.Free(); if (mask.IsFlagSet(HeaderItemMask.HDI_FILTER) && (type == 0 || type == HeaderItemFilterType.HDFT_ISSTRING)) Marshal.FreeCoTaskMem(pvFilter); } } /// /// Contains information used to set the size and position of a header control. HDLAYOUT is used with the HDM_LAYOUT message. This /// structure supersedes the HD_LAYOUT structure. /// /// [PInvokeData("Commctrl.h", MSDNShortId = "bb775249")] [StructLayout(LayoutKind.Sequential)] public sealed class HDLAYOUT : IDisposable { /// Structure that contains the coordinates of a rectangle that the header control will occupy. public IntPtr prc; /// Structure that receives information about the appropriate size and position of the header control. public IntPtr pwpos; /// /// Initializes a new instance of the class setting the prc member and allocating memory for the pwpos member. /// /// The coordinates of the header. public HDLAYOUT(RECT rc) { prc = rc.MarshalToPtr(Marshal.AllocHGlobal, out var _); pwpos = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(WINDOWPOS))); } /// Gets or sets the coordinates. /// The coordinates. public RECT Coordinates { get => prc.ToStructure(); set { Marshal.FreeHGlobal(prc); prc = value.MarshalToPtr(Marshal.AllocHGlobal, out var _); } } /// Gets the position. /// The position. public WINDOWPOS Position => pwpos.ToStructure(); /// Releases unmanaged and - optionally - managed resources. public void Dispose() { Marshal.FreeHGlobal(prc); Marshal.FreeHGlobal(pwpos); } } /// Contains information used in handling HDN_GETDISPINFO notification codes. [PInvokeData("Commctrl.h", MSDNShortId = "bb775253")] [StructLayout(LayoutKind.Sequential)] public sealed class NMHDDISPINFO { /// NMHDR structure containing information about this notification code public NMHDR hdr; /// The zero-based index of the item in the header control. public int iItem; /// A set of bit flags specifying which members of the structure must be filled in by the owner of the header control. public uint mask; /// A pointer to a null-terminated string containing the text that will be displayed for the header item. public StrPtrAuto pszText; /// The size of the buffer that pszText points to. public int cchTextMax; /// /// The zero-based index of an image within the image list. The specified image will be displayed with the header item, but it /// does not take the place of the item's bitmap. If iImage is set to I_IMAGECALLBACK, the control requests image information for /// this item by using an HDN_GETDISPINFO notification code. /// public int iImage; /// An application-defined value to associate with the item. public IntPtr lParam = IntPtr.Zero; } /// Specifies or receives the attributes of a filter button click. [PInvokeData("Commctrl.h", MSDNShortId = "bb775255")] [StructLayout(LayoutKind.Sequential)] public sealed class NMHDFILTERBTNCLICK { /// A handle of an NMHDR structure that contains additional information. public NMHDR hdr; /// The zero-based index of the control to which this structure refers. public int iItem; /// A pointer to a RECT structure that contains the client rectangle for the filter button. public RECT rc; } /// Contains information about header control notification messages. This structure supersedes the HD_NOTIFY structure. [PInvokeData("Commctrl.h", MSDNShortId = "bb775257")] [StructLayout(LayoutKind.Sequential)] public sealed class NMHEADER { /// A NMHDR structure that contains information about the notification message. public NMHDR nmhdr; /// The zero-based index of the header item that is the focus of the notification message. public int iItem; /// /// A value specifying the index of the mouse button used to generate the notification message. This member can be one of the /// following values: /// /// /// Value /// Meaning /// /// /// 0 /// Left button /// /// /// 1 /// Right button /// /// /// 2 /// Middle button /// /// /// public int iButton; /// /// An optional pointer to an HDITEM structure containing information about the item specified by iItem. The mask member of the /// HDITEM structure indicates which of its members are valid. /// public IntPtr pItem = IntPtr.Zero; } } }