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;
}
}
}