Completed work adding type attribute for all WindowMessage values.

nullableenabled
David Hall 2023-05-09 11:56:16 -06:00
parent 164664503e
commit 98b997e9e2
5 changed files with 2772 additions and 1641 deletions

36
PInvoke/User32/Macros.cs Normal file
View File

@ -0,0 +1,36 @@
using System;
using System.Runtime.InteropServices;
namespace Vanara.PInvoke;
public static partial class User32
{
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
public static HINSTANCE GetWindowInstance(HWND hwnd) => (HINSTANCE)GetWindowLongPtr(hwnd, WindowLongFlags.GWLP_HINSTANCE);
public static WindowStyles GetWindowStyle(HWND hwnd) => (WindowStyles)GetWindowLong(hwnd, WindowLongFlags.GWL_STYLE);
public static WindowStylesEx GetWindowExStyle(HWND hwnd) => (WindowStylesEx)GetWindowLong(hwnd, WindowLongFlags.GWL_EXSTYLE);
public static HWND GetWindowOwner(HWND hwnd) => GetWindow(hwnd, GetWindowCmd.GW_OWNER);
public static HWND GetFirstChild(HWND hwnd) => GetTopWindow(hwnd);
public static HWND GetFirstSibling(HWND hwnd) => GetWindow(hwnd, GetWindowCmd.GW_HWNDFIRST);
public static HWND GetLastSibling(HWND hwnd) => GetWindow(hwnd, GetWindowCmd.GW_HWNDLAST);
public static HWND GetNextSibling(HWND hwnd) => GetWindow(hwnd, GetWindowCmd.GW_HWNDNEXT);
public static HWND GetPrevSibling(HWND hwnd) => GetWindow(hwnd, GetWindowCmd.GW_HWNDPREV);
public static int GetWindowID(HWND hwnd) => GetDlgCtrlID(hwnd);
public static bool IsMinimized(HWND hwnd) => IsIconic(hwnd);
public static bool IsMaximized(HWND hwnd) => IsZoomed(hwnd);
public static bool IsRestored(HWND hwnd) => (GetWindowStyle(hwnd) & (WindowStyles.WS_MINIMIZE | WindowStyles.WS_MAXIMIZE)) == 0L;
public static HFONT GetWindowFont(HWND hwnd) => (HFONT)SendMessage(hwnd, WindowMessage.WM_GETFONT);
//public static void CheckDefDlgRecursion(ref bool fRecursion) { if (fRecursion) { fRecursion = false; return false; } }
public static bool IsLButtonDown() => GetKeyState((int)VK.VK_LBUTTON) < 0;
public static bool IsRButtonDown() => GetKeyState((int)VK.VK_RBUTTON) < 0;
public static bool IsMButtonDown() => GetKeyState((int)VK.VK_MBUTTON) < 0;
public static HWND SetWindowRedraw(HWND hwnd, BOOL fRedraw) => SendMessage(hwnd, WindowMessage.WM_SETREDRAW, (IntPtr)fRedraw);
public static WindowProc SubclassWindow(HWND hwnd, WindowProc lpfn) => Marshal.GetDelegateForFunctionPointer<WindowProc>(SetWindowLong(hwnd, WindowLongFlags.GWLP_WNDPROC, Marshal.GetFunctionPointerForDelegate(lpfn)));
public static HWND SetWindowFont(HWND hwnd, HFONT hfont, BOOL fRedraw) => SendMessage(hwnd, WindowMessage.WM_SETFONT, (IntPtr)hfont, (IntPtr)fRedraw);
public static int MapWindowRect(HWND hwndFrom, HWND hwndTo, ref RECT lprc) => MapWindowPoints(hwndFrom, hwndTo, ref lprc);
public static WindowProc SubclassDialog(HWND hwndDlg, WindowProc lpfn) => Marshal.GetDelegateForFunctionPointer<WindowProc>(SetWindowLong(hwndDlg, WindowLongFlags.DWLP_DLGPROC, Marshal.GetFunctionPointerForDelegate(lpfn)));
public static bool SetDlgMsgResult(HWND hwnd, WindowMessage msg, BOOL result) => (msg is WindowMessage.WM_CTLCOLORMSGBOX or WindowMessage.WM_CTLCOLOREDIT or WindowMessage.WM_CTLCOLORLISTBOX or WindowMessage.WM_CTLCOLORBTN or WindowMessage.WM_CTLCOLORDLG or WindowMessage.WM_CTLCOLORSCROLLBAR or WindowMessage.WM_CTLCOLORSTATIC or WindowMessage.WM_COMPAREITEM or WindowMessage.WM_VKEYTOITEM or WindowMessage.WM_CHARTOITEM or WindowMessage.WM_QUERYDRAGICON or WindowMessage.WM_INITDIALOG) ?
result :
SetWindowLong(hwnd, WindowLongFlags.DWLP_MSGRESULT, (IntPtr)result) != IntPtr.Zero;
public static IntPtr DefDlgProcEx(HWND hwnd, uint msg, IntPtr wParam, IntPtr lParam, ref bool pfRecursion) { pfRecursion = true; return DefDlgProc(hwnd, msg, wParam, lParam); }
}

View File

@ -1,47 +1,59 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Vanara.Extensions;
using Vanara.Extensions.Reflection;
namespace Vanara.PInvoke;
/// <summary>
/// Use this attribute to specify the types of the wParam and lParam values of a message. If not specified, the default is IntPtr for both.
/// </summary>
/// <seealso cref="System.Attribute"/>
public class MsgParamsAttribute : Attribute
{
/// <summary>Initializes a new instance of the <see cref="MsgParamsAttribute"/> class.</summary>
/// <param name="wParamType">Type of the wParam.</param>
/// <param name="lParamType">Type of the lParam.</param>
public MsgParamsAttribute(Type? wParamType, Type? lParamType)
{
WParamType = wParamType;
LParamType = lParamType;
WParamByRef = wParamType?.IsClass ?? false;
LParamByRef = lParamType?.IsClass ?? false;
}
public MsgParamsAttribute()
{
WParamType = LParamType = null;
WParamByRef = LParamByRef = false;
}
/// <summary>Initializes a new instance of the <see cref="MsgParamsAttribute"/> class.</summary>
public MsgParamsAttribute() => WParamType = LParamType = null;
public Type? WParamType { get; }
public bool WParamByRef { get; set; }
public Type? LParamType { get; }
public bool LParamByRef { get; set; }
/// <summary>Gets or sets the type of the lParam.</summary>
/// <value>The type of the lParam.</value>
public Type? LParamType { get; set; }
/// <summary>Gets or sets the type of the LRESULT.</summary>
/// <value>The type of the LRESULT.</value>
public Type? LResultType { get; set; } = typeof(int);
/// <summary>Gets or sets the type of the wParam.</summary>
/// <value>The type of the wParam.</value>
public Type? WParamType { get; set; }
}
/// <summary></summary>
public static class MsgExtensions
{
/// <summary>Gets the parameters for a message using the <see cref="MsgParamsAttribute"/> associated with the message.</summary>
/// <typeparam name="TEnum">The type of the message enum.</typeparam>
/// <param name="msg">The MSG value.</param>
/// <returns>The wParam and lParam in a tuple tied to their assigned value types.</returns>
public static (object? wParam, object? lParam) GetParams<TEnum>(this MSG msg) where TEnum : Enum
{
MsgParamsAttribute? attr = typeof(TEnum).GetCustomAttribute<MsgParamsAttribute>();
if (attr is null || (attr.WParamType == typeof(IntPtr) && attr.LParamType == typeof(IntPtr)))
if (attr is null || attr.WParamType == typeof(IntPtr) && attr.LParamType == typeof(IntPtr))
{
return (msg.wParam, msg.lParam);
}
else
{
object? wParam = attr.WParamType is null ? null : attr.WParamByRef ? msg.wParam.ToStructure(attr.WParamType) : msg.wParam.ToInt32().ConvertTo(attr.WParamType);
object? lParam = attr.LParamType is null ? null : attr.LParamByRef ? msg.lParam.ToStructure(attr.LParamType) : msg.lParam.ToInt32().ConvertTo(attr.LParamType);
object? wParam = attr.WParamType is null ? null : attr.WParamType.IsNullable() ? msg.wParam.ToStructure(attr.WParamType) : msg.wParam.ToInt32().ConvertTo(attr.WParamType);
object? lParam = attr.LParamType is null ? null : attr.LParamType.IsNullable() ? msg.lParam.ToStructure(attr.LParamType) : msg.lParam.ToInt32().ConvertTo(attr.LParamType);
return (wParam, lParam);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -160,6 +160,45 @@ public static partial class User32
DS_USEPIXELS = 0x8000,
}
/// <summary>The return value for WM_GETDLGCODE, indicating which type of input the application processes.</summary>
[PInvokeData("winuser.h")]
[Flags]
public enum DLGC : int
{
/// <summary>Direction keys.</summary>
DLGC_WANTARROWS = 0x0001,
/// <summary>TAB key.</summary>
DLGC_WANTTAB = 0x0002,
/// <summary>All keyboard input.</summary>
DLGC_WANTALLKEYS = 0x0004,
/// <summary>All keyboard input (the application passes this message in the MSG structure to the control).</summary>
DLGC_WANTMESSAGE = 0x0004,
/// <summary>EM_SETSEL messages.</summary>
DLGC_HASSETSEL = 0x0008,
/// <summary>Default push button.</summary>
DLGC_DEFPUSHBUTTON = 0x0010,
/// <summary>Non-default push button.</summary>
DLGC_UNDEFPUSHBUTTON = 0x0020,
/// <summary>Radio button.</summary>
DLGC_RADIOBUTTON = 0x0040,
/// <summary>WM_CHAR messages.</summary>
DLGC_WANTCHARS = 0x0080,
/// <summary>Static control.</summary>
DLGC_STATIC = 0x0100,
/// <summary>Button.</summary>
DLGC_BUTTON = 0x2000,
}
/// <summary>
/// <para>
/// Creates a modeless dialog box from a dialog box template resource. The <c>CreateDialog</c> macro uses the CreateDialogParam function.

View File

@ -2839,7 +2839,7 @@ public static partial class User32
[PInvokeData("winuser.h", MSDNShortId = "")]
public static extern short VkKeyScanW(char ch);
/// <summary>Provides a handle to a .</summary>
/// <summary>Provides a handle to an input locale identifier.</summary>
[StructLayout(LayoutKind.Sequential)]
public readonly struct HKL : IHandle
{
@ -2852,9 +2852,17 @@ public static partial class User32
/// <summary>Returns an invalid handle by instantiating a <see cref="HKL"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static HKL NULL => new(IntPtr.Zero);
/// <summary>Gets the device identifier tied to the HKL.</summary>
/// <value>The device identifier.</value>
public ushort DeviceId => Macros.HIWORD(unchecked((uint)handle.ToInt32()));
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
/// <summary>Gets the language identifier tied to the HKL.</summary>
/// <value>The language identifier.</value>
public LANGID LangId => new(Macros.LOWORD(unchecked((uint)handle.ToInt32())));
/// <summary>Performs an explicit conversion from <see cref="HKL"/> to <see cref="IntPtr"/>.</summary>
/// <param name="h">The handle.</param>
/// <returns>The result of the conversion.</returns>