using System;
using System.Runtime.InteropServices;
namespace Vanara.PInvoke
{
public static partial class User32
{
/// Flags used by .
[PInvokeData("winuser.h")]
[Flags]
public enum FVIRT : byte
{
///
/// The key member specifies a virtual-key code. If this flag is not specified, key is assumed to specify a character code.
///
FVIRTKEY = 0x01,
///
/// No top-level menu item is highlighted when the accelerator is used. If this flag is not specified, a top-level menu item will
/// be highlighted, if possible, when the accelerator is used. This attribute is obsolete and retained only for backward
/// compatibility with resource files designed for 16-bit Windows.
///
FNOINVERT = 0x02,
/// The SHIFT key must be held down when the accelerator key is pressed.
FSHIFT = 0x04,
/// The CTRL key must be held down when the accelerator key is pressed.
FCONTROL = 0x08,
/// The ALT key must be held down when the accelerator key is pressed.
FALT = 0x10,
}
///
/// Copies the specified accelerator table. This function is used to obtain the accelerator-table data that corresponds to an
/// accelerator-table handle, or to determine the size of the accelerator-table data.
///
///
/// Type: HACCEL
/// A handle to the accelerator table to copy.
///
///
/// Type: LPACCEL
/// An array of ACCEL structures that receives the accelerator-table information.
///
///
/// Type: int
/// The number of ACCEL structures to copy to the buffer pointed to by the lpAccelDst parameter.
///
///
/// Type: int
///
/// If lpAccelDst is NULL, the return value specifies the number of accelerator-table entries in the original table.
/// Otherwise, it specifies the number of accelerator-table entries that were copied.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-copyacceleratortablea int CopyAcceleratorTableA( HACCEL
// hAccelSrc, LPACCEL lpAccelDst, int cAccelEntries );
[DllImport(Lib.User32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winuser.h")]
public static extern int CopyAcceleratorTable(HACCEL hAccelSrc, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] ACCEL[] lpAccelDst, int cAccelEntries);
/// Creates an accelerator table.
///
/// Type: LPACCEL
/// An array of ACCEL structures that describes the accelerator table.
///
///
/// Type: int
/// The number of ACCEL structures in the array. This must be within the range 1 to 32767 or the function will fail.
///
///
/// Type: HACCEL
///
/// If the function succeeds, the return value is the handle to the created accelerator table; otherwise, it is NULL. To get
/// extended error information, call GetLastError.
///
///
///
///
/// Before an application closes, it can use the DestroyAcceleratorTable function to destroy any accelerator tables that it created
/// by using the CreateAcceleratorTable function.
///
/// Examples
/// For an example, see Creating User Editable Accelerators.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-createacceleratortablea HACCEL CreateAcceleratorTableA(
// LPACCEL paccel, int cAccel );
[DllImport(Lib.User32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("winuser.h")]
public static extern SafeHACCEL CreateAcceleratorTable([In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] ACCEL[] paccel, int cAccel);
/// Destroys an accelerator table.
///
/// Type: HACCEL
///
/// A handle to the accelerator table to be destroyed. This handle must have been created by a call to the CreateAcceleratorTable or
/// LoadAccelerators function.
///
///
///
/// Type: BOOL
///
/// If the function succeeds, the return value is nonzero. However, if the table has been loaded more than one call to
/// LoadAccelerators, the function will return a nonzero value only when DestroyAcceleratorTable has been called an equal
/// number of times.
///
/// If the function fails, the return value is zero.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-destroyacceleratortable BOOL DestroyAcceleratorTable(
// HACCEL hAccel );
[DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winuser.h")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DestroyAcceleratorTable(HACCEL hAccel);
/// Loads the specified accelerator table.
///
/// Type: HINSTANCE
/// A handle to the module whose executable file contains the accelerator table to be loaded.
///
///
/// Type: LPCTSTR
///
/// The name of the accelerator table to be loaded. Alternatively, this parameter can specify the resource identifier of an
/// accelerator-table resource in the low-order word and zero in the high-order word. To create this value, use the MAKEINTRESOURCE macro.
///
///
///
/// Type: HACCEL
/// If the function succeeds, the return value is a handle to the loaded accelerator table.
/// If the function fails, the return value is NULL. To get extended error information, call GetLastError.
///
///
/// If the accelerator table has not yet been loaded, the function loads it from the specified executable file.
/// Accelerator tables loaded from resources are freed automatically when the application terminates.
/// Examples
/// For an example, see Creating Accelerators for Font Attributes.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-loadacceleratorsa HACCEL LoadAcceleratorsA( HINSTANCE
// hInstance, LPCSTR lpTableName );
[DllImport(Lib.User32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("winuser.h")]
public static extern HACCEL LoadAccelerators(HINSTANCE hInstance, string lpTableName);
///
/// Processes accelerator keys for menu commands. The function translates a WM_KEYDOWN or WM_SYSKEYDOWN message to a WM_COMMAND or
/// WM_SYSCOMMAND message (if there is an entry for the key in the specified accelerator table) and then sends the WM_COMMAND
/// or WM_SYSCOMMAND message directly to the specified window procedure. TranslateAccelerator does not return until the
/// window procedure has processed the message.
///
///
/// Type: HWND
/// A handle to the window whose messages are to be translated.
///
///
/// Type: HACCEL
///
/// A handle to the accelerator table. The accelerator table must have been loaded by a call to the LoadAccelerators function or
/// created by a call to the CreateAcceleratorTable function.
///
///
///
/// Type: LPMSG
///
/// A pointer to an MSG structure that contains message information retrieved from the calling thread's message queue using the
/// GetMessage or PeekMessage function.
///
///
///
/// Type: int
/// If the function succeeds, the return value is nonzero.
/// If the function fails, the return value is zero. To get extended error information, call GetLastError.
///
///
///
/// To differentiate the message that this function sends from messages sent by menus or controls, the high-order word of the wParam
/// parameter of the WM_COMMAND or WM_SYSCOMMAND message contains the value 1.
///
///
/// Accelerator key combinations used to select items from the window menu are translated into WM_SYSCOMMAND messages; all
/// other accelerator key combinations are translated into WM_COMMAND messages.
///
///
/// When TranslateAccelerator returns a nonzero value and the message is translated, the application should not use the
/// TranslateMessage function to process the message again.
///
/// An accelerator need not correspond to a menu command.
///
/// If the accelerator command corresponds to a menu item, the application is sent WM_INITMENU and WM_INITMENUPOPUP messages, as if
/// the user were trying to display the menu. However, these messages are not sent if any of the following conditions exist:
///
///
/// -
/// The window is disabled.
///
/// -
/// The accelerator key combination does not correspond to an item on the window menu and the window is minimized.
///
/// -
/// A mouse capture is in effect. For information about mouse capture, see the SetCapture function.
///
///
///
/// If the specified window is the active window and no window has the keyboard focus (which is generally the case if the window is
/// minimized), TranslateAccelerator translates WM_SYSKEYUP and WM_SYSKEYDOWN messages instead of WM_KEYUP and WM_KEYDOWN messages.
///
///
/// If an accelerator keystroke occurs that corresponds to a menu item when the window that owns the menu is minimized,
/// TranslateAccelerator does not send a WM_COMMAND message. However, if an accelerator keystroke occurs that does not match
/// any of the items in the window's menu or in the window menu, the function sends a WM_COMMAND message, even if the
/// window is minimized.
///
/// Examples
/// For an example, see Creating Accelerators for Font Attributes.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-translateacceleratora int TranslateAcceleratorA( HWND
// hWnd, HACCEL hAccTable, LPMSG lpMsg );
[DllImport(Lib.User32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("winuser.h")]
public static extern int TranslateAccelerator(HWND hWnd, HACCEL hAccTable, in MSG lpMsg);
///
/// Defines an accelerator key used in an accelerator table.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagaccel typedef struct tagACCEL { #if ... BYTE fVirt;
// WORD key; #if ... WORD cmd; #else WORD fVirt; #endif #else DWORD cmd; #endif } ACCEL, *LPACCEL;
[PInvokeData("winuser.h")]
[StructLayout(LayoutKind.Sequential)]
public struct ACCEL
{
/// The accelerator behavior. This member can be one or more of the following values.
public FVIRT fVirt;
///
/// Type: WORD
/// The accelerator key. This member can be either a virtual-key code or a character code.
///
public ushort key;
///
/// The accelerator identifier. This value is placed in the low-order word of the wParam parameter of the WM_COMMAND or
/// WM_SYSCOMMAND message when the accelerator is pressed.
///
public ushort cmd;
}
/// Provides a for that is disposed using .
public class SafeHACCEL : SafeHANDLE, IUserHandle
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
///
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
///
public SafeHACCEL(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// Initializes a new instance of the class.
private SafeHACCEL() : base() { }
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator HACCEL(SafeHACCEL h) => h.handle;
///
protected override bool InternalReleaseHandle() => DestroyAcceleratorTable(this);
}
}
}