using System; using System.Runtime.InteropServices; namespace Vanara.PInvoke { public static partial class Gdi32 { /// End caps used by Pen functions and structures. [PInvokeData("wingdi.h", MSDNShortId = "34ffa71d-e94d-425e-9f9d-21e3df4990b7")] public enum PenEndCap : uint { /// End caps are round. PS_ENDCAP_ROUND = 0x00000000, /// End caps are square. PS_ENDCAP_SQUARE = 0x00000100, /// End caps are flat. PS_ENDCAP_FLAT = 0x00000200, } /// Joins used by Pen functions and structures. [PInvokeData("wingdi.h", MSDNShortId = "34ffa71d-e94d-425e-9f9d-21e3df4990b7")] public enum PenJoin : uint { /// Joins are round. PS_JOIN_ROUND = 0x00000000, /// Joins are beveled. PS_JOIN_BEVEL = 0x00001000, /// /// Joins are mitered when they are within the current limit set by the SetMiterLimit function. If it exceeds this limit, the /// join is beveled. /// PS_JOIN_MITER = 0x00002000, } /// Styles used by Pen functions and structures. [PInvokeData("wingdi.h", MSDNShortId = "34ffa71d-e94d-425e-9f9d-21e3df4990b7")] public enum PenStyle : uint { /// The pen is solid. PS_SOLID = 0, /// The pen is dashed. PS_DASH = 1, /// The pen is dotted. PS_DOT = 2, /// The pen has alternating dashes and dots. PS_DASHDOT = 3, /// The pen has alternating dashes and double dots. PS_DASHDOTDOT = 4, /// The pen is invisible. PS_NULL = 5, /// /// The pen is solid. When this pen is used in any GDI drawing function that takes a bounding rectangle, the dimensions of the /// figure are shrunk so that it fits entirely in the bounding rectangle, taking into account the width of the pen. This applies /// only to geometric pens. /// PS_INSIDEFRAME = 6, /// The pen uses a styling array supplied by the user. PS_USERSTYLE = 7, /// The pen sets every other pixel. (This style is applicable only for cosmetic pens.) PS_ALTERNATE = 8, } /// Joins used by Pen functions and structures. [PInvokeData("wingdi.h", MSDNShortId = "34ffa71d-e94d-425e-9f9d-21e3df4990b7")] public enum PenType : uint { /// The pen is cosmetic. PS_COSMETIC = 0x00000000, /// The pen is geometric. PS_GEOMETRIC = 0x00010000, } /// /// /// The CreatePen function creates a logical pen that has the specified style, width, and color. The pen can subsequently be /// selected into a device context and used to draw lines and curves. /// /// /// /// The pen style. It can be any one of the following values. /// /// /// Value /// Meaning /// /// /// PS_SOLID /// The pen is solid. /// /// /// PS_DASH /// The pen is dashed. This style is valid only when the pen width is one or less in device units. /// /// /// PS_DOT /// The pen is dotted. This style is valid only when the pen width is one or less in device units. /// /// /// PS_DASHDOT /// The pen has alternating dashes and dots. This style is valid only when the pen width is one or less in device units. /// /// /// PS_DASHDOTDOT /// The pen has alternating dashes and double dots. This style is valid only when the pen width is one or less in device units. /// /// /// PS_NULL /// The pen is invisible. /// /// /// PS_INSIDEFRAME /// /// The pen is solid. When this pen is used in any GDI drawing function that takes a bounding rectangle, the dimensions of the figure /// are shrunk so that it fits entirely in the bounding rectangle, taking into account the width of the pen. This applies only to /// geometric pens. /// /// /// /// /// /// The width of the pen, in logical units. If nWidth is zero, the pen is a single pixel wide, regardless of the current transformation. /// /// CreatePen returns a pen with the specified width bit with the PS_SOLID style if you specify a width greater than one for /// the following styles: PS_DASH, PS_DOT, PS_DASHDOT, PS_DASHDOTDOT. /// /// /// /// A color reference for the pen color. To generate a COLORREF structure, use the RGB macro. /// /// /// If the function succeeds, the return value is a handle that identifies a logical pen. /// If the function fails, the return value is NULL. /// /// /// /// After an application creates a logical pen, it can select that pen into a device context by calling the SelectObject function. /// After a pen is selected into a device context, it can be used to draw lines and curves. /// /// /// If the value specified by the nWidth parameter is zero, a line drawn with the created pen always is a single pixel wide /// regardless of the current transformation. /// /// If the value specified by nWidth is greater than 1, the fnPenStyle parameter must be PS_NULL, PS_SOLID, or PS_INSIDEFRAME. /// /// If the value specified by nWidth is greater than 1 and fnPenStyle is PS_INSIDEFRAME, the line associated with the pen is drawn /// inside the frame of all primitives except polygons and polylines. /// /// /// If the value specified by nWidth is greater than 1, fnPenStyle is PS_INSIDEFRAME, and the color specified by the crColor /// parameter does not match one of the entries in the logical palette, the system draws lines by using a dithered color. Dithered /// colors are not available with solid pens. /// /// When you no longer need the pen, call the DeleteObject function to delete it. /// /// ICM: No color management is done at creation. However, color management is performed when the pen is selected into an /// ICM-enabled device context. /// /// Examples /// For an example, see Creating Colored Pens and Brushes. /// // https://docs.microsoft.com/en-us/windows/desktop/api/wingdi/nf-wingdi-createpen HPEN CreatePen( int iStyle, int cWidth, COLORREF // color ); [DllImport(Lib.Gdi32, SetLastError = false, ExactSpelling = true)] [PInvokeData("wingdi.h", MSDNShortId = "882facd2-7e06-48f6-82e4-f20e4d5adc92")] public static extern SafeHPEN CreatePen(uint iStyle, int cWidth, COLORREF color); /// /// /// The CreatePenIndirect function creates a logical cosmetic pen that has the style, width, and color specified in a structure. /// /// /// /// Pointer to a LOGPEN structure that specifies the pen's style, width, and color. /// /// /// If the function succeeds, the return value is a handle that identifies a logical cosmetic pen. /// If the function fails, the return value is NULL. /// /// /// /// After an application creates a logical pen, it can select that pen into a device context by calling the SelectObject function. /// After a pen is selected into a device context, it can be used to draw lines and curves. /// /// When you no longer need the pen, call the DeleteObject function to delete it. /// // https://docs.microsoft.com/en-us/windows/desktop/api/wingdi/nf-wingdi-createpenindirect HPEN CreatePenIndirect( const LOGPEN // *plpen ); [DllImport(Lib.Gdi32, SetLastError = false, ExactSpelling = true)] [PInvokeData("wingdi.h", MSDNShortId = "638c0294-9a8f-44ed-a791-1be152cd92dd")] public static extern SafeHPEN CreatePenIndirect(in LOGPEN plpen); /// /// /// The ExtCreatePen function creates a logical cosmetic or geometric pen that has the specified style, width, and brush attributes. /// /// /// /// /// A combination of type, style, end cap, and join attributes. The values from each category are combined by using the bitwise OR /// operator ( | ). /// /// The pen type can be one of the following values. /// /// /// Value /// Meaning /// /// /// PS_GEOMETRIC /// The pen is geometric. /// /// /// PS_COSMETIC /// The pen is cosmetic. /// /// /// The pen style can be one of the following values. /// /// /// Value /// Meaning /// /// /// PS_ALTERNATE /// The pen sets every other pixel. (This style is applicable only for cosmetic pens.) /// /// /// PS_SOLID /// The pen is solid. /// /// /// PS_DASH /// The pen is dashed. /// /// /// PS_DOT /// The pen is dotted. /// /// /// PS_DASHDOT /// The pen has alternating dashes and dots. /// /// /// PS_DASHDOTDOT /// The pen has alternating dashes and double dots. /// /// /// PS_NULL /// The pen is invisible. /// /// /// PS_USERSTYLE /// The pen uses a styling array supplied by the user. /// /// /// PS_INSIDEFRAME /// /// The pen is solid. When this pen is used in any GDI drawing function that takes a bounding rectangle, the dimensions of the figure /// are shrunk so that it fits entirely in the bounding rectangle, taking into account the width of the pen. This applies only to /// geometric pens. /// /// /// /// The end cap is only specified for geometric pens. The end cap can be one of the following values. /// /// /// Value /// Meaning /// /// /// PS_ENDCAP_ROUND /// End caps are round. /// /// /// PS_ENDCAP_SQUARE /// End caps are square. /// /// /// PS_ENDCAP_FLAT /// End caps are flat. /// /// /// The join is only specified for geometric pens. The join can be one of the following values. /// /// /// Value /// Meaning /// /// /// PS_JOIN_BEVEL /// Joins are beveled. /// /// /// PS_JOIN_MITER /// /// Joins are mitered when they are within the current limit set by the SetMiterLimit function. If it exceeds this limit, the join is beveled. /// /// /// /// PS_JOIN_ROUND /// Joins are round. /// /// /// /// /// /// The width of the pen. If the dwPenStyle parameter is PS_GEOMETRIC, the width is given in logical units. If dwPenStyle is /// PS_COSMETIC, the width must be set to 1. /// /// /// /// /// A pointer to a LOGBRUSH structure. If dwPenStyle is PS_COSMETIC, the lbColor member specifies the color of the pen and the /// lpStyle member must be set to BS_SOLID. If dwPenStyle is PS_GEOMETRIC, all members must be used to specify the brush /// attributes of the pen. /// /// /// /// The length, in DWORD units, of the lpStyle array. This value must be zero if dwPenStyle is not PS_USERSTYLE. /// The style count is limited to 16. /// /// /// /// A pointer to an array. The first value specifies the length of the first dash in a user-defined style, the second value specifies /// the length of the first space, and so on. This pointer must be NULL if dwPenStyle is not PS_USERSTYLE. /// /// /// If the lpStyle array is exceeded during line drawing, the pointer is reset to the beginning of the array. When this happens and /// dwStyleCount is an even number, the pattern of dashes and spaces repeats. However, if dwStyleCount is odd, the pattern reverses /// when the pointer is reset -- the first element of lpStyle now refers to spaces, the second refers to dashes, and so forth. /// /// /// /// If the function succeeds, the return value is a handle that identifies a logical pen. /// If the function fails, the return value is zero. /// /// /// /// A geometric pen can have any width and can have any of the attributes of a brush, such as dithers and patterns. A cosmetic pen /// can only be a single pixel wide and must be a solid color, but cosmetic pens are generally faster than geometric pens. /// /// The width of a geometric pen is always specified in world units. The width of a cosmetic pen is always 1. /// End caps and joins are only specified for geometric pens. /// /// After an application creates a logical pen, it can select that pen into a device context by calling the SelectObject function. /// After a pen is selected into a device context, it can be used to draw lines and curves. /// /// /// If dwPenStyle is PS_COSMETIC and PS_USERSTYLE, the entries in the lpStyle array specify lengths of dashes and spaces in style /// units. A style unit is defined by the device where the pen is used to draw a line. /// /// /// If dwPenStyle is PS_GEOMETRIC and PS_USERSTYLE, the entries in the lpStyle array specify lengths of dashes and spaces in logical units. /// /// If dwPenStyle is PS_ALTERNATE, the style unit is ignored and every other pixel is set. /// /// If the lbStyle member of the LOGBRUSH structure pointed to by lplb is BS_PATTERN, the bitmap pointed to by the /// lbHatch member of that structure cannot be a DIB section. A DIB section is a bitmap created by CreateDIBSection. If that /// bitmap is a DIB section, the ExtCreatePen function fails. /// /// When an application no longer requires a specified pen, it should call the DeleteObject function to delete the pen. /// /// ICM: No color management is done at pen creation. However, color management is performed when the pen is selected into an /// ICM-enabled device context. /// /// Examples /// For an example, see Using Pens. /// // https://docs.microsoft.com/en-us/windows/desktop/api/wingdi/nf-wingdi-extcreatepen HPEN ExtCreatePen( DWORD iPenStyle, DWORD // cWidth, const LOGBRUSH *plbrush, DWORD cStyle, const DWORD *pstyle ); [DllImport(Lib.Gdi32, SetLastError = false, ExactSpelling = true)] [PInvokeData("wingdi.h", MSDNShortId = "a1e81314-4fe6-481f-af96-24ebf56332cf")] public static extern SafeHPEN ExtCreatePen(uint iPenStyle, uint cWidth, in LOGBRUSH plbrush, uint cStyle, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] uint[] pstyle); /// /// /// The EXTLOGPEN structure defines the pen style, width, and brush attributes for an extended pen. This structure is used by /// the GetObject function when it retrieves a description of a pen that was created when an application called the ExtCreatePen function. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/wingdi/ns-wingdi-tagextlogpen typedef struct tagEXTLOGPEN { DWORD // elpPenStyle; DWORD elpWidth; UINT elpBrushStyle; COLORREF elpColor; ULONG_PTR elpHatch; DWORD elpNumEntries; DWORD // elpStyleEntry[1]; } EXTLOGPEN, *PEXTLOGPEN, *NPEXTLOGPEN, *LPEXTLOGPEN; [PInvokeData("wingdi.h", MSDNShortId = "34ffa71d-e94d-425e-9f9d-21e3df4990b7")] [StructLayout(LayoutKind.Sequential, Pack = 4)] public struct EXTLOGPEN { /// /// /// A combination of pen type, style, end cap style, and join style. The values from each category can be retrieved by using a /// bitwise AND operator with the appropriate mask. /// /// The elpPenStyle member masked with PS_TYPE_MASK has one of the following pen type values. /// /// /// Value /// Meaning /// /// /// PS_GEOMETRIC /// The pen is geometric. /// /// /// PS_COSMETIC /// The pen is cosmetic. /// /// /// The elpPenStyle member masked with PS_STYLE_MASK has one of the following pen styles values: /// /// /// Value /// Meaning /// /// /// PS_DASH /// The pen is dashed. /// /// /// PS_DASHDOT /// The pen has alternating dashes and dots. /// /// /// PS_DASHDOTDOT /// The pen has alternating dashes and double dots. /// /// /// PS_DOT /// The pen is dotted. /// /// /// PS_INSIDEFRAME /// /// The pen is solid. When this pen is used in any GDI drawing function that takes a bounding rectangle, the dimensions of the /// figure are shrunk so that it fits entirely in the bounding rectangle, taking into account the width of the pen. This applies /// only to PS_GEOMETRIC pens. /// /// /// /// PS_NULL /// The pen is invisible. /// /// /// PS_SOLID /// The pen is solid. /// /// /// PS_USERSTYLE /// The pen uses a styling array supplied by the user. /// /// /// /// The following category applies only to PS_GEOMETRIC pens. The elpPenStyle member masked with PS_ENDCAP_MASK has one of /// the following end cap values. /// /// /// /// Value /// Meaning /// /// /// PS_ENDCAP_FLAT /// Line end caps are flat. /// /// /// PS_ENDCAP_ROUND /// Line end caps are round. /// /// /// PS_ENDCAP_SQUARE /// Line end caps are square. /// /// /// /// The following category applies only to PS_GEOMETRIC pens. The elpPenStyle member masked with PS_JOIN_MASK has one of /// the following join values. /// /// /// /// Value /// Meaning /// /// /// PS_JOIN_BEVEL /// Line joins are beveled. /// /// /// PS_JOIN_MITER /// /// Line joins are mitered when they are within the current limit set by the SetMiterLimit function. A join is beveled when it /// would exceed the limit. /// /// /// /// PS_JOIN_ROUND /// Line joins are round. /// /// /// public uint elpPenStyle; /// /// /// The width of the pen. If the elpPenStyle member is PS_GEOMETRIC, this value is the width of the line in logical units. /// Otherwise, the lines are cosmetic and this value is 1, which indicates a line with a width of one pixel. /// /// public uint elpWidth; /// /// The brush style of the pen. The elpBrushStyle member value can be one of the following. /// /// /// Value /// Meaning /// /// /// BS_DIBPATTERN /// /// Specifies a pattern brush defined by a DIB specification. If elpBrushStyle is BS_DIBPATTERN, the elpHatch member contains a /// handle to a packed DIB. For more information, see discussion in elpHatch /// /// /// /// BS_DIBPATTERNPT /// /// Specifies a pattern brush defined by a DIB specification. If elpBrushStyle is BS_DIBPATTERNPT, the elpHatch member contains a /// pointer to a packed DIB. For more information, see discussion in elpHatch. /// /// /// /// BS_HATCHED /// Specifies a hatched brush. /// /// /// BS_HOLLOW /// Specifies a hollow or NULL brush. /// /// /// BS_PATTERN /// Specifies a pattern brush defined by a memory bitmap. /// /// /// BS_SOLID /// Specifies a solid brush. /// /// /// public BrushStyle elpBrushStyle; /// /// /// If elpBrushStyle is BS_SOLID or BS_HATCHED, elpColor specifies the color in which the pen is to be drawn. For /// BS_HATCHED, the SetBkMode and SetBkColor functions determine the background color. /// /// If elpBrushStyle is BS_HOLLOW or BS_PATTERN, elpColor is ignored. /// /// If elpBrushStyle is BS_DIBPATTERN or BS_DIBPATTERNPT, the low-order word of elpColor specifies whether the /// bmiColors member of the BITMAPINFO structure contain explicit RGB values or indices into the currently realized /// logical palette. The elpColor value must be one of the following. /// /// /// /// Value /// Meaning /// /// /// DIB_PAL_COLORS /// The color table consists of an array of 16-bit indices into the currently realized logical palette. /// /// /// DIB_RGB_COLORS /// The color table contains literal RGB values. /// /// /// The RGB macro is used to generate a COLORREF structure. /// public COLORREF elpColor; /// /// If elpBrushStyle is BS_PATTERN, elpHatch is a handle to the bitmap that defines the pattern. /// If elpBrushStyle is BS_SOLID or BS_HOLLOW, elpHatch is ignored. /// /// If elpBrushStyle is BS_DIBPATTERN, the elpHatch member is a handle to a packed DIB. To obtain this handle, an /// application calls the GlobalAlloc function with GMEM_MOVEABLE (or LocalAlloc with LMEM_MOVEABLE) to allocate a block of /// memory and then fills the memory with the packed DIB. A packed DIB consists of a BITMAPINFO structure immediately followed by /// the array of bytes that define the pixels of the bitmap. /// /// /// If elpBrushStyle is BS_DIBPATTERNPT, the elpHatch member is a pointer to a packed DIB. The pointer derives from /// the memory block created by LocalAlloc with LMEM_FIXED set or by GlobalAlloc with GMEM_FIXED set, or it is the pointer /// returned by a call like LocalLock (handle_to_the_dib). A packed DIB consists of a BITMAPINFO structure immediately followed /// by the array of bytes that define the pixels of the bitmap. /// /// /// If elpBrushStyle is BS_HATCHED, the elpHatch member specifies the orientation of the lines used to create the /// hatch. It can be one of the following values. /// /// /// /// Value /// Meaning /// /// /// HS_BDIAGONAL /// 45-degree upward hatch (left to right) /// /// /// HS_CROSS /// Horizontal and vertical crosshatch /// /// /// HS_DIAGCROSS /// 45-degree crosshatch /// /// /// HS_FDIAGONAL /// 45-degree downward hatch (left to right) /// /// /// HS_HORIZONTAL /// Horizontal hatch /// /// /// HS_VERTICAL /// Vertical hatch /// /// /// public IntPtr elpHatch; /// /// /// The number of entries in the style array in the elpStyleEntry member. This value is zero if elpPenStyle does /// not specify PS_USERSTYLE. /// /// public uint elpNumEntries; /// /// /// A user-supplied style array. The array is specified with a finite length, but it is used as if it repeated indefinitely. The /// first entry in the array specifies the length of the first dash. The second entry specifies the length of the first gap. /// Thereafter, lengths of dashes and gaps alternate. /// /// /// If elpWidth specifies geometric lines, the lengths are in logical units. Otherwise, the lines are cosmetic and lengths /// are in device units. /// /// public IntPtr elpStyleEntry; /// Gets or sets the style of the pen. public PenStyle Style { get => (PenStyle)(elpPenStyle & 0xF); set => elpPenStyle = elpPenStyle & 0xFFFF0 | (uint)value; } /// Gets or sets the end cap style of the pen. public PenEndCap EndCap { get => (PenEndCap)(elpPenStyle & 0xF00); set => elpPenStyle = elpPenStyle & 0xFF0FF | (uint)value; } /// Gets or sets the join style for the pen. public PenJoin Join { get => (PenJoin)(elpPenStyle & 0xF000); set => elpPenStyle = elpPenStyle & 0xF0FFF | (uint)value; } /// Gets or sets the pen type. public PenType Type { get => (PenType)(elpPenStyle & 0xF0000); set => elpPenStyle = elpPenStyle & 0xFFFF | (uint)value; } } /// /// /// The LOGPEN structure defines the style, width, and color of a pen. The CreatePenIndirect function uses the LOGPEN structure. /// /// /// /// /// If the width of the pen is greater than 1 and the pen style is PS_INSIDEFRAME, the line is drawn inside the frame of all GDI /// objects except polygons and polylines. If the pen color does not match an available RGB value, the pen is drawn with a logical /// (dithered) color. If the pen width is less than or equal to 1, the PS_INSIDEFRAME style is identical to the PS_SOLID style. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/wingdi/ns-wingdi-taglogpen typedef struct tagLOGPEN { UINT lopnStyle; POINT // lopnWidth; COLORREF lopnColor; } LOGPEN, *PLOGPEN, *NPLOGPEN, *LPLOGPEN; [PInvokeData("wingdi.h", MSDNShortId = "0e098b5a-e249-43ad-a6d8-2509b6562453")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct LOGPEN { /// /// The pen style, which can be one of the following values. /// /// /// Value /// Meaning /// /// /// PS_SOLID /// The pen is solid. /// /// /// PS_DASH /// The pen is dashed. /// /// /// PS_DOT /// The pen is dotted. /// /// /// PS_DASHDOT /// The pen has alternating dashes and dots. /// /// /// PS_DASHDOTDOT /// The pen has dashes and double dots. /// /// /// PS_NULL /// The pen is invisible. /// /// /// PS_INSIDEFRAME /// /// The pen is solid. When this pen is used in any GDI drawing function that takes a bounding rectangle, the dimensions of the /// figure are shrunk so that it fits entirely in the bounding rectangle, taking into account the width of the pen. This applies /// only to geometric pens. /// /// /// /// public PenStyle lopnStyle; /// /// /// The POINT structure that contains the pen width, in logical units. If the pointer member is NULL, the pen is /// one pixel wide on raster devices. The y member in the POINT structure for lopnWidth is not used. /// /// public POINT lopnWidth; /// /// The pen color. To generate a COLORREF structure, use the RGB macro. /// public COLORREF lopnColor; } } }