#include <winapifamily.h>
/****************************************************************************
* *
* winuser.h -- USER procedure declarations, constant definitions and macros *
* *
* Copyright (c) Microsoft Corporation. All rights reserved. *
* *
****************************************************************************/
#ifndef _WINUSER_
#define _WINUSER_
#pragma once
//
// Define API decoration for direct importing of DLL references.
//
#if !defined(WINUSERAPI)
#if !defined(_USER32_)
#define WINUSERAPI DECLSPEC_IMPORT
#else
#define WINUSERAPI
#endif
#endif
#if !defined(WINABLEAPI)
#if !defined(_USER32_)
#define WINABLEAPI DECLSPEC_IMPORT
#else
#define WINABLEAPI
#endif
#endif
#ifdef _MAC
#include <macwin32.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#ifndef WINVER
#define WINVER 0x0500 /* version 5.0 */
#endif /* !WINVER */
#include <stdarg.h>
#ifndef NOAPISET
#include <libloaderapi.h> // LoadString%
#endif
#ifndef NOUSER
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef HANDLE HDWP;
typedef VOID MENUTEMPLATEA;
typedef VOID MENUTEMPLATEW;
#ifdef UNICODE
typedef MENUTEMPLATEW MENUTEMPLATE;
#else
typedef MENUTEMPLATEA MENUTEMPLATE;
#endif // UNICODE
typedef PVOID LPMENUTEMPLATEA;
typedef PVOID LPMENUTEMPLATEW;
#ifdef UNICODE
typedef LPMENUTEMPLATEW LPMENUTEMPLATE;
#else
typedef LPMENUTEMPLATEA LPMENUTEMPLATE;
#endif // UNICODE
typedef LRESULT (CALLBACK* WNDPROC)(HWND, UINT, WPARAM, LPARAM);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#ifdef STRICT
#pragma region Application Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
typedef INT_PTR (CALLBACK* DLGPROC)(HWND, UINT, WPARAM, LPARAM);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) */
#pragma endregion
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef VOID (CALLBACK* TIMERPROC)(HWND, UINT, UINT_PTR, DWORD);
typedef BOOL (CALLBACK* GRAYSTRINGPROC)(HDC, LPARAM, int);
typedef BOOL (CALLBACK* WNDENUMPROC)(HWND, LPARAM);
typedef LRESULT (CALLBACK* HOOKPROC)(int code, WPARAM wParam, LPARAM lParam);
typedef VOID (CALLBACK* SENDASYNCPROC)(HWND, UINT, ULONG_PTR, LRESULT);
typedef BOOL (CALLBACK* PROPENUMPROCA)(HWND, LPCSTR, HANDLE);
typedef BOOL (CALLBACK* PROPENUMPROCW)(HWND, LPCWSTR, HANDLE);
typedef BOOL (CALLBACK* PROPENUMPROCEXA)(HWND, LPSTR, HANDLE, ULONG_PTR);
typedef BOOL (CALLBACK* PROPENUMPROCEXW)(HWND, LPWSTR, HANDLE, ULONG_PTR);
typedef int (CALLBACK* EDITWORDBREAKPROCA)(LPSTR lpch, int ichCurrent, int cch, int code);
typedef int (CALLBACK* EDITWORDBREAKPROCW)(LPWSTR lpch, int ichCurrent, int cch, int code);
#if(WINVER >= 0x0400)
typedef BOOL (CALLBACK* DRAWSTATEPROC)(HDC hdc, LPARAM lData, WPARAM wData, int cx, int cy);
#endif /* WINVER >= 0x0400 */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#else /* !STRICT */
#pragma region Application Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
typedef FARPROC DLGPROC;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) */
#pragma endregion
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef FARPROC TIMERPROC;
typedef FARPROC GRAYSTRINGPROC;
typedef FARPROC WNDENUMPROC;
typedef FARPROC HOOKPROC;
typedef FARPROC SENDASYNCPROC;
typedef FARPROC EDITWORDBREAKPROCA;
typedef FARPROC EDITWORDBREAKPROCW;
typedef FARPROC PROPENUMPROCA;
typedef FARPROC PROPENUMPROCW;
typedef FARPROC PROPENUMPROCEXA;
typedef FARPROC PROPENUMPROCEXW;
#if(WINVER >= 0x0400)
typedef FARPROC DRAWSTATEPROC;
#endif /* WINVER >= 0x0400 */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* !STRICT */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#ifdef UNICODE
typedef PROPENUMPROCW PROPENUMPROC;
typedef PROPENUMPROCEXW PROPENUMPROCEX;
typedef EDITWORDBREAKPROCW EDITWORDBREAKPROC;
#else /* !UNICODE */
typedef PROPENUMPROCA PROPENUMPROC;
typedef PROPENUMPROCEXA PROPENUMPROCEX;
typedef EDITWORDBREAKPROCA EDITWORDBREAKPROC;
#endif /* UNICODE */
#ifdef STRICT
typedef BOOL (CALLBACK* NAMEENUMPROCA)(LPSTR, LPARAM);
typedef BOOL (CALLBACK* NAMEENUMPROCW)(LPWSTR, LPARAM);
typedef NAMEENUMPROCA WINSTAENUMPROCA;
typedef NAMEENUMPROCA DESKTOPENUMPROCA;
typedef NAMEENUMPROCW WINSTAENUMPROCW;
typedef NAMEENUMPROCW DESKTOPENUMPROCW;
#else /* !STRICT */
typedef FARPROC NAMEENUMPROCA;
typedef FARPROC NAMEENUMPROCW;
typedef FARPROC WINSTAENUMPROCA;
typedef FARPROC DESKTOPENUMPROCA;
typedef FARPROC WINSTAENUMPROCW;
typedef FARPROC DESKTOPENUMPROCW;
#endif /* !STRICT */
#ifdef UNICODE
typedef WINSTAENUMPROCW WINSTAENUMPROC;
typedef DESKTOPENUMPROCW DESKTOPENUMPROC;
#else /* !UNICODE */
typedef WINSTAENUMPROCA WINSTAENUMPROC;
typedef DESKTOPENUMPROCA DESKTOPENUMPROC;
#endif /* UNICODE */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#define IS_INTRESOURCE(_r) ((((ULONG_PTR)(_r)) >> 16) == 0)
#define MAKEINTRESOURCEA(i) ((LPSTR)((ULONG_PTR)((WORD)(i))))
#define MAKEINTRESOURCEW(i) ((LPWSTR)((ULONG_PTR)((WORD)(i))))
#ifdef UNICODE
#define MAKEINTRESOURCE MAKEINTRESOURCEW
#else
#define MAKEINTRESOURCE MAKEINTRESOURCEA
#endif // !UNICODE
#ifndef NORESOURCE
/*
* Predefined Resource Types
*/
#define RT_CURSOR MAKEINTRESOURCE(1)
#define RT_BITMAP MAKEINTRESOURCE(2)
#define RT_ICON MAKEINTRESOURCE(3)
#define RT_MENU MAKEINTRESOURCE(4)
#define RT_DIALOG MAKEINTRESOURCE(5)
#define RT_STRING MAKEINTRESOURCE(6)
#define RT_FONTDIR MAKEINTRESOURCE(7)
#define RT_FONT MAKEINTRESOURCE(8)
#define RT_ACCELERATOR MAKEINTRESOURCE(9)
#define RT_RCDATA MAKEINTRESOURCE(10)
#define RT_MESSAGETABLE MAKEINTRESOURCE(11)
#define DIFFERENCE 11
#define RT_GROUP_CURSOR MAKEINTRESOURCE((ULONG_PTR)(RT_CURSOR) + DIFFERENCE)
#define RT_GROUP_ICON MAKEINTRESOURCE((ULONG_PTR)(RT_ICON) + DIFFERENCE)
#define RT_VERSION MAKEINTRESOURCE(16)
#define RT_DLGINCLUDE MAKEINTRESOURCE(17)
#if(WINVER >= 0x0400)
#define RT_PLUGPLAY MAKEINTRESOURCE(19)
#define RT_VXD MAKEINTRESOURCE(20)
#define RT_ANICURSOR MAKEINTRESOURCE(21)
#define RT_ANIICON MAKEINTRESOURCE(22)
#endif /* WINVER >= 0x0400 */
#define RT_HTML MAKEINTRESOURCE(23)
#ifdef RC_INVOKED
#define RT_MANIFEST 24
#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
#define ISOLATIONAWARE_MANIFEST_RESOURCE_ID 2
#define ISOLATIONAWARE_NOSTATICIMPORT_MANIFEST_RESOURCE_ID 3
#define MINIMUM_RESERVED_MANIFEST_RESOURCE_ID 1 /* inclusive */
#define MAXIMUM_RESERVED_MANIFEST_RESOURCE_ID 16 /* inclusive */
#else /* RC_INVOKED */
#define RT_MANIFEST MAKEINTRESOURCE(24)
#define CREATEPROCESS_MANIFEST_RESOURCE_ID MAKEINTRESOURCE( 1)
#define ISOLATIONAWARE_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(2)
#define ISOLATIONAWARE_NOSTATICIMPORT_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(3)
#define MINIMUM_RESERVED_MANIFEST_RESOURCE_ID MAKEINTRESOURCE( 1 /*inclusive*/)
#define MAXIMUM_RESERVED_MANIFEST_RESOURCE_ID MAKEINTRESOURCE(16 /*inclusive*/)
#endif /* RC_INVOKED */
#endif /* !NORESOURCE */
#if defined(DEPRECATE_SUPPORTED)
#pragma warning(push)
#pragma warning(disable:4995)
#endif
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
int
WINAPI
wvsprintfA(
_Out_ LPSTR,
_In_ _Printf_format_string_ LPCSTR,
_In_ va_list arglist);
WINUSERAPI
int
WINAPI
wvsprintfW(
_Out_ LPWSTR,
_In_ _Printf_format_string_ LPCWSTR,
_In_ va_list arglist);
#ifdef UNICODE
#define wvsprintf wvsprintfW
#else
#define wvsprintf wvsprintfA
#endif // !UNICODE
WINUSERAPI
int
WINAPIV
wsprintfA(
_Out_ LPSTR,
_In_ _Printf_format_string_ LPCSTR,
...);
WINUSERAPI
int
WINAPIV
wsprintfW(
_Out_ LPWSTR,
_In_ _Printf_format_string_ LPCWSTR,
...);
#ifdef UNICODE
#define wsprintf wsprintfW
#else
#define wsprintf wsprintfA
#endif // !UNICODE
#if defined(DEPRECATE_SUPPORTED)
#pragma warning(pop)
#endif
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* SPI_SETDESKWALLPAPER defined constants
*/
#define SETWALLPAPER_DEFAULT ((LPWSTR)-1)
#ifndef NOSCROLL
/*
* Scroll Bar Constants
*/
#define SB_HORZ 0
#define SB_VERT 1
#define SB_CTL 2
#define SB_BOTH 3
/*
* Scroll Bar Commands
*/
#define SB_LINEUP 0
#define SB_LINELEFT 0
#define SB_LINEDOWN 1
#define SB_LINERIGHT 1
#define SB_PAGEUP 2
#define SB_PAGELEFT 2
#define SB_PAGEDOWN 3
#define SB_PAGERIGHT 3
#define SB_THUMBPOSITION 4
#define SB_THUMBTRACK 5
#define SB_TOP 6
#define SB_LEFT 6
#define SB_BOTTOM 7
#define SB_RIGHT 7
#define SB_ENDSCROLL 8
#endif /* !NOSCROLL */
#ifndef NOSHOWWINDOW
/*
* ShowWindow() Commands
*/
#define SW_HIDE 0
#define SW_SHOWNORMAL 1
#define SW_NORMAL 1
#define SW_SHOWMINIMIZED 2
#define SW_SHOWMAXIMIZED 3
#define SW_MAXIMIZE 3
#define SW_SHOWNOACTIVATE 4
#define SW_SHOW 5
#define SW_MINIMIZE 6
#define SW_SHOWMINNOACTIVE 7
#define SW_SHOWNA 8
#define SW_RESTORE 9
#define SW_SHOWDEFAULT 10
#define SW_FORCEMINIMIZE 11
#define SW_MAX 11
/*
* Old ShowWindow() Commands
*/
#define HIDE_WINDOW 0
#define SHOW_OPENWINDOW 1
#define SHOW_ICONWINDOW 2
#define SHOW_FULLSCREEN 3
#define SHOW_OPENNOACTIVATE 4
/*
* Identifiers for the WM_SHOWWINDOW message
*/
#define SW_PARENTCLOSING 1
#define SW_OTHERZOOM 2
#define SW_PARENTOPENING 3
#define SW_OTHERUNZOOM 4
#endif /* !NOSHOWWINDOW */
#if(WINVER >= 0x0500)
/*
* AnimateWindow() Commands
*/
#define AW_HOR_POSITIVE 0x00000001
#define AW_HOR_NEGATIVE 0x00000002
#define AW_VER_POSITIVE 0x00000004
#define AW_VER_NEGATIVE 0x00000008
#define AW_CENTER 0x00000010
#define AW_HIDE 0x00010000
#define AW_ACTIVATE 0x00020000
#define AW_SLIDE 0x00040000
#define AW_BLEND 0x00080000
#endif /* WINVER >= 0x0500 */
/*
* WM_KEYUP/DOWN/CHAR HIWORD(lParam) flags
*/
#define KF_EXTENDED 0x0100
#define KF_DLGMODE 0x0800
#define KF_MENUMODE 0x1000
#define KF_ALTDOWN 0x2000
#define KF_REPEAT 0x4000
#define KF_UP 0x8000
#ifndef NOVIRTUALKEYCODES
/*
* Virtual Keys, Standard Set
*/
#define VK_LBUTTON 0x01
#define VK_RBUTTON 0x02
#define VK_CANCEL 0x03
#define VK_MBUTTON 0x04 /* NOT contiguous with L & RBUTTON */
#if(_WIN32_WINNT >= 0x0500)
#define VK_XBUTTON1 0x05 /* NOT contiguous with L & RBUTTON */
#define VK_XBUTTON2 0x06 /* NOT contiguous with L & RBUTTON */
#endif /* _WIN32_WINNT >= 0x0500 */
/*
* 0x07 : unassigned
*/
#define VK_BACK 0x08
#define VK_TAB 0x09
/*
* 0x0A - 0x0B : reserved
*/
#define VK_CLEAR 0x0C
#define VK_RETURN 0x0D
#define VK_SHIFT 0x10
#define VK_CONTROL 0x11
#define VK_MENU 0x12
#define VK_PAUSE 0x13
#define VK_CAPITAL 0x14
#define VK_KANA 0x15
#define VK_HANGEUL 0x15 /* old name - should be here for compatibility */
#define VK_HANGUL 0x15
#define VK_JUNJA 0x17
#define VK_FINAL 0x18
#define VK_HANJA 0x19
#define VK_KANJI 0x19
#define VK_ESCAPE 0x1B
#define VK_CONVERT 0x1C
#define VK_NONCONVERT 0x1D
#define VK_ACCEPT 0x1E
#define VK_MODECHANGE 0x1F
#define VK_SPACE 0x20
#define VK_PRIOR 0x21
#define VK_NEXT 0x22
#define VK_END 0x23
#define VK_HOME 0x24
#define VK_LEFT 0x25
#define VK_UP 0x26
#define VK_RIGHT 0x27
#define VK_DOWN 0x28
#define VK_SELECT 0x29
#define VK_PRINT 0x2A
#define VK_EXECUTE 0x2B
#define VK_SNAPSHOT 0x2C
#define VK_INSERT 0x2D
#define VK_DELETE 0x2E
#define VK_HELP 0x2F
/*
* VK_0 - VK_9 are the same as ASCII '0' - '9' (0x30 - 0x39)
* 0x40 : unassigned
* VK_A - VK_Z are the same as ASCII 'A' - 'Z' (0x41 - 0x5A)
*/
#define VK_LWIN 0x5B
#define VK_RWIN 0x5C
#define VK_APPS 0x5D
/*
* 0x5E : reserved
*/
#define VK_SLEEP 0x5F
#define VK_NUMPAD0 0x60
#define VK_NUMPAD1 0x61
#define VK_NUMPAD2 0x62
#define VK_NUMPAD3 0x63
#define VK_NUMPAD4 0x64
#define VK_NUMPAD5 0x65
#define VK_NUMPAD6 0x66
#define VK_NUMPAD7 0x67
#define VK_NUMPAD8 0x68
#define VK_NUMPAD9 0x69
#define VK_MULTIPLY 0x6A
#define VK_ADD 0x6B
#define VK_SEPARATOR 0x6C
#define VK_SUBTRACT 0x6D
#define VK_DECIMAL 0x6E
#define VK_DIVIDE 0x6F
#define VK_F1 0x70
#define VK_F2 0x71
#define VK_F3 0x72
#define VK_F4 0x73
#define VK_F5 0x74
#define VK_F6 0x75
#define VK_F7 0x76
#define VK_F8 0x77
#define VK_F9 0x78
#define VK_F10 0x79
#define VK_F11 0x7A
#define VK_F12 0x7B
#define VK_F13 0x7C
#define VK_F14 0x7D
#define VK_F15 0x7E
#define VK_F16 0x7F
#define VK_F17 0x80
#define VK_F18 0x81
#define VK_F19 0x82
#define VK_F20 0x83
#define VK_F21 0x84
#define VK_F22 0x85
#define VK_F23 0x86
#define VK_F24 0x87
/*
* 0x88 - 0x8F : unassigned
*/
#define VK_NUMLOCK 0x90
#define VK_SCROLL 0x91
/*
* NEC PC-9800 kbd definitions
*/
#define VK_OEM_NEC_EQUAL 0x92 // '=' key on numpad
/*
* Fujitsu/OASYS kbd definitions
*/
#define VK_OEM_FJ_JISHO 0x92 // 'Dictionary' key
#define VK_OEM_FJ_MASSHOU 0x93 // 'Unregister word' key
#define VK_OEM_FJ_TOUROKU 0x94 // 'Register word' key
#define VK_OEM_FJ_LOYA 0x95 // 'Left OYAYUBI' key
#define VK_OEM_FJ_ROYA 0x96 // 'Right OYAYUBI' key
/*
* 0x97 - 0x9F : unassigned
*/
/*
* VK_L* & VK_R* - left and right Alt, Ctrl and Shift virtual keys.
* Used only as parameters to GetAsyncKeyState() and GetKeyState().
* No other API or message will distinguish left and right keys in this way.
*/
#define VK_LSHIFT 0xA0
#define VK_RSHIFT 0xA1
#define VK_LCONTROL 0xA2
#define VK_RCONTROL 0xA3
#define VK_LMENU 0xA4
#define VK_RMENU 0xA5
#if(_WIN32_WINNT >= 0x0500)
#define VK_BROWSER_BACK 0xA6
#define VK_BROWSER_FORWARD 0xA7
#define VK_BROWSER_REFRESH 0xA8
#define VK_BROWSER_STOP 0xA9
#define VK_BROWSER_SEARCH 0xAA
#define VK_BROWSER_FAVORITES 0xAB
#define VK_BROWSER_HOME 0xAC
#define VK_VOLUME_MUTE 0xAD
#define VK_VOLUME_DOWN 0xAE
#define VK_VOLUME_UP 0xAF
#define VK_MEDIA_NEXT_TRACK 0xB0
#define VK_MEDIA_PREV_TRACK 0xB1
#define VK_MEDIA_STOP 0xB2
#define VK_MEDIA_PLAY_PAUSE 0xB3
#define VK_LAUNCH_MAIL 0xB4
#define VK_LAUNCH_MEDIA_SELECT 0xB5
#define VK_LAUNCH_APP1 0xB6
#define VK_LAUNCH_APP2 0xB7
#endif /* _WIN32_WINNT >= 0x0500 */
/*
* 0xB8 - 0xB9 : reserved
*/
#define VK_OEM_1 0xBA // ';:' for US
#define VK_OEM_PLUS 0xBB // '+' any country
#define VK_OEM_COMMA 0xBC // ',' any country
#define VK_OEM_MINUS 0xBD // '-' any country
#define VK_OEM_PERIOD 0xBE // '.' any country
#define VK_OEM_2 0xBF // '/?' for US
#define VK_OEM_3 0xC0 // '`~' for US
/*
* 0xC1 - 0xD7 : reserved
*/
/*
* 0xD8 - 0xDA : unassigned
*/
#define VK_OEM_4 0xDB // '[{' for US
#define VK_OEM_5 0xDC // '\|' for US
#define VK_OEM_6 0xDD // ']}' for US
#define VK_OEM_7 0xDE // ''"' for US
#define VK_OEM_8 0xDF
/*
* 0xE0 : reserved
*/
/*
* Various extended or enhanced keyboards
*/
#define VK_OEM_AX 0xE1 // 'AX' key on Japanese AX kbd
#define VK_OEM_102 0xE2 // "<>" or "\|" on RT 102-key kbd.
#define VK_ICO_HELP 0xE3 // Help key on ICO
#define VK_ICO_00 0xE4 // 00 key on ICO
#if(WINVER >= 0x0400)
#define VK_PROCESSKEY 0xE5
#endif /* WINVER >= 0x0400 */
#define VK_ICO_CLEAR 0xE6
#if(_WIN32_WINNT >= 0x0500)
#define VK_PACKET 0xE7
#endif /* _WIN32_WINNT >= 0x0500 */
/*
* 0xE8 : unassigned
*/
/*
* Nokia/Ericsson definitions
*/
#define VK_OEM_RESET 0xE9
#define VK_OEM_JUMP 0xEA
#define VK_OEM_PA1 0xEB
#define VK_OEM_PA2 0xEC
#define VK_OEM_PA3 0xED
#define VK_OEM_WSCTRL 0xEE
#define VK_OEM_CUSEL 0xEF
#define VK_OEM_ATTN 0xF0
#define VK_OEM_FINISH 0xF1
#define VK_OEM_COPY 0xF2
#define VK_OEM_AUTO 0xF3
#define VK_OEM_ENLW 0xF4
#define VK_OEM_BACKTAB 0xF5
#define VK_ATTN 0xF6
#define VK_CRSEL 0xF7
#define VK_EXSEL 0xF8
#define VK_EREOF 0xF9
#define VK_PLAY 0xFA
#define VK_ZOOM 0xFB
#define VK_NONAME 0xFC
#define VK_PA1 0xFD
#define VK_OEM_CLEAR 0xFE
/*
* 0xFF : reserved
*/
#endif /* !NOVIRTUALKEYCODES */
#ifndef NOWH
/*
* SetWindowsHook() codes
*/
#define WH_MIN (-1)
#define WH_MSGFILTER (-1)
#define WH_JOURNALRECORD 0
#define WH_JOURNALPLAYBACK 1
#define WH_KEYBOARD 2
#define WH_GETMESSAGE 3
#define WH_CALLWNDPROC 4
#define WH_CBT 5
#define WH_SYSMSGFILTER 6
#define WH_MOUSE 7
#if defined(_WIN32_WINDOWS)
#define WH_HARDWARE 8
#endif
#define WH_DEBUG 9
#define WH_SHELL 10
#define WH_FOREGROUNDIDLE 11
#if(WINVER >= 0x0400)
#define WH_CALLWNDPROCRET 12
#endif /* WINVER >= 0x0400 */
#if (_WIN32_WINNT >= 0x0400)
#define WH_KEYBOARD_LL 13
#define WH_MOUSE_LL 14
#endif // (_WIN32_WINNT >= 0x0400)
#if(WINVER >= 0x0400)
#if (_WIN32_WINNT >= 0x0400)
#define WH_MAX 14
#else
#define WH_MAX 12
#endif // (_WIN32_WINNT >= 0x0400)
#else
#define WH_MAX 11
#endif
#define WH_MINHOOK WH_MIN
#define WH_MAXHOOK WH_MAX
/*
* Hook Codes
*/
#define HC_ACTION 0
#define HC_GETNEXT 1
#define HC_SKIP 2
#define HC_NOREMOVE 3
#define HC_NOREM HC_NOREMOVE
#define HC_SYSMODALON 4
#define HC_SYSMODALOFF 5
/*
* CBT Hook Codes
*/
#define HCBT_MOVESIZE 0
#define HCBT_MINMAX 1
#define HCBT_QS 2
#define HCBT_CREATEWND 3
#define HCBT_DESTROYWND 4
#define HCBT_ACTIVATE 5
#define HCBT_CLICKSKIPPED 6
#define HCBT_KEYSKIPPED 7
#define HCBT_SYSCOMMAND 8
#define HCBT_SETFOCUS 9
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
/*
* HCBT_CREATEWND parameters pointed to by lParam
*/
typedef struct tagCBT_CREATEWNDA
{
struct tagCREATESTRUCTA *lpcs;
HWND hwndInsertAfter;
} CBT_CREATEWNDA, *LPCBT_CREATEWNDA;
/*
* HCBT_CREATEWND parameters pointed to by lParam
*/
typedef struct tagCBT_CREATEWNDW
{
struct tagCREATESTRUCTW *lpcs;
HWND hwndInsertAfter;
} CBT_CREATEWNDW, *LPCBT_CREATEWNDW;
#ifdef UNICODE
typedef CBT_CREATEWNDW CBT_CREATEWND;
typedef LPCBT_CREATEWNDW LPCBT_CREATEWND;
#else
typedef CBT_CREATEWNDA CBT_CREATEWND;
typedef LPCBT_CREATEWNDA LPCBT_CREATEWND;
#endif // UNICODE
/*
* HCBT_ACTIVATE structure pointed to by lParam
*/
typedef struct tagCBTACTIVATESTRUCT
{
BOOL fMouse;
HWND hWndActive;
} CBTACTIVATESTRUCT, *LPCBTACTIVATESTRUCT;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#if(_WIN32_WINNT >= 0x0501)
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
/*
* WTSSESSION_NOTIFICATION struct pointed by lParam, for WM_WTSSESSION_CHANGE
*/
typedef struct tagWTSSESSION_NOTIFICATION
{
DWORD cbSize;
DWORD dwSessionId;
} WTSSESSION_NOTIFICATION, *PWTSSESSION_NOTIFICATION;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* codes passed in WPARAM for WM_WTSSESSION_CHANGE
*/
#define WTS_CONSOLE_CONNECT 0x1
#define WTS_CONSOLE_DISCONNECT 0x2
#define WTS_REMOTE_CONNECT 0x3
#define WTS_REMOTE_DISCONNECT 0x4
#define WTS_SESSION_LOGON 0x5
#define WTS_SESSION_LOGOFF 0x6
#define WTS_SESSION_LOCK 0x7
#define WTS_SESSION_UNLOCK 0x8
#define WTS_SESSION_REMOTE_CONTROL 0x9
#define WTS_SESSION_CREATE 0xa
#define WTS_SESSION_TERMINATE 0xb
#endif /* _WIN32_WINNT >= 0x0501 */
/*
* WH_MSGFILTER Filter Proc Codes
*/
#define MSGF_DIALOGBOX 0
#define MSGF_MESSAGEBOX 1
#define MSGF_MENU 2
#define MSGF_SCROLLBAR 5
#define MSGF_NEXTWINDOW 6
#define MSGF_MAX 8 // unused
#define MSGF_USER 4096
/*
* Shell support
*/
#define HSHELL_WINDOWCREATED 1
#define HSHELL_WINDOWDESTROYED 2
#define HSHELL_ACTIVATESHELLWINDOW 3
#if(WINVER >= 0x0400)
#define HSHELL_WINDOWACTIVATED 4
#define HSHELL_GETMINRECT 5
#define HSHELL_REDRAW 6
#define HSHELL_TASKMAN 7
#define HSHELL_LANGUAGE 8
#define HSHELL_SYSMENU 9
#define HSHELL_ENDTASK 10
#endif /* WINVER >= 0x0400 */
#if(_WIN32_WINNT >= 0x0500)
#define HSHELL_ACCESSIBILITYSTATE 11
#define HSHELL_APPCOMMAND 12
#endif /* _WIN32_WINNT >= 0x0500 */
#if(_WIN32_WINNT >= 0x0501)
#define HSHELL_WINDOWREPLACED 13
#define HSHELL_WINDOWREPLACING 14
#endif /* _WIN32_WINNT >= 0x0501 */
#if(_WIN32_WINNT >= 0x0602)
#define HSHELL_MONITORCHANGED 16
#endif /* _WIN32_WINNT >= 0x0602 */
#define HSHELL_HIGHBIT 0x8000
#define HSHELL_FLASH (HSHELL_REDRAW|HSHELL_HIGHBIT)
#define HSHELL_RUDEAPPACTIVATED (HSHELL_WINDOWACTIVATED|HSHELL_HIGHBIT)
#if(_WIN32_WINNT >= 0x0500)
/* cmd for HSHELL_APPCOMMAND and WM_APPCOMMAND */
#define APPCOMMAND_BROWSER_BACKWARD 1
#define APPCOMMAND_BROWSER_FORWARD 2
#define APPCOMMAND_BROWSER_REFRESH 3
#define APPCOMMAND_BROWSER_STOP 4
#define APPCOMMAND_BROWSER_SEARCH 5
#define APPCOMMAND_BROWSER_FAVORITES 6
#define APPCOMMAND_BROWSER_HOME 7
#define APPCOMMAND_VOLUME_MUTE 8
#define APPCOMMAND_VOLUME_DOWN 9
#define APPCOMMAND_VOLUME_UP 10
#define APPCOMMAND_MEDIA_NEXTTRACK 11
#define APPCOMMAND_MEDIA_PREVIOUSTRACK 12
#define APPCOMMAND_MEDIA_STOP 13
#define APPCOMMAND_MEDIA_PLAY_PAUSE 14
#define APPCOMMAND_LAUNCH_MAIL 15
#define APPCOMMAND_LAUNCH_MEDIA_SELECT 16
#define APPCOMMAND_LAUNCH_APP1 17
#define APPCOMMAND_LAUNCH_APP2 18
#define APPCOMMAND_BASS_DOWN 19
#define APPCOMMAND_BASS_BOOST 20
#define APPCOMMAND_BASS_UP 21
#define APPCOMMAND_TREBLE_DOWN 22
#define APPCOMMAND_TREBLE_UP 23
#if(_WIN32_WINNT >= 0x0501)
#define APPCOMMAND_MICROPHONE_VOLUME_MUTE 24
#define APPCOMMAND_MICROPHONE_VOLUME_DOWN 25
#define APPCOMMAND_MICROPHONE_VOLUME_UP 26
#define APPCOMMAND_HELP 27
#define APPCOMMAND_FIND 28
#define APPCOMMAND_NEW 29
#define APPCOMMAND_OPEN 30
#define APPCOMMAND_CLOSE 31
#define APPCOMMAND_SAVE 32
#define APPCOMMAND_PRINT 33
#define APPCOMMAND_UNDO 34
#define APPCOMMAND_REDO 35
#define APPCOMMAND_COPY 36
#define APPCOMMAND_CUT 37
#define APPCOMMAND_PASTE 38
#define APPCOMMAND_REPLY_TO_MAIL 39
#define APPCOMMAND_FORWARD_MAIL 40
#define APPCOMMAND_SEND_MAIL 41
#define APPCOMMAND_SPELL_CHECK 42
#define APPCOMMAND_DICTATE_OR_COMMAND_CONTROL_TOGGLE 43
#define APPCOMMAND_MIC_ON_OFF_TOGGLE 44
#define APPCOMMAND_CORRECTION_LIST 45
#define APPCOMMAND_MEDIA_PLAY 46
#define APPCOMMAND_MEDIA_PAUSE 47
#define APPCOMMAND_MEDIA_RECORD 48
#define APPCOMMAND_MEDIA_FAST_FORWARD 49
#define APPCOMMAND_MEDIA_REWIND 50
#define APPCOMMAND_MEDIA_CHANNEL_UP 51
#define APPCOMMAND_MEDIA_CHANNEL_DOWN 52
#endif /* _WIN32_WINNT >= 0x0501 */
#if(_WIN32_WINNT >= 0x0600)
#define APPCOMMAND_DELETE 53
#define APPCOMMAND_DWM_FLIP3D 54
#endif /* _WIN32_WINNT >= 0x0600 */
#define FAPPCOMMAND_MOUSE 0x8000
#define FAPPCOMMAND_KEY 0
#define FAPPCOMMAND_OEM 0x1000
#define FAPPCOMMAND_MASK 0xF000
#define GET_APPCOMMAND_LPARAM(lParam) ((short)(HIWORD(lParam) & ~FAPPCOMMAND_MASK))
#define GET_DEVICE_LPARAM(lParam) ((WORD)(HIWORD(lParam) & FAPPCOMMAND_MASK))
#define GET_MOUSEORKEY_LPARAM GET_DEVICE_LPARAM
#define GET_FLAGS_LPARAM(lParam) (LOWORD(lParam))
#define GET_KEYSTATE_LPARAM(lParam) GET_FLAGS_LPARAM(lParam)
#endif /* _WIN32_WINNT >= 0x0500 */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef struct
{
HWND hwnd;
RECT rc;
} SHELLHOOKINFO, *LPSHELLHOOKINFO;
/*
* Message Structure used in Journaling
*/
typedef struct tagEVENTMSG {
UINT message;
UINT paramL;
UINT paramH;
DWORD time;
HWND hwnd;
} EVENTMSG, *PEVENTMSGMSG, NEAR *NPEVENTMSGMSG, FAR *LPEVENTMSGMSG;
typedef struct tagEVENTMSG *PEVENTMSG, NEAR *NPEVENTMSG, FAR *LPEVENTMSG;
/*
* Message structure used by WH_CALLWNDPROC
*/
typedef struct tagCWPSTRUCT {
LPARAM lParam;
WPARAM wParam;
UINT message;
HWND hwnd;
} CWPSTRUCT, *PCWPSTRUCT, NEAR *NPCWPSTRUCT, FAR *LPCWPSTRUCT;
#if(WINVER >= 0x0400)
/*
* Message structure used by WH_CALLWNDPROCRET
*/
typedef struct tagCWPRETSTRUCT {
LRESULT lResult;
LPARAM lParam;
WPARAM wParam;
UINT message;
HWND hwnd;
} CWPRETSTRUCT, *PCWPRETSTRUCT, NEAR *NPCWPRETSTRUCT, FAR *LPCWPRETSTRUCT;
#endif /* WINVER >= 0x0400 */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#if (_WIN32_WINNT >= 0x0400)
/*
* Low level hook flags
*/
#define LLKHF_EXTENDED (KF_EXTENDED >> 8) /* 0x00000001 */
#define LLKHF_INJECTED 0x00000010
#define LLKHF_ALTDOWN (KF_ALTDOWN >> 8) /* 0x00000020 */
#define LLKHF_UP (KF_UP >> 8) /* 0x00000080 */
#define LLKHF_LOWER_IL_INJECTED 0x00000002
#define LLMHF_INJECTED 0x00000001
#define LLMHF_LOWER_IL_INJECTED 0x00000002
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
/*
* Structure used by WH_KEYBOARD_LL
*/
typedef struct tagKBDLLHOOKSTRUCT {
DWORD vkCode;
DWORD scanCode;
DWORD flags;
DWORD time;
ULONG_PTR dwExtraInfo;
} KBDLLHOOKSTRUCT, FAR *LPKBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT;
/*
* Structure used by WH_MOUSE_LL
*/
typedef struct tagMSLLHOOKSTRUCT {
POINT pt;
DWORD mouseData;
DWORD flags;
DWORD time;
ULONG_PTR dwExtraInfo;
} MSLLHOOKSTRUCT, FAR *LPMSLLHOOKSTRUCT, *PMSLLHOOKSTRUCT;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif // (_WIN32_WINNT >= 0x0400)
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
/*
* Structure used by WH_DEBUG
*/
typedef struct tagDEBUGHOOKINFO
{
DWORD idThread;
DWORD idThreadInstaller;
LPARAM lParam;
WPARAM wParam;
int code;
} DEBUGHOOKINFO, *PDEBUGHOOKINFO, NEAR *NPDEBUGHOOKINFO, FAR* LPDEBUGHOOKINFO;
/*
* Structure used by WH_MOUSE
*/
typedef struct tagMOUSEHOOKSTRUCT {
POINT pt;
HWND hwnd;
UINT wHitTestCode;
ULONG_PTR dwExtraInfo;
} MOUSEHOOKSTRUCT, FAR *LPMOUSEHOOKSTRUCT, *PMOUSEHOOKSTRUCT;
#if(_WIN32_WINNT >= 0x0500)
#ifdef __cplusplus
typedef struct tagMOUSEHOOKSTRUCTEX : public tagMOUSEHOOKSTRUCT
{
DWORD mouseData;
} MOUSEHOOKSTRUCTEX, *LPMOUSEHOOKSTRUCTEX, *PMOUSEHOOKSTRUCTEX;
#else // ndef __cplusplus
typedef struct tagMOUSEHOOKSTRUCTEX
{
MOUSEHOOKSTRUCT;
DWORD mouseData;
} MOUSEHOOKSTRUCTEX, *LPMOUSEHOOKSTRUCTEX, *PMOUSEHOOKSTRUCTEX;
#endif
#endif /* _WIN32_WINNT >= 0x0500 */
#if(WINVER >= 0x0400)
/*
* Structure used by WH_HARDWARE
*/
typedef struct tagHARDWAREHOOKSTRUCT {
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
} HARDWAREHOOKSTRUCT, FAR *LPHARDWAREHOOKSTRUCT, *PHARDWAREHOOKSTRUCT;
#endif /* WINVER >= 0x0400 */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* !NOWH */
/*
* Keyboard Layout API
*/
#define HKL_PREV 0
#define HKL_NEXT 1
#define KLF_ACTIVATE 0x00000001
#define KLF_SUBSTITUTE_OK 0x00000002
#define KLF_REORDER 0x00000008
#if(WINVER >= 0x0400)
#define KLF_REPLACELANG 0x00000010
#define KLF_NOTELLSHELL 0x00000080
#endif /* WINVER >= 0x0400 */
#define KLF_SETFORPROCESS 0x00000100
#if(_WIN32_WINNT >= 0x0500)
#define KLF_SHIFTLOCK 0x00010000
#define KLF_RESET 0x40000000
#endif /* _WIN32_WINNT >= 0x0500 */
#if(WINVER >= 0x0500)
/*
* Bits in wParam of WM_INPUTLANGCHANGEREQUEST message
*/
#define INPUTLANGCHANGE_SYSCHARSET 0x0001
#define INPUTLANGCHANGE_FORWARD 0x0002
#define INPUTLANGCHANGE_BACKWARD 0x0004
#endif /* WINVER >= 0x0500 */
/*
* Size of KeyboardLayoutName (number of characters), including nul terminator
*/
#define KL_NAMELENGTH 9
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
HKL
WINAPI
LoadKeyboardLayoutA(
_In_ LPCSTR pwszKLID,
_In_ UINT Flags);
WINUSERAPI
HKL
WINAPI
LoadKeyboardLayoutW(
_In_ LPCWSTR pwszKLID,
_In_ UINT Flags);
#ifdef UNICODE
#define LoadKeyboardLayout LoadKeyboardLayoutW
#else
#define LoadKeyboardLayout LoadKeyboardLayoutA
#endif // !UNICODE
#if(WINVER >= 0x0400)
WINUSERAPI
HKL
WINAPI
ActivateKeyboardLayout(
_In_ HKL hkl,
_In_ UINT Flags);
#else
WINUSERAPI
BOOL
WINAPI
ActivateKeyboardLayout(
_In_ HKL hkl,
_In_ UINT Flags);
#endif /* WINVER >= 0x0400 */
#if(WINVER >= 0x0400)
WINUSERAPI
int
WINAPI
ToUnicodeEx(
_In_ UINT wVirtKey,
_In_ UINT wScanCode,
_In_reads_bytes_(256) CONST BYTE *lpKeyState,
_Out_writes_(cchBuff) LPWSTR pwszBuff,
_In_ int cchBuff,
_In_ UINT wFlags,
_In_opt_ HKL dwhkl);
#endif /* WINVER >= 0x0400 */
WINUSERAPI
BOOL
WINAPI
UnloadKeyboardLayout(
_In_ HKL hkl);
WINUSERAPI
BOOL
WINAPI
GetKeyboardLayoutNameA(
_Out_writes_(KL_NAMELENGTH) LPSTR pwszKLID);
WINUSERAPI
BOOL
WINAPI
GetKeyboardLayoutNameW(
_Out_writes_(KL_NAMELENGTH) LPWSTR pwszKLID);
#ifdef UNICODE
#define GetKeyboardLayoutName GetKeyboardLayoutNameW
#else
#define GetKeyboardLayoutName GetKeyboardLayoutNameA
#endif // !UNICODE
#if(WINVER >= 0x0400)
WINUSERAPI
int
WINAPI
GetKeyboardLayoutList(
_In_ int nBuff,
_Out_writes_to_opt_(nBuff, return) HKL FAR *lpList);
WINUSERAPI
HKL
WINAPI
GetKeyboardLayout(
_In_ DWORD idThread);
#endif /* WINVER >= 0x0400 */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#if(WINVER >= 0x0500)
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef struct tagMOUSEMOVEPOINT {
int x;
int y;
DWORD time;
ULONG_PTR dwExtraInfo;
} MOUSEMOVEPOINT, *PMOUSEMOVEPOINT, FAR* LPMOUSEMOVEPOINT;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* Values for resolution parameter of GetMouseMovePointsEx
*/
#define GMMP_USE_DISPLAY_POINTS 1
#define GMMP_USE_HIGH_RESOLUTION_POINTS 2
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
int
WINAPI
GetMouseMovePointsEx(
_In_ UINT cbSize,
_In_ LPMOUSEMOVEPOINT lppt,
_Out_writes_(nBufPoints) LPMOUSEMOVEPOINT lpptBuf,
_In_ int nBufPoints,
_In_ DWORD resolution);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* WINVER >= 0x0500 */
#ifndef NODESKTOP
/*
* Desktop-specific access flags
*/
#define DESKTOP_READOBJECTS 0x0001L
#define DESKTOP_CREATEWINDOW 0x0002L
#define DESKTOP_CREATEMENU 0x0004L
#define DESKTOP_HOOKCONTROL 0x0008L
#define DESKTOP_JOURNALRECORD 0x0010L
#define DESKTOP_JOURNALPLAYBACK 0x0020L
#define DESKTOP_ENUMERATE 0x0040L
#define DESKTOP_WRITEOBJECTS 0x0080L
#define DESKTOP_SWITCHDESKTOP 0x0100L
/*
* Desktop-specific control flags
*/
#define DF_ALLOWOTHERACCOUNTHOOK 0x0001L
#ifdef _WINGDI_
#ifndef NOGDI
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
HDESK
WINAPI
CreateDesktopA(
_In_ LPCSTR lpszDesktop,
_Reserved_ LPCSTR lpszDevice,
_Reserved_ DEVMODEA* pDevmode,
_In_ DWORD dwFlags,
_In_ ACCESS_MASK dwDesiredAccess,
_In_opt_ LPSECURITY_ATTRIBUTES lpsa);
WINUSERAPI
HDESK
WINAPI
CreateDesktopW(
_In_ LPCWSTR lpszDesktop,
_Reserved_ LPCWSTR lpszDevice,
_Reserved_ DEVMODEW* pDevmode,
_In_ DWORD dwFlags,
_In_ ACCESS_MASK dwDesiredAccess,
_In_opt_ LPSECURITY_ATTRIBUTES lpsa);
#ifdef UNICODE
#define CreateDesktop CreateDesktopW
#else
#define CreateDesktop CreateDesktopA
#endif // !UNICODE
WINUSERAPI
HDESK
WINAPI
CreateDesktopExA(
_In_ LPCSTR lpszDesktop,
_Reserved_ LPCSTR lpszDevice,
_Reserved_ DEVMODEA* pDevmode,
_In_ DWORD dwFlags,
_In_ ACCESS_MASK dwDesiredAccess,
_In_opt_ LPSECURITY_ATTRIBUTES lpsa,
_In_ ULONG ulHeapSize,
_Reserved_ PVOID pvoid);
WINUSERAPI
HDESK
WINAPI
CreateDesktopExW(
_In_ LPCWSTR lpszDesktop,
_Reserved_ LPCWSTR lpszDevice,
_Reserved_ DEVMODEW* pDevmode,
_In_ DWORD dwFlags,
_In_ ACCESS_MASK dwDesiredAccess,
_In_opt_ LPSECURITY_ATTRIBUTES lpsa,
_In_ ULONG ulHeapSize,
_Reserved_ PVOID pvoid);
#ifdef UNICODE
#define CreateDesktopEx CreateDesktopExW
#else
#define CreateDesktopEx CreateDesktopExA
#endif // !UNICODE
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* NOGDI */
#endif /* _WINGDI_ */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
HDESK
WINAPI
OpenDesktopA(
_In_ LPCSTR lpszDesktop,
_In_ DWORD dwFlags,
_In_ BOOL fInherit,
_In_ ACCESS_MASK dwDesiredAccess);
WINUSERAPI
HDESK
WINAPI
OpenDesktopW(
_In_ LPCWSTR lpszDesktop,
_In_ DWORD dwFlags,
_In_ BOOL fInherit,
_In_ ACCESS_MASK dwDesiredAccess);
#ifdef UNICODE
#define OpenDesktop OpenDesktopW
#else
#define OpenDesktop OpenDesktopA
#endif // !UNICODE
WINUSERAPI
HDESK
WINAPI
OpenInputDesktop(
_In_ DWORD dwFlags,
_In_ BOOL fInherit,
_In_ ACCESS_MASK dwDesiredAccess);
WINUSERAPI
BOOL
WINAPI
EnumDesktopsA(
_In_opt_ HWINSTA hwinsta,
_In_ DESKTOPENUMPROCA lpEnumFunc,
_In_ LPARAM lParam);
WINUSERAPI
BOOL
WINAPI
EnumDesktopsW(
_In_opt_ HWINSTA hwinsta,
_In_ DESKTOPENUMPROCW lpEnumFunc,
_In_ LPARAM lParam);
#ifdef UNICODE
#define EnumDesktops EnumDesktopsW
#else
#define EnumDesktops EnumDesktopsA
#endif // !UNICODE
WINUSERAPI
BOOL
WINAPI
EnumDesktopWindows(
_In_opt_ HDESK hDesktop,
_In_ WNDENUMPROC lpfn,
_In_ LPARAM lParam);
WINUSERAPI
BOOL
WINAPI
SwitchDesktop(
_In_ HDESK hDesktop);
WINUSERAPI
BOOL
WINAPI
SetThreadDesktop(
_In_ HDESK hDesktop);
WINUSERAPI
BOOL
WINAPI
CloseDesktop(
_In_ HDESK hDesktop);
WINUSERAPI
HDESK
WINAPI
GetThreadDesktop(
_In_ DWORD dwThreadId);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* !NODESKTOP */
#ifndef NOWINDOWSTATION
/*
* Windowstation-specific access flags
*/
#define WINSTA_ENUMDESKTOPS 0x0001L
#define WINSTA_READATTRIBUTES 0x0002L
#define WINSTA_ACCESSCLIPBOARD 0x0004L
#define WINSTA_CREATEDESKTOP 0x0008L
#define WINSTA_WRITEATTRIBUTES 0x0010L
#define WINSTA_ACCESSGLOBALATOMS 0x0020L
#define WINSTA_EXITWINDOWS 0x0040L
#define WINSTA_ENUMERATE 0x0100L
#define WINSTA_READSCREEN 0x0200L
#define WINSTA_ALL_ACCESS (WINSTA_ENUMDESKTOPS | WINSTA_READATTRIBUTES | WINSTA_ACCESSCLIPBOARD | \
WINSTA_CREATEDESKTOP | WINSTA_WRITEATTRIBUTES | WINSTA_ACCESSGLOBALATOMS | \
WINSTA_EXITWINDOWS | WINSTA_ENUMERATE | WINSTA_READSCREEN)
/*
* Windowstation creation flags.
*/
#define CWF_CREATE_ONLY 0x00000001
/*
* Windowstation-specific attribute flags
*/
#define WSF_VISIBLE 0x0001L
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
HWINSTA
WINAPI
CreateWindowStationA(
_In_opt_ LPCSTR lpwinsta,
_In_ DWORD dwFlags,
_In_ ACCESS_MASK dwDesiredAccess,
_In_opt_ LPSECURITY_ATTRIBUTES lpsa);
WINUSERAPI
HWINSTA
WINAPI
CreateWindowStationW(
_In_opt_ LPCWSTR lpwinsta,
_In_ DWORD dwFlags,
_In_ ACCESS_MASK dwDesiredAccess,
_In_opt_ LPSECURITY_ATTRIBUTES lpsa);
#ifdef UNICODE
#define CreateWindowStation CreateWindowStationW
#else
#define CreateWindowStation CreateWindowStationA
#endif // !UNICODE
WINUSERAPI
HWINSTA
WINAPI
OpenWindowStationA(
_In_ LPCSTR lpszWinSta,
_In_ BOOL fInherit,
_In_ ACCESS_MASK dwDesiredAccess);
WINUSERAPI
HWINSTA
WINAPI
OpenWindowStationW(
_In_ LPCWSTR lpszWinSta,
_In_ BOOL fInherit,
_In_ ACCESS_MASK dwDesiredAccess);
#ifdef UNICODE
#define OpenWindowStation OpenWindowStationW
#else
#define OpenWindowStation OpenWindowStationA
#endif // !UNICODE
WINUSERAPI
BOOL
WINAPI
EnumWindowStationsA(
_In_ WINSTAENUMPROCA lpEnumFunc,
_In_ LPARAM lParam);
WINUSERAPI
BOOL
WINAPI
EnumWindowStationsW(
_In_ WINSTAENUMPROCW lpEnumFunc,
_In_ LPARAM lParam);
#ifdef UNICODE
#define EnumWindowStations EnumWindowStationsW
#else
#define EnumWindowStations EnumWindowStationsA
#endif // !UNICODE
WINUSERAPI
BOOL
WINAPI
CloseWindowStation(
_In_ HWINSTA hWinSta);
WINUSERAPI
BOOL
WINAPI
SetProcessWindowStation(
_In_ HWINSTA hWinSta);
WINUSERAPI
HWINSTA
WINAPI
GetProcessWindowStation(
VOID);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* !NOWINDOWSTATION */
#ifndef NOSECURITY
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
SetUserObjectSecurity(
_In_ HANDLE hObj,
_In_ PSECURITY_INFORMATION pSIRequested,
_In_ PSECURITY_DESCRIPTOR pSID);
WINUSERAPI
BOOL
WINAPI
GetUserObjectSecurity(
_In_ HANDLE hObj,
_In_ PSECURITY_INFORMATION pSIRequested,
_Out_writes_bytes_opt_(nLength) PSECURITY_DESCRIPTOR pSID,
_In_ DWORD nLength,
_Out_ LPDWORD lpnLengthNeeded);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#define UOI_FLAGS 1
#define UOI_NAME 2
#define UOI_TYPE 3
#define UOI_USER_SID 4
#if(WINVER >= 0x0600)
#define UOI_HEAPSIZE 5
#define UOI_IO 6
#endif /* WINVER >= 0x0600 */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef struct tagUSEROBJECTFLAGS {
BOOL fInherit;
BOOL fReserved;
DWORD dwFlags;
} USEROBJECTFLAGS, *PUSEROBJECTFLAGS;
WINUSERAPI
BOOL
WINAPI
GetUserObjectInformationA(
_In_ HANDLE hObj,
_In_ int nIndex,
_Out_writes_bytes_opt_(nLength) PVOID pvInfo,
_In_ DWORD nLength,
_Out_opt_ LPDWORD lpnLengthNeeded);
WINUSERAPI
BOOL
WINAPI
GetUserObjectInformationW(
_In_ HANDLE hObj,
_In_ int nIndex,
_Out_writes_bytes_opt_(nLength) PVOID pvInfo,
_In_ DWORD nLength,
_Out_opt_ LPDWORD lpnLengthNeeded);
#ifdef UNICODE
#define GetUserObjectInformation GetUserObjectInformationW
#else
#define GetUserObjectInformation GetUserObjectInformationA
#endif // !UNICODE
WINUSERAPI
BOOL
WINAPI
SetUserObjectInformationA(
_In_ HANDLE hObj,
_In_ int nIndex,
_In_reads_bytes_(nLength) PVOID pvInfo,
_In_ DWORD nLength);
WINUSERAPI
BOOL
WINAPI
SetUserObjectInformationW(
_In_ HANDLE hObj,
_In_ int nIndex,
_In_reads_bytes_(nLength) PVOID pvInfo,
_In_ DWORD nLength);
#ifdef UNICODE
#define SetUserObjectInformation SetUserObjectInformationW
#else
#define SetUserObjectInformation SetUserObjectInformationA
#endif // !UNICODE
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* !NOSECURITY */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#if(WINVER >= 0x0400)
typedef struct tagWNDCLASSEXA {
UINT cbSize;
/* Win 3.x */
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCSTR lpszMenuName;
LPCSTR lpszClassName;
/* Win 4.0 */
HICON hIconSm;
} WNDCLASSEXA, *PWNDCLASSEXA, NEAR *NPWNDCLASSEXA, FAR *LPWNDCLASSEXA;
typedef struct tagWNDCLASSEXW {
UINT cbSize;
/* Win 3.x */
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCWSTR lpszMenuName;
LPCWSTR lpszClassName;
/* Win 4.0 */
HICON hIconSm;
} WNDCLASSEXW, *PWNDCLASSEXW, NEAR *NPWNDCLASSEXW, FAR *LPWNDCLASSEXW;
#ifdef UNICODE
typedef WNDCLASSEXW WNDCLASSEX;
typedef PWNDCLASSEXW PWNDCLASSEX;
typedef NPWNDCLASSEXW NPWNDCLASSEX;
typedef LPWNDCLASSEXW LPWNDCLASSEX;
#else
typedef WNDCLASSEXA WNDCLASSEX;
typedef PWNDCLASSEXA PWNDCLASSEX;
typedef NPWNDCLASSEXA NPWNDCLASSEX;
typedef LPWNDCLASSEXA LPWNDCLASSEX;
#endif // UNICODE
#endif /* WINVER >= 0x0400 */
typedef struct tagWNDCLASSA {
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCSTR lpszMenuName;
LPCSTR lpszClassName;
} WNDCLASSA, *PWNDCLASSA, NEAR *NPWNDCLASSA, FAR *LPWNDCLASSA;
typedef struct tagWNDCLASSW {
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCWSTR lpszMenuName;
LPCWSTR lpszClassName;
} WNDCLASSW, *PWNDCLASSW, NEAR *NPWNDCLASSW, FAR *LPWNDCLASSW;
#ifdef UNICODE
typedef WNDCLASSW WNDCLASS;
typedef PWNDCLASSW PWNDCLASS;
typedef NPWNDCLASSW NPWNDCLASS;
typedef LPWNDCLASSW LPWNDCLASS;
#else
typedef WNDCLASSA WNDCLASS;
typedef PWNDCLASSA PWNDCLASS;
typedef NPWNDCLASSA NPWNDCLASS;
typedef LPWNDCLASSA LPWNDCLASS;
#endif // UNICODE
WINUSERAPI
BOOL
WINAPI
IsHungAppWindow(
_In_ HWND hwnd);
#if(WINVER >= 0x0501)
WINUSERAPI
VOID
WINAPI
DisableProcessWindowsGhosting(
VOID);
#endif /* WINVER >= 0x0501 */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#ifndef NOMSG
#pragma region Application Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
/*
* Message structure
*/
typedef struct tagMSG {
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
#ifdef _MAC
DWORD lPrivate;
#endif
} MSG, *PMSG, NEAR *NPMSG, FAR *LPMSG;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) */
#pragma endregion
#define POINTSTOPOINT(pt, pts) \
{ (pt).x = (LONG)(SHORT)LOWORD(*(LONG*)&pts); \
(pt).y = (LONG)(SHORT)HIWORD(*(LONG*)&pts); }
#define POINTTOPOINTS(pt) (MAKELONG((short)((pt).x), (short)((pt).y)))
#define MAKEWPARAM(l, h) ((WPARAM)(DWORD)MAKELONG(l, h))
#define MAKELPARAM(l, h) ((LPARAM)(DWORD)MAKELONG(l, h))
#define MAKELRESULT(l, h) ((LRESULT)(DWORD)MAKELONG(l, h))
#endif /* !NOMSG */
#ifndef NOWINOFFSETS
/*
* Window field offsets for GetWindowLong()
*/
#define GWL_WNDPROC (-4)
#define GWL_HINSTANCE (-6)
#define GWL_HWNDPARENT (-8)
#define GWL_STYLE (-16)
#define GWL_EXSTYLE (-20)
#define GWL_USERDATA (-21)
#define GWL_ID (-12)
#ifdef _WIN64
#undef GWL_WNDPROC
#undef GWL_HINSTANCE
#undef GWL_HWNDPARENT
#undef GWL_USERDATA
#endif /* _WIN64 */
#define GWLP_WNDPROC (-4)
#define GWLP_HINSTANCE (-6)
#define GWLP_HWNDPARENT (-8)
#define GWLP_USERDATA (-21)
#define GWLP_ID (-12)
/*
* Class field offsets for GetClassLong()
*/
#define GCL_MENUNAME (-8)
#define GCL_HBRBACKGROUND (-10)
#define GCL_HCURSOR (-12)
#define GCL_HICON (-14)
#define GCL_HMODULE (-16)
#define GCL_CBWNDEXTRA (-18)
#define GCL_CBCLSEXTRA (-20)
#define GCL_WNDPROC (-24)
#define GCL_STYLE (-26)
#define GCW_ATOM (-32)
#if(WINVER >= 0x0400)
#define GCL_HICONSM (-34)
#endif /* WINVER >= 0x0400 */
#ifdef _WIN64
#undef GCL_MENUNAME
#undef GCL_HBRBACKGROUND
#undef GCL_HCURSOR
#undef GCL_HICON
#undef GCL_HMODULE
#undef GCL_WNDPROC
#undef GCL_HICONSM
#endif /* _WIN64 */
#define GCLP_MENUNAME (-8)
#define GCLP_HBRBACKGROUND (-10)
#define GCLP_HCURSOR (-12)
#define GCLP_HICON (-14)
#define GCLP_HMODULE (-16)
#define GCLP_WNDPROC (-24)
#define GCLP_HICONSM (-34)
#endif /* !NOWINOFFSETS */
#ifndef NOWINMESSAGES
/*
* Window Messages
*/
#define WM_NULL 0x0000
#define WM_CREATE 0x0001
#define WM_DESTROY 0x0002
#define WM_MOVE 0x0003
#define WM_SIZE 0x0005
#define WM_ACTIVATE 0x0006
/*
* WM_ACTIVATE state values
*/
#define WA_INACTIVE 0
#define WA_ACTIVE 1
#define WA_CLICKACTIVE 2
#define WM_SETFOCUS 0x0007
#define WM_KILLFOCUS 0x0008
#define WM_ENABLE 0x000A
#define WM_SETREDRAW 0x000B
#define WM_SETTEXT 0x000C
#define WM_GETTEXT 0x000D
#define WM_GETTEXTLENGTH 0x000E
#define WM_PAINT 0x000F
#define WM_CLOSE 0x0010
#ifndef _WIN32_WCE
#define WM_QUERYENDSESSION 0x0011
#define WM_QUERYOPEN 0x0013
#define WM_ENDSESSION 0x0016
#endif
#define WM_QUIT 0x0012
#define WM_ERASEBKGND 0x0014
#define WM_SYSCOLORCHANGE 0x0015
#define WM_SHOWWINDOW 0x0018
#define WM_WININICHANGE 0x001A
#if(WINVER >= 0x0400)
#define WM_SETTINGCHANGE WM_WININICHANGE
#endif /* WINVER >= 0x0400 */
#define WM_DEVMODECHANGE 0x001B
#define WM_ACTIVATEAPP 0x001C
#define WM_FONTCHANGE 0x001D
#define WM_TIMECHANGE 0x001E
#define WM_CANCELMODE 0x001F
#define WM_SETCURSOR 0x0020
#define WM_MOUSEACTIVATE 0x0021
#define WM_CHILDACTIVATE 0x0022
#define WM_QUEUESYNC 0x0023
#define WM_GETMINMAXINFO 0x0024
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
/*
* Struct pointed to by WM_GETMINMAXINFO lParam
*/
typedef struct tagMINMAXINFO {
POINT ptReserved;
POINT ptMaxSize;
POINT ptMaxPosition;
POINT ptMinTrackSize;
POINT ptMaxTrackSize;
} MINMAXINFO, *PMINMAXINFO, *LPMINMAXINFO;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#define WM_PAINTICON 0x0026
#define WM_ICONERASEBKGND 0x0027
#define WM_NEXTDLGCTL 0x0028
#define WM_SPOOLERSTATUS 0x002A
#define WM_DRAWITEM 0x002B
#define WM_MEASUREITEM 0x002C
#define WM_DELETEITEM 0x002D
#define WM_VKEYTOITEM 0x002E
#define WM_CHARTOITEM 0x002F
#define WM_SETFONT 0x0030
#define WM_GETFONT 0x0031
#define WM_SETHOTKEY 0x0032
#define WM_GETHOTKEY 0x0033
#define WM_QUERYDRAGICON 0x0037
#define WM_COMPAREITEM 0x0039
#if(WINVER >= 0x0500)
#ifndef _WIN32_WCE
#define WM_GETOBJECT 0x003D
#endif
#endif /* WINVER >= 0x0500 */
#define WM_COMPACTING 0x0041
#define WM_COMMNOTIFY 0x0044 /* no longer suported */
#define WM_WINDOWPOSCHANGING 0x0046
#define WM_WINDOWPOSCHANGED 0x0047
#define WM_POWER 0x0048
/*
* wParam for WM_POWER window message and DRV_POWER driver notification
*/
#define PWR_OK 1
#define PWR_FAIL (-1)
#define PWR_SUSPENDREQUEST 1
#define PWR_SUSPENDRESUME 2
#define PWR_CRITICALRESUME 3
#define WM_COPYDATA 0x004A
#define WM_CANCELJOURNAL 0x004B
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
/*
* lParam of WM_COPYDATA message points to...
*/
typedef struct tagCOPYDATASTRUCT {
ULONG_PTR dwData;
DWORD cbData;
_Field_size_bytes_(cbData) PVOID lpData;
} COPYDATASTRUCT, *PCOPYDATASTRUCT;
#if(WINVER >= 0x0400)
typedef struct tagMDINEXTMENU
{
HMENU hmenuIn;
HMENU hmenuNext;
HWND hwndNext;
} MDINEXTMENU, * PMDINEXTMENU, FAR * LPMDINEXTMENU;
#endif /* WINVER >= 0x0400 */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#if(WINVER >= 0x0400)
#define WM_NOTIFY 0x004E
#define WM_INPUTLANGCHANGEREQUEST 0x0050
#define WM_INPUTLANGCHANGE 0x0051
#define WM_TCARD 0x0052
#define WM_HELP 0x0053
#define WM_USERCHANGED 0x0054
#define WM_NOTIFYFORMAT 0x0055
#define NFR_ANSI 1
#define NFR_UNICODE 2
#define NF_QUERY 3
#define NF_REQUERY 4
#define WM_CONTEXTMENU 0x007B
#define WM_STYLECHANGING 0x007C
#define WM_STYLECHANGED 0x007D
#define WM_DISPLAYCHANGE 0x007E
#define WM_GETICON 0x007F
#define WM_SETICON 0x0080
#endif /* WINVER >= 0x0400 */
#define WM_NCCREATE 0x0081
#define WM_NCDESTROY 0x0082
#define WM_NCCALCSIZE 0x0083
#define WM_NCHITTEST 0x0084
#define WM_NCPAINT 0x0085
#define WM_NCACTIVATE 0x0086
#define WM_GETDLGCODE 0x0087
#ifndef _WIN32_WCE
#define WM_SYNCPAINT 0x0088
#endif
#define WM_NCMOUSEMOVE 0x00A0
#define WM_NCLBUTTONDOWN 0x00A1
#define WM_NCLBUTTONUP 0x00A2
#define WM_NCLBUTTONDBLCLK 0x00A3
#define WM_NCRBUTTONDOWN 0x00A4
#define WM_NCRBUTTONUP 0x00A5
#define WM_NCRBUTTONDBLCLK 0x00A6
#define WM_NCMBUTTONDOWN 0x00A7
#define WM_NCMBUTTONUP 0x00A8
#define WM_NCMBUTTONDBLCLK 0x00A9
#if(_WIN32_WINNT >= 0x0500)
#define WM_NCXBUTTONDOWN 0x00AB
#define WM_NCXBUTTONUP 0x00AC
#define WM_NCXBUTTONDBLCLK 0x00AD
#endif /* _WIN32_WINNT >= 0x0500 */
#if(_WIN32_WINNT >= 0x0501)
#define WM_INPUT_DEVICE_CHANGE 0x00FE
#endif /* _WIN32_WINNT >= 0x0501 */
#if(_WIN32_WINNT >= 0x0501)
#define WM_INPUT 0x00FF
#endif /* _WIN32_WINNT >= 0x0501 */
#define WM_KEYFIRST 0x0100
#define WM_KEYDOWN 0x0100
#define WM_KEYUP 0x0101
#define WM_CHAR 0x0102
#define WM_DEADCHAR 0x0103
#define WM_SYSKEYDOWN 0x0104
#define WM_SYSKEYUP 0x0105
#define WM_SYSCHAR 0x0106
#define WM_SYSDEADCHAR 0x0107
#if(_WIN32_WINNT >= 0x0501)
#define WM_UNICHAR 0x0109
#define WM_KEYLAST 0x0109
#define UNICODE_NOCHAR 0xFFFF
#else
#define WM_KEYLAST 0x0108
#endif /* _WIN32_WINNT >= 0x0501 */
#if(WINVER >= 0x0400)
#define WM_IME_STARTCOMPOSITION 0x010D
#define WM_IME_ENDCOMPOSITION 0x010E
#define WM_IME_COMPOSITION 0x010F
#define WM_IME_KEYLAST 0x010F
#endif /* WINVER >= 0x0400 */
#define WM_INITDIALOG 0x0110
#define WM_COMMAND 0x0111
#define WM_SYSCOMMAND 0x0112
#define WM_TIMER 0x0113
#define WM_HSCROLL 0x0114
#define WM_VSCROLL 0x0115
#define WM_INITMENU 0x0116
#define WM_INITMENUPOPUP 0x0117
#if(WINVER >= 0x0601)
#define WM_GESTURE 0x0119
#define WM_GESTURENOTIFY 0x011A
#endif /* WINVER >= 0x0601 */
#define WM_MENUSELECT 0x011F
#define WM_MENUCHAR 0x0120
#define WM_ENTERIDLE 0x0121
#if(WINVER >= 0x0500)
#ifndef _WIN32_WCE
#define WM_MENURBUTTONUP 0x0122
#define WM_MENUDRAG 0x0123
#define WM_MENUGETOBJECT 0x0124
#define WM_UNINITMENUPOPUP 0x0125
#define WM_MENUCOMMAND 0x0126
#ifndef _WIN32_WCE
#if(_WIN32_WINNT >= 0x0500)
#define WM_CHANGEUISTATE 0x0127
#define WM_UPDATEUISTATE 0x0128
#define WM_QUERYUISTATE 0x0129
/*
* LOWORD(wParam) values in WM_*UISTATE*
*/
#define UIS_SET 1
#define UIS_CLEAR 2
#define UIS_INITIALIZE 3
/*
* HIWORD(wParam) values in WM_*UISTATE*
*/
#define UISF_HIDEFOCUS 0x1
#define UISF_HIDEACCEL 0x2
#if(_WIN32_WINNT >= 0x0501)
#define UISF_ACTIVE 0x4
#endif /* _WIN32_WINNT >= 0x0501 */
#endif /* _WIN32_WINNT >= 0x0500 */
#endif
#endif
#endif /* WINVER >= 0x0500 */
#define WM_CTLCOLORMSGBOX 0x0132
#define WM_CTLCOLOREDIT 0x0133
#define WM_CTLCOLORLISTBOX 0x0134
#define WM_CTLCOLORBTN 0x0135
#define WM_CTLCOLORDLG 0x0136
#define WM_CTLCOLORSCROLLBAR 0x0137
#define WM_CTLCOLORSTATIC 0x0138
#define MN_GETHMENU 0x01E1
#define WM_MOUSEFIRST 0x0200
#define WM_MOUSEMOVE 0x0200
#define WM_LBUTTONDOWN 0x0201
#define WM_LBUTTONUP 0x0202
#define WM_LBUTTONDBLCLK 0x0203
#define WM_RBUTTONDOWN 0x0204
#define WM_RBUTTONUP 0x0205
#define WM_RBUTTONDBLCLK 0x0206
#define WM_MBUTTONDOWN 0x0207
#define WM_MBUTTONUP 0x0208
#define WM_MBUTTONDBLCLK 0x0209
#if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
#define WM_MOUSEWHEEL 0x020A
#endif
#if (_WIN32_WINNT >= 0x0500)
#define WM_XBUTTONDOWN 0x020B
#define WM_XBUTTONUP 0x020C
#define WM_XBUTTONDBLCLK 0x020D
#endif
#if (_WIN32_WINNT >= 0x0600)
#define WM_MOUSEHWHEEL 0x020E
#endif
#if (_WIN32_WINNT >= 0x0600)
#define WM_MOUSELAST 0x020E
#elif (_WIN32_WINNT >= 0x0500)
#define WM_MOUSELAST 0x020D
#elif (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
#define WM_MOUSELAST 0x020A
#else
#define WM_MOUSELAST 0x0209
#endif /* (_WIN32_WINNT >= 0x0600) */
#if(_WIN32_WINNT >= 0x0400)
/* Value for rolling one detent */
#define WHEEL_DELTA 120
#define GET_WHEEL_DELTA_WPARAM(wParam) ((short)HIWORD(wParam))
/* Setting to scroll one page for SPI_GET/SETWHEELSCROLLLINES */
#define WHEEL_PAGESCROLL (UINT_MAX)
#endif /* _WIN32_WINNT >= 0x0400 */
#if(_WIN32_WINNT >= 0x0500)
#define GET_KEYSTATE_WPARAM(wParam) (LOWORD(wParam))
#define GET_NCHITTEST_WPARAM(wParam) ((short)LOWORD(wParam))
#define GET_XBUTTON_WPARAM(wParam) (HIWORD(wParam))
/* XButton values are WORD flags */
#define XBUTTON1 0x0001
#define XBUTTON2 0x0002
/* Were there to be an XBUTTON3, its value would be 0x0004 */
#endif /* _WIN32_WINNT >= 0x0500 */
#define WM_PARENTNOTIFY 0x0210
#define WM_ENTERMENULOOP 0x0211
#define WM_EXITMENULOOP 0x0212
#if(WINVER >= 0x0400)
#define WM_NEXTMENU 0x0213
#define WM_SIZING 0x0214
#define WM_CAPTURECHANGED 0x0215
#define WM_MOVING 0x0216
#endif /* WINVER >= 0x0400 */
#if(WINVER >= 0x0400)
#define WM_POWERBROADCAST 0x0218
#ifndef _WIN32_WCE
#define PBT_APMQUERYSUSPEND 0x0000
#define PBT_APMQUERYSTANDBY 0x0001
#define PBT_APMQUERYSUSPENDFAILED 0x0002
#define PBT_APMQUERYSTANDBYFAILED 0x0003
#define PBT_APMSUSPEND 0x0004
#define PBT_APMSTANDBY 0x0005
#define PBT_APMRESUMECRITICAL 0x0006
#define PBT_APMRESUMESUSPEND 0x0007
#define PBT_APMRESUMESTANDBY 0x0008
#define PBTF_APMRESUMEFROMFAILURE 0x00000001
#define PBT_APMBATTERYLOW 0x0009
#define PBT_APMPOWERSTATUSCHANGE 0x000A
#define PBT_APMOEMEVENT 0x000B
#define PBT_APMRESUMEAUTOMATIC 0x0012
#if (_WIN32_WINNT >= 0x0502)
#ifndef PBT_POWERSETTINGCHANGE
#define PBT_POWERSETTINGCHANGE 0x8013
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef struct {
GUID PowerSetting;
DWORD DataLength;
UCHAR Data[1];
} POWERBROADCAST_SETTING, *PPOWERBROADCAST_SETTING;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif // PBT_POWERSETTINGCHANGE
#endif // (_WIN32_WINNT >= 0x0502)
#endif
#endif /* WINVER >= 0x0400 */
#if(WINVER >= 0x0400)
#define WM_DEVICECHANGE 0x0219
#endif /* WINVER >= 0x0400 */
#define WM_MDICREATE 0x0220
#define WM_MDIDESTROY 0x0221
#define WM_MDIACTIVATE 0x0222
#define WM_MDIRESTORE 0x0223
#define WM_MDINEXT 0x0224
#define WM_MDIMAXIMIZE 0x0225
#define WM_MDITILE 0x0226
#define WM_MDICASCADE 0x0227
#define WM_MDIICONARRANGE 0x0228
#define WM_MDIGETACTIVE 0x0229
#define WM_MDISETMENU 0x0230
#define WM_ENTERSIZEMOVE 0x0231
#define WM_EXITSIZEMOVE 0x0232
#define WM_DROPFILES 0x0233
#define WM_MDIREFRESHMENU 0x0234
#if(WINVER >= 0x0602)
#define WM_POINTERDEVICECHANGE 0x238
#define WM_POINTERDEVICEINRANGE 0x239
#define WM_POINTERDEVICEOUTOFRANGE 0x23A
#endif /* WINVER >= 0x0602 */
#if(WINVER >= 0x0601)
#define WM_TOUCH 0x0240
#endif /* WINVER >= 0x0601 */
#if(WINVER >= 0x0602)
#define WM_NCPOINTERUPDATE 0x0241
#define WM_NCPOINTERDOWN 0x0242
#define WM_NCPOINTERUP 0x0243
#define WM_POINTERUPDATE 0x0245
#define WM_POINTERDOWN 0x0246
#define WM_POINTERUP 0x0247
#define WM_POINTERENTER 0x0249
#define WM_POINTERLEAVE 0x024A
#define WM_POINTERACTIVATE 0x024B
#define WM_POINTERCAPTURECHANGED 0x024C
#define WM_TOUCHHITTESTING 0x024D
#define WM_POINTERWHEEL 0x024E
#define WM_POINTERHWHEEL 0x024F
#define DM_POINTERHITTEST 0x0250
#endif /* WINVER >= 0x0602 */
#if(WINVER >= 0x0400)
#define WM_IME_SETCONTEXT 0x0281
#define WM_IME_NOTIFY 0x0282
#define WM_IME_CONTROL 0x0283
#define WM_IME_COMPOSITIONFULL 0x0284
#define WM_IME_SELECT 0x0285
#define WM_IME_CHAR 0x0286
#endif /* WINVER >= 0x0400 */
#if(WINVER >= 0x0500)
#define WM_IME_REQUEST 0x0288
#endif /* WINVER >= 0x0500 */
#if(WINVER >= 0x0400)
#define WM_IME_KEYDOWN 0x0290
#define WM_IME_KEYUP 0x0291
#endif /* WINVER >= 0x0400 */
#if((_WIN32_WINNT >= 0x0400) || (WINVER >= 0x0500))
#define WM_MOUSEHOVER 0x02A1
#define WM_MOUSELEAVE 0x02A3
#endif
#if(WINVER >= 0x0500)
#define WM_NCMOUSEHOVER 0x02A0
#define WM_NCMOUSELEAVE 0x02A2
#endif /* WINVER >= 0x0500 */
#if(_WIN32_WINNT >= 0x0501)
#define WM_WTSSESSION_CHANGE 0x02B1
#define WM_TABLET_FIRST 0x02c0
#define WM_TABLET_LAST 0x02df
#endif /* _WIN32_WINNT >= 0x0501 */
#if(WINVER >= 0x0601)
#define WM_DPICHANGED 0x02E0
#endif /* WINVER >= 0x0601 */
#define WM_CUT 0x0300
#define WM_COPY 0x0301
#define WM_PASTE 0x0302
#define WM_CLEAR 0x0303
#define WM_UNDO 0x0304
#define WM_RENDERFORMAT 0x0305
#define WM_RENDERALLFORMATS 0x0306
#define WM_DESTROYCLIPBOARD 0x0307
#define WM_DRAWCLIPBOARD 0x0308
#define WM_PAINTCLIPBOARD 0x0309
#define WM_VSCROLLCLIPBOARD 0x030A
#define WM_SIZECLIPBOARD 0x030B
#define WM_ASKCBFORMATNAME 0x030C
#define WM_CHANGECBCHAIN 0x030D
#define WM_HSCROLLCLIPBOARD 0x030E
#define WM_QUERYNEWPALETTE 0x030F
#define WM_PALETTEISCHANGING 0x0310
#define WM_PALETTECHANGED 0x0311
#define WM_HOTKEY 0x0312
#if(WINVER >= 0x0400)
#define WM_PRINT 0x0317
#define WM_PRINTCLIENT 0x0318
#endif /* WINVER >= 0x0400 */
#if(_WIN32_WINNT >= 0x0500)
#define WM_APPCOMMAND 0x0319
#endif /* _WIN32_WINNT >= 0x0500 */
#if(_WIN32_WINNT >= 0x0501)
#define WM_THEMECHANGED 0x031A
#endif /* _WIN32_WINNT >= 0x0501 */
#if(_WIN32_WINNT >= 0x0501)
#define WM_CLIPBOARDUPDATE 0x031D
#endif /* _WIN32_WINNT >= 0x0501 */
#if(_WIN32_WINNT >= 0x0600)
#define WM_DWMCOMPOSITIONCHANGED 0x031E
#define WM_DWMNCRENDERINGCHANGED 0x031F
#define WM_DWMCOLORIZATIONCOLORCHANGED 0x0320
#define WM_DWMWINDOWMAXIMIZEDCHANGE 0x0321
#endif /* _WIN32_WINNT >= 0x0600 */
#if(_WIN32_WINNT >= 0x0601)
#define WM_DWMSENDICONICTHUMBNAIL 0x0323
#define WM_DWMSENDICONICLIVEPREVIEWBITMAP 0x0326
#endif /* _WIN32_WINNT >= 0x0601 */
#if(WINVER >= 0x0600)
#define WM_GETTITLEBARINFOEX 0x033F
#endif /* WINVER >= 0x0600 */
#if(WINVER >= 0x0400)
#define WM_HANDHELDFIRST 0x0358
#define WM_HANDHELDLAST 0x035F
#define WM_AFXFIRST 0x0360
#define WM_AFXLAST 0x037F
#endif /* WINVER >= 0x0400 */
#define WM_PENWINFIRST 0x0380
#define WM_PENWINLAST 0x038F
#if(WINVER >= 0x0400)
#define WM_APP 0x8000
#endif /* WINVER >= 0x0400 */
/*
* NOTE: All Message Numbers below 0x0400 are RESERVED.
*
* Private Window Messages Start Here:
*/
#define WM_USER 0x0400
#if(WINVER >= 0x0400)
/* wParam for WM_SIZING message */
#define WMSZ_LEFT 1
#define WMSZ_RIGHT 2
#define WMSZ_TOP 3
#define WMSZ_TOPLEFT 4
#define WMSZ_TOPRIGHT 5
#define WMSZ_BOTTOM 6
#define WMSZ_BOTTOMLEFT 7
#define WMSZ_BOTTOMRIGHT 8
#endif /* WINVER >= 0x0400 */
#ifndef NONCMESSAGES
/*
* WM_NCHITTEST and MOUSEHOOKSTRUCT Mouse Position Codes
*/
#define HTERROR (-2)
#define HTTRANSPARENT (-1)
#define HTNOWHERE 0
#define HTCLIENT 1
#define HTCAPTION 2
#define HTSYSMENU 3
#define HTGROWBOX 4
#define HTSIZE HTGROWBOX
#define HTMENU 5
#define HTHSCROLL 6
#define HTVSCROLL 7
#define HTMINBUTTON 8
#define HTMAXBUTTON 9
#define HTLEFT 10
#define HTRIGHT 11
#define HTTOP 12
#define HTTOPLEFT 13
#define HTTOPRIGHT 14
#define HTBOTTOM 15
#define HTBOTTOMLEFT 16
#define HTBOTTOMRIGHT 17
#define HTBORDER 18
#define HTREDUCE HTMINBUTTON
#define HTZOOM HTMAXBUTTON
#define HTSIZEFIRST HTLEFT
#define HTSIZELAST HTBOTTOMRIGHT
#if(WINVER >= 0x0400)
#define HTOBJECT 19
#define HTCLOSE 20
#define HTHELP 21
#endif /* WINVER >= 0x0400 */
/*
* SendMessageTimeout values
*/
#define SMTO_NORMAL 0x0000
#define SMTO_BLOCK 0x0001
#define SMTO_ABORTIFHUNG 0x0002
#if(WINVER >= 0x0500)
#define SMTO_NOTIMEOUTIFNOTHUNG 0x0008
#endif /* WINVER >= 0x0500 */
#if(WINVER >= 0x0600)
#define SMTO_ERRORONEXIT 0x0020
#endif /* WINVER >= 0x0600 */
#if(WINVER >= 0x0602)
#endif /* WINVER >= 0x0602 */
#endif /* !NONCMESSAGES */
/*
* WM_MOUSEACTIVATE Return Codes
*/
#define MA_ACTIVATE 1
#define MA_ACTIVATEANDEAT 2
#define MA_NOACTIVATE 3
#define MA_NOACTIVATEANDEAT 4
/*
* WM_SETICON / WM_GETICON Type Codes
*/
#define ICON_SMALL 0
#define ICON_BIG 1
#if(_WIN32_WINNT >= 0x0501)
#define ICON_SMALL2 2
#endif /* _WIN32_WINNT >= 0x0501 */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
UINT
WINAPI
RegisterWindowMessageA(
_In_ LPCSTR lpString);
WINUSERAPI
UINT
WINAPI
RegisterWindowMessageW(
_In_ LPCWSTR lpString);
#ifdef UNICODE
#define RegisterWindowMessage RegisterWindowMessageW
#else
#define RegisterWindowMessage RegisterWindowMessageA
#endif // !UNICODE
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* WM_SIZE message wParam values
*/
#define SIZE_RESTORED 0
#define SIZE_MINIMIZED 1
#define SIZE_MAXIMIZED 2
#define SIZE_MAXSHOW 3
#define SIZE_MAXHIDE 4
/*
* Obsolete constant names
*/
#define SIZENORMAL SIZE_RESTORED
#define SIZEICONIC SIZE_MINIMIZED
#define SIZEFULLSCREEN SIZE_MAXIMIZED
#define SIZEZOOMSHOW SIZE_MAXSHOW
#define SIZEZOOMHIDE SIZE_MAXHIDE
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
/*
* WM_WINDOWPOSCHANGING/CHANGED struct pointed to by lParam
*/
typedef struct tagWINDOWPOS {
HWND hwnd;
HWND hwndInsertAfter;
int x;
int y;
int cx;
int cy;
UINT flags;
} WINDOWPOS, *LPWINDOWPOS, *PWINDOWPOS;
/*
* WM_NCCALCSIZE parameter structure
*/
typedef struct tagNCCALCSIZE_PARAMS {
RECT rgrc[3];
PWINDOWPOS lppos;
} NCCALCSIZE_PARAMS, *LPNCCALCSIZE_PARAMS;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* WM_NCCALCSIZE "window valid rect" return values
*/
#define WVR_ALIGNTOP 0x0010
#define WVR_ALIGNLEFT 0x0020
#define WVR_ALIGNBOTTOM 0x0040
#define WVR_ALIGNRIGHT 0x0080
#define WVR_HREDRAW 0x0100
#define WVR_VREDRAW 0x0200
#define WVR_REDRAW (WVR_HREDRAW | \
WVR_VREDRAW)
#define WVR_VALIDRECTS 0x0400
#ifndef NOKEYSTATES
/*
* Key State Masks for Mouse Messages
*/
#define MK_LBUTTON 0x0001
#define MK_RBUTTON 0x0002
#define MK_SHIFT 0x0004
#define MK_CONTROL 0x0008
#define MK_MBUTTON 0x0010
#if(_WIN32_WINNT >= 0x0500)
#define MK_XBUTTON1 0x0020
#define MK_XBUTTON2 0x0040
#endif /* _WIN32_WINNT >= 0x0500 */
#endif /* !NOKEYSTATES */
#if(_WIN32_WINNT >= 0x0400)
#ifndef NOTRACKMOUSEEVENT
#define TME_HOVER 0x00000001
#define TME_LEAVE 0x00000002
#if(WINVER >= 0x0500)
#define TME_NONCLIENT 0x00000010
#endif /* WINVER >= 0x0500 */
#define TME_QUERY 0x40000000
#define TME_CANCEL 0x80000000
#define HOVER_DEFAULT 0xFFFFFFFF
#endif /* _WIN32_WINNT >= 0x0400 */
#if(_WIN32_WINNT >= 0x0400)
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef struct tagTRACKMOUSEEVENT {
DWORD cbSize;
DWORD dwFlags;
HWND hwndTrack;
DWORD dwHoverTime;
} TRACKMOUSEEVENT, *LPTRACKMOUSEEVENT;
WINUSERAPI
BOOL
WINAPI
TrackMouseEvent(
_Inout_ LPTRACKMOUSEEVENT lpEventTrack);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* _WIN32_WINNT >= 0x0400 */
#if(_WIN32_WINNT >= 0x0400)
#endif /* !NOTRACKMOUSEEVENT */
#endif /* _WIN32_WINNT >= 0x0400 */
#endif /* !NOWINMESSAGES */
#ifndef NOWINSTYLES
/*
* Window Styles
*/
#define WS_OVERLAPPED 0x00000000L
#define WS_POPUP 0x80000000L
#define WS_CHILD 0x40000000L
#define WS_MINIMIZE 0x20000000L
#define WS_VISIBLE 0x10000000L
#define WS_DISABLED 0x08000000L
#define WS_CLIPSIBLINGS 0x04000000L
#define WS_CLIPCHILDREN 0x02000000L
#define WS_MAXIMIZE 0x01000000L
#define WS_CAPTION 0x00C00000L /* WS_BORDER | WS_DLGFRAME */
#define WS_BORDER 0x00800000L
#define WS_DLGFRAME 0x00400000L
#define WS_VSCROLL 0x00200000L
#define WS_HSCROLL 0x00100000L
#define WS_SYSMENU 0x00080000L
#define WS_THICKFRAME 0x00040000L
#define WS_GROUP 0x00020000L
#define WS_TABSTOP 0x00010000L
#define WS_MINIMIZEBOX 0x00020000L
#define WS_MAXIMIZEBOX 0x00010000L
#define WS_TILED WS_OVERLAPPED
#define WS_ICONIC WS_MINIMIZE
#define WS_SIZEBOX WS_THICKFRAME
#define WS_TILEDWINDOW WS_OVERLAPPEDWINDOW
/*
* Common Window Styles
*/
#define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED | \
WS_CAPTION | \
WS_SYSMENU | \
WS_THICKFRAME | \
WS_MINIMIZEBOX | \
WS_MAXIMIZEBOX)
#define WS_POPUPWINDOW (WS_POPUP | \
WS_BORDER | \
WS_SYSMENU)
#define WS_CHILDWINDOW (WS_CHILD)
/*
* Extended Window Styles
*/
#define WS_EX_DLGMODALFRAME 0x00000001L
#define WS_EX_NOPARENTNOTIFY 0x00000004L
#define WS_EX_TOPMOST 0x00000008L
#define WS_EX_ACCEPTFILES 0x00000010L
#define WS_EX_TRANSPARENT 0x00000020L
#if(WINVER >= 0x0400)
#define WS_EX_MDICHILD 0x00000040L
#define WS_EX_TOOLWINDOW 0x00000080L
#define WS_EX_WINDOWEDGE 0x00000100L
#define WS_EX_CLIENTEDGE 0x00000200L
#define WS_EX_CONTEXTHELP 0x00000400L
#endif /* WINVER >= 0x0400 */
#if(WINVER >= 0x0400)
#define WS_EX_RIGHT 0x00001000L
#define WS_EX_LEFT 0x00000000L
#define WS_EX_RTLREADING 0x00002000L
#define WS_EX_LTRREADING 0x00000000L
#define WS_EX_LEFTSCROLLBAR 0x00004000L
#define WS_EX_RIGHTSCROLLBAR 0x00000000L
#define WS_EX_CONTROLPARENT 0x00010000L
#define WS_EX_STATICEDGE 0x00020000L
#define WS_EX_APPWINDOW 0x00040000L
#define WS_EX_OVERLAPPEDWINDOW (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE)
#define WS_EX_PALETTEWINDOW (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST)
#endif /* WINVER >= 0x0400 */
#if(_WIN32_WINNT >= 0x0500)
#define WS_EX_LAYERED 0x00080000
#endif /* _WIN32_WINNT >= 0x0500 */
#if(WINVER >= 0x0500)
#define WS_EX_NOINHERITLAYOUT 0x00100000L // Disable inheritence of mirroring by children
#endif /* WINVER >= 0x0500 */
#if(WINVER >= 0x0602)
#define WS_EX_NOREDIRECTIONBITMAP 0x00200000L
#endif /* WINVER >= 0x0602 */
#if(WINVER >= 0x0500)
#define WS_EX_LAYOUTRTL 0x00400000L // Right to left mirroring
#endif /* WINVER >= 0x0500 */
#if(_WIN32_WINNT >= 0x0501)
#define WS_EX_COMPOSITED 0x02000000L
#endif /* _WIN32_WINNT >= 0x0501 */
#if(_WIN32_WINNT >= 0x0500)
#define WS_EX_NOACTIVATE 0x08000000L
#endif /* _WIN32_WINNT >= 0x0500 */
/*
* Class styles
*/
#define CS_VREDRAW 0x0001
#define CS_HREDRAW 0x0002
#define CS_DBLCLKS 0x0008
#define CS_OWNDC 0x0020
#define CS_CLASSDC 0x0040
#define CS_PARENTDC 0x0080
#define CS_NOCLOSE 0x0200
#define CS_SAVEBITS 0x0800
#define CS_BYTEALIGNCLIENT 0x1000
#define CS_BYTEALIGNWINDOW 0x2000
#define CS_GLOBALCLASS 0x4000
#define CS_IME 0x00010000
#if(_WIN32_WINNT >= 0x0501)
#define CS_DROPSHADOW 0x00020000
#endif /* _WIN32_WINNT >= 0x0501 */
#endif /* !NOWINSTYLES */
#if(WINVER >= 0x0400)
/* WM_PRINT flags */
#define PRF_CHECKVISIBLE 0x00000001L
#define PRF_NONCLIENT 0x00000002L
#define PRF_CLIENT 0x00000004L
#define PRF_ERASEBKGND 0x00000008L
#define PRF_CHILDREN 0x00000010L
#define PRF_OWNED 0x00000020L
/* 3D border styles */
#define BDR_RAISEDOUTER 0x0001
#define BDR_SUNKENOUTER 0x0002
#define BDR_RAISEDINNER 0x0004
#define BDR_SUNKENINNER 0x0008
#define BDR_OUTER (BDR_RAISEDOUTER | BDR_SUNKENOUTER)
#define BDR_INNER (BDR_RAISEDINNER | BDR_SUNKENINNER)
#define BDR_RAISED (BDR_RAISEDOUTER | BDR_RAISEDINNER)
#define BDR_SUNKEN (BDR_SUNKENOUTER | BDR_SUNKENINNER)
#define EDGE_RAISED (BDR_RAISEDOUTER | BDR_RAISEDINNER)
#define EDGE_SUNKEN (BDR_SUNKENOUTER | BDR_SUNKENINNER)
#define EDGE_ETCHED (BDR_SUNKENOUTER | BDR_RAISEDINNER)
#define EDGE_BUMP (BDR_RAISEDOUTER | BDR_SUNKENINNER)
/* Border flags */
#define BF_LEFT 0x0001
#define BF_TOP 0x0002
#define BF_RIGHT 0x0004
#define BF_BOTTOM 0x0008
#define BF_TOPLEFT (BF_TOP | BF_LEFT)
#define BF_TOPRIGHT (BF_TOP | BF_RIGHT)
#define BF_BOTTOMLEFT (BF_BOTTOM | BF_LEFT)
#define BF_BOTTOMRIGHT (BF_BOTTOM | BF_RIGHT)
#define BF_RECT (BF_LEFT | BF_TOP | BF_RIGHT | BF_BOTTOM)
#define BF_DIAGONAL 0x0010
// For diagonal lines, the BF_RECT flags specify the end point of the
// vector bounded by the rectangle parameter.
#define BF_DIAGONAL_ENDTOPRIGHT (BF_DIAGONAL | BF_TOP | BF_RIGHT)
#define BF_DIAGONAL_ENDTOPLEFT (BF_DIAGONAL | BF_TOP | BF_LEFT)
#define BF_DIAGONAL_ENDBOTTOMLEFT (BF_DIAGONAL | BF_BOTTOM | BF_LEFT)
#define BF_DIAGONAL_ENDBOTTOMRIGHT (BF_DIAGONAL | BF_BOTTOM | BF_RIGHT)
#define BF_MIDDLE 0x0800 /* Fill in the middle */
#define BF_SOFT 0x1000 /* For softer buttons */
#define BF_ADJUST 0x2000 /* Calculate the space left over */
#define BF_FLAT 0x4000 /* For flat rather than 3D borders */
#define BF_MONO 0x8000 /* For monochrome borders */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
DrawEdge(
_In_ HDC hdc,
_Inout_ LPRECT qrc,
_In_ UINT edge,
_In_ UINT grfFlags);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/* flags for DrawFrameControl */
#define DFC_CAPTION 1
#define DFC_MENU 2
#define DFC_SCROLL 3
#define DFC_BUTTON 4
#if(WINVER >= 0x0500)
#define DFC_POPUPMENU 5
#endif /* WINVER >= 0x0500 */
#define DFCS_CAPTIONCLOSE 0x0000
#define DFCS_CAPTIONMIN 0x0001
#define DFCS_CAPTIONMAX 0x0002
#define DFCS_CAPTIONRESTORE 0x0003
#define DFCS_CAPTIONHELP 0x0004
#define DFCS_MENUARROW 0x0000
#define DFCS_MENUCHECK 0x0001
#define DFCS_MENUBULLET 0x0002
#define DFCS_MENUARROWRIGHT 0x0004
#define DFCS_SCROLLUP 0x0000
#define DFCS_SCROLLDOWN 0x0001
#define DFCS_SCROLLLEFT 0x0002
#define DFCS_SCROLLRIGHT 0x0003
#define DFCS_SCROLLCOMBOBOX 0x0005
#define DFCS_SCROLLSIZEGRIP 0x0008
#define DFCS_SCROLLSIZEGRIPRIGHT 0x0010
#define DFCS_BUTTONCHECK 0x0000
#define DFCS_BUTTONRADIOIMAGE 0x0001
#define DFCS_BUTTONRADIOMASK 0x0002
#define DFCS_BUTTONRADIO 0x0004
#define DFCS_BUTTON3STATE 0x0008
#define DFCS_BUTTONPUSH 0x0010
#define DFCS_INACTIVE 0x0100
#define DFCS_PUSHED 0x0200
#define DFCS_CHECKED 0x0400
#if(WINVER >= 0x0500)
#define DFCS_TRANSPARENT 0x0800
#define DFCS_HOT 0x1000
#endif /* WINVER >= 0x0500 */
#define DFCS_ADJUSTRECT 0x2000
#define DFCS_FLAT 0x4000
#define DFCS_MONO 0x8000
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
DrawFrameControl(
_In_ HDC,
_Inout_ LPRECT,
_In_ UINT,
_In_ UINT);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/* flags for DrawCaption */
#define DC_ACTIVE 0x0001
#define DC_SMALLCAP 0x0002
#define DC_ICON 0x0004
#define DC_TEXT 0x0008
#define DC_INBUTTON 0x0010
#if(WINVER >= 0x0500)
#define DC_GRADIENT 0x0020
#endif /* WINVER >= 0x0500 */
#if(_WIN32_WINNT >= 0x0501)
#define DC_BUTTONS 0x1000
#endif /* _WIN32_WINNT >= 0x0501 */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
DrawCaption(
_In_ HWND hwnd,
_In_ HDC hdc,
_In_ CONST RECT * lprect,
_In_ UINT flags);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#define IDANI_OPEN 1
#define IDANI_CAPTION 3
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
DrawAnimatedRects(
_In_opt_ HWND hwnd,
_In_ int idAni,
_In_ CONST RECT *lprcFrom,
_In_ CONST RECT *lprcTo);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* WINVER >= 0x0400 */
#ifndef NOCLIPBOARD
/*
* Predefined Clipboard Formats
*/
#define CF_TEXT 1
#define CF_BITMAP 2
#define CF_METAFILEPICT 3
#define CF_SYLK 4
#define CF_DIF 5
#define CF_TIFF 6
#define CF_OEMTEXT 7
#define CF_DIB 8
#define CF_PALETTE 9
#define CF_PENDATA 10
#define CF_RIFF 11
#define CF_WAVE 12
#define CF_UNICODETEXT 13
#define CF_ENHMETAFILE 14
#if(WINVER >= 0x0400)
#define CF_HDROP 15
#define CF_LOCALE 16
#endif /* WINVER >= 0x0400 */
#if(WINVER >= 0x0500)
#define CF_DIBV5 17
#endif /* WINVER >= 0x0500 */
#if(WINVER >= 0x0500)
#define CF_MAX 18
#elif(WINVER >= 0x0400)
#define CF_MAX 17
#else
#define CF_MAX 15
#endif
#define CF_OWNERDISPLAY 0x0080
#define CF_DSPTEXT 0x0081
#define CF_DSPBITMAP 0x0082
#define CF_DSPMETAFILEPICT 0x0083
#define CF_DSPENHMETAFILE 0x008E
/*
* "Private" formats don't get GlobalFree()'d
*/
#define CF_PRIVATEFIRST 0x0200
#define CF_PRIVATELAST 0x02FF
/*
* "GDIOBJ" formats do get DeleteObject()'d
*/
#define CF_GDIOBJFIRST 0x0300
#define CF_GDIOBJLAST 0x03FF
#endif /* !NOCLIPBOARD */
/*
* Defines for the fVirt field of the Accelerator table structure.
*/
#define FVIRTKEY TRUE /* Assumed to be == TRUE */
#define FNOINVERT 0x02
#define FSHIFT 0x04
#define FCONTROL 0x08
#define FALT 0x10
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef struct tagACCEL {
#ifndef _MAC
BYTE fVirt; /* Also called the flags field */
WORD key;
WORD cmd;
#else
WORD fVirt; /* Also called the flags field */
WORD key;
DWORD cmd;
#endif
} ACCEL, *LPACCEL;
typedef struct tagPAINTSTRUCT {
HDC hdc;
BOOL fErase;
RECT rcPaint;
BOOL fRestore;
BOOL fIncUpdate;
BYTE rgbReserved[32];
} PAINTSTRUCT, *PPAINTSTRUCT, *NPPAINTSTRUCT, *LPPAINTSTRUCT;
typedef struct tagCREATESTRUCTA {
LPVOID lpCreateParams;
HINSTANCE hInstance;
HMENU hMenu;
HWND hwndParent;
int cy;
int cx;
int y;
int x;
LONG style;
LPCSTR lpszName;
LPCSTR lpszClass;
DWORD dwExStyle;
} CREATESTRUCTA, *LPCREATESTRUCTA;
typedef struct tagCREATESTRUCTW {
LPVOID lpCreateParams;
HINSTANCE hInstance;
HMENU hMenu;
HWND hwndParent;
int cy;
int cx;
int y;
int x;
LONG style;
LPCWSTR lpszName;
LPCWSTR lpszClass;
DWORD dwExStyle;
} CREATESTRUCTW, *LPCREATESTRUCTW;
#ifdef UNICODE
typedef CREATESTRUCTW CREATESTRUCT;
typedef LPCREATESTRUCTW LPCREATESTRUCT;
#else
typedef CREATESTRUCTA CREATESTRUCT;
typedef LPCREATESTRUCTA LPCREATESTRUCT;
#endif // UNICODE
typedef struct tagWINDOWPLACEMENT {
UINT length;
UINT flags;
UINT showCmd;
POINT ptMinPosition;
POINT ptMaxPosition;
RECT rcNormalPosition;
#ifdef _MAC
RECT rcDevice;
#endif
} WINDOWPLACEMENT;
typedef WINDOWPLACEMENT *PWINDOWPLACEMENT, *LPWINDOWPLACEMENT;
#define WPF_SETMINPOSITION 0x0001
#define WPF_RESTORETOMAXIMIZED 0x0002
#if(_WIN32_WINNT >= 0x0500)
#define WPF_ASYNCWINDOWPLACEMENT 0x0004
#endif /* _WIN32_WINNT >= 0x0500 */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#if(WINVER >= 0x0400)
#pragma region Application Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
typedef struct tagNMHDR
{
HWND hwndFrom;
UINT_PTR idFrom;
UINT code; // NM_ code
} NMHDR;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) */
#pragma endregion
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef NMHDR FAR * LPNMHDR;
typedef struct tagSTYLESTRUCT
{
DWORD styleOld;
DWORD styleNew;
} STYLESTRUCT, * LPSTYLESTRUCT;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* WINVER >= 0x0400 */
/*
* Owner draw control types
*/
#define ODT_MENU 1
#define ODT_LISTBOX 2
#define ODT_COMBOBOX 3
#define ODT_BUTTON 4
#if(WINVER >= 0x0400)
#define ODT_STATIC 5
#endif /* WINVER >= 0x0400 */
/*
* Owner draw actions
*/
#define ODA_DRAWENTIRE 0x0001
#define ODA_SELECT 0x0002
#define ODA_FOCUS 0x0004
/*
* Owner draw state
*/
#define ODS_SELECTED 0x0001
#define ODS_GRAYED 0x0002
#define ODS_DISABLED 0x0004
#define ODS_CHECKED 0x0008
#define ODS_FOCUS 0x0010
#if(WINVER >= 0x0400)
#define ODS_DEFAULT 0x0020
#define ODS_COMBOBOXEDIT 0x1000
#endif /* WINVER >= 0x0400 */
#if(WINVER >= 0x0500)
#define ODS_HOTLIGHT 0x0040
#define ODS_INACTIVE 0x0080
#if(_WIN32_WINNT >= 0x0500)
#define ODS_NOACCEL 0x0100
#define ODS_NOFOCUSRECT 0x0200
#endif /* _WIN32_WINNT >= 0x0500 */
#endif /* WINVER >= 0x0500 */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
/*
* MEASUREITEMSTRUCT for ownerdraw
*/
typedef struct tagMEASUREITEMSTRUCT {
UINT CtlType;
UINT CtlID;
UINT itemID;
UINT itemWidth;
UINT itemHeight;
ULONG_PTR itemData;
} MEASUREITEMSTRUCT, NEAR *PMEASUREITEMSTRUCT, FAR *LPMEASUREITEMSTRUCT;
/*
* DRAWITEMSTRUCT for ownerdraw
*/
typedef struct tagDRAWITEMSTRUCT {
UINT CtlType;
UINT CtlID;
UINT itemID;
UINT itemAction;
UINT itemState;
HWND hwndItem;
HDC hDC;
RECT rcItem;
ULONG_PTR itemData;
} DRAWITEMSTRUCT, NEAR *PDRAWITEMSTRUCT, FAR *LPDRAWITEMSTRUCT;
/*
* DELETEITEMSTRUCT for ownerdraw
*/
typedef struct tagDELETEITEMSTRUCT {
UINT CtlType;
UINT CtlID;
UINT itemID;
HWND hwndItem;
ULONG_PTR itemData;
} DELETEITEMSTRUCT, NEAR *PDELETEITEMSTRUCT, FAR *LPDELETEITEMSTRUCT;
/*
* COMPAREITEMSTUCT for ownerdraw sorting
*/
typedef struct tagCOMPAREITEMSTRUCT {
UINT CtlType;
UINT CtlID;
HWND hwndItem;
UINT itemID1;
ULONG_PTR itemData1;
UINT itemID2;
ULONG_PTR itemData2;
DWORD dwLocaleId;
} COMPAREITEMSTRUCT, NEAR *PCOMPAREITEMSTRUCT, FAR *LPCOMPAREITEMSTRUCT;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#ifndef NOMSG
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
/*
* Message Function Templates
*/
WINUSERAPI
BOOL
WINAPI
GetMessageA(
_Out_ LPMSG lpMsg,
_In_opt_ HWND hWnd,
_In_ UINT wMsgFilterMin,
_In_ UINT wMsgFilterMax);
WINUSERAPI
BOOL
WINAPI
GetMessageW(
_Out_ LPMSG lpMsg,
_In_opt_ HWND hWnd,
_In_ UINT wMsgFilterMin,
_In_ UINT wMsgFilterMax);
#ifdef UNICODE
#define GetMessage GetMessageW
#else
#define GetMessage GetMessageA
#endif // !UNICODE
#if defined(_M_CEE)
#undef GetMessage
__inline
BOOL
GetMessage(
LPMSG lpMsg,
HWND hWnd,
UINT wMsgFilterMin,
UINT wMsgFilterMax
)
{
#ifdef UNICODE
return GetMessageW(
#else
return GetMessageA(
#endif
lpMsg,
hWnd,
wMsgFilterMin,
wMsgFilterMax
);
}
#endif /* _M_CEE */
WINUSERAPI
BOOL
WINAPI
TranslateMessage(
_In_ CONST MSG *lpMsg);
WINUSERAPI
LRESULT
WINAPI
DispatchMessageA(
_In_ CONST MSG *lpMsg);
WINUSERAPI
LRESULT
WINAPI
DispatchMessageW(
_In_ CONST MSG *lpMsg);
#ifdef UNICODE
#define DispatchMessage DispatchMessageW
#else
#define DispatchMessage DispatchMessageA
#endif // !UNICODE
#if defined(_M_CEE)
#undef DispatchMessage
__inline
LRESULT
DispatchMessage(
CONST MSG *lpMsg
)
{
#ifdef UNICODE
return DispatchMessageW(
#else
return DispatchMessageA(
#endif
lpMsg
);
}
#endif /* _M_CEE */
WINUSERAPI
BOOL
WINAPI
SetMessageQueue(
_In_ int cMessagesMax);
WINUSERAPI
BOOL
WINAPI
PeekMessageA(
_Out_ LPMSG lpMsg,
_In_opt_ HWND hWnd,
_In_ UINT wMsgFilterMin,
_In_ UINT wMsgFilterMax,
_In_ UINT wRemoveMsg);
WINUSERAPI
BOOL
WINAPI
PeekMessageW(
_Out_ LPMSG lpMsg,
_In_opt_ HWND hWnd,
_In_ UINT wMsgFilterMin,
_In_ UINT wMsgFilterMax,
_In_ UINT wRemoveMsg);
#ifdef UNICODE
#define PeekMessage PeekMessageW
#else
#define PeekMessage PeekMessageA
#endif // !UNICODE
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* PeekMessage() Options
*/
#define PM_NOREMOVE 0x0000
#define PM_REMOVE 0x0001
#define PM_NOYIELD 0x0002
#if(WINVER >= 0x0500)
#define PM_QS_INPUT (QS_INPUT << 16)
#define PM_QS_POSTMESSAGE ((QS_POSTMESSAGE | QS_HOTKEY | QS_TIMER) << 16)
#define PM_QS_PAINT (QS_PAINT << 16)
#define PM_QS_SENDMESSAGE (QS_SENDMESSAGE << 16)
#endif /* WINVER >= 0x0500 */
#endif /* !NOMSG */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
RegisterHotKey(
_In_opt_ HWND hWnd,
_In_ int id,
_In_ UINT fsModifiers,
_In_ UINT vk);
WINUSERAPI
BOOL
WINAPI
UnregisterHotKey(
_In_opt_ HWND hWnd,
_In_ int id);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#define MOD_ALT 0x0001
#define MOD_CONTROL 0x0002
#define MOD_SHIFT 0x0004
#define MOD_WIN 0x0008
#if(WINVER >= 0x0601)
#define MOD_NOREPEAT 0x4000
#endif /* WINVER >= 0x0601 */
#define IDHOT_SNAPWINDOW (-1) /* SHIFT-PRINTSCRN */
#define IDHOT_SNAPDESKTOP (-2) /* PRINTSCRN */
#ifdef WIN_INTERNAL
#ifndef LSTRING
#define NOLSTRING
#endif /* LSTRING */
#ifndef LFILEIO
#define NOLFILEIO
#endif /* LFILEIO */
#endif /* WIN_INTERNAL */
#if(WINVER >= 0x0400)
#endif /* WINVER >= 0x0400 */
#if(_WIN32_WINNT >= 0x0400)
#define ENDSESSION_CLOSEAPP 0x00000001
#endif /* _WIN32_WINNT >= 0x0400 */
#if(_WIN32_WINNT >= 0x0400)
#define ENDSESSION_CRITICAL 0x40000000
#endif /* _WIN32_WINNT >= 0x0400 */
#if(_WIN32_WINNT >= 0x0400)
#define ENDSESSION_LOGOFF 0x80000000
#endif /* _WIN32_WINNT >= 0x0400 */
#define EWX_LOGOFF 0x00000000
#define EWX_SHUTDOWN 0x00000001
#define EWX_REBOOT 0x00000002
#define EWX_FORCE 0x00000004
#define EWX_POWEROFF 0x00000008
#if(_WIN32_WINNT >= 0x0500)
#define EWX_FORCEIFHUNG 0x00000010
#endif /* _WIN32_WINNT >= 0x0500 */
#define EWX_QUICKRESOLVE 0x00000020
#if(_WIN32_WINNT >= 0x0600)
#define EWX_RESTARTAPPS 0x00000040
#endif /* _WIN32_WINNT >= 0x0600 */
#define EWX_HYBRID_SHUTDOWN 0x00400000
#define EWX_BOOTOPTIONS 0x01000000
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#define ExitWindows(dwReserved, Code) ExitWindowsEx(EWX_LOGOFF, 0xFFFFFFFF)
_When_((uFlags&(EWX_POWEROFF|EWX_SHUTDOWN|EWX_FORCE))!=0,
__drv_preferredFunction("InitiateSystemShutdownEx",
"Legacy API. Rearchitect to avoid Reboot"))
WINUSERAPI
BOOL
WINAPI
ExitWindowsEx(
_In_ UINT uFlags,
_In_ DWORD dwReason);
WINUSERAPI
BOOL
WINAPI
SwapMouseButton(
_In_ BOOL fSwap);
WINUSERAPI
DWORD
WINAPI
GetMessagePos(
VOID);
WINUSERAPI
LONG
WINAPI
GetMessageTime(
VOID);
WINUSERAPI
LPARAM
WINAPI
GetMessageExtraInfo(
VOID);
#if(_WIN32_WINNT >= 0x0602)
WINUSERAPI
DWORD
WINAPI
GetUnpredictedMessagePos(
VOID);
#endif /* _WIN32_WINNT >= 0x0602 */
#if(_WIN32_WINNT >= 0x0501)
WINUSERAPI
BOOL
WINAPI
IsWow64Message(
VOID);
#endif /* _WIN32_WINNT >= 0x0501 */
#if(WINVER >= 0x0400)
WINUSERAPI
LPARAM
WINAPI
SetMessageExtraInfo(
_In_ LPARAM lParam);
#endif /* WINVER >= 0x0400 */
WINUSERAPI
LRESULT
WINAPI
SendMessageA(
_In_ HWND hWnd,
_In_ UINT Msg,
_Pre_maybenull_ _Post_valid_ WPARAM wParam,
_Pre_maybenull_ _Post_valid_ LPARAM lParam);
WINUSERAPI
LRESULT
WINAPI
SendMessageW(
_In_ HWND hWnd,
_In_ UINT Msg,
_Pre_maybenull_ _Post_valid_ WPARAM wParam,
_Pre_maybenull_ _Post_valid_ LPARAM lParam);
#ifdef UNICODE
#define SendMessage SendMessageW
#else
#define SendMessage SendMessageA
#endif // !UNICODE
#if defined(_M_CEE)
#undef SendMessage
__inline
LRESULT
SendMessage(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam
)
{
#ifdef UNICODE
return SendMessageW(
#else
return SendMessageA(
#endif
hWnd,
Msg,
wParam,
lParam
);
}
#endif /* _M_CEE */
WINUSERAPI
LRESULT
WINAPI
SendMessageTimeoutA(
_In_ HWND hWnd,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam,
_In_ UINT fuFlags,
_In_ UINT uTimeout,
_Out_opt_ PDWORD_PTR lpdwResult);
WINUSERAPI
LRESULT
WINAPI
SendMessageTimeoutW(
_In_ HWND hWnd,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam,
_In_ UINT fuFlags,
_In_ UINT uTimeout,
_Out_opt_ PDWORD_PTR lpdwResult);
#ifdef UNICODE
#define SendMessageTimeout SendMessageTimeoutW
#else
#define SendMessageTimeout SendMessageTimeoutA
#endif // !UNICODE
WINUSERAPI
BOOL
WINAPI
SendNotifyMessageA(
_In_ HWND hWnd,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam);
WINUSERAPI
BOOL
WINAPI
SendNotifyMessageW(
_In_ HWND hWnd,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam);
#ifdef UNICODE
#define SendNotifyMessage SendNotifyMessageW
#else
#define SendNotifyMessage SendNotifyMessageA
#endif // !UNICODE
WINUSERAPI
BOOL
WINAPI
SendMessageCallbackA(
_In_ HWND hWnd,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam,
_In_ SENDASYNCPROC lpResultCallBack,
_In_ ULONG_PTR dwData);
WINUSERAPI
BOOL
WINAPI
SendMessageCallbackW(
_In_ HWND hWnd,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam,
_In_ SENDASYNCPROC lpResultCallBack,
_In_ ULONG_PTR dwData);
#ifdef UNICODE
#define SendMessageCallback SendMessageCallbackW
#else
#define SendMessageCallback SendMessageCallbackA
#endif // !UNICODE
#if(_WIN32_WINNT >= 0x0501)
typedef struct {
UINT cbSize;
HDESK hdesk;
HWND hwnd;
LUID luid;
} BSMINFO, *PBSMINFO;
WINUSERAPI
long
WINAPI
BroadcastSystemMessageExA(
_In_ DWORD flags,
_Inout_opt_ LPDWORD lpInfo,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam,
_Out_opt_ PBSMINFO pbsmInfo);
WINUSERAPI
long
WINAPI
BroadcastSystemMessageExW(
_In_ DWORD flags,
_Inout_opt_ LPDWORD lpInfo,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam,
_Out_opt_ PBSMINFO pbsmInfo);
#ifdef UNICODE
#define BroadcastSystemMessageEx BroadcastSystemMessageExW
#else
#define BroadcastSystemMessageEx BroadcastSystemMessageExA
#endif // !UNICODE
#endif /* _WIN32_WINNT >= 0x0501 */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#if(WINVER >= 0x0400)
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#if defined(_WIN32_WINNT)
WINUSERAPI
long
WINAPI
BroadcastSystemMessageA(
_In_ DWORD flags,
_Inout_opt_ LPDWORD lpInfo,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam);
WINUSERAPI
long
WINAPI
BroadcastSystemMessageW(
_In_ DWORD flags,
_Inout_opt_ LPDWORD lpInfo,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam);
#ifdef UNICODE
#define BroadcastSystemMessage BroadcastSystemMessageW
#else
#define BroadcastSystemMessage BroadcastSystemMessageA
#endif // !UNICODE
#elif defined(_WIN32_WINDOWS)
// The Win95 version isn't A/W decorated
WINUSERAPI
long
WINAPI
BroadcastSystemMessage(
_In_ DWORD flags,
_Inout_opt_ LPDWORD lpInfo,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam);
#endif
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
//Broadcast Special Message Recipient list
#define BSM_ALLCOMPONENTS 0x00000000
#define BSM_VXDS 0x00000001
#define BSM_NETDRIVER 0x00000002
#define BSM_INSTALLABLEDRIVERS 0x00000004
#define BSM_APPLICATIONS 0x00000008
#define BSM_ALLDESKTOPS 0x00000010
//Broadcast Special Message Flags
#define BSF_QUERY 0x00000001
#define BSF_IGNORECURRENTTASK 0x00000002
#define BSF_FLUSHDISK 0x00000004
#define BSF_NOHANG 0x00000008
#define BSF_POSTMESSAGE 0x00000010
#define BSF_FORCEIFHUNG 0x00000020
#define BSF_NOTIMEOUTIFNOTHUNG 0x00000040
#if(_WIN32_WINNT >= 0x0500)
#define BSF_ALLOWSFW 0x00000080
#define BSF_SENDNOTIFYMESSAGE 0x00000100
#endif /* _WIN32_WINNT >= 0x0500 */
#if(_WIN32_WINNT >= 0x0501)
#define BSF_RETURNHDESK 0x00000200
#define BSF_LUID 0x00000400
#endif /* _WIN32_WINNT >= 0x0501 */
#define BROADCAST_QUERY_DENY 0x424D5144 // Return this value to deny a query.
#endif /* WINVER >= 0x0400 */
// RegisterDeviceNotification
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#if(WINVER >= 0x0500)
typedef PVOID HDEVNOTIFY;
typedef HDEVNOTIFY *PHDEVNOTIFY;
#define DEVICE_NOTIFY_WINDOW_HANDLE 0x00000000
#define DEVICE_NOTIFY_SERVICE_HANDLE 0x00000001
#if(_WIN32_WINNT >= 0x0501)
#define DEVICE_NOTIFY_ALL_INTERFACE_CLASSES 0x00000004
#endif /* _WIN32_WINNT >= 0x0501 */
WINUSERAPI
HDEVNOTIFY
WINAPI
RegisterDeviceNotificationA(
_In_ HANDLE hRecipient,
_In_ LPVOID NotificationFilter,
_In_ DWORD Flags);
WINUSERAPI
HDEVNOTIFY
WINAPI
RegisterDeviceNotificationW(
_In_ HANDLE hRecipient,
_In_ LPVOID NotificationFilter,
_In_ DWORD Flags);
#ifdef UNICODE
#define RegisterDeviceNotification RegisterDeviceNotificationW
#else
#define RegisterDeviceNotification RegisterDeviceNotificationA
#endif // !UNICODE
WINUSERAPI
BOOL
WINAPI
UnregisterDeviceNotification(
_In_ HDEVNOTIFY Handle
);
#if (_WIN32_WINNT >= 0x0502)
#if !defined(_HPOWERNOTIFY_DEF_)
#define _HPOWERNOTIFY_DEF_
typedef PVOID HPOWERNOTIFY;
typedef HPOWERNOTIFY *PHPOWERNOTIFY;
#endif
WINUSERAPI
HPOWERNOTIFY
WINAPI
RegisterPowerSettingNotification(
IN HANDLE hRecipient,
IN LPCGUID PowerSettingGuid,
IN DWORD Flags
);
WINUSERAPI
BOOL
WINAPI
UnregisterPowerSettingNotification(
IN HPOWERNOTIFY Handle
);
WINUSERAPI
HPOWERNOTIFY
WINAPI
RegisterSuspendResumeNotification (
IN HANDLE hRecipient,
IN DWORD Flags
);
WINUSERAPI
BOOL
WINAPI
UnregisterSuspendResumeNotification (
IN HPOWERNOTIFY Handle
);
#endif // (_WIN32_WINNT >= 0x0502)
#endif /* WINVER >= 0x0500 */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
PostMessageA(
_In_opt_ HWND hWnd,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam);
WINUSERAPI
BOOL
WINAPI
PostMessageW(
_In_opt_ HWND hWnd,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam);
#ifdef UNICODE
#define PostMessage PostMessageW
#else
#define PostMessage PostMessageA
#endif // !UNICODE
WINUSERAPI
BOOL
WINAPI
PostThreadMessageA(
_In_ DWORD idThread,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam);
WINUSERAPI
BOOL
WINAPI
PostThreadMessageW(
_In_ DWORD idThread,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam);
#ifdef UNICODE
#define PostThreadMessage PostThreadMessageW
#else
#define PostThreadMessage PostThreadMessageA
#endif // !UNICODE
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#define PostAppMessageA(idThread, wMsg, wParam, lParam)\
PostThreadMessageA((DWORD)idThread, wMsg, wParam, lParam)
#define PostAppMessageW(idThread, wMsg, wParam, lParam)\
PostThreadMessageW((DWORD)idThread, wMsg, wParam, lParam)
#ifdef UNICODE
#define PostAppMessage PostAppMessageW
#else
#define PostAppMessage PostAppMessageA
#endif // !UNICODE
/*
* Special HWND value for use with PostMessage() and SendMessage()
*/
#define HWND_BROADCAST ((HWND)0xffff)
#if(WINVER >= 0x0500)
#define HWND_MESSAGE ((HWND)-3)
#endif /* WINVER >= 0x0500 */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
AttachThreadInput(
_In_ DWORD idAttach,
_In_ DWORD idAttachTo,
_In_ BOOL fAttach);
WINUSERAPI
BOOL
WINAPI
ReplyMessage(
_In_ LRESULT lResult);
WINUSERAPI
BOOL
WINAPI
WaitMessage(
VOID);
#if (_WIN32_WINNT >= 0x602)
#endif
WINUSERAPI
DWORD
WINAPI
WaitForInputIdle(
_In_ HANDLE hProcess,
_In_ DWORD dwMilliseconds);
WINUSERAPI
#ifndef _MAC
LRESULT
WINAPI
#else
LRESULT
CALLBACK
#endif
DefWindowProcA(
_In_ HWND hWnd,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam);
WINUSERAPI
#ifndef _MAC
LRESULT
WINAPI
#else
LRESULT
CALLBACK
#endif
DefWindowProcW(
_In_ HWND hWnd,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam);
#ifdef UNICODE
#define DefWindowProc DefWindowProcW
#else
#define DefWindowProc DefWindowProcA
#endif // !UNICODE
WINUSERAPI
VOID
WINAPI
PostQuitMessage(
_In_ int nExitCode);
#ifdef STRICT
WINUSERAPI
LRESULT
WINAPI
CallWindowProcA(
_In_ WNDPROC lpPrevWndFunc,
_In_ HWND hWnd,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam);
WINUSERAPI
LRESULT
WINAPI
CallWindowProcW(
_In_ WNDPROC lpPrevWndFunc,
_In_ HWND hWnd,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam);
#ifdef UNICODE
#define CallWindowProc CallWindowProcW
#else
#define CallWindowProc CallWindowProcA
#endif // !UNICODE
#else /* !STRICT */
WINUSERAPI
LRESULT
WINAPI
CallWindowProcA(
_In_ FARPROC lpPrevWndFunc,
_In_ HWND hWnd,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam);
WINUSERAPI
LRESULT
WINAPI
CallWindowProcW(
_In_ FARPROC lpPrevWndFunc,
_In_ HWND hWnd,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam);
#ifdef UNICODE
#define CallWindowProc CallWindowProcW
#else
#define CallWindowProc CallWindowProcA
#endif // !UNICODE
#endif /* !STRICT */
WINUSERAPI
BOOL
WINAPI
InSendMessage(
VOID);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#if(WINVER >= 0x0500)
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
DWORD
WINAPI
InSendMessageEx(
_Reserved_ LPVOID lpReserved);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* InSendMessageEx return value
*/
#define ISMEX_NOSEND 0x00000000
#define ISMEX_SEND 0x00000001
#define ISMEX_NOTIFY 0x00000002
#define ISMEX_CALLBACK 0x00000004
#define ISMEX_REPLIED 0x00000008
#endif /* WINVER >= 0x0500 */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
UINT
WINAPI
GetDoubleClickTime(
VOID);
WINUSERAPI
BOOL
WINAPI
SetDoubleClickTime(
_In_ UINT);
WINUSERAPI
ATOM
WINAPI
RegisterClassA(
_In_ CONST WNDCLASSA *lpWndClass);
WINUSERAPI
ATOM
WINAPI
RegisterClassW(
_In_ CONST WNDCLASSW *lpWndClass);
#ifdef UNICODE
#define RegisterClass RegisterClassW
#else
#define RegisterClass RegisterClassA
#endif // !UNICODE
WINUSERAPI
BOOL
WINAPI
UnregisterClassA(
_In_ LPCSTR lpClassName,
_In_opt_ HINSTANCE hInstance);
WINUSERAPI
BOOL
WINAPI
UnregisterClassW(
_In_ LPCWSTR lpClassName,
_In_opt_ HINSTANCE hInstance);
#ifdef UNICODE
#define UnregisterClass UnregisterClassW
#else
#define UnregisterClass UnregisterClassA
#endif // !UNICODE
_Success_(return)
WINUSERAPI
BOOL
WINAPI
GetClassInfoA(
_In_opt_ HINSTANCE hInstance,
_In_ LPCSTR lpClassName,
_Out_ LPWNDCLASSA lpWndClass);
_Success_(return)
WINUSERAPI
BOOL
WINAPI
GetClassInfoW(
_In_opt_ HINSTANCE hInstance,
_In_ LPCWSTR lpClassName,
_Out_ LPWNDCLASSW lpWndClass);
#ifdef UNICODE
#define GetClassInfo GetClassInfoW
#else
#define GetClassInfo GetClassInfoA
#endif // !UNICODE
#if(WINVER >= 0x0400)
WINUSERAPI
ATOM
WINAPI
RegisterClassExA(
_In_ CONST WNDCLASSEXA *);
WINUSERAPI
ATOM
WINAPI
RegisterClassExW(
_In_ CONST WNDCLASSEXW *);
#ifdef UNICODE
#define RegisterClassEx RegisterClassExW
#else
#define RegisterClassEx RegisterClassExA
#endif // !UNICODE
_Success_(return)
WINUSERAPI
BOOL
WINAPI
GetClassInfoExA(
_In_opt_ HINSTANCE hInstance,
_In_ LPCSTR lpszClass,
_Out_ LPWNDCLASSEXA lpwcx);
_Success_(return)
WINUSERAPI
BOOL
WINAPI
GetClassInfoExW(
_In_opt_ HINSTANCE hInstance,
_In_ LPCWSTR lpszClass,
_Out_ LPWNDCLASSEXW lpwcx);
#ifdef UNICODE
#define GetClassInfoEx GetClassInfoExW
#else
#define GetClassInfoEx GetClassInfoExA
#endif // !UNICODE
#endif /* WINVER >= 0x0400 */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#define CW_USEDEFAULT ((int)0x80000000)
/*
* Special value for CreateWindow, et al.
*/
#define HWND_DESKTOP ((HWND)0)
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#if(_WIN32_WINNT >= 0x0501)
typedef BOOLEAN (WINAPI * PREGISTERCLASSNAMEW)(LPCWSTR);
#endif /* _WIN32_WINNT >= 0x0501 */
WINUSERAPI
HWND
WINAPI
CreateWindowExA(
_In_ DWORD dwExStyle,
_In_opt_ LPCSTR lpClassName,
_In_opt_ LPCSTR lpWindowName,
_In_ DWORD dwStyle,
_In_ int X,
_In_ int Y,
_In_ int nWidth,
_In_ int nHeight,
_In_opt_ HWND hWndParent,
_In_opt_ HMENU hMenu,
_In_opt_ HINSTANCE hInstance,
_In_opt_ LPVOID lpParam);
WINUSERAPI
HWND
WINAPI
CreateWindowExW(
_In_ DWORD dwExStyle,
_In_opt_ LPCWSTR lpClassName,
_In_opt_ LPCWSTR lpWindowName,
_In_ DWORD dwStyle,
_In_ int X,
_In_ int Y,
_In_ int nWidth,
_In_ int nHeight,
_In_opt_ HWND hWndParent,
_In_opt_ HMENU hMenu,
_In_opt_ HINSTANCE hInstance,
_In_opt_ LPVOID lpParam);
#ifdef UNICODE
#define CreateWindowEx CreateWindowExW
#else
#define CreateWindowEx CreateWindowExA
#endif // !UNICODE
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#define CreateWindowA(lpClassName, lpWindowName, dwStyle, x, y,\
nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam)\
CreateWindowExA(0L, lpClassName, lpWindowName, dwStyle, x, y,\
nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam)
#define CreateWindowW(lpClassName, lpWindowName, dwStyle, x, y,\
nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam)\
CreateWindowExW(0L, lpClassName, lpWindowName, dwStyle, x, y,\
nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam)
#ifdef UNICODE
#define CreateWindow CreateWindowW
#else
#define CreateWindow CreateWindowA
#endif // !UNICODE
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
IsWindow(
_In_opt_ HWND hWnd);
WINUSERAPI
BOOL
WINAPI
IsMenu(
_In_ HMENU hMenu);
WINUSERAPI
BOOL
WINAPI
IsChild(
_In_ HWND hWndParent,
_In_ HWND hWnd);
WINUSERAPI
BOOL
WINAPI
DestroyWindow(
_In_ HWND hWnd);
WINUSERAPI
BOOL
WINAPI
ShowWindow(
_In_ HWND hWnd,
_In_ int nCmdShow);
#if(WINVER >= 0x0500)
WINUSERAPI
BOOL
WINAPI
AnimateWindow(
_In_ HWND hWnd,
_In_ DWORD dwTime,
_In_ DWORD dwFlags);
#endif /* WINVER >= 0x0500 */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#if(_WIN32_WINNT >= 0x0500)
#if defined(_WINGDI_) && !defined(NOGDI)
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
UpdateLayeredWindow(
_In_ HWND hWnd,
_In_opt_ HDC hdcDst,
_In_opt_ POINT* pptDst,
_In_opt_ SIZE* psize,
_In_opt_ HDC hdcSrc,
_In_opt_ POINT* pptSrc,
_In_ COLORREF crKey,
_In_opt_ BLENDFUNCTION* pblend,
_In_ DWORD dwFlags);
/*
* Layered Window Update information
*/
typedef struct tagUPDATELAYEREDWINDOWINFO
{
DWORD cbSize;
HDC hdcDst;
const POINT* pptDst;
const SIZE* psize;
HDC hdcSrc;
const POINT* pptSrc;
COLORREF crKey;
const BLENDFUNCTION* pblend;
DWORD dwFlags;
const RECT* prcDirty;
} UPDATELAYEREDWINDOWINFO, *PUPDATELAYEREDWINDOWINFO;
#if (_WIN32_WINNT < 0x0502)
typedef
#endif /* _WIN32_WINNT < 0x0502 */
WINUSERAPI
BOOL
WINAPI
UpdateLayeredWindowIndirect(
_In_ HWND hWnd,
_In_ const UPDATELAYEREDWINDOWINFO* pULWInfo);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif
#if(_WIN32_WINNT >= 0x0501)
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
GetLayeredWindowAttributes(
_In_ HWND hwnd,
_Out_opt_ COLORREF* pcrKey,
_Out_opt_ BYTE* pbAlpha,
_Out_opt_ DWORD* pdwFlags);
#define PW_CLIENTONLY 0x00000001
#if(_WIN32_WINNT >= 0x0603)
#define PW_RENDERFULLCONTENT 0x00000002
#endif /* _WIN32_WINNT >= 0x0603 */
WINUSERAPI
BOOL
WINAPI
PrintWindow(
_In_ HWND hwnd,
_In_ HDC hdcBlt,
_In_ UINT nFlags);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* _WIN32_WINNT >= 0x0501 */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
SetLayeredWindowAttributes(
_In_ HWND hwnd,
_In_ COLORREF crKey,
_In_ BYTE bAlpha,
_In_ DWORD dwFlags);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#define LWA_COLORKEY 0x00000001
#define LWA_ALPHA 0x00000002
#define ULW_COLORKEY 0x00000001
#define ULW_ALPHA 0x00000002
#define ULW_OPAQUE 0x00000004
#define ULW_EX_NORESIZE 0x00000008
#endif /* _WIN32_WINNT >= 0x0500 */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#if(WINVER >= 0x0400)
WINUSERAPI
BOOL
WINAPI
ShowWindowAsync(
_In_ HWND hWnd,
_In_ int nCmdShow);
#endif /* WINVER >= 0x0400 */
WINUSERAPI
BOOL
WINAPI
FlashWindow(
_In_ HWND hWnd,
_In_ BOOL bInvert);
#if(WINVER >= 0x0500)
typedef struct {
UINT cbSize;
HWND hwnd;
DWORD dwFlags;
UINT uCount;
DWORD dwTimeout;
} FLASHWINFO, *PFLASHWINFO;
WINUSERAPI
BOOL
WINAPI
FlashWindowEx(
_In_ PFLASHWINFO pfwi);
#define FLASHW_STOP 0
#define FLASHW_CAPTION 0x00000001
#define FLASHW_TRAY 0x00000002
#define FLASHW_ALL (FLASHW_CAPTION | FLASHW_TRAY)
#define FLASHW_TIMER 0x00000004
#define FLASHW_TIMERNOFG 0x0000000C
#endif /* WINVER >= 0x0500 */
WINUSERAPI
BOOL
WINAPI
ShowOwnedPopups(
_In_ HWND hWnd,
_In_ BOOL fShow);
WINUSERAPI
BOOL
WINAPI
OpenIcon(
_In_ HWND hWnd);
WINUSERAPI
BOOL
WINAPI
CloseWindow(
_In_ HWND hWnd);
WINUSERAPI
BOOL
WINAPI
MoveWindow(
_In_ HWND hWnd,
_In_ int X,
_In_ int Y,
_In_ int nWidth,
_In_ int nHeight,
_In_ BOOL bRepaint);
WINUSERAPI
BOOL
WINAPI
SetWindowPos(
_In_ HWND hWnd,
_In_opt_ HWND hWndInsertAfter,
_In_ int X,
_In_ int Y,
_In_ int cx,
_In_ int cy,
_In_ UINT uFlags);
WINUSERAPI
BOOL
WINAPI
GetWindowPlacement(
_In_ HWND hWnd,
_Inout_ WINDOWPLACEMENT *lpwndpl);
WINUSERAPI
BOOL
WINAPI
SetWindowPlacement(
_In_ HWND hWnd,
_In_ CONST WINDOWPLACEMENT *lpwndpl);
#if(_WIN32_WINNT >= 0x0601)
#define WDA_NONE 0x00000000
#define WDA_MONITOR 0x00000001
WINUSERAPI
BOOL
WINAPI
GetWindowDisplayAffinity(
_In_ HWND hWnd,
_Out_ DWORD* pdwAffinity);
WINUSERAPI
BOOL
WINAPI
SetWindowDisplayAffinity(
_In_ HWND hWnd,
_In_ DWORD dwAffinity);
#endif /* _WIN32_WINNT >= 0x0601 */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#ifndef NODEFERWINDOWPOS
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
HDWP
WINAPI
BeginDeferWindowPos(
_In_ int nNumWindows);
WINUSERAPI
HDWP
WINAPI
DeferWindowPos(
_In_ HDWP hWinPosInfo,
_In_ HWND hWnd,
_In_opt_ HWND hWndInsertAfter,
_In_ int x,
_In_ int y,
_In_ int cx,
_In_ int cy,
_In_ UINT uFlags);
WINUSERAPI
BOOL
WINAPI
EndDeferWindowPos(
_In_ HDWP hWinPosInfo);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* !NODEFERWINDOWPOS */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
IsWindowVisible(
_In_ HWND hWnd);
WINUSERAPI
BOOL
WINAPI
IsIconic(
_In_ HWND hWnd);
WINUSERAPI
BOOL
WINAPI
AnyPopup(
VOID);
WINUSERAPI
BOOL
WINAPI
BringWindowToTop(
_In_ HWND hWnd);
WINUSERAPI
BOOL
WINAPI
IsZoomed(
_In_ HWND hWnd);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* SetWindowPos Flags
*/
#define SWP_NOSIZE 0x0001
#define SWP_NOMOVE 0x0002
#define SWP_NOZORDER 0x0004
#define SWP_NOREDRAW 0x0008
#define SWP_NOACTIVATE 0x0010
#define SWP_FRAMECHANGED 0x0020 /* The frame changed: send WM_NCCALCSIZE */
#define SWP_SHOWWINDOW 0x0040
#define SWP_HIDEWINDOW 0x0080
#define SWP_NOCOPYBITS 0x0100
#define SWP_NOOWNERZORDER 0x0200 /* Don't do owner Z ordering */
#define SWP_NOSENDCHANGING 0x0400 /* Don't send WM_WINDOWPOSCHANGING */
#define SWP_DRAWFRAME SWP_FRAMECHANGED
#define SWP_NOREPOSITION SWP_NOOWNERZORDER
#if(WINVER >= 0x0400)
#define SWP_DEFERERASE 0x2000
#define SWP_ASYNCWINDOWPOS 0x4000
#endif /* WINVER >= 0x0400 */
#define HWND_TOP ((HWND)0)
#define HWND_BOTTOM ((HWND)1)
#define HWND_TOPMOST ((HWND)-1)
#define HWND_NOTOPMOST ((HWND)-2)
#ifndef NOCTLMGR
/*
* WARNING:
* The following structures must NOT be DWORD padded because they are
* followed by strings, etc that do not have to be DWORD aligned.
*/
#include <pshpack2.h>
#pragma region Application Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
/*
* original NT 32 bit dialog template:
*/
typedef struct {
DWORD style;
DWORD dwExtendedStyle;
WORD cdit;
short x;
short y;
short cx;
short cy;
} DLGTEMPLATE;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) */
#pragma endregion
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef DLGTEMPLATE *LPDLGTEMPLATEA;
typedef DLGTEMPLATE *LPDLGTEMPLATEW;
#ifdef UNICODE
typedef LPDLGTEMPLATEW LPDLGTEMPLATE;
#else
typedef LPDLGTEMPLATEA LPDLGTEMPLATE;
#endif // UNICODE
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#pragma region Application Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
typedef CONST DLGTEMPLATE *LPCDLGTEMPLATEA;
typedef CONST DLGTEMPLATE *LPCDLGTEMPLATEW;
#ifdef UNICODE
typedef LPCDLGTEMPLATEW LPCDLGTEMPLATE;
#else
typedef LPCDLGTEMPLATEA LPCDLGTEMPLATE;
#endif // UNICODE
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) */
#pragma endregion
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
/*
* 32 bit Dialog item template.
*/
typedef struct {
DWORD style;
DWORD dwExtendedStyle;
short x;
short y;
short cx;
short cy;
WORD id;
} DLGITEMTEMPLATE;
typedef DLGITEMTEMPLATE *PDLGITEMTEMPLATEA;
typedef DLGITEMTEMPLATE *PDLGITEMTEMPLATEW;
#ifdef UNICODE
typedef PDLGITEMTEMPLATEW PDLGITEMTEMPLATE;
#else
typedef PDLGITEMTEMPLATEA PDLGITEMTEMPLATE;
#endif // UNICODE
typedef DLGITEMTEMPLATE *LPDLGITEMTEMPLATEA;
typedef DLGITEMTEMPLATE *LPDLGITEMTEMPLATEW;
#ifdef UNICODE
typedef LPDLGITEMTEMPLATEW LPDLGITEMTEMPLATE;
#else
typedef LPDLGITEMTEMPLATEA LPDLGITEMTEMPLATE;
#endif // UNICODE
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#include <poppack.h> /* Resume normal packing */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
HWND
WINAPI
CreateDialogParamA(
_In_opt_ HINSTANCE hInstance,
_In_ LPCSTR lpTemplateName,
_In_opt_ HWND hWndParent,
_In_opt_ DLGPROC lpDialogFunc,
_In_ LPARAM dwInitParam);
WINUSERAPI
HWND
WINAPI
CreateDialogParamW(
_In_opt_ HINSTANCE hInstance,
_In_ LPCWSTR lpTemplateName,
_In_opt_ HWND hWndParent,
_In_opt_ DLGPROC lpDialogFunc,
_In_ LPARAM dwInitParam);
#ifdef UNICODE
#define CreateDialogParam CreateDialogParamW
#else
#define CreateDialogParam CreateDialogParamA
#endif // !UNICODE
WINUSERAPI
HWND
WINAPI
CreateDialogIndirectParamA(
_In_opt_ HINSTANCE hInstance,
_In_ LPCDLGTEMPLATEA lpTemplate,
_In_opt_ HWND hWndParent,
_In_opt_ DLGPROC lpDialogFunc,
_In_ LPARAM dwInitParam);
WINUSERAPI
HWND
WINAPI
CreateDialogIndirectParamW(
_In_opt_ HINSTANCE hInstance,
_In_ LPCDLGTEMPLATEW lpTemplate,
_In_opt_ HWND hWndParent,
_In_opt_ DLGPROC lpDialogFunc,
_In_ LPARAM dwInitParam);
#ifdef UNICODE
#define CreateDialogIndirectParam CreateDialogIndirectParamW
#else
#define CreateDialogIndirectParam CreateDialogIndirectParamA
#endif // !UNICODE
#define CreateDialogA(hInstance, lpName, hWndParent, lpDialogFunc) \
CreateDialogParamA(hInstance, lpName, hWndParent, lpDialogFunc, 0L)
#define CreateDialogW(hInstance, lpName, hWndParent, lpDialogFunc) \
CreateDialogParamW(hInstance, lpName, hWndParent, lpDialogFunc, 0L)
#ifdef UNICODE
#define CreateDialog CreateDialogW
#else
#define CreateDialog CreateDialogA
#endif // !UNICODE
#define CreateDialogIndirectA(hInstance, lpTemplate, hWndParent, lpDialogFunc) \
CreateDialogIndirectParamA(hInstance, lpTemplate, hWndParent, lpDialogFunc, 0L)
#define CreateDialogIndirectW(hInstance, lpTemplate, hWndParent, lpDialogFunc) \
CreateDialogIndirectParamW(hInstance, lpTemplate, hWndParent, lpDialogFunc, 0L)
#ifdef UNICODE
#define CreateDialogIndirect CreateDialogIndirectW
#else
#define CreateDialogIndirect CreateDialogIndirectA
#endif // !UNICODE
WINUSERAPI
INT_PTR
WINAPI
DialogBoxParamA(
_In_opt_ HINSTANCE hInstance,
_In_ LPCSTR lpTemplateName,
_In_opt_ HWND hWndParent,
_In_opt_ DLGPROC lpDialogFunc,
_In_ LPARAM dwInitParam);
WINUSERAPI
INT_PTR
WINAPI
DialogBoxParamW(
_In_opt_ HINSTANCE hInstance,
_In_ LPCWSTR lpTemplateName,
_In_opt_ HWND hWndParent,
_In_opt_ DLGPROC lpDialogFunc,
_In_ LPARAM dwInitParam);
#ifdef UNICODE
#define DialogBoxParam DialogBoxParamW
#else
#define DialogBoxParam DialogBoxParamA
#endif // !UNICODE
WINUSERAPI
INT_PTR
WINAPI
DialogBoxIndirectParamA(
_In_opt_ HINSTANCE hInstance,
_In_ LPCDLGTEMPLATEA hDialogTemplate,
_In_opt_ HWND hWndParent,
_In_opt_ DLGPROC lpDialogFunc,
_In_ LPARAM dwInitParam);
WINUSERAPI
INT_PTR
WINAPI
DialogBoxIndirectParamW(
_In_opt_ HINSTANCE hInstance,
_In_ LPCDLGTEMPLATEW hDialogTemplate,
_In_opt_ HWND hWndParent,
_In_opt_ DLGPROC lpDialogFunc,
_In_ LPARAM dwInitParam);
#ifdef UNICODE
#define DialogBoxIndirectParam DialogBoxIndirectParamW
#else
#define DialogBoxIndirectParam DialogBoxIndirectParamA
#endif // !UNICODE
#define DialogBoxA(hInstance, lpTemplate, hWndParent, lpDialogFunc) \
DialogBoxParamA(hInstance, lpTemplate, hWndParent, lpDialogFunc, 0L)
#define DialogBoxW(hInstance, lpTemplate, hWndParent, lpDialogFunc) \
DialogBoxParamW(hInstance, lpTemplate, hWndParent, lpDialogFunc, 0L)
#ifdef UNICODE
#define DialogBox DialogBoxW
#else
#define DialogBox DialogBoxA
#endif // !UNICODE
#define DialogBoxIndirectA(hInstance, lpTemplate, hWndParent, lpDialogFunc) \
DialogBoxIndirectParamA(hInstance, lpTemplate, hWndParent, lpDialogFunc, 0L)
#define DialogBoxIndirectW(hInstance, lpTemplate, hWndParent, lpDialogFunc) \
DialogBoxIndirectParamW(hInstance, lpTemplate, hWndParent, lpDialogFunc, 0L)
#ifdef UNICODE
#define DialogBoxIndirect DialogBoxIndirectW
#else
#define DialogBoxIndirect DialogBoxIndirectA
#endif // !UNICODE
WINUSERAPI
BOOL
WINAPI
EndDialog(
_In_ HWND hDlg,
_In_ INT_PTR nResult);
WINUSERAPI
HWND
WINAPI
GetDlgItem(
_In_opt_ HWND hDlg,
_In_ int nIDDlgItem);
WINUSERAPI
BOOL
WINAPI
SetDlgItemInt(
_In_ HWND hDlg,
_In_ int nIDDlgItem,
_In_ UINT uValue,
_In_ BOOL bSigned);
WINUSERAPI
UINT
WINAPI
GetDlgItemInt(
_In_ HWND hDlg,
_In_ int nIDDlgItem,
_Out_opt_ BOOL *lpTranslated,
_In_ BOOL bSigned);
WINUSERAPI
BOOL
WINAPI
SetDlgItemTextA(
_In_ HWND hDlg,
_In_ int nIDDlgItem,
_In_ LPCSTR lpString);
WINUSERAPI
BOOL
WINAPI
SetDlgItemTextW(
_In_ HWND hDlg,
_In_ int nIDDlgItem,
_In_ LPCWSTR lpString);
#ifdef UNICODE
#define SetDlgItemText SetDlgItemTextW
#else
#define SetDlgItemText SetDlgItemTextA
#endif // !UNICODE
_Ret_range_(0, cchMax)
WINUSERAPI
UINT
WINAPI
GetDlgItemTextA(
_In_ HWND hDlg,
_In_ int nIDDlgItem,
_Out_writes_(cchMax) LPSTR lpString,
_In_ int cchMax);
_Ret_range_(0, cchMax)
WINUSERAPI
UINT
WINAPI
GetDlgItemTextW(
_In_ HWND hDlg,
_In_ int nIDDlgItem,
_Out_writes_(cchMax) LPWSTR lpString,
_In_ int cchMax);
#ifdef UNICODE
#define GetDlgItemText GetDlgItemTextW
#else
#define GetDlgItemText GetDlgItemTextA
#endif // !UNICODE
WINUSERAPI
BOOL
WINAPI
CheckDlgButton(
_In_ HWND hDlg,
_In_ int nIDButton,
_In_ UINT uCheck);
WINUSERAPI
BOOL
WINAPI
CheckRadioButton(
_In_ HWND hDlg,
_In_ int nIDFirstButton,
_In_ int nIDLastButton,
_In_ int nIDCheckButton);
WINUSERAPI
UINT
WINAPI
IsDlgButtonChecked(
_In_ HWND hDlg,
_In_ int nIDButton);
WINUSERAPI
LRESULT
WINAPI
SendDlgItemMessageA(
_In_ HWND hDlg,
_In_ int nIDDlgItem,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam);
WINUSERAPI
LRESULT
WINAPI
SendDlgItemMessageW(
_In_ HWND hDlg,
_In_ int nIDDlgItem,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam);
#ifdef UNICODE
#define SendDlgItemMessage SendDlgItemMessageW
#else
#define SendDlgItemMessage SendDlgItemMessageA
#endif // !UNICODE
WINUSERAPI
HWND
WINAPI
GetNextDlgGroupItem(
_In_ HWND hDlg,
_In_opt_ HWND hCtl,
_In_ BOOL bPrevious);
WINUSERAPI
HWND
WINAPI
GetNextDlgTabItem(
_In_ HWND hDlg,
_In_opt_ HWND hCtl,
_In_ BOOL bPrevious);
WINUSERAPI
int
WINAPI
GetDlgCtrlID(
_In_ HWND hWnd);
WINUSERAPI
long
WINAPI
GetDialogBaseUnits(VOID);
WINUSERAPI
#ifndef _MAC
LRESULT
WINAPI
#else
LRESULT
CALLBACK
#endif
DefDlgProcA(
_In_ HWND hDlg,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam);
WINUSERAPI
#ifndef _MAC
LRESULT
WINAPI
#else
LRESULT
CALLBACK
#endif
DefDlgProcW(
_In_ HWND hDlg,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam);
#ifdef UNICODE
#define DefDlgProc DefDlgProcW
#else
#define DefDlgProc DefDlgProcA
#endif // !UNICODE
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* Window extra byted needed for private dialog classes.
*/
#ifndef _MAC
#define DLGWINDOWEXTRA 30
#else
#define DLGWINDOWEXTRA 48
#endif
#endif /* !NOCTLMGR */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#ifndef NOMSG
WINUSERAPI
BOOL
WINAPI
CallMsgFilterA(
_In_ LPMSG lpMsg,
_In_ int nCode);
WINUSERAPI
BOOL
WINAPI
CallMsgFilterW(
_In_ LPMSG lpMsg,
_In_ int nCode);
#ifdef UNICODE
#define CallMsgFilter CallMsgFilterW
#else
#define CallMsgFilter CallMsgFilterA
#endif // !UNICODE
#endif /* !NOMSG */
#ifndef NOCLIPBOARD
/*
* Clipboard Manager Functions
*/
WINUSERAPI
BOOL
WINAPI
OpenClipboard(
_In_opt_ HWND hWndNewOwner);
WINUSERAPI
BOOL
WINAPI
CloseClipboard(
VOID);
#if(WINVER >= 0x0500)
WINUSERAPI
DWORD
WINAPI
GetClipboardSequenceNumber(
VOID);
#endif /* WINVER >= 0x0500 */
WINUSERAPI
HWND
WINAPI
GetClipboardOwner(
VOID);
WINUSERAPI
HWND
WINAPI
SetClipboardViewer(
_In_ HWND hWndNewViewer);
WINUSERAPI
HWND
WINAPI
GetClipboardViewer(
VOID);
WINUSERAPI
BOOL
WINAPI
ChangeClipboardChain(
_In_ HWND hWndRemove,
_In_ HWND hWndNewNext);
WINUSERAPI
HANDLE
WINAPI
SetClipboardData(
_In_ UINT uFormat,
_In_opt_ HANDLE hMem);
WINUSERAPI
HANDLE
WINAPI
GetClipboardData(
_In_ UINT uFormat);
WINUSERAPI
UINT
WINAPI
RegisterClipboardFormatA(
_In_ LPCSTR lpszFormat);
WINUSERAPI
UINT
WINAPI
RegisterClipboardFormatW(
_In_ LPCWSTR lpszFormat);
#ifdef UNICODE
#define RegisterClipboardFormat RegisterClipboardFormatW
#else
#define RegisterClipboardFormat RegisterClipboardFormatA
#endif // !UNICODE
WINUSERAPI
int
WINAPI
CountClipboardFormats(
VOID);
WINUSERAPI
UINT
WINAPI
EnumClipboardFormats(
_In_ UINT format);
WINUSERAPI
int
WINAPI
GetClipboardFormatNameA(
_In_ UINT format,
_Out_writes_(cchMaxCount) LPSTR lpszFormatName,
_In_ int cchMaxCount);
WINUSERAPI
int
WINAPI
GetClipboardFormatNameW(
_In_ UINT format,
_Out_writes_(cchMaxCount) LPWSTR lpszFormatName,
_In_ int cchMaxCount);
#ifdef UNICODE
#define GetClipboardFormatName GetClipboardFormatNameW
#else
#define GetClipboardFormatName GetClipboardFormatNameA
#endif // !UNICODE
WINUSERAPI
BOOL
WINAPI
EmptyClipboard(
VOID);
WINUSERAPI
BOOL
WINAPI
IsClipboardFormatAvailable(
_In_ UINT format);
WINUSERAPI
int
WINAPI
GetPriorityClipboardFormat(
_In_reads_(cFormats) UINT *paFormatPriorityList,
_In_ int cFormats);
WINUSERAPI
HWND
WINAPI
GetOpenClipboardWindow(
VOID);
#if(WINVER >= 0x0600)
WINUSERAPI
BOOL
WINAPI
AddClipboardFormatListener(
_In_ HWND hwnd);
WINUSERAPI
BOOL
WINAPI
RemoveClipboardFormatListener(
_In_ HWND hwnd);
WINUSERAPI
BOOL
WINAPI
GetUpdatedClipboardFormats(
_Out_writes_(cFormats) PUINT lpuiFormats,
_In_ UINT cFormats,
_Out_ PUINT pcFormatsOut);
#endif /* WINVER >= 0x0600 */
#endif /* !NOCLIPBOARD */
/*
* Character Translation Routines
*/
WINUSERAPI
BOOL
WINAPI
CharToOemA(
_In_ LPCSTR pSrc,
_Out_writes_(_Inexpressible_(strlen(pSrc) + 1)) LPSTR pDst);
WINUSERAPI
BOOL
WINAPI
CharToOemW(
_In_ LPCWSTR pSrc,
_Out_writes_(_Inexpressible_(strlen(pSrc) + 1)) LPSTR pDst);
#ifdef UNICODE
#define CharToOem CharToOemW
#else
#define CharToOem CharToOemA
#endif // !UNICODE
__drv_preferredFunction("OemToCharBuff","Does not validate buffer size")
WINUSERAPI
BOOL
WINAPI
OemToCharA(
_In_ LPCSTR pSrc,
_Out_writes_(_Inexpressible_(strlen(pSrc) + 1)) LPSTR pDst);
__drv_preferredFunction("OemToCharBuff","Does not validate buffer size")
WINUSERAPI
BOOL
WINAPI
OemToCharW(
_In_ LPCSTR pSrc,
_Out_writes_(_Inexpressible_(strlen(pSrc) + 1)) LPWSTR pDst);
#ifdef UNICODE
#define OemToChar OemToCharW
#else
#define OemToChar OemToCharA
#endif // !UNICODE
WINUSERAPI
BOOL
WINAPI
CharToOemBuffA(
_In_ LPCSTR lpszSrc,
_Out_writes_(cchDstLength) LPSTR lpszDst,
_In_ DWORD cchDstLength);
WINUSERAPI
BOOL
WINAPI
CharToOemBuffW(
_In_ LPCWSTR lpszSrc,
_Out_writes_(cchDstLength) LPSTR lpszDst,
_In_ DWORD cchDstLength);
#ifdef UNICODE
#define CharToOemBuff CharToOemBuffW
#else
#define CharToOemBuff CharToOemBuffA
#endif // !UNICODE
WINUSERAPI
BOOL
WINAPI
OemToCharBuffA(
_In_ LPCSTR lpszSrc,
_Out_writes_(cchDstLength) LPSTR lpszDst,
_In_ DWORD cchDstLength);
WINUSERAPI
BOOL
WINAPI
OemToCharBuffW(
_In_ LPCSTR lpszSrc,
_Out_writes_(cchDstLength) LPWSTR lpszDst,
_In_ DWORD cchDstLength);
#ifdef UNICODE
#define OemToCharBuff OemToCharBuffW
#else
#define OemToCharBuff OemToCharBuffA
#endif // !UNICODE
WINUSERAPI
LPSTR
WINAPI
CharUpperA(
_Inout_ LPSTR lpsz);
WINUSERAPI
LPWSTR
WINAPI
CharUpperW(
_Inout_ LPWSTR lpsz);
#ifdef UNICODE
#define CharUpper CharUpperW
#else
#define CharUpper CharUpperA
#endif // !UNICODE
WINUSERAPI
DWORD
WINAPI
CharUpperBuffA(
_Inout_updates_(cchLength) LPSTR lpsz,
_In_ DWORD cchLength);
WINUSERAPI
DWORD
WINAPI
CharUpperBuffW(
_Inout_updates_(cchLength) LPWSTR lpsz,
_In_ DWORD cchLength);
#ifdef UNICODE
#define CharUpperBuff CharUpperBuffW
#else
#define CharUpperBuff CharUpperBuffA
#endif // !UNICODE
WINUSERAPI
LPSTR
WINAPI
CharLowerA(
_Inout_ LPSTR lpsz);
WINUSERAPI
LPWSTR
WINAPI
CharLowerW(
_Inout_ LPWSTR lpsz);
#ifdef UNICODE
#define CharLower CharLowerW
#else
#define CharLower CharLowerA
#endif // !UNICODE
WINUSERAPI
DWORD
WINAPI
CharLowerBuffA(
_Inout_updates_(cchLength) LPSTR lpsz,
_In_ DWORD cchLength);
WINUSERAPI
DWORD
WINAPI
CharLowerBuffW(
_Inout_updates_(cchLength) LPWSTR lpsz,
_In_ DWORD cchLength);
#ifdef UNICODE
#define CharLowerBuff CharLowerBuffW
#else
#define CharLowerBuff CharLowerBuffA
#endif // !UNICODE
WINUSERAPI
LPSTR
WINAPI
CharNextA(
_In_ LPCSTR lpsz);
WINUSERAPI
LPWSTR
WINAPI
CharNextW(
_In_ LPCWSTR lpsz);
#ifdef UNICODE
#define CharNext CharNextW
#else
#define CharNext CharNextA
#endif // !UNICODE
WINUSERAPI
LPSTR
WINAPI
CharPrevA(
_In_ LPCSTR lpszStart,
_In_ LPCSTR lpszCurrent);
WINUSERAPI
LPWSTR
WINAPI
CharPrevW(
_In_ LPCWSTR lpszStart,
_In_ LPCWSTR lpszCurrent);
#ifdef UNICODE
#define CharPrev CharPrevW
#else
#define CharPrev CharPrevA
#endif // !UNICODE
#if(WINVER >= 0x0400)
WINUSERAPI
LPSTR
WINAPI
CharNextExA(
_In_ WORD CodePage,
_In_ LPCSTR lpCurrentChar,
_In_ DWORD dwFlags);
WINUSERAPI
LPSTR
WINAPI
CharPrevExA(
_In_ WORD CodePage,
_In_ LPCSTR lpStart,
_In_ LPCSTR lpCurrentChar,
_In_ DWORD dwFlags);
#endif /* WINVER >= 0x0400 */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* Compatibility defines for character translation routines
*/
#define AnsiToOem CharToOemA
#define OemToAnsi OemToCharA
#define AnsiToOemBuff CharToOemBuffA
#define OemToAnsiBuff OemToCharBuffA
#define AnsiUpper CharUpperA
#define AnsiUpperBuff CharUpperBuffA
#define AnsiLower CharLowerA
#define AnsiLowerBuff CharLowerBuffA
#define AnsiNext CharNextA
#define AnsiPrev CharPrevA
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#ifndef NOLANGUAGE
/*
* Language dependent Routines
*/
WINUSERAPI
BOOL
WINAPI
IsCharAlphaA(
_In_ CHAR ch);
WINUSERAPI
BOOL
WINAPI
IsCharAlphaW(
_In_ WCHAR ch);
#ifdef UNICODE
#define IsCharAlpha IsCharAlphaW
#else
#define IsCharAlpha IsCharAlphaA
#endif // !UNICODE
WINUSERAPI
BOOL
WINAPI
IsCharAlphaNumericA(
_In_ CHAR ch);
WINUSERAPI
BOOL
WINAPI
IsCharAlphaNumericW(
_In_ WCHAR ch);
#ifdef UNICODE
#define IsCharAlphaNumeric IsCharAlphaNumericW
#else
#define IsCharAlphaNumeric IsCharAlphaNumericA
#endif // !UNICODE
WINUSERAPI
BOOL
WINAPI
IsCharUpperA(
_In_ CHAR ch);
WINUSERAPI
BOOL
WINAPI
IsCharUpperW(
_In_ WCHAR ch);
#ifdef UNICODE
#define IsCharUpper IsCharUpperW
#else
#define IsCharUpper IsCharUpperA
#endif // !UNICODE
WINUSERAPI
BOOL
WINAPI
IsCharLowerA(
_In_ CHAR ch);
WINUSERAPI
BOOL
WINAPI
IsCharLowerW(
_In_ WCHAR ch);
#ifdef UNICODE
#define IsCharLower IsCharLowerW
#else
#define IsCharLower IsCharLowerA
#endif // !UNICODE
#endif /* !NOLANGUAGE */
WINUSERAPI
HWND
WINAPI
SetFocus(
_In_opt_ HWND hWnd);
WINUSERAPI
HWND
WINAPI
GetActiveWindow(
VOID);
WINUSERAPI
HWND
WINAPI
GetFocus(
VOID);
WINUSERAPI
UINT
WINAPI
GetKBCodePage(
VOID);
WINUSERAPI
SHORT
WINAPI
GetKeyState(
_In_ int nVirtKey);
WINUSERAPI
SHORT
WINAPI
GetAsyncKeyState(
_In_ int vKey);
WINUSERAPI
_Check_return_
BOOL
WINAPI
GetKeyboardState(
_Out_writes_(256) PBYTE lpKeyState);
WINUSERAPI
BOOL
WINAPI
SetKeyboardState(
_In_reads_(256) LPBYTE lpKeyState);
WINUSERAPI
int
WINAPI
GetKeyNameTextA(
_In_ LONG lParam,
_Out_writes_(cchSize) LPSTR lpString,
_In_ int cchSize);
WINUSERAPI
int
WINAPI
GetKeyNameTextW(
_In_ LONG lParam,
_Out_writes_(cchSize) LPWSTR lpString,
_In_ int cchSize);
#ifdef UNICODE
#define GetKeyNameText GetKeyNameTextW
#else
#define GetKeyNameText GetKeyNameTextA
#endif // !UNICODE
WINUSERAPI
int
WINAPI
GetKeyboardType(
_In_ int nTypeFlag);
WINUSERAPI
int
WINAPI
ToAscii(
_In_ UINT uVirtKey,
_In_ UINT uScanCode,
_In_reads_opt_(256) CONST BYTE *lpKeyState,
_Out_ LPWORD lpChar,
_In_ UINT uFlags);
#if(WINVER >= 0x0400)
WINUSERAPI
int
WINAPI
ToAsciiEx(
_In_ UINT uVirtKey,
_In_ UINT uScanCode,
_In_reads_opt_(256) CONST BYTE *lpKeyState,
_Out_ LPWORD lpChar,
_In_ UINT uFlags,
_In_opt_ HKL dwhkl);
#endif /* WINVER >= 0x0400 */
WINUSERAPI
int
WINAPI
ToUnicode(
_In_ UINT wVirtKey,
_In_ UINT wScanCode,
_In_reads_bytes_opt_(256) CONST BYTE *lpKeyState,
_Out_writes_(cchBuff) LPWSTR pwszBuff,
_In_ int cchBuff,
_In_ UINT wFlags);
WINUSERAPI
DWORD
WINAPI
OemKeyScan(
_In_ WORD wOemChar);
WINUSERAPI
SHORT
WINAPI
VkKeyScanA(
_In_ CHAR ch);
WINUSERAPI
SHORT
WINAPI
VkKeyScanW(
_In_ WCHAR ch);
#ifdef UNICODE
#define VkKeyScan VkKeyScanW
#else
#define VkKeyScan VkKeyScanA
#endif // !UNICODE
#if(WINVER >= 0x0400)
WINUSERAPI
SHORT
WINAPI
VkKeyScanExA(
_In_ CHAR ch,
_In_ HKL dwhkl);
WINUSERAPI
SHORT
WINAPI
VkKeyScanExW(
_In_ WCHAR ch,
_In_ HKL dwhkl);
#ifdef UNICODE
#define VkKeyScanEx VkKeyScanExW
#else
#define VkKeyScanEx VkKeyScanExA
#endif // !UNICODE
#endif /* WINVER >= 0x0400 */
#define KEYEVENTF_EXTENDEDKEY 0x0001
#define KEYEVENTF_KEYUP 0x0002
#if(_WIN32_WINNT >= 0x0500)
#define KEYEVENTF_UNICODE 0x0004
#define KEYEVENTF_SCANCODE 0x0008
#endif /* _WIN32_WINNT >= 0x0500 */
WINUSERAPI
VOID
WINAPI
keybd_event(
_In_ BYTE bVk,
_In_ BYTE bScan,
_In_ DWORD dwFlags,
_In_ ULONG_PTR dwExtraInfo);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#define MOUSEEVENTF_MOVE 0x0001 /* mouse move */
#define MOUSEEVENTF_LEFTDOWN 0x0002 /* left button down */
#define MOUSEEVENTF_LEFTUP 0x0004 /* left button up */
#define MOUSEEVENTF_RIGHTDOWN 0x0008 /* right button down */
#define MOUSEEVENTF_RIGHTUP 0x0010 /* right button up */
#define MOUSEEVENTF_MIDDLEDOWN 0x0020 /* middle button down */
#define MOUSEEVENTF_MIDDLEUP 0x0040 /* middle button up */
#define MOUSEEVENTF_XDOWN 0x0080 /* x button down */
#define MOUSEEVENTF_XUP 0x0100 /* x button down */
#define MOUSEEVENTF_WHEEL 0x0800 /* wheel button rolled */
#if (_WIN32_WINNT >= 0x0600)
#define MOUSEEVENTF_HWHEEL 0x01000 /* hwheel button rolled */
#endif
#if(WINVER >= 0x0600)
#define MOUSEEVENTF_MOVE_NOCOALESCE 0x2000 /* do not coalesce mouse moves */
#endif /* WINVER >= 0x0600 */
#define MOUSEEVENTF_VIRTUALDESK 0x4000 /* map to entire virtual desktop */
#define MOUSEEVENTF_ABSOLUTE 0x8000 /* absolute move */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
VOID
WINAPI
mouse_event(
_In_ DWORD dwFlags,
_In_ DWORD dx,
_In_ DWORD dy,
_In_ DWORD dwData,
_In_ ULONG_PTR dwExtraInfo);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#if (_WIN32_WINNT > 0x0400)
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef struct tagMOUSEINPUT {
LONG dx;
LONG dy;
DWORD mouseData;
DWORD dwFlags;
DWORD time;
ULONG_PTR dwExtraInfo;
} MOUSEINPUT, *PMOUSEINPUT, FAR* LPMOUSEINPUT;
typedef struct tagKEYBDINPUT {
WORD wVk;
WORD wScan;
DWORD dwFlags;
DWORD time;
ULONG_PTR dwExtraInfo;
} KEYBDINPUT, *PKEYBDINPUT, FAR* LPKEYBDINPUT;
typedef struct tagHARDWAREINPUT {
DWORD uMsg;
WORD wParamL;
WORD wParamH;
} HARDWAREINPUT, *PHARDWAREINPUT, FAR* LPHARDWAREINPUT;
#define INPUT_MOUSE 0
#define INPUT_KEYBOARD 1
#define INPUT_HARDWARE 2
typedef struct tagINPUT {
DWORD type;
union
{
MOUSEINPUT mi;
KEYBDINPUT ki;
HARDWAREINPUT hi;
};
} INPUT, *PINPUT, FAR* LPINPUT;
WINUSERAPI
UINT
WINAPI
SendInput(
_In_ UINT cInputs, // number of input in the array
_In_reads_(cInputs) LPINPUT pInputs, // array of inputs
_In_ int cbSize); // sizeof(INPUT)
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif // (_WIN32_WINNT > 0x0400)
#if(WINVER >= 0x0601)
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
/*
* Touch Input defines and functions
*/
/*
* Touch input handle
*/
DECLARE_HANDLE(HTOUCHINPUT);
typedef struct tagTOUCHINPUT {
LONG x;
LONG y;
HANDLE hSource;
DWORD dwID;
DWORD dwFlags;
DWORD dwMask;
DWORD dwTime;
ULONG_PTR dwExtraInfo;
DWORD cxContact;
DWORD cyContact;
} TOUCHINPUT, *PTOUCHINPUT;
typedef TOUCHINPUT const * PCTOUCHINPUT;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* Conversion of touch input coordinates to pixels
*/
#define TOUCH_COORD_TO_PIXEL(l) ((l) / 100)
/*
* Touch input flag values (TOUCHINPUT.dwFlags)
*/
#define TOUCHEVENTF_MOVE 0x0001
#define TOUCHEVENTF_DOWN 0x0002
#define TOUCHEVENTF_UP 0x0004
#define TOUCHEVENTF_INRANGE 0x0008
#define TOUCHEVENTF_PRIMARY 0x0010
#define TOUCHEVENTF_NOCOALESCE 0x0020
#define TOUCHEVENTF_PEN 0x0040
#define TOUCHEVENTF_PALM 0x0080
/*
* Touch input mask values (TOUCHINPUT.dwMask)
*/
#define TOUCHINPUTMASKF_TIMEFROMSYSTEM 0x0001 // the dwTime field contains a system generated value
#define TOUCHINPUTMASKF_EXTRAINFO 0x0002 // the dwExtraInfo field is valid
#define TOUCHINPUTMASKF_CONTACTAREA 0x0004 // the cxContact and cyContact fields are valid
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
GetTouchInputInfo(
_In_ HTOUCHINPUT hTouchInput, // input event handle; from touch message lParam
_In_ UINT cInputs, // number of elements in the array
_Out_writes_(cInputs) PTOUCHINPUT pInputs, // array of touch inputs
_In_ int cbSize); // sizeof(TOUCHINPUT)
WINUSERAPI
BOOL
WINAPI
CloseTouchInputHandle(
_In_ HTOUCHINPUT hTouchInput); // input event handle; from touch message lParam
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* RegisterTouchWindow flag values
*/
#define TWF_FINETOUCH (0x00000001)
#define TWF_WANTPALM (0x00000002)
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
RegisterTouchWindow(
_In_ HWND hwnd,
_In_ ULONG ulFlags);
WINUSERAPI
BOOL
WINAPI
UnregisterTouchWindow(
_In_ HWND hwnd);
WINUSERAPI
BOOL
WINAPI
IsTouchWindow(
_In_ HWND hwnd,
_Out_opt_ PULONG pulFlags);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* WINVER >= 0x0601 */
#if(WINVER >= 0x0602)
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
enum tagPOINTER_INPUT_TYPE {
PT_POINTER = 0x00000001, // Generic pointer
PT_TOUCH = 0x00000002, // Touch
PT_PEN = 0x00000003, // Pen
PT_MOUSE = 0x00000004, // Mouse
#if(WINVER >= 0x0603)
PT_TOUCHPAD = 0x00000005, // Touchpad
#endif /* WINVER >= 0x0603 */
};
typedef DWORD POINTER_INPUT_TYPE;
typedef UINT32 POINTER_FLAGS;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#define POINTER_FLAG_NONE 0x00000000 // Default
#define POINTER_FLAG_NEW 0x00000001 // New pointer
#define POINTER_FLAG_INRANGE 0x00000002 // Pointer has not departed
#define POINTER_FLAG_INCONTACT 0x00000004 // Pointer is in contact
#define POINTER_FLAG_FIRSTBUTTON 0x00000010 // Primary action
#define POINTER_FLAG_SECONDBUTTON 0x00000020 // Secondary action
#define POINTER_FLAG_THIRDBUTTON 0x00000040 // Third button
#define POINTER_FLAG_FOURTHBUTTON 0x00000080 // Fourth button
#define POINTER_FLAG_FIFTHBUTTON 0x00000100 // Fifth button
#define POINTER_FLAG_PRIMARY 0x00002000 // Pointer is primary
#define POINTER_FLAG_CONFIDENCE 0x00004000 // Pointer is considered unlikely to be accidental
#define POINTER_FLAG_CANCELED 0x00008000 // Pointer is departing in an abnormal manner
#define POINTER_FLAG_DOWN 0x00010000 // Pointer transitioned to down state (made contact)
#define POINTER_FLAG_UPDATE 0x00020000 // Pointer update
#define POINTER_FLAG_UP 0x00040000 // Pointer transitioned from down state (broke contact)
#define POINTER_FLAG_WHEEL 0x00080000 // Vertical wheel
#define POINTER_FLAG_HWHEEL 0x00100000 // Horizontal wheel
#define POINTER_FLAG_CAPTURECHANGED 0x00200000 // Lost capture
#define POINTER_FLAG_HASTRANSFORM 0x00400000 // Input has a transform associated with it
/*
* Pointer info key states defintions.
*/
#define POINTER_MOD_SHIFT (0x0004) // Shift key is held down.
#define POINTER_MOD_CTRL (0x0008) // Ctrl key is held down.
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef enum tagPOINTER_BUTTON_CHANGE_TYPE {
POINTER_CHANGE_NONE,
POINTER_CHANGE_FIRSTBUTTON_DOWN,
POINTER_CHANGE_FIRSTBUTTON_UP,
POINTER_CHANGE_SECONDBUTTON_DOWN,
POINTER_CHANGE_SECONDBUTTON_UP,
POINTER_CHANGE_THIRDBUTTON_DOWN,
POINTER_CHANGE_THIRDBUTTON_UP,
POINTER_CHANGE_FOURTHBUTTON_DOWN,
POINTER_CHANGE_FOURTHBUTTON_UP,
POINTER_CHANGE_FIFTHBUTTON_DOWN,
POINTER_CHANGE_FIFTHBUTTON_UP,
} POINTER_BUTTON_CHANGE_TYPE;
typedef struct tagPOINTER_INFO {
POINTER_INPUT_TYPE pointerType;
UINT32 pointerId;
UINT32 frameId;
POINTER_FLAGS pointerFlags;
HANDLE sourceDevice;
HWND hwndTarget;
POINT ptPixelLocation;
POINT ptHimetricLocation;
POINT ptPixelLocationRaw;
POINT ptHimetricLocationRaw;
DWORD dwTime;
UINT32 historyCount;
INT32 InputData;
DWORD dwKeyStates;
UINT64 PerformanceCount;
POINTER_BUTTON_CHANGE_TYPE ButtonChangeType;
} POINTER_INFO;
typedef UINT32 TOUCH_FLAGS;
#define TOUCH_FLAG_NONE 0x00000000 // Default
typedef UINT32 TOUCH_MASK;
#define TOUCH_MASK_NONE 0x00000000 // Default - none of the optional fields are valid
#define TOUCH_MASK_CONTACTAREA 0x00000001 // The rcContact field is valid
#define TOUCH_MASK_ORIENTATION 0x00000002 // The orientation field is valid
#define TOUCH_MASK_PRESSURE 0x00000004 // The pressure field is valid
typedef struct tagPOINTER_TOUCH_INFO {
POINTER_INFO pointerInfo;
TOUCH_FLAGS touchFlags;
TOUCH_MASK touchMask;
RECT rcContact;
RECT rcContactRaw;
UINT32 orientation;
UINT32 pressure;
} POINTER_TOUCH_INFO;
typedef UINT32 PEN_FLAGS;
#define PEN_FLAG_NONE 0x00000000 // Default
#define PEN_FLAG_BARREL 0x00000001 // The barrel button is pressed
#define PEN_FLAG_INVERTED 0x00000002 // The pen is inverted
#define PEN_FLAG_ERASER 0x00000004 // The eraser button is pressed
typedef UINT32 PEN_MASK;
#define PEN_MASK_NONE 0x00000000 // Default - none of the optional fields are valid
#define PEN_MASK_PRESSURE 0x00000001 // The pressure field is valid
#define PEN_MASK_ROTATION 0x00000002 // The rotation field is valid
#define PEN_MASK_TILT_X 0x00000004 // The tiltX field is valid
#define PEN_MASK_TILT_Y 0x00000008 // The tiltY field is valid
typedef struct tagPOINTER_PEN_INFO {
POINTER_INFO pointerInfo;
PEN_FLAGS penFlags;
PEN_MASK penMask;
UINT32 pressure;
UINT32 rotation;
INT32 tiltX;
INT32 tiltY;
} POINTER_PEN_INFO;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* Flags that appear in pointer input message parameters
*/
#define POINTER_MESSAGE_FLAG_NEW 0x00000001 // New pointer
#define POINTER_MESSAGE_FLAG_INRANGE 0x00000002 // Pointer has not departed
#define POINTER_MESSAGE_FLAG_INCONTACT 0x00000004 // Pointer is in contact
#define POINTER_MESSAGE_FLAG_FIRSTBUTTON 0x00000010 // Primary action
#define POINTER_MESSAGE_FLAG_SECONDBUTTON 0x00000020 // Secondary action
#define POINTER_MESSAGE_FLAG_THIRDBUTTON 0x00000040 // Third button
#define POINTER_MESSAGE_FLAG_FOURTHBUTTON 0x00000080 // Fourth button
#define POINTER_MESSAGE_FLAG_FIFTHBUTTON 0x00000100 // Fifth button
#define POINTER_MESSAGE_FLAG_PRIMARY 0x00002000 // Pointer is primary
#define POINTER_MESSAGE_FLAG_CONFIDENCE 0x00004000 // Pointer is considered unlikely to be accidental
#define POINTER_MESSAGE_FLAG_CANCELED 0x00008000 // Pointer is departing in an abnormal manner
/*
* Macros to retrieve information from pointer input message parameters
*/
#define GET_POINTERID_WPARAM(wParam) (LOWORD(wParam))
#define IS_POINTER_FLAG_SET_WPARAM(wParam, flag) (((DWORD)HIWORD(wParam) & (flag)) == (flag))
#define IS_POINTER_NEW_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_NEW)
#define IS_POINTER_INRANGE_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_INRANGE)
#define IS_POINTER_INCONTACT_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_INCONTACT)
#define IS_POINTER_FIRSTBUTTON_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_FIRSTBUTTON)
#define IS_POINTER_SECONDBUTTON_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_SECONDBUTTON)
#define IS_POINTER_THIRDBUTTON_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_THIRDBUTTON)
#define IS_POINTER_FOURTHBUTTON_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_FOURTHBUTTON)
#define IS_POINTER_FIFTHBUTTON_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_FIFTHBUTTON)
#define IS_POINTER_PRIMARY_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_PRIMARY)
#define HAS_POINTER_CONFIDENCE_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_CONFIDENCE)
#define IS_POINTER_CANCELED_WPARAM(wParam) IS_POINTER_FLAG_SET_WPARAM(wParam, POINTER_MESSAGE_FLAG_CANCELED)
/*
* WM_POINTERACTIVATE return codes
*/
#define PA_ACTIVATE MA_ACTIVATE
#define PA_NOACTIVATE MA_NOACTIVATE
#define MAX_TOUCH_COUNT 256
#define TOUCH_FEEDBACK_DEFAULT 0x1
#define TOUCH_FEEDBACK_INDIRECT 0x2
#define TOUCH_FEEDBACK_NONE 0x3
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
InitializeTouchInjection(
_In_ UINT32 maxCount,
_In_ DWORD dwMode);
WINUSERAPI
BOOL
WINAPI
InjectTouchInput(
_In_ UINT32 count,
_In_reads_(count) CONST POINTER_TOUCH_INFO *contacts);
WINUSERAPI
BOOL
WINAPI
GetPointerType(
_In_ UINT32 pointerId,
_Out_ POINTER_INPUT_TYPE *pointerType);
WINUSERAPI
BOOL
WINAPI
GetPointerCursorId(
_In_ UINT32 pointerId,
_Out_ UINT32 *cursorId);
WINUSERAPI
BOOL
WINAPI
GetPointerInfo(
_In_ UINT32 pointerId,
_Out_writes_(1) POINTER_INFO *pointerInfo);
WINUSERAPI
BOOL
WINAPI
GetPointerInfoHistory(
_In_ UINT32 pointerId,
_Inout_ UINT32 *entriesCount,
_Out_writes_opt_(*entriesCount) POINTER_INFO *pointerInfo);
WINUSERAPI
BOOL
WINAPI
GetPointerFrameInfo(
_In_ UINT32 pointerId,
_Inout_ UINT32 *pointerCount,
_Out_writes_opt_(*pointerCount) POINTER_INFO *pointerInfo);
WINUSERAPI
BOOL
WINAPI
GetPointerFrameInfoHistory(
_In_ UINT32 pointerId,
_Inout_ UINT32 *entriesCount,
_Inout_ UINT32 *pointerCount,
_Out_writes_opt_(*entriesCount * *pointerCount) POINTER_INFO *pointerInfo);
WINUSERAPI
BOOL
WINAPI
GetPointerTouchInfo(
_In_ UINT32 pointerId,
_Out_writes_(1) POINTER_TOUCH_INFO *touchInfo);
WINUSERAPI
BOOL
WINAPI
GetPointerTouchInfoHistory(
_In_ UINT32 pointerId,
_Inout_ UINT32 *entriesCount,
_Out_writes_opt_(*entriesCount) POINTER_TOUCH_INFO *touchInfo);
WINUSERAPI
BOOL
WINAPI
GetPointerFrameTouchInfo(
_In_ UINT32 pointerId,
_Inout_ UINT32 *pointerCount,
_Out_writes_opt_(*pointerCount) POINTER_TOUCH_INFO *touchInfo);
WINUSERAPI
BOOL
WINAPI
GetPointerFrameTouchInfoHistory(
_In_ UINT32 pointerId,
_Inout_ UINT32 *entriesCount,
_Inout_ UINT32 *pointerCount,
_Out_writes_opt_(*entriesCount * *pointerCount) POINTER_TOUCH_INFO *touchInfo);
WINUSERAPI
BOOL
WINAPI
GetPointerPenInfo(
_In_ UINT32 pointerId,
_Out_writes_(1) POINTER_PEN_INFO *penInfo);
WINUSERAPI
BOOL
WINAPI
GetPointerPenInfoHistory(
_In_ UINT32 pointerId,
_Inout_ UINT32 *entriesCount,
_Out_writes_opt_(*entriesCount) POINTER_PEN_INFO *penInfo);
WINUSERAPI
BOOL
WINAPI
GetPointerFramePenInfo(
_In_ UINT32 pointerId,
_Inout_ UINT32 *pointerCount,
_Out_writes_opt_(*pointerCount) POINTER_PEN_INFO *penInfo);
WINUSERAPI
BOOL
WINAPI
GetPointerFramePenInfoHistory(
_In_ UINT32 pointerId,
_Inout_ UINT32 *entriesCount,
_Inout_ UINT32 *pointerCount,
_Out_writes_opt_(*entriesCount * *pointerCount) POINTER_PEN_INFO *penInfo);
WINUSERAPI
BOOL
WINAPI
SkipPointerFrameMessages(
_In_ UINT32 pointerId);
WINUSERAPI
BOOL
WINAPI
RegisterPointerInputTarget(
_In_ HWND hwnd,
_In_ POINTER_INPUT_TYPE pointerType);
WINUSERAPI
BOOL
WINAPI
UnregisterPointerInputTarget(
_In_ HWND hwnd,
_In_ POINTER_INPUT_TYPE pointerType);
WINUSERAPI
BOOL
WINAPI
EnableMouseInPointer(
_In_ BOOL fEnable);
WINUSERAPI
BOOL
WINAPI
IsMouseInPointerEnabled(
VOID);
#define TOUCH_HIT_TESTING_DEFAULT 0x0
#define TOUCH_HIT_TESTING_CLIENT 0x1
#define TOUCH_HIT_TESTING_NONE 0x2
WINUSERAPI
BOOL
WINAPI
RegisterTouchHitTestingWindow(
_In_ HWND hwnd,
_In_ ULONG value);
typedef struct tagTOUCH_HIT_TESTING_PROXIMITY_EVALUATION
{
UINT16 score;
POINT adjustedPoint;
} TOUCH_HIT_TESTING_PROXIMITY_EVALUATION, *PTOUCH_HIT_TESTING_PROXIMITY_EVALUATION;
/*
* WM_TOUCHHITTESTING structure
*/
typedef struct tagTOUCH_HIT_TESTING_INPUT
{
UINT32 pointerId;
POINT point;
RECT boundingBox;
RECT nonOccludedBoundingBox;
UINT32 orientation;
} TOUCH_HIT_TESTING_INPUT, *PTOUCH_HIT_TESTING_INPUT;
#define TOUCH_HIT_TESTING_PROXIMITY_CLOSEST 0x0
#define TOUCH_HIT_TESTING_PROXIMITY_FARTHEST 0xFFF
WINUSERAPI
BOOL
WINAPI
EvaluateProximityToRect(
_In_ const RECT *controlBoundingBox,
_In_ const TOUCH_HIT_TESTING_INPUT *pHitTestingInput,
_Out_ TOUCH_HIT_TESTING_PROXIMITY_EVALUATION *pProximityEval);
WINUSERAPI
BOOL
WINAPI
EvaluateProximityToPolygon(
UINT32 numVertices,
_In_reads_(numVertices) const POINT *controlPolygon,
_In_ const TOUCH_HIT_TESTING_INPUT *pHitTestingInput,
_Out_ TOUCH_HIT_TESTING_PROXIMITY_EVALUATION *pProximityEval);
WINUSERAPI
LRESULT
WINAPI
PackTouchHitTestingProximityEvaluation(
_In_ const TOUCH_HIT_TESTING_INPUT *pHitTestingInput,
_In_ const TOUCH_HIT_TESTING_PROXIMITY_EVALUATION *pProximityEval);
typedef enum tagFEEDBACK_TYPE {
FEEDBACK_TOUCH_CONTACTVISUALIZATION = 1,
FEEDBACK_PEN_BARRELVISUALIZATION = 2,
FEEDBACK_PEN_TAP = 3,
FEEDBACK_PEN_DOUBLETAP = 4,
FEEDBACK_PEN_PRESSANDHOLD = 5,
FEEDBACK_PEN_RIGHTTAP = 6,
FEEDBACK_TOUCH_TAP = 7,
FEEDBACK_TOUCH_DOUBLETAP = 8,
FEEDBACK_TOUCH_PRESSANDHOLD = 9,
FEEDBACK_TOUCH_RIGHTTAP = 10,
FEEDBACK_GESTURE_PRESSANDTAP = 11,
FEEDBACK_MAX = 0xFFFFFFFF
} FEEDBACK_TYPE;
#define GWFS_INCLUDE_ANCESTORS 0x00000001
WINUSERAPI
BOOL
WINAPI
GetWindowFeedbackSetting(
_In_ HWND hwnd,
_In_ FEEDBACK_TYPE feedback,
_In_ DWORD dwFlags,
_Inout_ UINT32* pSize,
_Out_writes_bytes_opt_(*pSize) VOID* config);
WINUSERAPI
BOOL
WINAPI
SetWindowFeedbackSetting(
_In_ HWND hwnd,
_In_ FEEDBACK_TYPE feedback,
_In_ DWORD dwFlags,
_In_ UINT32 size,
_In_reads_bytes_opt_(size) CONST VOID* configuration);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* WINVER >= 0x0602 */
#if(WINVER >= 0x0603)
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef struct tagINPUT_TRANSFORM {
union {
struct {
float _11, _12, _13, _14;
float _21, _22, _23, _24;
float _31, _32, _33, _34;
float _41, _42, _43, _44;
};
float m[4][4];
};
} INPUT_TRANSFORM;
WINUSERAPI
BOOL
WINAPI
GetPointerInputTransform(
_In_ UINT32 pointerId,
_In_ UINT32 historyCount,
_Out_writes_(historyCount) INPUT_TRANSFORM *inputTransform);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* WINVER >= 0x0603 */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#if(_WIN32_WINNT >= 0x0500)
typedef struct tagLASTINPUTINFO {
UINT cbSize;
DWORD dwTime;
} LASTINPUTINFO, * PLASTINPUTINFO;
WINUSERAPI
BOOL
WINAPI
GetLastInputInfo(
_Out_ PLASTINPUTINFO plii);
#endif /* _WIN32_WINNT >= 0x0500 */
WINUSERAPI
UINT
WINAPI
MapVirtualKeyA(
_In_ UINT uCode,
_In_ UINT uMapType);
WINUSERAPI
UINT
WINAPI
MapVirtualKeyW(
_In_ UINT uCode,
_In_ UINT uMapType);
#ifdef UNICODE
#define MapVirtualKey MapVirtualKeyW
#else
#define MapVirtualKey MapVirtualKeyA
#endif // !UNICODE
#if(WINVER >= 0x0400)
WINUSERAPI
UINT
WINAPI
MapVirtualKeyExA(
_In_ UINT uCode,
_In_ UINT uMapType,
_In_opt_ HKL dwhkl);
WINUSERAPI
UINT
WINAPI
MapVirtualKeyExW(
_In_ UINT uCode,
_In_ UINT uMapType,
_In_opt_ HKL dwhkl);
#ifdef UNICODE
#define MapVirtualKeyEx MapVirtualKeyExW
#else
#define MapVirtualKeyEx MapVirtualKeyExA
#endif // !UNICODE
#define MAPVK_VK_TO_VSC (0)
#define MAPVK_VSC_TO_VK (1)
#define MAPVK_VK_TO_CHAR (2)
#define MAPVK_VSC_TO_VK_EX (3)
#endif /* WINVER >= 0x0400 */
#if(WINVER >= 0x0600)
#define MAPVK_VK_TO_VSC_EX (4)
#endif /* WINVER >= 0x0600 */
WINUSERAPI
BOOL
WINAPI
GetInputState(
VOID);
WINUSERAPI
DWORD
WINAPI
GetQueueStatus(
_In_ UINT flags);
WINUSERAPI
HWND
WINAPI
GetCapture(
VOID);
WINUSERAPI
HWND
WINAPI
SetCapture(
_In_ HWND hWnd);
WINUSERAPI
BOOL
WINAPI
ReleaseCapture(
VOID);
WINUSERAPI
DWORD
WINAPI
MsgWaitForMultipleObjects(
_In_ DWORD nCount,
_In_reads_opt_(nCount) CONST HANDLE *pHandles,
_In_ BOOL fWaitAll,
_In_ DWORD dwMilliseconds,
_In_ DWORD dwWakeMask);
WINUSERAPI
DWORD
WINAPI
MsgWaitForMultipleObjectsEx(
_In_ DWORD nCount,
_In_reads_opt_(nCount) CONST HANDLE *pHandles,
_In_ DWORD dwMilliseconds,
_In_ DWORD dwWakeMask,
_In_ DWORD dwFlags);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#define MWMO_WAITALL 0x0001
#define MWMO_ALERTABLE 0x0002
#define MWMO_INPUTAVAILABLE 0x0004
/*
* Queue status flags for GetQueueStatus() and MsgWaitForMultipleObjects()
*/
#define QS_KEY 0x0001
#define QS_MOUSEMOVE 0x0002
#define QS_MOUSEBUTTON 0x0004
#define QS_POSTMESSAGE 0x0008
#define QS_TIMER 0x0010
#define QS_PAINT 0x0020
#define QS_SENDMESSAGE 0x0040
#define QS_HOTKEY 0x0080
#define QS_ALLPOSTMESSAGE 0x0100
#if(_WIN32_WINNT >= 0x0501)
#define QS_RAWINPUT 0x0400
#endif /* _WIN32_WINNT >= 0x0501 */
#if(_WIN32_WINNT >= 0x0602)
#define QS_TOUCH 0x0800
#define QS_POINTER 0x1000
#endif /* _WIN32_WINNT >= 0x0602 */
#define QS_MOUSE (QS_MOUSEMOVE | \
QS_MOUSEBUTTON)
#if (_WIN32_WINNT >= 0x602)
#define QS_INPUT (QS_MOUSE | \
QS_KEY | \
QS_RAWINPUT | \
QS_TOUCH | \
QS_POINTER)
#else
#if (_WIN32_WINNT >= 0x0501)
#define QS_INPUT (QS_MOUSE | \
QS_KEY | \
QS_RAWINPUT)
#else
#define QS_INPUT (QS_MOUSE | \
QS_KEY)
#endif // (_WIN32_WINNT >= 0x0501)
#endif
#define QS_ALLEVENTS (QS_INPUT | \
QS_POSTMESSAGE | \
QS_TIMER | \
QS_PAINT | \
QS_HOTKEY)
#define QS_ALLINPUT (QS_INPUT | \
QS_POSTMESSAGE | \
QS_TIMER | \
QS_PAINT | \
QS_HOTKEY | \
QS_SENDMESSAGE)
#define USER_TIMER_MAXIMUM 0x7FFFFFFF
#define USER_TIMER_MINIMUM 0x0000000A
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
/*
* Windows Functions
*/
WINUSERAPI
UINT_PTR
WINAPI
SetTimer(
_In_opt_ HWND hWnd,
_In_ UINT_PTR nIDEvent,
_In_ UINT uElapse,
_In_opt_ TIMERPROC lpTimerFunc);
#if(WINVER >= 0x0601)
#define TIMERV_DEFAULT_COALESCING (0)
#define TIMERV_NO_COALESCING (0xFFFFFFFF)
#define TIMERV_COALESCING_MIN (1)
#define TIMERV_COALESCING_MAX (0x7FFFFFF5)
WINUSERAPI
UINT_PTR
WINAPI
SetCoalescableTimer(
_In_opt_ HWND hWnd,
_In_ UINT_PTR nIDEvent,
_In_ UINT uElapse,
_In_opt_ TIMERPROC lpTimerFunc,
_In_ ULONG uToleranceDelay);
#endif /* WINVER >= 0x0601 */
WINUSERAPI
BOOL
WINAPI
KillTimer(
_In_opt_ HWND hWnd,
_In_ UINT_PTR uIDEvent);
WINUSERAPI
BOOL
WINAPI
IsWindowUnicode(
_In_ HWND hWnd);
WINUSERAPI
BOOL
WINAPI
EnableWindow(
_In_ HWND hWnd,
_In_ BOOL bEnable);
WINUSERAPI
BOOL
WINAPI
IsWindowEnabled(
_In_ HWND hWnd);
WINUSERAPI
HACCEL
WINAPI
LoadAcceleratorsA(
_In_opt_ HINSTANCE hInstance,
_In_ LPCSTR lpTableName);
WINUSERAPI
HACCEL
WINAPI
LoadAcceleratorsW(
_In_opt_ HINSTANCE hInstance,
_In_ LPCWSTR lpTableName);
#ifdef UNICODE
#define LoadAccelerators LoadAcceleratorsW
#else
#define LoadAccelerators LoadAcceleratorsA
#endif // !UNICODE
WINUSERAPI
HACCEL
WINAPI
CreateAcceleratorTableA(
_In_reads_(cAccel) LPACCEL paccel,
_In_ int cAccel);
WINUSERAPI
HACCEL
WINAPI
CreateAcceleratorTableW(
_In_reads_(cAccel) LPACCEL paccel,
_In_ int cAccel);
#ifdef UNICODE
#define CreateAcceleratorTable CreateAcceleratorTableW
#else
#define CreateAcceleratorTable CreateAcceleratorTableA
#endif // !UNICODE
WINUSERAPI
BOOL
WINAPI
DestroyAcceleratorTable(
_In_ HACCEL hAccel);
WINUSERAPI
int
WINAPI
CopyAcceleratorTableA(
_In_ HACCEL hAccelSrc,
_Out_writes_to_opt_(cAccelEntries, return) LPACCEL lpAccelDst,
_In_ int cAccelEntries);
WINUSERAPI
int
WINAPI
CopyAcceleratorTableW(
_In_ HACCEL hAccelSrc,
_Out_writes_to_opt_(cAccelEntries, return) LPACCEL lpAccelDst,
_In_ int cAccelEntries);
#ifdef UNICODE
#define CopyAcceleratorTable CopyAcceleratorTableW
#else
#define CopyAcceleratorTable CopyAcceleratorTableA
#endif // !UNICODE
#ifndef NOMSG
WINUSERAPI
int
WINAPI
TranslateAcceleratorA(
_In_ HWND hWnd,
_In_ HACCEL hAccTable,
_In_ LPMSG lpMsg);
WINUSERAPI
int
WINAPI
TranslateAcceleratorW(
_In_ HWND hWnd,
_In_ HACCEL hAccTable,
_In_ LPMSG lpMsg);
#ifdef UNICODE
#define TranslateAccelerator TranslateAcceleratorW
#else
#define TranslateAccelerator TranslateAcceleratorA
#endif // !UNICODE
#endif /* !NOMSG */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#ifndef NOSYSMETRICS
/*
* GetSystemMetrics() codes
*/
#define SM_CXSCREEN 0
#define SM_CYSCREEN 1
#define SM_CXVSCROLL 2
#define SM_CYHSCROLL 3
#define SM_CYCAPTION 4
#define SM_CXBORDER 5
#define SM_CYBORDER 6
#define SM_CXDLGFRAME 7
#define SM_CYDLGFRAME 8
#define SM_CYVTHUMB 9
#define SM_CXHTHUMB 10
#define SM_CXICON 11
#define SM_CYICON 12
#define SM_CXCURSOR 13
#define SM_CYCURSOR 14
#define SM_CYMENU 15
#define SM_CXFULLSCREEN 16
#define SM_CYFULLSCREEN 17
#define SM_CYKANJIWINDOW 18
#define SM_MOUSEPRESENT 19
#define SM_CYVSCROLL 20
#define SM_CXHSCROLL 21
#define SM_DEBUG 22
#define SM_SWAPBUTTON 23
#define SM_RESERVED1 24
#define SM_RESERVED2 25
#define SM_RESERVED3 26
#define SM_RESERVED4 27
#define SM_CXMIN 28
#define SM_CYMIN 29
#define SM_CXSIZE 30
#define SM_CYSIZE 31
#define SM_CXFRAME 32
#define SM_CYFRAME 33
#define SM_CXMINTRACK 34
#define SM_CYMINTRACK 35
#define SM_CXDOUBLECLK 36
#define SM_CYDOUBLECLK 37
#define SM_CXICONSPACING 38
#define SM_CYICONSPACING 39
#define SM_MENUDROPALIGNMENT 40
#define SM_PENWINDOWS 41
#define SM_DBCSENABLED 42
#define SM_CMOUSEBUTTONS 43
#if(WINVER >= 0x0400)
#define SM_CXFIXEDFRAME SM_CXDLGFRAME /* ;win40 name change */
#define SM_CYFIXEDFRAME SM_CYDLGFRAME /* ;win40 name change */
#define SM_CXSIZEFRAME SM_CXFRAME /* ;win40 name change */
#define SM_CYSIZEFRAME SM_CYFRAME /* ;win40 name change */
#define SM_SECURE 44
#define SM_CXEDGE 45
#define SM_CYEDGE 46
#define SM_CXMINSPACING 47
#define SM_CYMINSPACING 48
#define SM_CXSMICON 49
#define SM_CYSMICON 50
#define SM_CYSMCAPTION 51
#define SM_CXSMSIZE 52
#define SM_CYSMSIZE 53
#define SM_CXMENUSIZE 54
#define SM_CYMENUSIZE 55
#define SM_ARRANGE 56
#define SM_CXMINIMIZED 57
#define SM_CYMINIMIZED 58
#define SM_CXMAXTRACK 59
#define SM_CYMAXTRACK 60
#define SM_CXMAXIMIZED 61
#define SM_CYMAXIMIZED 62
#define SM_NETWORK 63
#define SM_CLEANBOOT 67
#define SM_CXDRAG 68
#define SM_CYDRAG 69
#endif /* WINVER >= 0x0400 */
#define SM_SHOWSOUNDS 70
#if(WINVER >= 0x0400)
#define SM_CXMENUCHECK 71 /* Use instead of GetMenuCheckMarkDimensions()! */
#define SM_CYMENUCHECK 72
#define SM_SLOWMACHINE 73
#define SM_MIDEASTENABLED 74
#endif /* WINVER >= 0x0400 */
#if (WINVER >= 0x0500) || (_WIN32_WINNT >= 0x0400)
#define SM_MOUSEWHEELPRESENT 75
#endif
#if(WINVER >= 0x0500)
#define SM_XVIRTUALSCREEN 76
#define SM_YVIRTUALSCREEN 77
#define SM_CXVIRTUALSCREEN 78
#define SM_CYVIRTUALSCREEN 79
#define SM_CMONITORS 80
#define SM_SAMEDISPLAYFORMAT 81
#endif /* WINVER >= 0x0500 */
#if(_WIN32_WINNT >= 0x0500)
#define SM_IMMENABLED 82
#endif /* _WIN32_WINNT >= 0x0500 */
#if(_WIN32_WINNT >= 0x0501)
#define SM_CXFOCUSBORDER 83
#define SM_CYFOCUSBORDER 84
#endif /* _WIN32_WINNT >= 0x0501 */
#if(_WIN32_WINNT >= 0x0501)
#define SM_TABLETPC 86
#define SM_MEDIACENTER 87
#define SM_STARTER 88
#define SM_SERVERR2 89
#endif /* _WIN32_WINNT >= 0x0501 */
#if(_WIN32_WINNT >= 0x0600)
#define SM_MOUSEHORIZONTALWHEELPRESENT 91
#define SM_CXPADDEDBORDER 92
#endif /* _WIN32_WINNT >= 0x0600 */
#if(WINVER >= 0x0601)
#define SM_DIGITIZER 94
#define SM_MAXIMUMTOUCHES 95
#endif /* WINVER >= 0x0601 */
#if (WINVER < 0x0500) && (!defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0400))
#define SM_CMETRICS 76
#elif WINVER == 0x500
#define SM_CMETRICS 83
#elif WINVER == 0x501
#define SM_CMETRICS 91
#elif WINVER == 0x600
#define SM_CMETRICS 93
#else
#define SM_CMETRICS 97
#endif
#if(WINVER >= 0x0500)
#define SM_REMOTESESSION 0x1000
#if(_WIN32_WINNT >= 0x0501)
#define SM_SHUTTINGDOWN 0x2000
#endif /* _WIN32_WINNT >= 0x0501 */
#if(WINVER >= 0x0501)
#define SM_REMOTECONTROL 0x2001
#endif /* WINVER >= 0x0501 */
#if(WINVER >= 0x0501)
#define SM_CARETBLINKINGENABLED 0x2002
#endif /* WINVER >= 0x0501 */
#if(WINVER >= 0x0602)
#define SM_CONVERTIBLESLATEMODE 0x2003
#define SM_SYSTEMDOCKED 0x2004
#endif /* WINVER >= 0x0602 */
#endif /* WINVER >= 0x0500 */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
int
WINAPI
GetSystemMetrics(
_In_ int nIndex);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* !NOSYSMETRICS */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#ifndef NOMENUS
WINUSERAPI
HMENU
WINAPI
LoadMenuA(
_In_opt_ HINSTANCE hInstance,
_In_ LPCSTR lpMenuName);
WINUSERAPI
HMENU
WINAPI
LoadMenuW(
_In_opt_ HINSTANCE hInstance,
_In_ LPCWSTR lpMenuName);
#ifdef UNICODE
#define LoadMenu LoadMenuW
#else
#define LoadMenu LoadMenuA
#endif // !UNICODE
WINUSERAPI
HMENU
WINAPI
LoadMenuIndirectA(
_In_ CONST MENUTEMPLATEA *lpMenuTemplate);
WINUSERAPI
HMENU
WINAPI
LoadMenuIndirectW(
_In_ CONST MENUTEMPLATEW *lpMenuTemplate);
#ifdef UNICODE
#define LoadMenuIndirect LoadMenuIndirectW
#else
#define LoadMenuIndirect LoadMenuIndirectA
#endif // !UNICODE
WINUSERAPI
HMENU
WINAPI
GetMenu(
_In_ HWND hWnd);
WINUSERAPI
BOOL
WINAPI
SetMenu(
_In_ HWND hWnd,
_In_opt_ HMENU hMenu);
WINUSERAPI
BOOL
WINAPI
ChangeMenuA(
_In_ HMENU hMenu,
_In_ UINT cmd,
_In_opt_ LPCSTR lpszNewItem,
_In_ UINT cmdInsert,
_In_ UINT flags);
WINUSERAPI
BOOL
WINAPI
ChangeMenuW(
_In_ HMENU hMenu,
_In_ UINT cmd,
_In_opt_ LPCWSTR lpszNewItem,
_In_ UINT cmdInsert,
_In_ UINT flags);
#ifdef UNICODE
#define ChangeMenu ChangeMenuW
#else
#define ChangeMenu ChangeMenuA
#endif // !UNICODE
WINUSERAPI
BOOL
WINAPI
HiliteMenuItem(
_In_ HWND hWnd,
_In_ HMENU hMenu,
_In_ UINT uIDHiliteItem,
_In_ UINT uHilite);
WINUSERAPI
int
WINAPI
GetMenuStringA(
_In_ HMENU hMenu,
_In_ UINT uIDItem,
_Out_writes_opt_(cchMax) LPSTR lpString,
_In_ int cchMax,
_In_ UINT flags);
WINUSERAPI
int
WINAPI
GetMenuStringW(
_In_ HMENU hMenu,
_In_ UINT uIDItem,
_Out_writes_opt_(cchMax) LPWSTR lpString,
_In_ int cchMax,
_In_ UINT flags);
#ifdef UNICODE
#define GetMenuString GetMenuStringW
#else
#define GetMenuString GetMenuStringA
#endif // !UNICODE
WINUSERAPI
UINT
WINAPI
GetMenuState(
_In_ HMENU hMenu,
_In_ UINT uId,
_In_ UINT uFlags);
WINUSERAPI
BOOL
WINAPI
DrawMenuBar(
_In_ HWND hWnd);
#if(_WIN32_WINNT >= 0x0501)
#define PMB_ACTIVE 0x00000001
#endif /* _WIN32_WINNT >= 0x0501 */
WINUSERAPI
HMENU
WINAPI
GetSystemMenu(
_In_ HWND hWnd,
_In_ BOOL bRevert);
WINUSERAPI
HMENU
WINAPI
CreateMenu(
VOID);
WINUSERAPI
HMENU
WINAPI
CreatePopupMenu(
VOID);
WINUSERAPI
BOOL
WINAPI
DestroyMenu(
_In_ HMENU hMenu);
WINUSERAPI
DWORD
WINAPI
CheckMenuItem(
_In_ HMENU hMenu,
_In_ UINT uIDCheckItem,
_In_ UINT uCheck);
WINUSERAPI
BOOL
WINAPI
EnableMenuItem(
_In_ HMENU hMenu,
_In_ UINT uIDEnableItem,
_In_ UINT uEnable);
WINUSERAPI
HMENU
WINAPI
GetSubMenu(
_In_ HMENU hMenu,
_In_ int nPos);
WINUSERAPI
UINT
WINAPI
GetMenuItemID(
_In_ HMENU hMenu,
_In_ int nPos);
WINUSERAPI
int
WINAPI
GetMenuItemCount(
_In_opt_ HMENU hMenu);
WINUSERAPI
BOOL
WINAPI
InsertMenuA(
_In_ HMENU hMenu,
_In_ UINT uPosition,
_In_ UINT uFlags,
_In_ UINT_PTR uIDNewItem,
_In_opt_ LPCSTR lpNewItem);
WINUSERAPI
BOOL
WINAPI
InsertMenuW(
_In_ HMENU hMenu,
_In_ UINT uPosition,
_In_ UINT uFlags,
_In_ UINT_PTR uIDNewItem,
_In_opt_ LPCWSTR lpNewItem);
#ifdef UNICODE
#define InsertMenu InsertMenuW
#else
#define InsertMenu InsertMenuA
#endif // !UNICODE
WINUSERAPI
BOOL
WINAPI
AppendMenuA(
_In_ HMENU hMenu,
_In_ UINT uFlags,
_In_ UINT_PTR uIDNewItem,
_In_opt_ LPCSTR lpNewItem);
WINUSERAPI
BOOL
WINAPI
AppendMenuW(
_In_ HMENU hMenu,
_In_ UINT uFlags,
_In_ UINT_PTR uIDNewItem,
_In_opt_ LPCWSTR lpNewItem);
#ifdef UNICODE
#define AppendMenu AppendMenuW
#else
#define AppendMenu AppendMenuA
#endif // !UNICODE
WINUSERAPI
BOOL
WINAPI
ModifyMenuA(
_In_ HMENU hMnu,
_In_ UINT uPosition,
_In_ UINT uFlags,
_In_ UINT_PTR uIDNewItem,
_In_opt_ LPCSTR lpNewItem);
WINUSERAPI
BOOL
WINAPI
ModifyMenuW(
_In_ HMENU hMnu,
_In_ UINT uPosition,
_In_ UINT uFlags,
_In_ UINT_PTR uIDNewItem,
_In_opt_ LPCWSTR lpNewItem);
#ifdef UNICODE
#define ModifyMenu ModifyMenuW
#else
#define ModifyMenu ModifyMenuA
#endif // !UNICODE
WINUSERAPI
BOOL
WINAPI RemoveMenu(
_In_ HMENU hMenu,
_In_ UINT uPosition,
_In_ UINT uFlags);
WINUSERAPI
BOOL
WINAPI
DeleteMenu(
_In_ HMENU hMenu,
_In_ UINT uPosition,
_In_ UINT uFlags);
WINUSERAPI
BOOL
WINAPI
SetMenuItemBitmaps(
_In_ HMENU hMenu,
_In_ UINT uPosition,
_In_ UINT uFlags,
_In_opt_ HBITMAP hBitmapUnchecked,
_In_opt_ HBITMAP hBitmapChecked);
WINUSERAPI
LONG
WINAPI
GetMenuCheckMarkDimensions(
VOID);
WINUSERAPI
BOOL
WINAPI
TrackPopupMenu(
_In_ HMENU hMenu,
_In_ UINT uFlags,
_In_ int x,
_In_ int y,
_Reserved_ int nReserved,
_In_ HWND hWnd,
_Reserved_ CONST RECT *prcRect);
#if(WINVER >= 0x0400)
/* return codes for WM_MENUCHAR */
#define MNC_IGNORE 0
#define MNC_CLOSE 1
#define MNC_EXECUTE 2
#define MNC_SELECT 3
typedef struct tagTPMPARAMS
{
UINT cbSize; /* Size of structure */
RECT rcExclude; /* Screen coordinates of rectangle to exclude when positioning */
} TPMPARAMS;
typedef TPMPARAMS FAR *LPTPMPARAMS;
WINUSERAPI
BOOL
WINAPI
TrackPopupMenuEx(
_In_ HMENU hMenu,
_In_ UINT uFlags,
_In_ int x,
_In_ int y,
_In_ HWND hwnd,
_In_opt_ LPTPMPARAMS lptpm);
#endif /* WINVER >= 0x0400 */
#if(_WIN32_WINNT >= 0x0601)
WINUSERAPI
BOOL
WINAPI
CalculatePopupWindowPosition(
_In_ const POINT *anchorPoint,
_In_ const SIZE *windowSize,
_In_ UINT /* TPM_XXX values */ flags,
_In_opt_ RECT *excludeRect,
_Out_ RECT *popupWindowPosition);
#endif /* _WIN32_WINNT >= 0x0601 */
#if(WINVER >= 0x0500)
#define MNS_NOCHECK 0x80000000
#define MNS_MODELESS 0x40000000
#define MNS_DRAGDROP 0x20000000
#define MNS_AUTODISMISS 0x10000000
#define MNS_NOTIFYBYPOS 0x08000000
#define MNS_CHECKORBMP 0x04000000
#define MIM_MAXHEIGHT 0x00000001
#define MIM_BACKGROUND 0x00000002
#define MIM_HELPID 0x00000004
#define MIM_MENUDATA 0x00000008
#define MIM_STYLE 0x00000010
#define MIM_APPLYTOSUBMENUS 0x80000000
typedef struct tagMENUINFO
{
DWORD cbSize;
DWORD fMask;
DWORD dwStyle;
UINT cyMax;
HBRUSH hbrBack;
DWORD dwContextHelpID;
ULONG_PTR dwMenuData;
} MENUINFO, FAR *LPMENUINFO;
typedef MENUINFO CONST FAR *LPCMENUINFO;
WINUSERAPI
BOOL
WINAPI
GetMenuInfo(
_In_ HMENU,
_Inout_ LPMENUINFO);
WINUSERAPI
BOOL
WINAPI
SetMenuInfo(
_In_ HMENU,
_In_ LPCMENUINFO);
WINUSERAPI
BOOL
WINAPI
EndMenu(
VOID);
/*
* WM_MENUDRAG return values.
*/
#define MND_CONTINUE 0
#define MND_ENDMENU 1
typedef struct tagMENUGETOBJECTINFO
{
DWORD dwFlags;
UINT uPos;
HMENU hmenu;
PVOID riid;
PVOID pvObj;
} MENUGETOBJECTINFO, * PMENUGETOBJECTINFO;
/*
* MENUGETOBJECTINFO dwFlags values
*/
#define MNGOF_TOPGAP 0x00000001
#define MNGOF_BOTTOMGAP 0x00000002
/*
* WM_MENUGETOBJECT return values
*/
#define MNGO_NOINTERFACE 0x00000000
#define MNGO_NOERROR 0x00000001
#endif /* WINVER >= 0x0500 */
#if(WINVER >= 0x0400)
#define MIIM_STATE 0x00000001
#define MIIM_ID 0x00000002
#define MIIM_SUBMENU 0x00000004
#define MIIM_CHECKMARKS 0x00000008
#define MIIM_TYPE 0x00000010
#define MIIM_DATA 0x00000020
#endif /* WINVER >= 0x0400 */
#if(WINVER >= 0x0500)
#define MIIM_STRING 0x00000040
#define MIIM_BITMAP 0x00000080
#define MIIM_FTYPE 0x00000100
#define HBMMENU_CALLBACK ((HBITMAP) -1)
#define HBMMENU_SYSTEM ((HBITMAP) 1)
#define HBMMENU_MBAR_RESTORE ((HBITMAP) 2)
#define HBMMENU_MBAR_MINIMIZE ((HBITMAP) 3)
#define HBMMENU_MBAR_CLOSE ((HBITMAP) 5)
#define HBMMENU_MBAR_CLOSE_D ((HBITMAP) 6)
#define HBMMENU_MBAR_MINIMIZE_D ((HBITMAP) 7)
#define HBMMENU_POPUP_CLOSE ((HBITMAP) 8)
#define HBMMENU_POPUP_RESTORE ((HBITMAP) 9)
#define HBMMENU_POPUP_MAXIMIZE ((HBITMAP) 10)
#define HBMMENU_POPUP_MINIMIZE ((HBITMAP) 11)
#endif /* WINVER >= 0x0500 */
#if(WINVER >= 0x0400)
typedef struct tagMENUITEMINFOA
{
UINT cbSize;
UINT fMask;
UINT fType; // used if MIIM_TYPE (4.0) or MIIM_FTYPE (>4.0)
UINT fState; // used if MIIM_STATE
UINT wID; // used if MIIM_ID
HMENU hSubMenu; // used if MIIM_SUBMENU
HBITMAP hbmpChecked; // used if MIIM_CHECKMARKS
HBITMAP hbmpUnchecked; // used if MIIM_CHECKMARKS
ULONG_PTR dwItemData; // used if MIIM_DATA
LPSTR dwTypeData; // used if MIIM_TYPE (4.0) or MIIM_STRING (>4.0)
UINT cch; // used if MIIM_TYPE (4.0) or MIIM_STRING (>4.0)
#if(WINVER >= 0x0500)
HBITMAP hbmpItem; // used if MIIM_BITMAP
#endif /* WINVER >= 0x0500 */
} MENUITEMINFOA, FAR *LPMENUITEMINFOA;
typedef struct tagMENUITEMINFOW
{
UINT cbSize;
UINT fMask;
UINT fType; // used if MIIM_TYPE (4.0) or MIIM_FTYPE (>4.0)
UINT fState; // used if MIIM_STATE
UINT wID; // used if MIIM_ID
HMENU hSubMenu; // used if MIIM_SUBMENU
HBITMAP hbmpChecked; // used if MIIM_CHECKMARKS
HBITMAP hbmpUnchecked; // used if MIIM_CHECKMARKS
ULONG_PTR dwItemData; // used if MIIM_DATA
LPWSTR dwTypeData; // used if MIIM_TYPE (4.0) or MIIM_STRING (>4.0)
UINT cch; // used if MIIM_TYPE (4.0) or MIIM_STRING (>4.0)
#if(WINVER >= 0x0500)
HBITMAP hbmpItem; // used if MIIM_BITMAP
#endif /* WINVER >= 0x0500 */
} MENUITEMINFOW, FAR *LPMENUITEMINFOW;
#ifdef UNICODE
typedef MENUITEMINFOW MENUITEMINFO;
typedef LPMENUITEMINFOW LPMENUITEMINFO;
#else
typedef MENUITEMINFOA MENUITEMINFO;
typedef LPMENUITEMINFOA LPMENUITEMINFO;
#endif // UNICODE
typedef MENUITEMINFOA CONST FAR *LPCMENUITEMINFOA;
typedef MENUITEMINFOW CONST FAR *LPCMENUITEMINFOW;
#ifdef UNICODE
typedef LPCMENUITEMINFOW LPCMENUITEMINFO;
#else
typedef LPCMENUITEMINFOA LPCMENUITEMINFO;
#endif // UNICODE
WINUSERAPI
BOOL
WINAPI
InsertMenuItemA(
_In_ HMENU hmenu,
_In_ UINT item,
_In_ BOOL fByPosition,
_In_ LPCMENUITEMINFOA lpmi);
WINUSERAPI
BOOL
WINAPI
InsertMenuItemW(
_In_ HMENU hmenu,
_In_ UINT item,
_In_ BOOL fByPosition,
_In_ LPCMENUITEMINFOW lpmi);
#ifdef UNICODE
#define InsertMenuItem InsertMenuItemW
#else
#define InsertMenuItem InsertMenuItemA
#endif // !UNICODE
WINUSERAPI
BOOL
WINAPI
GetMenuItemInfoA(
_In_ HMENU hmenu,
_In_ UINT item,
_In_ BOOL fByPosition,
_Inout_ LPMENUITEMINFOA lpmii);
WINUSERAPI
BOOL
WINAPI
GetMenuItemInfoW(
_In_ HMENU hmenu,
_In_ UINT item,
_In_ BOOL fByPosition,
_Inout_ LPMENUITEMINFOW lpmii);
#ifdef UNICODE
#define GetMenuItemInfo GetMenuItemInfoW
#else
#define GetMenuItemInfo GetMenuItemInfoA
#endif // !UNICODE
WINUSERAPI
BOOL
WINAPI
SetMenuItemInfoA(
_In_ HMENU hmenu,
_In_ UINT item,
_In_ BOOL fByPositon,
_In_ LPCMENUITEMINFOA lpmii);
WINUSERAPI
BOOL
WINAPI
SetMenuItemInfoW(
_In_ HMENU hmenu,
_In_ UINT item,
_In_ BOOL fByPositon,
_In_ LPCMENUITEMINFOW lpmii);
#ifdef UNICODE
#define SetMenuItemInfo SetMenuItemInfoW
#else
#define SetMenuItemInfo SetMenuItemInfoA
#endif // !UNICODE
#define GMDI_USEDISABLED 0x0001L
#define GMDI_GOINTOPOPUPS 0x0002L
WINUSERAPI
UINT
WINAPI
GetMenuDefaultItem(
_In_ HMENU hMenu,
_In_ UINT fByPos,
_In_ UINT gmdiFlags);
WINUSERAPI
BOOL
WINAPI
SetMenuDefaultItem(
_In_ HMENU hMenu,
_In_ UINT uItem,
_In_ UINT fByPos);
WINUSERAPI
BOOL
WINAPI
GetMenuItemRect(
_In_opt_ HWND hWnd,
_In_ HMENU hMenu,
_In_ UINT uItem,
_Out_ LPRECT lprcItem);
WINUSERAPI
int
WINAPI
MenuItemFromPoint(
_In_opt_ HWND hWnd,
_In_ HMENU hMenu,
_In_ POINT ptScreen);
#endif /* WINVER >= 0x0400 */
/*
* Flags for TrackPopupMenu
*/
#define TPM_LEFTBUTTON 0x0000L
#define TPM_RIGHTBUTTON 0x0002L
#define TPM_LEFTALIGN 0x0000L
#define TPM_CENTERALIGN 0x0004L
#define TPM_RIGHTALIGN 0x0008L
#if(WINVER >= 0x0400)
#define TPM_TOPALIGN 0x0000L
#define TPM_VCENTERALIGN 0x0010L
#define TPM_BOTTOMALIGN 0x0020L
#define TPM_HORIZONTAL 0x0000L /* Horz alignment matters more */
#define TPM_VERTICAL 0x0040L /* Vert alignment matters more */
#define TPM_NONOTIFY 0x0080L /* Don't send any notification msgs */
#define TPM_RETURNCMD 0x0100L
#endif /* WINVER >= 0x0400 */
#if(WINVER >= 0x0500)
#define TPM_RECURSE 0x0001L
#define TPM_HORPOSANIMATION 0x0400L
#define TPM_HORNEGANIMATION 0x0800L
#define TPM_VERPOSANIMATION 0x1000L
#define TPM_VERNEGANIMATION 0x2000L
#if(_WIN32_WINNT >= 0x0500)
#define TPM_NOANIMATION 0x4000L
#endif /* _WIN32_WINNT >= 0x0500 */
#if(_WIN32_WINNT >= 0x0501)
#define TPM_LAYOUTRTL 0x8000L
#endif /* _WIN32_WINNT >= 0x0501 */
#endif /* WINVER >= 0x0500 */
#if(_WIN32_WINNT >= 0x0601)
#define TPM_WORKAREA 0x10000L
#endif /* _WIN32_WINNT >= 0x0601 */
#endif /* !NOMENUS */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#if(WINVER >= 0x0400)
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
//
// Drag-and-drop support
// Obsolete - use OLE instead
//
typedef struct tagDROPSTRUCT
{
HWND hwndSource;
HWND hwndSink;
DWORD wFmt;
ULONG_PTR dwData;
POINT ptDrop;
DWORD dwControlData;
} DROPSTRUCT, *PDROPSTRUCT, *LPDROPSTRUCT;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#define DOF_EXECUTABLE 0x8001 // wFmt flags
#define DOF_DOCUMENT 0x8002
#define DOF_DIRECTORY 0x8003
#define DOF_MULTIPLE 0x8004
#define DOF_PROGMAN 0x0001
#define DOF_SHELLDATA 0x0002
#define DO_DROPFILE 0x454C4946L
#define DO_PRINTFILE 0x544E5250L
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
DWORD
WINAPI
DragObject(
_In_ HWND hwndParent,
_In_ HWND hwndFrom,
_In_ UINT fmt,
_In_ ULONG_PTR data,
_In_opt_ HCURSOR hcur);
WINUSERAPI
BOOL
WINAPI
DragDetect(
_In_ HWND hwnd,
_In_ POINT pt);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* WINVER >= 0x0400 */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
DrawIcon(
_In_ HDC hDC,
_In_ int X,
_In_ int Y,
_In_ HICON hIcon);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#ifndef NODRAWTEXT
/*
* DrawText() Format Flags
*/
#define DT_TOP 0x00000000
#define DT_LEFT 0x00000000
#define DT_CENTER 0x00000001
#define DT_RIGHT 0x00000002
#define DT_VCENTER 0x00000004
#define DT_BOTTOM 0x00000008
#define DT_WORDBREAK 0x00000010
#define DT_SINGLELINE 0x00000020
#define DT_EXPANDTABS 0x00000040
#define DT_TABSTOP 0x00000080
#define DT_NOCLIP 0x00000100
#define DT_EXTERNALLEADING 0x00000200
#define DT_CALCRECT 0x00000400
#define DT_NOPREFIX 0x00000800
#define DT_INTERNAL 0x00001000
#if(WINVER >= 0x0400)
#define DT_EDITCONTROL 0x00002000
#define DT_PATH_ELLIPSIS 0x00004000
#define DT_END_ELLIPSIS 0x00008000
#define DT_MODIFYSTRING 0x00010000
#define DT_RTLREADING 0x00020000
#define DT_WORD_ELLIPSIS 0x00040000
#if(WINVER >= 0x0500)
#define DT_NOFULLWIDTHCHARBREAK 0x00080000
#if(_WIN32_WINNT >= 0x0500)
#define DT_HIDEPREFIX 0x00100000
#define DT_PREFIXONLY 0x00200000
#endif /* _WIN32_WINNT >= 0x0500 */
#endif /* WINVER >= 0x0500 */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef struct tagDRAWTEXTPARAMS
{
UINT cbSize;
int iTabLength;
int iLeftMargin;
int iRightMargin;
UINT uiLengthDrawn;
} DRAWTEXTPARAMS, FAR *LPDRAWTEXTPARAMS;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* WINVER >= 0x0400 */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#define _In_bypassable_reads_or_z_(size) \
_When_(((size) == -1) || (_String_length_(_Curr_) < (size)), _In_z_) \
_When_(((size) != -1) && (_String_length_(_Curr_) >= (size)), _In_reads_(size))
#define _Inout_grows_updates_bypassable_or_z_(size, grows) \
_When_(((size) == -1) || (_String_length_(_Curr_) < (size)), _Pre_z_ _Pre_valid_ _Out_writes_z_(_String_length_(_Curr_) + (grows))) \
_When_(((size) != -1) && (_String_length_(_Curr_) >= (size)), _Pre_count_(size) _Pre_valid_ _Out_writes_z_((size) + (grows)))
WINUSERAPI
_Success_(return)
int
WINAPI
DrawTextA(
_In_ HDC hdc,
_When_((format & DT_MODIFYSTRING), _At_((LPSTR)lpchText, _Inout_grows_updates_bypassable_or_z_(cchText, 4)))
_When_((!(format & DT_MODIFYSTRING)), _In_bypassable_reads_or_z_(cchText))
LPCSTR lpchText,
_In_ int cchText,
_Inout_ LPRECT lprc,
_In_ UINT format);
WINUSERAPI
_Success_(return)
int
WINAPI
DrawTextW(
_In_ HDC hdc,
_When_((format & DT_MODIFYSTRING), _At_((LPWSTR)lpchText, _Inout_grows_updates_bypassable_or_z_(cchText, 4)))
_When_((!(format & DT_MODIFYSTRING)), _In_bypassable_reads_or_z_(cchText))
LPCWSTR lpchText,
_In_ int cchText,
_Inout_ LPRECT lprc,
_In_ UINT format);
#ifdef UNICODE
#define DrawText DrawTextW
#else
#define DrawText DrawTextA
#endif // !UNICODE
#if defined(_M_CEE)
#undef DrawText
__inline
int
DrawText(
HDC hdc,
LPCTSTR lpchText,
int cchText,
LPRECT lprc,
UINT format
)
{
#ifdef UNICODE
return DrawTextW(
#else
return DrawTextA(
#endif
hdc,
lpchText,
cchText,
lprc,
format
);
}
#endif /* _M_CEE */
#if(WINVER >= 0x0400)
WINUSERAPI
_Success_(return)
int
WINAPI
DrawTextExA(
_In_ HDC hdc,
_When_((cchText) < -1, _Unreferenced_parameter_)
_When_((format & DT_MODIFYSTRING), _Inout_grows_updates_bypassable_or_z_(cchText, 4))
_When_((!(format & DT_MODIFYSTRING)), _At_((LPCSTR)lpchText, _In_bypassable_reads_or_z_(cchText)))
LPSTR lpchText,
_In_ int cchText,
_Inout_ LPRECT lprc,
_In_ UINT format,
_In_opt_ LPDRAWTEXTPARAMS lpdtp);
WINUSERAPI
_Success_(return)
int
WINAPI
DrawTextExW(
_In_ HDC hdc,
_When_((cchText) < -1, _Unreferenced_parameter_)
_When_((format & DT_MODIFYSTRING), _Inout_grows_updates_bypassable_or_z_(cchText, 4))
_When_((!(format & DT_MODIFYSTRING)), _At_((LPCWSTR)lpchText, _In_bypassable_reads_or_z_(cchText)))
LPWSTR lpchText,
_In_ int cchText,
_Inout_ LPRECT lprc,
_In_ UINT format,
_In_opt_ LPDRAWTEXTPARAMS lpdtp);
#ifdef UNICODE
#define DrawTextEx DrawTextExW
#else
#define DrawTextEx DrawTextExA
#endif // !UNICODE
#endif /* WINVER >= 0x0400 */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* !NODRAWTEXT */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
GrayStringA(
_In_ HDC hDC,
_In_opt_ HBRUSH hBrush,
_In_opt_ GRAYSTRINGPROC lpOutputFunc,
_In_ LPARAM lpData,
_In_ int nCount,
_In_ int X,
_In_ int Y,
_In_ int nWidth,
_In_ int nHeight);
WINUSERAPI
BOOL
WINAPI
GrayStringW(
_In_ HDC hDC,
_In_opt_ HBRUSH hBrush,
_In_opt_ GRAYSTRINGPROC lpOutputFunc,
_In_ LPARAM lpData,
_In_ int nCount,
_In_ int X,
_In_ int Y,
_In_ int nWidth,
_In_ int nHeight);
#ifdef UNICODE
#define GrayString GrayStringW
#else
#define GrayString GrayStringA
#endif // !UNICODE
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#if(WINVER >= 0x0400)
/* Monolithic state-drawing routine */
/* Image type */
#define DST_COMPLEX 0x0000
#define DST_TEXT 0x0001
#define DST_PREFIXTEXT 0x0002
#define DST_ICON 0x0003
#define DST_BITMAP 0x0004
/* State type */
#define DSS_NORMAL 0x0000
#define DSS_UNION 0x0010 /* Gray string appearance */
#define DSS_DISABLED 0x0020
#define DSS_MONO 0x0080
#if(_WIN32_WINNT >= 0x0500)
#define DSS_HIDEPREFIX 0x0200
#define DSS_PREFIXONLY 0x0400
#endif /* _WIN32_WINNT >= 0x0500 */
#define DSS_RIGHT 0x8000
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
DrawStateA(
_In_ HDC hdc,
_In_opt_ HBRUSH hbrFore,
_In_opt_ DRAWSTATEPROC qfnCallBack,
_In_ LPARAM lData,
_In_ WPARAM wData,
_In_ int x,
_In_ int y,
_In_ int cx,
_In_ int cy,
_In_ UINT uFlags);
WINUSERAPI
BOOL
WINAPI
DrawStateW(
_In_ HDC hdc,
_In_opt_ HBRUSH hbrFore,
_In_opt_ DRAWSTATEPROC qfnCallBack,
_In_ LPARAM lData,
_In_ WPARAM wData,
_In_ int x,
_In_ int y,
_In_ int cx,
_In_ int cy,
_In_ UINT uFlags);
#ifdef UNICODE
#define DrawState DrawStateW
#else
#define DrawState DrawStateA
#endif // !UNICODE
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* WINVER >= 0x0400 */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
LONG
WINAPI
TabbedTextOutA(
_In_ HDC hdc,
_In_ int x,
_In_ int y,
_In_reads_(chCount) LPCSTR lpString,
_In_ int chCount,
_In_ int nTabPositions,
_In_reads_opt_(nTabPositions) CONST INT *lpnTabStopPositions,
_In_ int nTabOrigin);
WINUSERAPI
LONG
WINAPI
TabbedTextOutW(
_In_ HDC hdc,
_In_ int x,
_In_ int y,
_In_reads_(chCount) LPCWSTR lpString,
_In_ int chCount,
_In_ int nTabPositions,
_In_reads_opt_(nTabPositions) CONST INT *lpnTabStopPositions,
_In_ int nTabOrigin);
#ifdef UNICODE
#define TabbedTextOut TabbedTextOutW
#else
#define TabbedTextOut TabbedTextOutA
#endif // !UNICODE
WINUSERAPI
DWORD
WINAPI
GetTabbedTextExtentA(
_In_ HDC hdc,
_In_reads_(chCount) LPCSTR lpString,
_In_ int chCount,
_In_ int nTabPositions,
_In_reads_opt_(nTabPositions) CONST INT *lpnTabStopPositions);
WINUSERAPI
DWORD
WINAPI
GetTabbedTextExtentW(
_In_ HDC hdc,
_In_reads_(chCount) LPCWSTR lpString,
_In_ int chCount,
_In_ int nTabPositions,
_In_reads_opt_(nTabPositions) CONST INT *lpnTabStopPositions);
#ifdef UNICODE
#define GetTabbedTextExtent GetTabbedTextExtentW
#else
#define GetTabbedTextExtent GetTabbedTextExtentA
#endif // !UNICODE
WINUSERAPI
BOOL
WINAPI
UpdateWindow(
_In_ HWND hWnd);
WINUSERAPI
HWND
WINAPI
SetActiveWindow(
_In_ HWND hWnd);
WINUSERAPI
HWND
WINAPI
GetForegroundWindow(
VOID);
#if(WINVER >= 0x0400)
WINUSERAPI
BOOL
WINAPI
PaintDesktop(
_In_ HDC hdc);
WINUSERAPI
VOID
WINAPI
SwitchToThisWindow(
_In_ HWND hwnd,
_In_ BOOL fUnknown);
#endif /* WINVER >= 0x0400 */
WINUSERAPI
BOOL
WINAPI
SetForegroundWindow(
_In_ HWND hWnd);
#if(_WIN32_WINNT >= 0x0500)
WINUSERAPI
BOOL
WINAPI
AllowSetForegroundWindow(
_In_ DWORD dwProcessId);
#define ASFW_ANY ((DWORD)-1)
WINUSERAPI
BOOL
WINAPI
LockSetForegroundWindow(
_In_ UINT uLockCode);
#define LSFW_LOCK 1
#define LSFW_UNLOCK 2
#endif /* _WIN32_WINNT >= 0x0500 */
WINUSERAPI
HWND
WINAPI
WindowFromDC(
_In_ HDC hDC);
WINUSERAPI
HDC
WINAPI
GetDC(
_In_opt_ HWND hWnd);
WINUSERAPI
HDC
WINAPI
GetDCEx(
_In_opt_ HWND hWnd,
_In_opt_ HRGN hrgnClip,
_In_ DWORD flags);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* GetDCEx() flags
*/
#define DCX_WINDOW 0x00000001L
#define DCX_CACHE 0x00000002L
#define DCX_NORESETATTRS 0x00000004L
#define DCX_CLIPCHILDREN 0x00000008L
#define DCX_CLIPSIBLINGS 0x00000010L
#define DCX_PARENTCLIP 0x00000020L
#define DCX_EXCLUDERGN 0x00000040L
#define DCX_INTERSECTRGN 0x00000080L
#define DCX_EXCLUDEUPDATE 0x00000100L
#define DCX_INTERSECTUPDATE 0x00000200L
#define DCX_LOCKWINDOWUPDATE 0x00000400L
#define DCX_VALIDATE 0x00200000L
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
HDC
WINAPI
GetWindowDC(
_In_opt_ HWND hWnd);
WINUSERAPI
int
WINAPI
ReleaseDC(
_In_opt_ HWND hWnd,
_In_ HDC hDC);
WINUSERAPI
HDC
WINAPI
BeginPaint(
_In_ HWND hWnd,
_Out_ LPPAINTSTRUCT lpPaint);
WINUSERAPI
BOOL
WINAPI
EndPaint(
_In_ HWND hWnd,
_In_ CONST PAINTSTRUCT *lpPaint);
WINUSERAPI
BOOL
WINAPI
GetUpdateRect(
_In_ HWND hWnd,
_Out_opt_ LPRECT lpRect,
_In_ BOOL bErase);
WINUSERAPI
int
WINAPI
GetUpdateRgn(
_In_ HWND hWnd,
_In_ HRGN hRgn,
_In_ BOOL bErase);
WINUSERAPI
int
WINAPI
SetWindowRgn(
_In_ HWND hWnd,
_In_opt_ HRGN hRgn,
_In_ BOOL bRedraw);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
int
WINAPI
GetWindowRgn(
_In_ HWND hWnd,
_In_ HRGN hRgn);
#if(_WIN32_WINNT >= 0x0501)
WINUSERAPI
int
WINAPI
GetWindowRgnBox(
_In_ HWND hWnd,
_Out_ LPRECT lprc);
#endif /* _WIN32_WINNT >= 0x0501 */
WINUSERAPI
int
WINAPI
ExcludeUpdateRgn(
_In_ HDC hDC,
_In_ HWND hWnd);
WINUSERAPI
BOOL
WINAPI
InvalidateRect(
_In_opt_ HWND hWnd,
_In_opt_ CONST RECT *lpRect,
_In_ BOOL bErase);
WINUSERAPI
BOOL
WINAPI
ValidateRect(
_In_opt_ HWND hWnd,
_In_opt_ CONST RECT *lpRect);
WINUSERAPI
BOOL
WINAPI
InvalidateRgn(
_In_ HWND hWnd,
_In_opt_ HRGN hRgn,
_In_ BOOL bErase);
WINUSERAPI
BOOL
WINAPI
ValidateRgn(
_In_ HWND hWnd,
_In_opt_ HRGN hRgn);
WINUSERAPI
BOOL
WINAPI
RedrawWindow(
_In_opt_ HWND hWnd,
_In_opt_ CONST RECT *lprcUpdate,
_In_opt_ HRGN hrgnUpdate,
_In_ UINT flags);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* RedrawWindow() flags
*/
#define RDW_INVALIDATE 0x0001
#define RDW_INTERNALPAINT 0x0002
#define RDW_ERASE 0x0004
#define RDW_VALIDATE 0x0008
#define RDW_NOINTERNALPAINT 0x0010
#define RDW_NOERASE 0x0020
#define RDW_NOCHILDREN 0x0040
#define RDW_ALLCHILDREN 0x0080
#define RDW_UPDATENOW 0x0100
#define RDW_ERASENOW 0x0200
#define RDW_FRAME 0x0400
#define RDW_NOFRAME 0x0800
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
/*
* LockWindowUpdate API
*/
WINUSERAPI
BOOL
WINAPI
LockWindowUpdate(
_In_opt_ HWND hWndLock);
WINUSERAPI
BOOL
WINAPI
ScrollWindow(
_In_ HWND hWnd,
_In_ int XAmount,
_In_ int YAmount,
_In_opt_ CONST RECT *lpRect,
_In_opt_ CONST RECT *lpClipRect);
WINUSERAPI
BOOL
WINAPI
ScrollDC(
_In_ HDC hDC,
_In_ int dx,
_In_ int dy,
_In_opt_ CONST RECT *lprcScroll,
_In_opt_ CONST RECT *lprcClip,
_In_opt_ HRGN hrgnUpdate,
_Out_opt_ LPRECT lprcUpdate);
WINUSERAPI
int
WINAPI
ScrollWindowEx(
_In_ HWND hWnd,
_In_ int dx,
_In_ int dy,
_In_opt_ CONST RECT *prcScroll,
_In_opt_ CONST RECT *prcClip,
_In_opt_ HRGN hrgnUpdate,
_Out_opt_ LPRECT prcUpdate,
_In_ UINT flags);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#define SW_SCROLLCHILDREN 0x0001 /* Scroll children within *lprcScroll. */
#define SW_INVALIDATE 0x0002 /* Invalidate after scrolling */
#define SW_ERASE 0x0004 /* If SW_INVALIDATE, don't send WM_ERASEBACKGROUND */
#if(WINVER >= 0x0500)
#define SW_SMOOTHSCROLL 0x0010 /* Use smooth scrolling */
#endif /* WINVER >= 0x0500 */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#ifndef NOSCROLL
WINUSERAPI
int
WINAPI
SetScrollPos(
_In_ HWND hWnd,
_In_ int nBar,
_In_ int nPos,
_In_ BOOL bRedraw);
WINUSERAPI
int
WINAPI
GetScrollPos(
_In_ HWND hWnd,
_In_ int nBar);
WINUSERAPI
BOOL
WINAPI
SetScrollRange(
_In_ HWND hWnd,
_In_ int nBar,
_In_ int nMinPos,
_In_ int nMaxPos,
_In_ BOOL bRedraw);
WINUSERAPI
BOOL
WINAPI
GetScrollRange(
_In_ HWND hWnd,
_In_ int nBar,
_Out_ LPINT lpMinPos,
_Out_ LPINT lpMaxPos);
WINUSERAPI
BOOL
WINAPI
ShowScrollBar(
_In_ HWND hWnd,
_In_ int wBar,
_In_ BOOL bShow);
WINUSERAPI
BOOL
WINAPI
EnableScrollBar(
_In_ HWND hWnd,
_In_ UINT wSBflags,
_In_ UINT wArrows);
/*
* EnableScrollBar() flags
*/
#define ESB_ENABLE_BOTH 0x0000
#define ESB_DISABLE_BOTH 0x0003
#define ESB_DISABLE_LEFT 0x0001
#define ESB_DISABLE_RIGHT 0x0002
#define ESB_DISABLE_UP 0x0001
#define ESB_DISABLE_DOWN 0x0002
#define ESB_DISABLE_LTUP ESB_DISABLE_LEFT
#define ESB_DISABLE_RTDN ESB_DISABLE_RIGHT
#endif /* !NOSCROLL */
WINUSERAPI
BOOL
WINAPI
SetPropA(
_In_ HWND hWnd,
_In_ LPCSTR lpString,
_In_opt_ HANDLE hData);
WINUSERAPI
BOOL
WINAPI
SetPropW(
_In_ HWND hWnd,
_In_ LPCWSTR lpString,
_In_opt_ HANDLE hData);
#ifdef UNICODE
#define SetProp SetPropW
#else
#define SetProp SetPropA
#endif // !UNICODE
WINUSERAPI
HANDLE
WINAPI
GetPropA(
_In_ HWND hWnd,
_In_ LPCSTR lpString);
WINUSERAPI
HANDLE
WINAPI
GetPropW(
_In_ HWND hWnd,
_In_ LPCWSTR lpString);
#ifdef UNICODE
#define GetProp GetPropW
#else
#define GetProp GetPropA
#endif // !UNICODE
WINUSERAPI
HANDLE
WINAPI
RemovePropA(
_In_ HWND hWnd,
_In_ LPCSTR lpString);
WINUSERAPI
HANDLE
WINAPI
RemovePropW(
_In_ HWND hWnd,
_In_ LPCWSTR lpString);
#ifdef UNICODE
#define RemoveProp RemovePropW
#else
#define RemoveProp RemovePropA
#endif // !UNICODE
WINUSERAPI
int
WINAPI
EnumPropsExA(
_In_ HWND hWnd,
_In_ PROPENUMPROCEXA lpEnumFunc,
_In_ LPARAM lParam);
WINUSERAPI
int
WINAPI
EnumPropsExW(
_In_ HWND hWnd,
_In_ PROPENUMPROCEXW lpEnumFunc,
_In_ LPARAM lParam);
#ifdef UNICODE
#define EnumPropsEx EnumPropsExW
#else
#define EnumPropsEx EnumPropsExA
#endif // !UNICODE
WINUSERAPI
int
WINAPI
EnumPropsA(
_In_ HWND hWnd,
_In_ PROPENUMPROCA lpEnumFunc);
WINUSERAPI
int
WINAPI
EnumPropsW(
_In_ HWND hWnd,
_In_ PROPENUMPROCW lpEnumFunc);
#ifdef UNICODE
#define EnumProps EnumPropsW
#else
#define EnumProps EnumPropsA
#endif // !UNICODE
WINUSERAPI
BOOL
WINAPI
SetWindowTextA(
_In_ HWND hWnd,
_In_opt_ LPCSTR lpString);
WINUSERAPI
BOOL
WINAPI
SetWindowTextW(
_In_ HWND hWnd,
_In_opt_ LPCWSTR lpString);
#ifdef UNICODE
#define SetWindowText SetWindowTextW
#else
#define SetWindowText SetWindowTextA
#endif // !UNICODE
_Ret_range_(0, nMaxCount)
WINUSERAPI
int
WINAPI
GetWindowTextA(
_In_ HWND hWnd,
_Out_writes_(nMaxCount) LPSTR lpString,
_In_ int nMaxCount);
_Ret_range_(0, nMaxCount)
WINUSERAPI
int
WINAPI
GetWindowTextW(
_In_ HWND hWnd,
_Out_writes_(nMaxCount) LPWSTR lpString,
_In_ int nMaxCount);
#ifdef UNICODE
#define GetWindowText GetWindowTextW
#else
#define GetWindowText GetWindowTextA
#endif // !UNICODE
WINUSERAPI
int
WINAPI
GetWindowTextLengthA(
_In_ HWND hWnd);
WINUSERAPI
int
WINAPI
GetWindowTextLengthW(
_In_ HWND hWnd);
#ifdef UNICODE
#define GetWindowTextLength GetWindowTextLengthW
#else
#define GetWindowTextLength GetWindowTextLengthA
#endif // !UNICODE
WINUSERAPI
BOOL
WINAPI
GetClientRect(
_In_ HWND hWnd,
_Out_ LPRECT lpRect);
WINUSERAPI
BOOL
WINAPI
GetWindowRect(
_In_ HWND hWnd,
_Out_ LPRECT lpRect);
WINUSERAPI
BOOL
WINAPI
AdjustWindowRect(
_Inout_ LPRECT lpRect,
_In_ DWORD dwStyle,
_In_ BOOL bMenu);
WINUSERAPI
BOOL
WINAPI
AdjustWindowRectEx(
_Inout_ LPRECT lpRect,
_In_ DWORD dwStyle,
_In_ BOOL bMenu,
_In_ DWORD dwExStyle);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#if(WINVER >= 0x0400)
#define HELPINFO_WINDOW 0x0001
#define HELPINFO_MENUITEM 0x0002
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef struct tagHELPINFO /* Structure pointed to by lParam of WM_HELP */
{
UINT cbSize; /* Size in bytes of this struct */
int iContextType; /* Either HELPINFO_WINDOW or HELPINFO_MENUITEM */
int iCtrlId; /* Control Id or a Menu item Id. */
HANDLE hItemHandle; /* hWnd of control or hMenu. */
DWORD_PTR dwContextId; /* Context Id associated with this item */
POINT MousePos; /* Mouse Position in screen co-ordinates */
} HELPINFO, FAR *LPHELPINFO;
WINUSERAPI
BOOL
WINAPI
SetWindowContextHelpId(
_In_ HWND,
_In_ DWORD);
WINUSERAPI
DWORD
WINAPI
GetWindowContextHelpId(
_In_ HWND);
WINUSERAPI
BOOL
WINAPI
SetMenuContextHelpId(
_In_ HMENU,
_In_ DWORD);
WINUSERAPI
DWORD
WINAPI
GetMenuContextHelpId(
_In_ HMENU);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* WINVER >= 0x0400 */
#ifndef NOMB
/*
* MessageBox() Flags
*/
#define MB_OK 0x00000000L
#define MB_OKCANCEL 0x00000001L
#define MB_ABORTRETRYIGNORE 0x00000002L
#define MB_YESNOCANCEL 0x00000003L
#define MB_YESNO 0x00000004L
#define MB_RETRYCANCEL 0x00000005L
#if(WINVER >= 0x0500)
#define MB_CANCELTRYCONTINUE 0x00000006L
#endif /* WINVER >= 0x0500 */
#define MB_ICONHAND 0x00000010L
#define MB_ICONQUESTION 0x00000020L
#define MB_ICONEXCLAMATION 0x00000030L
#define MB_ICONASTERISK 0x00000040L
#if(WINVER >= 0x0400)
#define MB_USERICON 0x00000080L
#define MB_ICONWARNING MB_ICONEXCLAMATION
#define MB_ICONERROR MB_ICONHAND
#endif /* WINVER >= 0x0400 */
#define MB_ICONINFORMATION MB_ICONASTERISK
#define MB_ICONSTOP MB_ICONHAND
#define MB_DEFBUTTON1 0x00000000L
#define MB_DEFBUTTON2 0x00000100L
#define MB_DEFBUTTON3 0x00000200L
#if(WINVER >= 0x0400)
#define MB_DEFBUTTON4 0x00000300L
#endif /* WINVER >= 0x0400 */
#define MB_APPLMODAL 0x00000000L
#define MB_SYSTEMMODAL 0x00001000L
#define MB_TASKMODAL 0x00002000L
#if(WINVER >= 0x0400)
#define MB_HELP 0x00004000L // Help Button
#endif /* WINVER >= 0x0400 */
#define MB_NOFOCUS 0x00008000L
#define MB_SETFOREGROUND 0x00010000L
#define MB_DEFAULT_DESKTOP_ONLY 0x00020000L
#if(WINVER >= 0x0400)
#define MB_TOPMOST 0x00040000L
#define MB_RIGHT 0x00080000L
#define MB_RTLREADING 0x00100000L
#endif /* WINVER >= 0x0400 */
#ifdef _WIN32_WINNT
#if (_WIN32_WINNT >= 0x0400)
#define MB_SERVICE_NOTIFICATION 0x00200000L
#else
#define MB_SERVICE_NOTIFICATION 0x00040000L
#endif
#define MB_SERVICE_NOTIFICATION_NT3X 0x00040000L
#endif
#define MB_TYPEMASK 0x0000000FL
#define MB_ICONMASK 0x000000F0L
#define MB_DEFMASK 0x00000F00L
#define MB_MODEMASK 0x00003000L
#define MB_MISCMASK 0x0000C000L
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
int
WINAPI
MessageBoxA(
_In_opt_ HWND hWnd,
_In_opt_ LPCSTR lpText,
_In_opt_ LPCSTR lpCaption,
_In_ UINT uType);
WINUSERAPI
int
WINAPI
MessageBoxW(
_In_opt_ HWND hWnd,
_In_opt_ LPCWSTR lpText,
_In_opt_ LPCWSTR lpCaption,
_In_ UINT uType);
#ifdef UNICODE
#define MessageBox MessageBoxW
#else
#define MessageBox MessageBoxA
#endif // !UNICODE
#if defined(_M_CEE)
#undef MessageBox
__inline
int
MessageBox(
HWND hWnd,
LPCTSTR lpText,
LPCTSTR lpCaption,
UINT uType
)
{
#ifdef UNICODE
return MessageBoxW(
#else
return MessageBoxA(
#endif
hWnd,
lpText,
lpCaption,
uType
);
}
#endif /* _M_CEE */
WINUSERAPI
int
WINAPI
MessageBoxExA(
_In_opt_ HWND hWnd,
_In_opt_ LPCSTR lpText,
_In_opt_ LPCSTR lpCaption,
_In_ UINT uType,
_In_ WORD wLanguageId);
WINUSERAPI
int
WINAPI
MessageBoxExW(
_In_opt_ HWND hWnd,
_In_opt_ LPCWSTR lpText,
_In_opt_ LPCWSTR lpCaption,
_In_ UINT uType,
_In_ WORD wLanguageId);
#ifdef UNICODE
#define MessageBoxEx MessageBoxExW
#else
#define MessageBoxEx MessageBoxExA
#endif // !UNICODE
#if(WINVER >= 0x0400)
typedef VOID (CALLBACK *MSGBOXCALLBACK)(LPHELPINFO lpHelpInfo);
typedef struct tagMSGBOXPARAMSA
{
UINT cbSize;
HWND hwndOwner;
HINSTANCE hInstance;
LPCSTR lpszText;
LPCSTR lpszCaption;
DWORD dwStyle;
LPCSTR lpszIcon;
DWORD_PTR dwContextHelpId;
MSGBOXCALLBACK lpfnMsgBoxCallback;
DWORD dwLanguageId;
} MSGBOXPARAMSA, *PMSGBOXPARAMSA, *LPMSGBOXPARAMSA;
typedef struct tagMSGBOXPARAMSW
{
UINT cbSize;
HWND hwndOwner;
HINSTANCE hInstance;
LPCWSTR lpszText;
LPCWSTR lpszCaption;
DWORD dwStyle;
LPCWSTR lpszIcon;
DWORD_PTR dwContextHelpId;
MSGBOXCALLBACK lpfnMsgBoxCallback;
DWORD dwLanguageId;
} MSGBOXPARAMSW, *PMSGBOXPARAMSW, *LPMSGBOXPARAMSW;
#ifdef UNICODE
typedef MSGBOXPARAMSW MSGBOXPARAMS;
typedef PMSGBOXPARAMSW PMSGBOXPARAMS;
typedef LPMSGBOXPARAMSW LPMSGBOXPARAMS;
#else
typedef MSGBOXPARAMSA MSGBOXPARAMS;
typedef PMSGBOXPARAMSA PMSGBOXPARAMS;
typedef LPMSGBOXPARAMSA LPMSGBOXPARAMS;
#endif // UNICODE
WINUSERAPI
int
WINAPI
MessageBoxIndirectA(
_In_ CONST MSGBOXPARAMSA * lpmbp);
WINUSERAPI
int
WINAPI
MessageBoxIndirectW(
_In_ CONST MSGBOXPARAMSW * lpmbp);
#ifdef UNICODE
#define MessageBoxIndirect MessageBoxIndirectW
#else
#define MessageBoxIndirect MessageBoxIndirectA
#endif // !UNICODE
#endif /* WINVER >= 0x0400 */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
MessageBeep(
_In_ UINT uType);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* !NOMB */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
int
WINAPI
ShowCursor(
_In_ BOOL bShow);
WINUSERAPI
BOOL
WINAPI
SetCursorPos(
_In_ int X,
_In_ int Y);
#if(WINVER >= 0x0600)
WINUSERAPI
BOOL
WINAPI
SetPhysicalCursorPos(
_In_ int X,
_In_ int Y);
#endif /* WINVER >= 0x0600 */
WINUSERAPI
HCURSOR
WINAPI
SetCursor(
_In_opt_ HCURSOR hCursor);
WINUSERAPI
BOOL
WINAPI
GetCursorPos(
_Out_ LPPOINT lpPoint);
#if(WINVER >= 0x0600)
WINUSERAPI
BOOL
WINAPI
GetPhysicalCursorPos(
_Out_ LPPOINT lpPoint);
#endif /* WINVER >= 0x0600 */
WINUSERAPI
BOOL
WINAPI
ClipCursor(
_In_opt_ CONST RECT *lpRect);
WINUSERAPI
BOOL
WINAPI
GetClipCursor(
_Out_ LPRECT lpRect);
WINUSERAPI
HCURSOR
WINAPI
GetCursor(
VOID);
WINUSERAPI
BOOL
WINAPI
CreateCaret(
_In_ HWND hWnd,
_In_opt_ HBITMAP hBitmap,
_In_ int nWidth,
_In_ int nHeight);
WINUSERAPI
UINT
WINAPI
GetCaretBlinkTime(
VOID);
WINUSERAPI
BOOL
WINAPI
SetCaretBlinkTime(
_In_ UINT uMSeconds);
WINUSERAPI
BOOL
WINAPI
DestroyCaret(
VOID);
WINUSERAPI
BOOL
WINAPI
HideCaret(
_In_opt_ HWND hWnd);
WINUSERAPI
BOOL
WINAPI
ShowCaret(
_In_opt_ HWND hWnd);
WINUSERAPI
BOOL
WINAPI
SetCaretPos(
_In_ int X,
_In_ int Y);
WINUSERAPI
BOOL
WINAPI
GetCaretPos(
_Out_ LPPOINT lpPoint);
WINUSERAPI
BOOL
WINAPI
ClientToScreen(
_In_ HWND hWnd,
_Inout_ LPPOINT lpPoint);
WINUSERAPI
BOOL
WINAPI
ScreenToClient(
_In_ HWND hWnd,
_Inout_ LPPOINT lpPoint);
#if(WINVER >= 0x0600)
WINUSERAPI
BOOL
WINAPI
LogicalToPhysicalPoint(
_In_ HWND hWnd,
_Inout_ LPPOINT lpPoint);
WINUSERAPI
BOOL
WINAPI
PhysicalToLogicalPoint(
_In_ HWND hWnd,
_Inout_ LPPOINT lpPoint);
#endif /* WINVER >= 0x0600 */
#if(WINVER >= 0x0603)
WINUSERAPI
BOOL
WINAPI
LogicalToPhysicalPointForPerMonitorDPI(
_In_opt_ HWND hWnd,
_Inout_ LPPOINT lpPoint);
WINUSERAPI
BOOL
WINAPI
PhysicalToLogicalPointForPerMonitorDPI(
_In_opt_ HWND hWnd,
_Inout_ LPPOINT lpPoint);
#endif /* WINVER >= 0x0603 */
WINUSERAPI
int
WINAPI
MapWindowPoints(
_In_opt_ HWND hWndFrom,
_In_opt_ HWND hWndTo,
_Inout_updates_(cPoints) LPPOINT lpPoints,
_In_ UINT cPoints);
WINUSERAPI
HWND
WINAPI
WindowFromPoint(
_In_ POINT Point);
#if(WINVER >= 0x0600)
WINUSERAPI
HWND
WINAPI
WindowFromPhysicalPoint(
_In_ POINT Point);
#endif /* WINVER >= 0x0600 */
WINUSERAPI
HWND
WINAPI
ChildWindowFromPoint(
_In_ HWND hWndParent,
_In_ POINT Point);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#if(WINVER >= 0x0400)
#define CWP_ALL 0x0000
#define CWP_SKIPINVISIBLE 0x0001
#define CWP_SKIPDISABLED 0x0002
#define CWP_SKIPTRANSPARENT 0x0004
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
HWND
WINAPI
ChildWindowFromPointEx(
_In_ HWND hwnd,
_In_ POINT pt,
_In_ UINT flags);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* WINVER >= 0x0400 */
#ifndef NOCOLOR
/*
* Color Types
*/
#define CTLCOLOR_MSGBOX 0
#define CTLCOLOR_EDIT 1
#define CTLCOLOR_LISTBOX 2
#define CTLCOLOR_BTN 3
#define CTLCOLOR_DLG 4
#define CTLCOLOR_SCROLLBAR 5
#define CTLCOLOR_STATIC 6
#define CTLCOLOR_MAX 7
#define COLOR_SCROLLBAR 0
#define COLOR_BACKGROUND 1
#define COLOR_ACTIVECAPTION 2
#define COLOR_INACTIVECAPTION 3
#define COLOR_MENU 4
#define COLOR_WINDOW 5
#define COLOR_WINDOWFRAME 6
#define COLOR_MENUTEXT 7
#define COLOR_WINDOWTEXT 8
#define COLOR_CAPTIONTEXT 9
#define COLOR_ACTIVEBORDER 10
#define COLOR_INACTIVEBORDER 11
#define COLOR_APPWORKSPACE 12
#define COLOR_HIGHLIGHT 13
#define COLOR_HIGHLIGHTTEXT 14
#define COLOR_BTNFACE 15
#define COLOR_BTNSHADOW 16
#define COLOR_GRAYTEXT 17
#define COLOR_BTNTEXT 18
#define COLOR_INACTIVECAPTIONTEXT 19
#define COLOR_BTNHIGHLIGHT 20
#if(WINVER >= 0x0400)
#define COLOR_3DDKSHADOW 21
#define COLOR_3DLIGHT 22
#define COLOR_INFOTEXT 23
#define COLOR_INFOBK 24
#endif /* WINVER >= 0x0400 */
#if(WINVER >= 0x0500)
#define COLOR_HOTLIGHT 26
#define COLOR_GRADIENTACTIVECAPTION 27
#define COLOR_GRADIENTINACTIVECAPTION 28
#if(WINVER >= 0x0501)
#define COLOR_MENUHILIGHT 29
#define COLOR_MENUBAR 30
#endif /* WINVER >= 0x0501 */
#endif /* WINVER >= 0x0500 */
#if(WINVER >= 0x0400)
#define COLOR_DESKTOP COLOR_BACKGROUND
#define COLOR_3DFACE COLOR_BTNFACE
#define COLOR_3DSHADOW COLOR_BTNSHADOW
#define COLOR_3DHIGHLIGHT COLOR_BTNHIGHLIGHT
#define COLOR_3DHILIGHT COLOR_BTNHIGHLIGHT
#define COLOR_BTNHILIGHT COLOR_BTNHIGHLIGHT
#endif /* WINVER >= 0x0400 */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
DWORD
WINAPI
GetSysColor(
_In_ int nIndex);
#if(WINVER >= 0x0400)
WINUSERAPI
HBRUSH
WINAPI
GetSysColorBrush(
_In_ int nIndex);
#endif /* WINVER >= 0x0400 */
WINUSERAPI
BOOL
WINAPI
SetSysColors(
_In_ int cElements,
_In_reads_(cElements) CONST INT * lpaElements,
_In_reads_(cElements) CONST COLORREF * lpaRgbValues);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* !NOCOLOR */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
DrawFocusRect(
_In_ HDC hDC,
_In_ CONST RECT * lprc);
WINUSERAPI
int
WINAPI
FillRect(
_In_ HDC hDC,
_In_ CONST RECT *lprc,
_In_ HBRUSH hbr);
WINUSERAPI
int
WINAPI
FrameRect(
_In_ HDC hDC,
_In_ CONST RECT *lprc,
_In_ HBRUSH hbr);
WINUSERAPI
BOOL
WINAPI
InvertRect(
_In_ HDC hDC,
_In_ CONST RECT *lprc);
WINUSERAPI
BOOL
WINAPI
SetRect(
_Out_ LPRECT lprc,
_In_ int xLeft,
_In_ int yTop,
_In_ int xRight,
_In_ int yBottom);
WINUSERAPI
BOOL
WINAPI
SetRectEmpty(
_Out_ LPRECT lprc);
WINUSERAPI
BOOL
WINAPI
CopyRect(
_Out_ LPRECT lprcDst,
_In_ CONST RECT *lprcSrc);
WINUSERAPI
BOOL
WINAPI
InflateRect(
_Inout_ LPRECT lprc,
_In_ int dx,
_In_ int dy);
WINUSERAPI
BOOL
WINAPI
IntersectRect(
_Out_ LPRECT lprcDst,
_In_ CONST RECT *lprcSrc1,
_In_ CONST RECT *lprcSrc2);
WINUSERAPI
BOOL
WINAPI
UnionRect(
_Out_ LPRECT lprcDst,
_In_ CONST RECT *lprcSrc1,
_In_ CONST RECT *lprcSrc2);
WINUSERAPI
BOOL
WINAPI
SubtractRect(
_Out_ LPRECT lprcDst,
_In_ CONST RECT *lprcSrc1,
_In_ CONST RECT *lprcSrc2);
WINUSERAPI
BOOL
WINAPI
OffsetRect(
_Inout_ LPRECT lprc,
_In_ int dx,
_In_ int dy);
WINUSERAPI
BOOL
WINAPI
IsRectEmpty(
_In_ CONST RECT *lprc);
WINUSERAPI
BOOL
WINAPI
EqualRect(
_In_ CONST RECT *lprc1,
_In_ CONST RECT *lprc2);
WINUSERAPI
BOOL
WINAPI
PtInRect(
_In_ CONST RECT *lprc,
_In_ POINT pt);
#ifndef NOWINOFFSETS
WINUSERAPI
WORD
WINAPI
GetWindowWord(
_In_ HWND hWnd,
_In_ int nIndex);
WINUSERAPI
WORD
WINAPI
SetWindowWord(
_In_ HWND hWnd,
_In_ int nIndex,
_In_ WORD wNewWord);
WINUSERAPI
LONG
WINAPI
GetWindowLongA(
_In_ HWND hWnd,
_In_ int nIndex);
WINUSERAPI
LONG
WINAPI
GetWindowLongW(
_In_ HWND hWnd,
_In_ int nIndex);
#ifdef UNICODE
#define GetWindowLong GetWindowLongW
#else
#define GetWindowLong GetWindowLongA
#endif // !UNICODE
WINUSERAPI
LONG
WINAPI
SetWindowLongA(
_In_ HWND hWnd,
_In_ int nIndex,
_In_ LONG dwNewLong);
WINUSERAPI
LONG
WINAPI
SetWindowLongW(
_In_ HWND hWnd,
_In_ int nIndex,
_In_ LONG dwNewLong);
#ifdef UNICODE
#define SetWindowLong SetWindowLongW
#else
#define SetWindowLong SetWindowLongA
#endif // !UNICODE
#ifdef _WIN64
WINUSERAPI
LONG_PTR
WINAPI
GetWindowLongPtrA(
_In_ HWND hWnd,
_In_ int nIndex);
WINUSERAPI
LONG_PTR
WINAPI
GetWindowLongPtrW(
_In_ HWND hWnd,
_In_ int nIndex);
#ifdef UNICODE
#define GetWindowLongPtr GetWindowLongPtrW
#else
#define GetWindowLongPtr GetWindowLongPtrA
#endif // !UNICODE
WINUSERAPI
LONG_PTR
WINAPI
SetWindowLongPtrA(
_In_ HWND hWnd,
_In_ int nIndex,
_In_ LONG_PTR dwNewLong);
WINUSERAPI
LONG_PTR
WINAPI
SetWindowLongPtrW(
_In_ HWND hWnd,
_In_ int nIndex,
_In_ LONG_PTR dwNewLong);
#ifdef UNICODE
#define SetWindowLongPtr SetWindowLongPtrW
#else
#define SetWindowLongPtr SetWindowLongPtrA
#endif // !UNICODE
#else /* _WIN64 */
#define GetWindowLongPtrA GetWindowLongA
#define GetWindowLongPtrW GetWindowLongW
#ifdef UNICODE
#define GetWindowLongPtr GetWindowLongPtrW
#else
#define GetWindowLongPtr GetWindowLongPtrA
#endif // !UNICODE
#define SetWindowLongPtrA SetWindowLongA
#define SetWindowLongPtrW SetWindowLongW
#ifdef UNICODE
#define SetWindowLongPtr SetWindowLongPtrW
#else
#define SetWindowLongPtr SetWindowLongPtrA
#endif // !UNICODE
#endif /* _WIN64 */
WINUSERAPI
WORD
WINAPI
GetClassWord(
_In_ HWND hWnd,
_In_ int nIndex);
WINUSERAPI
WORD
WINAPI
SetClassWord(
_In_ HWND hWnd,
_In_ int nIndex,
_In_ WORD wNewWord);
WINUSERAPI
DWORD
WINAPI
GetClassLongA(
_In_ HWND hWnd,
_In_ int nIndex);
WINUSERAPI
DWORD
WINAPI
GetClassLongW(
_In_ HWND hWnd,
_In_ int nIndex);
#ifdef UNICODE
#define GetClassLong GetClassLongW
#else
#define GetClassLong GetClassLongA
#endif // !UNICODE
WINUSERAPI
DWORD
WINAPI
SetClassLongA(
_In_ HWND hWnd,
_In_ int nIndex,
_In_ LONG dwNewLong);
WINUSERAPI
DWORD
WINAPI
SetClassLongW(
_In_ HWND hWnd,
_In_ int nIndex,
_In_ LONG dwNewLong);
#ifdef UNICODE
#define SetClassLong SetClassLongW
#else
#define SetClassLong SetClassLongA
#endif // !UNICODE
#ifdef _WIN64
WINUSERAPI
ULONG_PTR
WINAPI
GetClassLongPtrA(
_In_ HWND hWnd,
_In_ int nIndex);
WINUSERAPI
ULONG_PTR
WINAPI
GetClassLongPtrW(
_In_ HWND hWnd,
_In_ int nIndex);
#ifdef UNICODE
#define GetClassLongPtr GetClassLongPtrW
#else
#define GetClassLongPtr GetClassLongPtrA
#endif // !UNICODE
WINUSERAPI
ULONG_PTR
WINAPI
SetClassLongPtrA(
_In_ HWND hWnd,
_In_ int nIndex,
_In_ LONG_PTR dwNewLong);
WINUSERAPI
ULONG_PTR
WINAPI
SetClassLongPtrW(
_In_ HWND hWnd,
_In_ int nIndex,
_In_ LONG_PTR dwNewLong);
#ifdef UNICODE
#define SetClassLongPtr SetClassLongPtrW
#else
#define SetClassLongPtr SetClassLongPtrA
#endif // !UNICODE
#else /* _WIN64 */
#define GetClassLongPtrA GetClassLongA
#define GetClassLongPtrW GetClassLongW
#ifdef UNICODE
#define GetClassLongPtr GetClassLongPtrW
#else
#define GetClassLongPtr GetClassLongPtrA
#endif // !UNICODE
#define SetClassLongPtrA SetClassLongA
#define SetClassLongPtrW SetClassLongW
#ifdef UNICODE
#define SetClassLongPtr SetClassLongPtrW
#else
#define SetClassLongPtr SetClassLongPtrA
#endif // !UNICODE
#endif /* _WIN64 */
#endif /* !NOWINOFFSETS */
#if(WINVER >= 0x0500)
WINUSERAPI
BOOL
WINAPI
GetProcessDefaultLayout(
_Out_ DWORD *pdwDefaultLayout);
WINUSERAPI
BOOL
WINAPI
SetProcessDefaultLayout(
_In_ DWORD dwDefaultLayout);
#endif /* WINVER >= 0x0500 */
WINUSERAPI
HWND
WINAPI
GetDesktopWindow(
VOID);
WINUSERAPI
HWND
WINAPI
GetParent(
_In_ HWND hWnd);
WINUSERAPI
HWND
WINAPI
SetParent(
_In_ HWND hWndChild,
_In_opt_ HWND hWndNewParent);
WINUSERAPI
BOOL
WINAPI
EnumChildWindows(
_In_opt_ HWND hWndParent,
_In_ WNDENUMPROC lpEnumFunc,
_In_ LPARAM lParam);
WINUSERAPI
HWND
WINAPI
FindWindowA(
_In_opt_ LPCSTR lpClassName,
_In_opt_ LPCSTR lpWindowName);
WINUSERAPI
HWND
WINAPI
FindWindowW(
_In_opt_ LPCWSTR lpClassName,
_In_opt_ LPCWSTR lpWindowName);
#ifdef UNICODE
#define FindWindow FindWindowW
#else
#define FindWindow FindWindowA
#endif // !UNICODE
#if(WINVER >= 0x0400)
WINUSERAPI
HWND
WINAPI
FindWindowExA(
_In_opt_ HWND hWndParent,
_In_opt_ HWND hWndChildAfter,
_In_opt_ LPCSTR lpszClass,
_In_opt_ LPCSTR lpszWindow);
WINUSERAPI
HWND
WINAPI
FindWindowExW(
_In_opt_ HWND hWndParent,
_In_opt_ HWND hWndChildAfter,
_In_opt_ LPCWSTR lpszClass,
_In_opt_ LPCWSTR lpszWindow);
#ifdef UNICODE
#define FindWindowEx FindWindowExW
#else
#define FindWindowEx FindWindowExA
#endif // !UNICODE
WINUSERAPI
HWND
WINAPI
GetShellWindow(
VOID);
#endif /* WINVER >= 0x0400 */
WINUSERAPI
BOOL
WINAPI
RegisterShellHookWindow(
_In_ HWND hwnd);
WINUSERAPI
BOOL
WINAPI
DeregisterShellHookWindow(
_In_ HWND hwnd);
WINUSERAPI
BOOL
WINAPI
EnumWindows(
_In_ WNDENUMPROC lpEnumFunc,
_In_ LPARAM lParam);
WINUSERAPI
BOOL
WINAPI
EnumThreadWindows(
_In_ DWORD dwThreadId,
_In_ WNDENUMPROC lpfn,
_In_ LPARAM lParam);
#define EnumTaskWindows(hTask, lpfn, lParam) EnumThreadWindows(HandleToUlong(hTask), lpfn, lParam)
WINUSERAPI
int
WINAPI
GetClassNameA(
_In_ HWND hWnd,
_Out_writes_to_(nMaxCount, return) LPSTR lpClassName,
_In_ int nMaxCount
);
WINUSERAPI
int
WINAPI
GetClassNameW(
_In_ HWND hWnd,
_Out_writes_to_(nMaxCount, return) LPWSTR lpClassName,
_In_ int nMaxCount
);
#ifdef UNICODE
#define GetClassName GetClassNameW
#else
#define GetClassName GetClassNameA
#endif // !UNICODE
#if defined(_M_CEE)
#undef GetClassName
__inline
int
GetClassName(
HWND hWnd,
LPTSTR lpClassName,
int nMaxCount
)
{
#ifdef UNICODE
return GetClassNameW(
#else
return GetClassNameA(
#endif
hWnd,
lpClassName,
nMaxCount
);
}
#endif /* _M_CEE */
WINUSERAPI
HWND
WINAPI
GetTopWindow(
_In_opt_ HWND hWnd);
#define GetNextWindow(hWnd, wCmd) GetWindow(hWnd, wCmd)
#define GetSysModalWindow() (NULL)
#define SetSysModalWindow(hWnd) (NULL)
WINUSERAPI
DWORD
WINAPI
GetWindowThreadProcessId(
_In_ HWND hWnd,
_Out_opt_ LPDWORD lpdwProcessId);
#if(_WIN32_WINNT >= 0x0501)
WINUSERAPI
BOOL
WINAPI
IsGUIThread(
_In_ BOOL bConvert);
#endif /* _WIN32_WINNT >= 0x0501 */
#define GetWindowTask(hWnd) \
((HANDLE)(DWORD_PTR)GetWindowThreadProcessId(hWnd, NULL))
WINUSERAPI
HWND
WINAPI
GetLastActivePopup(
_In_ HWND hWnd);
/*
* GetWindow() Constants
*/
#define GW_HWNDFIRST 0
#define GW_HWNDLAST 1
#define GW_HWNDNEXT 2
#define GW_HWNDPREV 3
#define GW_OWNER 4
#define GW_CHILD 5
#if(WINVER <= 0x0400)
#define GW_MAX 5
#else
#define GW_ENABLEDPOPUP 6
#define GW_MAX 6
#endif
WINUSERAPI
HWND
WINAPI
GetWindow(
_In_ HWND hWnd,
_In_ UINT uCmd);
#ifndef NOWH
#ifdef STRICT
WINUSERAPI
HHOOK
WINAPI
SetWindowsHookA(
_In_ int nFilterType,
_In_ HOOKPROC pfnFilterProc);
WINUSERAPI
HHOOK
WINAPI
SetWindowsHookW(
_In_ int nFilterType,
_In_ HOOKPROC pfnFilterProc);
#ifdef UNICODE
#define SetWindowsHook SetWindowsHookW
#else
#define SetWindowsHook SetWindowsHookA
#endif // !UNICODE
#else /* !STRICT */
WINUSERAPI
HOOKPROC
WINAPI
SetWindowsHookA(
_In_ int nFilterType,
_In_ HOOKPROC pfnFilterProc);
WINUSERAPI
HOOKPROC
WINAPI
SetWindowsHookW(
_In_ int nFilterType,
_In_ HOOKPROC pfnFilterProc);
#ifdef UNICODE
#define SetWindowsHook SetWindowsHookW
#else
#define SetWindowsHook SetWindowsHookA
#endif // !UNICODE
#endif /* !STRICT */
WINUSERAPI
BOOL
WINAPI
UnhookWindowsHook(
_In_ int nCode,
_In_ HOOKPROC pfnFilterProc);
WINUSERAPI
HHOOK
WINAPI
SetWindowsHookExA(
_In_ int idHook,
_In_ HOOKPROC lpfn,
_In_opt_ HINSTANCE hmod,
_In_ DWORD dwThreadId);
WINUSERAPI
HHOOK
WINAPI
SetWindowsHookExW(
_In_ int idHook,
_In_ HOOKPROC lpfn,
_In_opt_ HINSTANCE hmod,
_In_ DWORD dwThreadId);
#ifdef UNICODE
#define SetWindowsHookEx SetWindowsHookExW
#else
#define SetWindowsHookEx SetWindowsHookExA
#endif // !UNICODE
WINUSERAPI
BOOL
WINAPI
UnhookWindowsHookEx(
_In_ HHOOK hhk);
WINUSERAPI
LRESULT
WINAPI
CallNextHookEx(
_In_opt_ HHOOK hhk,
_In_ int nCode,
_In_ WPARAM wParam,
_In_ LPARAM lParam);
/*
* Macros for source-level compatibility with old functions.
*/
#ifdef STRICT
#define DefHookProc(nCode, wParam, lParam, phhk)\
CallNextHookEx(*phhk, nCode, wParam, lParam)
#else
#define DefHookProc(nCode, wParam, lParam, phhk)\
CallNextHookEx((HHOOK)*phhk, nCode, wParam, lParam)
#endif /* STRICT */
#endif /* !NOWH */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#ifndef NOMENUS
/* ;win40 -- A lot of MF_* flags have been renamed as MFT_* and MFS_* flags */
/*
* Menu flags for Add/Check/EnableMenuItem()
*/
#define MF_INSERT 0x00000000L
#define MF_CHANGE 0x00000080L
#define MF_APPEND 0x00000100L
#define MF_DELETE 0x00000200L
#define MF_REMOVE 0x00001000L
#define MF_BYCOMMAND 0x00000000L
#define MF_BYPOSITION 0x00000400L
#define MF_SEPARATOR 0x00000800L
#define MF_ENABLED 0x00000000L
#define MF_GRAYED 0x00000001L
#define MF_DISABLED 0x00000002L
#define MF_UNCHECKED 0x00000000L
#define MF_CHECKED 0x00000008L
#define MF_USECHECKBITMAPS 0x00000200L
#define MF_STRING 0x00000000L
#define MF_BITMAP 0x00000004L
#define MF_OWNERDRAW 0x00000100L
#define MF_POPUP 0x00000010L
#define MF_MENUBARBREAK 0x00000020L
#define MF_MENUBREAK 0x00000040L
#define MF_UNHILITE 0x00000000L
#define MF_HILITE 0x00000080L
#if(WINVER >= 0x0400)
#define MF_DEFAULT 0x00001000L
#endif /* WINVER >= 0x0400 */
#define MF_SYSMENU 0x00002000L
#define MF_HELP 0x00004000L
#if(WINVER >= 0x0400)
#define MF_RIGHTJUSTIFY 0x00004000L
#endif /* WINVER >= 0x0400 */
#define MF_MOUSESELECT 0x00008000L
#if(WINVER >= 0x0400)
#define MF_END 0x00000080L /* Obsolete -- only used by old RES files */
#endif /* WINVER >= 0x0400 */
#if(WINVER >= 0x0400)
#define MFT_STRING MF_STRING
#define MFT_BITMAP MF_BITMAP
#define MFT_MENUBARBREAK MF_MENUBARBREAK
#define MFT_MENUBREAK MF_MENUBREAK
#define MFT_OWNERDRAW MF_OWNERDRAW
#define MFT_RADIOCHECK 0x00000200L
#define MFT_SEPARATOR MF_SEPARATOR
#define MFT_RIGHTORDER 0x00002000L
#define MFT_RIGHTJUSTIFY MF_RIGHTJUSTIFY
/* Menu flags for Add/Check/EnableMenuItem() */
#define MFS_GRAYED 0x00000003L
#define MFS_DISABLED MFS_GRAYED
#define MFS_CHECKED MF_CHECKED
#define MFS_HILITE MF_HILITE
#define MFS_ENABLED MF_ENABLED
#define MFS_UNCHECKED MF_UNCHECKED
#define MFS_UNHILITE MF_UNHILITE
#define MFS_DEFAULT MF_DEFAULT
#endif /* WINVER >= 0x0400 */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#if(WINVER >= 0x0400)
WINUSERAPI
BOOL
WINAPI
CheckMenuRadioItem(
_In_ HMENU hmenu,
_In_ UINT first,
_In_ UINT last,
_In_ UINT check,
_In_ UINT flags);
#endif /* WINVER >= 0x0400 */
/*
* Menu item resource format
*/
typedef struct {
WORD versionNumber;
WORD offset;
} MENUITEMTEMPLATEHEADER, *PMENUITEMTEMPLATEHEADER;
typedef struct { // version 0
WORD mtOption;
WORD mtID;
WCHAR mtString[1];
} MENUITEMTEMPLATE, *PMENUITEMTEMPLATE;
#define MF_END 0x00000080L
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* !NOMENUS */
#ifndef NOSYSCOMMANDS
/*
* System Menu Command Values
*/
#define SC_SIZE 0xF000
#define SC_MOVE 0xF010
#define SC_MINIMIZE 0xF020
#define SC_MAXIMIZE 0xF030
#define SC_NEXTWINDOW 0xF040
#define SC_PREVWINDOW 0xF050
#define SC_CLOSE 0xF060
#define SC_VSCROLL 0xF070
#define SC_HSCROLL 0xF080
#define SC_MOUSEMENU 0xF090
#define SC_KEYMENU 0xF100
#define SC_ARRANGE 0xF110
#define SC_RESTORE 0xF120
#define SC_TASKLIST 0xF130
#define SC_SCREENSAVE 0xF140
#define SC_HOTKEY 0xF150
#if(WINVER >= 0x0400)
#define SC_DEFAULT 0xF160
#define SC_MONITORPOWER 0xF170
#define SC_CONTEXTHELP 0xF180
#define SC_SEPARATOR 0xF00F
#endif /* WINVER >= 0x0400 */
#if(WINVER >= 0x0600)
#define SCF_ISSECURE 0x00000001
#endif /* WINVER >= 0x0600 */
#define GET_SC_WPARAM(wParam) ((int)wParam & 0xFFF0)
/*
* Obsolete names
*/
#define SC_ICON SC_MINIMIZE
#define SC_ZOOM SC_MAXIMIZE
#endif /* !NOSYSCOMMANDS */
/*
* Resource Loading Routines
*/
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
HBITMAP
WINAPI
LoadBitmapA(
_In_opt_ HINSTANCE hInstance,
_In_ LPCSTR lpBitmapName);
WINUSERAPI
HBITMAP
WINAPI
LoadBitmapW(
_In_opt_ HINSTANCE hInstance,
_In_ LPCWSTR lpBitmapName);
#ifdef UNICODE
#define LoadBitmap LoadBitmapW
#else
#define LoadBitmap LoadBitmapA
#endif // !UNICODE
WINUSERAPI
HCURSOR
WINAPI
LoadCursorA(
_In_opt_ HINSTANCE hInstance,
_In_ LPCSTR lpCursorName);
WINUSERAPI
HCURSOR
WINAPI
LoadCursorW(
_In_opt_ HINSTANCE hInstance,
_In_ LPCWSTR lpCursorName);
#ifdef UNICODE
#define LoadCursor LoadCursorW
#else
#define LoadCursor LoadCursorA
#endif // !UNICODE
WINUSERAPI
HCURSOR
WINAPI
LoadCursorFromFileA(
_In_ LPCSTR lpFileName);
WINUSERAPI
HCURSOR
WINAPI
LoadCursorFromFileW(
_In_ LPCWSTR lpFileName);
#ifdef UNICODE
#define LoadCursorFromFile LoadCursorFromFileW
#else
#define LoadCursorFromFile LoadCursorFromFileA
#endif // !UNICODE
WINUSERAPI
HCURSOR
WINAPI
CreateCursor(
_In_opt_ HINSTANCE hInst,
_In_ int xHotSpot,
_In_ int yHotSpot,
_In_ int nWidth,
_In_ int nHeight,
_In_ CONST VOID *pvANDPlane,
_In_ CONST VOID *pvXORPlane);
WINUSERAPI
BOOL
WINAPI
DestroyCursor(
_In_ HCURSOR hCursor);
#ifndef _MAC
#define CopyCursor(pcur) ((HCURSOR)CopyIcon((HICON)(pcur)))
#else
WINUSERAPI
HCURSOR
WINAPI
CopyCursor(
_In_ HCURSOR hCursor);
#endif
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* Standard Cursor IDs
*/
#define IDC_ARROW MAKEINTRESOURCE(32512)
#define IDC_IBEAM MAKEINTRESOURCE(32513)
#define IDC_WAIT MAKEINTRESOURCE(32514)
#define IDC_CROSS MAKEINTRESOURCE(32515)
#define IDC_UPARROW MAKEINTRESOURCE(32516)
#define IDC_SIZE MAKEINTRESOURCE(32640) /* OBSOLETE: use IDC_SIZEALL */
#define IDC_ICON MAKEINTRESOURCE(32641) /* OBSOLETE: use IDC_ARROW */
#define IDC_SIZENWSE MAKEINTRESOURCE(32642)
#define IDC_SIZENESW MAKEINTRESOURCE(32643)
#define IDC_SIZEWE MAKEINTRESOURCE(32644)
#define IDC_SIZENS MAKEINTRESOURCE(32645)
#define IDC_SIZEALL MAKEINTRESOURCE(32646)
#define IDC_NO MAKEINTRESOURCE(32648) /*not in win3.1 */
#if(WINVER >= 0x0500)
#define IDC_HAND MAKEINTRESOURCE(32649)
#endif /* WINVER >= 0x0500 */
#define IDC_APPSTARTING MAKEINTRESOURCE(32650) /*not in win3.1 */
#if(WINVER >= 0x0400)
#define IDC_HELP MAKEINTRESOURCE(32651)
#endif /* WINVER >= 0x0400 */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
SetSystemCursor(
_In_ HCURSOR hcur,
_In_ DWORD id);
typedef struct _ICONINFO {
BOOL fIcon;
DWORD xHotspot;
DWORD yHotspot;
HBITMAP hbmMask;
HBITMAP hbmColor;
} ICONINFO;
typedef ICONINFO *PICONINFO;
WINUSERAPI
HICON
WINAPI
LoadIconA(
_In_opt_ HINSTANCE hInstance,
_In_ LPCSTR lpIconName);
WINUSERAPI
HICON
WINAPI
LoadIconW(
_In_opt_ HINSTANCE hInstance,
_In_ LPCWSTR lpIconName);
#ifdef UNICODE
#define LoadIcon LoadIconW
#else
#define LoadIcon LoadIconA
#endif // !UNICODE
WINUSERAPI
UINT
WINAPI
PrivateExtractIconsA(
_In_reads_(MAX_PATH) LPCSTR szFileName,
_In_ int nIconIndex,
_In_ int cxIcon,
_In_ int cyIcon,
_Out_writes_opt_(nIcons) HICON *phicon,
_Out_writes_opt_(nIcons) UINT *piconid,
_In_ UINT nIcons,
_In_ UINT flags);
WINUSERAPI
UINT
WINAPI
PrivateExtractIconsW(
_In_reads_(MAX_PATH) LPCWSTR szFileName,
_In_ int nIconIndex,
_In_ int cxIcon,
_In_ int cyIcon,
_Out_writes_opt_(nIcons) HICON *phicon,
_Out_writes_opt_(nIcons) UINT *piconid,
_In_ UINT nIcons,
_In_ UINT flags);
#ifdef UNICODE
#define PrivateExtractIcons PrivateExtractIconsW
#else
#define PrivateExtractIcons PrivateExtractIconsA
#endif // !UNICODE
WINUSERAPI
HICON
WINAPI
CreateIcon(
_In_opt_ HINSTANCE hInstance,
_In_ int nWidth,
_In_ int nHeight,
_In_ BYTE cPlanes,
_In_ BYTE cBitsPixel,
_In_ CONST BYTE *lpbANDbits,
_In_ CONST BYTE *lpbXORbits);
WINUSERAPI
BOOL
WINAPI
DestroyIcon(
_In_ HICON hIcon);
WINUSERAPI
int
WINAPI
LookupIconIdFromDirectory(
_In_reads_bytes_(sizeof(WORD) * 3) PBYTE presbits,
_In_ BOOL fIcon);
#if(WINVER >= 0x0400)
WINUSERAPI
int
WINAPI
LookupIconIdFromDirectoryEx(
_In_reads_bytes_(sizeof(WORD) * 3) PBYTE presbits,
_In_ BOOL fIcon,
_In_ int cxDesired,
_In_ int cyDesired,
_In_ UINT Flags);
#endif /* WINVER >= 0x0400 */
WINUSERAPI
HICON
WINAPI
CreateIconFromResource(
_In_reads_bytes_(dwResSize) PBYTE presbits,
_In_ DWORD dwResSize,
_In_ BOOL fIcon,
_In_ DWORD dwVer);
#if(WINVER >= 0x0400)
WINUSERAPI
HICON
WINAPI
CreateIconFromResourceEx(
_In_reads_bytes_(dwResSize) PBYTE presbits,
_In_ DWORD dwResSize,
_In_ BOOL fIcon,
_In_ DWORD dwVer,
_In_ int cxDesired,
_In_ int cyDesired,
_In_ UINT Flags);
/* Icon/Cursor header */
typedef struct tagCURSORSHAPE
{
int xHotSpot;
int yHotSpot;
int cx;
int cy;
int cbWidth;
BYTE Planes;
BYTE BitsPixel;
} CURSORSHAPE, FAR *LPCURSORSHAPE;
#endif /* WINVER >= 0x0400 */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#define IMAGE_BITMAP 0
#define IMAGE_ICON 1
#define IMAGE_CURSOR 2
#if(WINVER >= 0x0400)
#define IMAGE_ENHMETAFILE 3
#define LR_DEFAULTCOLOR 0x00000000
#define LR_MONOCHROME 0x00000001
#define LR_COLOR 0x00000002
#define LR_COPYRETURNORG 0x00000004
#define LR_COPYDELETEORG 0x00000008
#define LR_LOADFROMFILE 0x00000010
#define LR_LOADTRANSPARENT 0x00000020
#define LR_DEFAULTSIZE 0x00000040
#define LR_VGACOLOR 0x00000080
#define LR_LOADMAP3DCOLORS 0x00001000
#define LR_CREATEDIBSECTION 0x00002000
#define LR_COPYFROMRESOURCE 0x00004000
#define LR_SHARED 0x00008000
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
HANDLE
WINAPI
LoadImageA(
_In_opt_ HINSTANCE hInst,
_In_ LPCSTR name,
_In_ UINT type,
_In_ int cx,
_In_ int cy,
_In_ UINT fuLoad);
WINUSERAPI
HANDLE
WINAPI
LoadImageW(
_In_opt_ HINSTANCE hInst,
_In_ LPCWSTR name,
_In_ UINT type,
_In_ int cx,
_In_ int cy,
_In_ UINT fuLoad);
#ifdef UNICODE
#define LoadImage LoadImageW
#else
#define LoadImage LoadImageA
#endif // !UNICODE
WINUSERAPI
HANDLE
WINAPI
CopyImage(
_In_ HANDLE h,
_In_ UINT type,
_In_ int cx,
_In_ int cy,
_In_ UINT flags);
#define DI_MASK 0x0001
#define DI_IMAGE 0x0002
#define DI_NORMAL 0x0003
#define DI_COMPAT 0x0004
#define DI_DEFAULTSIZE 0x0008
#if(_WIN32_WINNT >= 0x0501)
#define DI_NOMIRROR 0x0010
#endif /* _WIN32_WINNT >= 0x0501 */
WINUSERAPI BOOL WINAPI DrawIconEx(
_In_ HDC hdc,
_In_ int xLeft,
_In_ int yTop,
_In_ HICON hIcon,
_In_ int cxWidth,
_In_ int cyWidth,
_In_ UINT istepIfAniCur,
_In_opt_ HBRUSH hbrFlickerFreeDraw,
_In_ UINT diFlags);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* WINVER >= 0x0400 */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
HICON
WINAPI
CreateIconIndirect(
_In_ PICONINFO piconinfo);
WINUSERAPI
HICON
WINAPI
CopyIcon(
_In_ HICON hIcon);
WINUSERAPI
BOOL
WINAPI
GetIconInfo(
_In_ HICON hIcon,
_Out_ PICONINFO piconinfo);
#if(_WIN32_WINNT >= 0x0600)
typedef struct _ICONINFOEXA {
DWORD cbSize;
BOOL fIcon;
DWORD xHotspot;
DWORD yHotspot;
HBITMAP hbmMask;
HBITMAP hbmColor;
WORD wResID;
CHAR szModName[MAX_PATH];
CHAR szResName[MAX_PATH];
} ICONINFOEXA, *PICONINFOEXA;
typedef struct _ICONINFOEXW {
DWORD cbSize;
BOOL fIcon;
DWORD xHotspot;
DWORD yHotspot;
HBITMAP hbmMask;
HBITMAP hbmColor;
WORD wResID;
WCHAR szModName[MAX_PATH];
WCHAR szResName[MAX_PATH];
} ICONINFOEXW, *PICONINFOEXW;
#ifdef UNICODE
typedef ICONINFOEXW ICONINFOEX;
typedef PICONINFOEXW PICONINFOEX;
#else
typedef ICONINFOEXA ICONINFOEX;
typedef PICONINFOEXA PICONINFOEX;
#endif // UNICODE
WINUSERAPI
BOOL
WINAPI
GetIconInfoExA(
_In_ HICON hicon,
_Inout_ PICONINFOEXA piconinfo);
WINUSERAPI
BOOL
WINAPI
GetIconInfoExW(
_In_ HICON hicon,
_Inout_ PICONINFOEXW piconinfo);
#ifdef UNICODE
#define GetIconInfoEx GetIconInfoExW
#else
#define GetIconInfoEx GetIconInfoExA
#endif // !UNICODE
#endif /* _WIN32_WINNT >= 0x0600 */
#if(WINVER >= 0x0400)
#define RES_ICON 1
#define RES_CURSOR 2
#endif /* WINVER >= 0x0400 */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#ifdef OEMRESOURCE
/*
* OEM Resource Ordinal Numbers
*/
#define OBM_CLOSE 32754
#define OBM_UPARROW 32753
#define OBM_DNARROW 32752
#define OBM_RGARROW 32751
#define OBM_LFARROW 32750
#define OBM_REDUCE 32749
#define OBM_ZOOM 32748
#define OBM_RESTORE 32747
#define OBM_REDUCED 32746
#define OBM_ZOOMD 32745
#define OBM_RESTORED 32744
#define OBM_UPARROWD 32743
#define OBM_DNARROWD 32742
#define OBM_RGARROWD 32741
#define OBM_LFARROWD 32740
#define OBM_MNARROW 32739
#define OBM_COMBO 32738
#define OBM_UPARROWI 32737
#define OBM_DNARROWI 32736
#define OBM_RGARROWI 32735
#define OBM_LFARROWI 32734
#define OBM_OLD_CLOSE 32767
#define OBM_SIZE 32766
#define OBM_OLD_UPARROW 32765
#define OBM_OLD_DNARROW 32764
#define OBM_OLD_RGARROW 32763
#define OBM_OLD_LFARROW 32762
#define OBM_BTSIZE 32761
#define OBM_CHECK 32760
#define OBM_CHECKBOXES 32759
#define OBM_BTNCORNERS 32758
#define OBM_OLD_REDUCE 32757
#define OBM_OLD_ZOOM 32756
#define OBM_OLD_RESTORE 32755
#define OCR_NORMAL 32512
#define OCR_IBEAM 32513
#define OCR_WAIT 32514
#define OCR_CROSS 32515
#define OCR_UP 32516
#define OCR_SIZE 32640 /* OBSOLETE: use OCR_SIZEALL */
#define OCR_ICON 32641 /* OBSOLETE: use OCR_NORMAL */
#define OCR_SIZENWSE 32642
#define OCR_SIZENESW 32643
#define OCR_SIZEWE 32644
#define OCR_SIZENS 32645
#define OCR_SIZEALL 32646
#define OCR_ICOCUR 32647 /* OBSOLETE: use OIC_WINLOGO */
#define OCR_NO 32648
#if(WINVER >= 0x0500)
#define OCR_HAND 32649
#endif /* WINVER >= 0x0500 */
#if(WINVER >= 0x0400)
#define OCR_APPSTARTING 32650
#endif /* WINVER >= 0x0400 */
#define OIC_SAMPLE 32512
#define OIC_HAND 32513
#define OIC_QUES 32514
#define OIC_BANG 32515
#define OIC_NOTE 32516
#if(WINVER >= 0x0400)
#define OIC_WINLOGO 32517
#define OIC_WARNING OIC_BANG
#define OIC_ERROR OIC_HAND
#define OIC_INFORMATION OIC_NOTE
#endif /* WINVER >= 0x0400 */
#if(WINVER >= 0x0600)
#define OIC_SHIELD 32518
#endif /* WINVER >= 0x0600 */
#endif /* OEMRESOURCE */
#define ORD_LANGDRIVER 1 /* The ordinal number for the entry point of
** language drivers.
*/
#ifndef NOICONS
/*
* Standard Icon IDs
*/
#ifdef RC_INVOKED
#define IDI_APPLICATION 32512
#define IDI_HAND 32513
#define IDI_QUESTION 32514
#define IDI_EXCLAMATION 32515
#define IDI_ASTERISK 32516
#if(WINVER >= 0x0400)
#define IDI_WINLOGO 32517
#endif /* WINVER >= 0x0400 */
#if(WINVER >= 0x0600)
#define IDI_SHIELD 32518
#endif /* WINVER >= 0x0600 */
#else
#define IDI_APPLICATION MAKEINTRESOURCE(32512)
#define IDI_HAND MAKEINTRESOURCE(32513)
#define IDI_QUESTION MAKEINTRESOURCE(32514)
#define IDI_EXCLAMATION MAKEINTRESOURCE(32515)
#define IDI_ASTERISK MAKEINTRESOURCE(32516)
#if(WINVER >= 0x0400)
#define IDI_WINLOGO MAKEINTRESOURCE(32517)
#endif /* WINVER >= 0x0400 */
#if(WINVER >= 0x0600)
#define IDI_SHIELD MAKEINTRESOURCE(32518)
#endif /* WINVER >= 0x0600 */
#endif /* RC_INVOKED */
#if(WINVER >= 0x0400)
#define IDI_WARNING IDI_EXCLAMATION
#define IDI_ERROR IDI_HAND
#define IDI_INFORMATION IDI_ASTERISK
#endif /* WINVER >= 0x0400 */
#endif /* !NOICONS */
#ifdef NOAPISET
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
int
WINAPI
LoadStringA(
_In_opt_ HINSTANCE hInstance,
_In_ UINT uID,
_Out_writes_to_(cchBufferMax, return + 1) LPSTR lpBuffer,
_In_ int cchBufferMax);
WINUSERAPI
int
WINAPI
LoadStringW(
_In_opt_ HINSTANCE hInstance,
_In_ UINT uID,
_Out_writes_to_(cchBufferMax, return + 1) LPWSTR lpBuffer,
_In_ int cchBufferMax);
#ifdef UNICODE
#define LoadString LoadStringW
#else
#define LoadString LoadStringA
#endif // !UNICODE
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif
/*
* Dialog Box Command IDs
*/
#define IDOK 1
#define IDCANCEL 2
#define IDABORT 3
#define IDRETRY 4
#define IDIGNORE 5
#define IDYES 6
#define IDNO 7
#if(WINVER >= 0x0400)
#define IDCLOSE 8
#define IDHELP 9
#endif /* WINVER >= 0x0400 */
#if(WINVER >= 0x0500)
#define IDTRYAGAIN 10
#define IDCONTINUE 11
#endif /* WINVER >= 0x0500 */
#if(WINVER >= 0x0501)
#ifndef IDTIMEOUT
#define IDTIMEOUT 32000
#endif
#endif /* WINVER >= 0x0501 */
#ifndef NOCTLMGR
/*
* Control Manager Structures and Definitions
*/
#ifndef NOWINSTYLES
/*
* Edit Control Styles
*/
#define ES_LEFT 0x0000L
#define ES_CENTER 0x0001L
#define ES_RIGHT 0x0002L
#define ES_MULTILINE 0x0004L
#define ES_UPPERCASE 0x0008L
#define ES_LOWERCASE 0x0010L
#define ES_PASSWORD 0x0020L
#define ES_AUTOVSCROLL 0x0040L
#define ES_AUTOHSCROLL 0x0080L
#define ES_NOHIDESEL 0x0100L
#define ES_OEMCONVERT 0x0400L
#define ES_READONLY 0x0800L
#define ES_WANTRETURN 0x1000L
#if(WINVER >= 0x0400)
#define ES_NUMBER 0x2000L
#endif /* WINVER >= 0x0400 */
#endif /* !NOWINSTYLES */
/*
* Edit Control Notification Codes
*/
#define EN_SETFOCUS 0x0100
#define EN_KILLFOCUS 0x0200
#define EN_CHANGE 0x0300
#define EN_UPDATE 0x0400
#define EN_ERRSPACE 0x0500
#define EN_MAXTEXT 0x0501
#define EN_HSCROLL 0x0601
#define EN_VSCROLL 0x0602
#if(_WIN32_WINNT >= 0x0500)
#define EN_ALIGN_LTR_EC 0x0700
#define EN_ALIGN_RTL_EC 0x0701
#endif /* _WIN32_WINNT >= 0x0500 */
#if(WINVER >= 0x0400)
/* Edit control EM_SETMARGIN parameters */
#define EC_LEFTMARGIN 0x0001
#define EC_RIGHTMARGIN 0x0002
#define EC_USEFONTINFO 0xffff
#endif /* WINVER >= 0x0400 */
#if(WINVER >= 0x0500)
/* wParam of EM_GET/SETIMESTATUS */
#define EMSIS_COMPOSITIONSTRING 0x0001
/* lParam for EMSIS_COMPOSITIONSTRING */
#define EIMES_GETCOMPSTRATONCE 0x0001
#define EIMES_CANCELCOMPSTRINFOCUS 0x0002
#define EIMES_COMPLETECOMPSTRKILLFOCUS 0x0004
#endif /* WINVER >= 0x0500 */
#ifndef NOWINMESSAGES
/*
* Edit Control Messages
*/
#define EM_GETSEL 0x00B0
#define EM_SETSEL 0x00B1
#define EM_GETRECT 0x00B2
#define EM_SETRECT 0x00B3
#define EM_SETRECTNP 0x00B4
#define EM_SCROLL 0x00B5
#define EM_LINESCROLL 0x00B6
#define EM_SCROLLCARET 0x00B7
#define EM_GETMODIFY 0x00B8
#define EM_SETMODIFY 0x00B9
#define EM_GETLINECOUNT 0x00BA
#define EM_LINEINDEX 0x00BB
#define EM_SETHANDLE 0x00BC
#define EM_GETHANDLE 0x00BD
#define EM_GETTHUMB 0x00BE
#define EM_LINELENGTH 0x00C1
#define EM_REPLACESEL 0x00C2
#define EM_GETLINE 0x00C4
#define EM_LIMITTEXT 0x00C5
#define EM_CANUNDO 0x00C6
#define EM_UNDO 0x00C7
#define EM_FMTLINES 0x00C8
#define EM_LINEFROMCHAR 0x00C9
#define EM_SETTABSTOPS 0x00CB
#define EM_SETPASSWORDCHAR 0x00CC
#define EM_EMPTYUNDOBUFFER 0x00CD
#define EM_GETFIRSTVISIBLELINE 0x00CE
#define EM_SETREADONLY 0x00CF
#define EM_SETWORDBREAKPROC 0x00D0
#define EM_GETWORDBREAKPROC 0x00D1
#define EM_GETPASSWORDCHAR 0x00D2
#if(WINVER >= 0x0400)
#define EM_SETMARGINS 0x00D3
#define EM_GETMARGINS 0x00D4
#define EM_SETLIMITTEXT EM_LIMITTEXT /* ;win40 Name change */
#define EM_GETLIMITTEXT 0x00D5
#define EM_POSFROMCHAR 0x00D6
#define EM_CHARFROMPOS 0x00D7
#endif /* WINVER >= 0x0400 */
#if(WINVER >= 0x0500)
#define EM_SETIMESTATUS 0x00D8
#define EM_GETIMESTATUS 0x00D9
#endif /* WINVER >= 0x0500 */
#endif /* !NOWINMESSAGES */
/*
* EDITWORDBREAKPROC code values
*/
#define WB_LEFT 0
#define WB_RIGHT 1
#define WB_ISDELIMITER 2
/*
* Button Control Styles
*/
#define BS_PUSHBUTTON 0x00000000L
#define BS_DEFPUSHBUTTON 0x00000001L
#define BS_CHECKBOX 0x00000002L
#define BS_AUTOCHECKBOX 0x00000003L
#define BS_RADIOBUTTON 0x00000004L
#define BS_3STATE 0x00000005L
#define BS_AUTO3STATE 0x00000006L
#define BS_GROUPBOX 0x00000007L
#define BS_USERBUTTON 0x00000008L
#define BS_AUTORADIOBUTTON 0x00000009L
#define BS_PUSHBOX 0x0000000AL
#define BS_OWNERDRAW 0x0000000BL
#define BS_TYPEMASK 0x0000000FL
#define BS_LEFTTEXT 0x00000020L
#if(WINVER >= 0x0400)
#define BS_TEXT 0x00000000L
#define BS_ICON 0x00000040L
#define BS_BITMAP 0x00000080L
#define BS_LEFT 0x00000100L
#define BS_RIGHT 0x00000200L
#define BS_CENTER 0x00000300L
#define BS_TOP 0x00000400L
#define BS_BOTTOM 0x00000800L
#define BS_VCENTER 0x00000C00L
#define BS_PUSHLIKE 0x00001000L
#define BS_MULTILINE 0x00002000L
#define BS_NOTIFY 0x00004000L
#define BS_FLAT 0x00008000L
#define BS_RIGHTBUTTON BS_LEFTTEXT
#endif /* WINVER >= 0x0400 */
/*
* User Button Notification Codes
*/
#define BN_CLICKED 0
#define BN_PAINT 1
#define BN_HILITE 2
#define BN_UNHILITE 3
#define BN_DISABLE 4
#define BN_DOUBLECLICKED 5
#if(WINVER >= 0x0400)
#define BN_PUSHED BN_HILITE
#define BN_UNPUSHED BN_UNHILITE
#define BN_DBLCLK BN_DOUBLECLICKED
#define BN_SETFOCUS 6
#define BN_KILLFOCUS 7
#endif /* WINVER >= 0x0400 */
/*
* Button Control Messages
*/
#define BM_GETCHECK 0x00F0
#define BM_SETCHECK 0x00F1
#define BM_GETSTATE 0x00F2
#define BM_SETSTATE 0x00F3
#define BM_SETSTYLE 0x00F4
#if(WINVER >= 0x0400)
#define BM_CLICK 0x00F5
#define BM_GETIMAGE 0x00F6
#define BM_SETIMAGE 0x00F7
#endif /* WINVER >= 0x0400 */
#if(WINVER >= 0x0600)
#define BM_SETDONTCLICK 0x00F8
#endif /* WINVER >= 0x0600 */
#if(WINVER >= 0x0400)
#define BST_UNCHECKED 0x0000
#define BST_CHECKED 0x0001
#define BST_INDETERMINATE 0x0002
#define BST_PUSHED 0x0004
#define BST_FOCUS 0x0008
#endif /* WINVER >= 0x0400 */
/*
* Static Control Constants
*/
#define SS_LEFT 0x00000000L
#define SS_CENTER 0x00000001L
#define SS_RIGHT 0x00000002L
#define SS_ICON 0x00000003L
#define SS_BLACKRECT 0x00000004L
#define SS_GRAYRECT 0x00000005L
#define SS_WHITERECT 0x00000006L
#define SS_BLACKFRAME 0x00000007L
#define SS_GRAYFRAME 0x00000008L
#define SS_WHITEFRAME 0x00000009L
#define SS_USERITEM 0x0000000AL
#define SS_SIMPLE 0x0000000BL
#define SS_LEFTNOWORDWRAP 0x0000000CL
#if(WINVER >= 0x0400)
#define SS_OWNERDRAW 0x0000000DL
#define SS_BITMAP 0x0000000EL
#define SS_ENHMETAFILE 0x0000000FL
#define SS_ETCHEDHORZ 0x00000010L
#define SS_ETCHEDVERT 0x00000011L
#define SS_ETCHEDFRAME 0x00000012L
#define SS_TYPEMASK 0x0000001FL
#endif /* WINVER >= 0x0400 */
#if(WINVER >= 0x0501)
#define SS_REALSIZECONTROL 0x00000040L
#endif /* WINVER >= 0x0501 */
#define SS_NOPREFIX 0x00000080L /* Don't do "&" character translation */
#if(WINVER >= 0x0400)
#define SS_NOTIFY 0x00000100L
#define SS_CENTERIMAGE 0x00000200L
#define SS_RIGHTJUST 0x00000400L
#define SS_REALSIZEIMAGE 0x00000800L
#define SS_SUNKEN 0x00001000L
#define SS_EDITCONTROL 0x00002000L
#define SS_ENDELLIPSIS 0x00004000L
#define SS_PATHELLIPSIS 0x00008000L
#define SS_WORDELLIPSIS 0x0000C000L
#define SS_ELLIPSISMASK 0x0000C000L
#endif /* WINVER >= 0x0400 */
#ifndef NOWINMESSAGES
/*
* Static Control Mesages
*/
#define STM_SETICON 0x0170
#define STM_GETICON 0x0171
#if(WINVER >= 0x0400)
#define STM_SETIMAGE 0x0172
#define STM_GETIMAGE 0x0173
#define STN_CLICKED 0
#define STN_DBLCLK 1
#define STN_ENABLE 2
#define STN_DISABLE 3
#endif /* WINVER >= 0x0400 */
#define STM_MSGMAX 0x0174
#endif /* !NOWINMESSAGES */
/*
* Dialog window class
*/
#define WC_DIALOG (MAKEINTATOM(0x8002))
/*
* Get/SetWindowWord/Long offsets for use with WC_DIALOG windows
*/
#define DWL_MSGRESULT 0
#define DWL_DLGPROC 4
#define DWL_USER 8
#ifdef _WIN64
#undef DWL_MSGRESULT
#undef DWL_DLGPROC
#undef DWL_USER
#endif /* _WIN64 */
#define DWLP_MSGRESULT 0
#define DWLP_DLGPROC DWLP_MSGRESULT + sizeof(LRESULT)
#define DWLP_USER DWLP_DLGPROC + sizeof(DLGPROC)
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
/*
* Dialog Manager Routines
*/
#ifndef NOMSG
WINUSERAPI
BOOL
WINAPI
IsDialogMessageA(
_In_ HWND hDlg,
_In_ LPMSG lpMsg);
WINUSERAPI
BOOL
WINAPI
IsDialogMessageW(
_In_ HWND hDlg,
_In_ LPMSG lpMsg);
#ifdef UNICODE
#define IsDialogMessage IsDialogMessageW
#else
#define IsDialogMessage IsDialogMessageA
#endif // !UNICODE
#endif /* !NOMSG */
WINUSERAPI
BOOL
WINAPI
MapDialogRect(
_In_ HWND hDlg,
_Inout_ LPRECT lpRect);
WINUSERAPI
int
WINAPI
DlgDirListA(
_In_ HWND hDlg,
_Inout_ LPSTR lpPathSpec,
_In_ int nIDListBox,
_In_ int nIDStaticPath,
_In_ UINT uFileType);
WINUSERAPI
int
WINAPI
DlgDirListW(
_In_ HWND hDlg,
_Inout_ LPWSTR lpPathSpec,
_In_ int nIDListBox,
_In_ int nIDStaticPath,
_In_ UINT uFileType);
#ifdef UNICODE
#define DlgDirList DlgDirListW
#else
#define DlgDirList DlgDirListA
#endif // !UNICODE
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* DlgDirList, DlgDirListComboBox flags values
*/
#define DDL_READWRITE 0x0000
#define DDL_READONLY 0x0001
#define DDL_HIDDEN 0x0002
#define DDL_SYSTEM 0x0004
#define DDL_DIRECTORY 0x0010
#define DDL_ARCHIVE 0x0020
#define DDL_POSTMSGS 0x2000
#define DDL_DRIVES 0x4000
#define DDL_EXCLUSIVE 0x8000
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
DlgDirSelectExA(
_In_ HWND hwndDlg,
_Out_writes_(chCount) LPSTR lpString,
_In_ int chCount,
_In_ int idListBox);
WINUSERAPI
BOOL
WINAPI
DlgDirSelectExW(
_In_ HWND hwndDlg,
_Out_writes_(chCount) LPWSTR lpString,
_In_ int chCount,
_In_ int idListBox);
#ifdef UNICODE
#define DlgDirSelectEx DlgDirSelectExW
#else
#define DlgDirSelectEx DlgDirSelectExA
#endif // !UNICODE
WINUSERAPI
int
WINAPI
DlgDirListComboBoxA(
_In_ HWND hDlg,
_Inout_ LPSTR lpPathSpec,
_In_ int nIDComboBox,
_In_ int nIDStaticPath,
_In_ UINT uFiletype);
WINUSERAPI
int
WINAPI
DlgDirListComboBoxW(
_In_ HWND hDlg,
_Inout_ LPWSTR lpPathSpec,
_In_ int nIDComboBox,
_In_ int nIDStaticPath,
_In_ UINT uFiletype);
#ifdef UNICODE
#define DlgDirListComboBox DlgDirListComboBoxW
#else
#define DlgDirListComboBox DlgDirListComboBoxA
#endif // !UNICODE
WINUSERAPI
BOOL
WINAPI
DlgDirSelectComboBoxExA(
_In_ HWND hwndDlg,
_Out_writes_(cchOut) LPSTR lpString,
_In_ int cchOut,
_In_ int idComboBox);
WINUSERAPI
BOOL
WINAPI
DlgDirSelectComboBoxExW(
_In_ HWND hwndDlg,
_Out_writes_(cchOut) LPWSTR lpString,
_In_ int cchOut,
_In_ int idComboBox);
#ifdef UNICODE
#define DlgDirSelectComboBoxEx DlgDirSelectComboBoxExW
#else
#define DlgDirSelectComboBoxEx DlgDirSelectComboBoxExA
#endif // !UNICODE
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* Dialog Styles
*/
#define DS_ABSALIGN 0x01L
#define DS_SYSMODAL 0x02L
#define DS_LOCALEDIT 0x20L /* Edit items get Local storage. */
#define DS_SETFONT 0x40L /* User specified font for Dlg controls */
#define DS_MODALFRAME 0x80L /* Can be combined with WS_CAPTION */
#define DS_NOIDLEMSG 0x100L /* WM_ENTERIDLE message will not be sent */
#define DS_SETFOREGROUND 0x200L /* not in win3.1 */
#if(WINVER >= 0x0400)
#define DS_3DLOOK 0x0004L
#define DS_FIXEDSYS 0x0008L
#define DS_NOFAILCREATE 0x0010L
#define DS_CONTROL 0x0400L
#define DS_CENTER 0x0800L
#define DS_CENTERMOUSE 0x1000L
#define DS_CONTEXTHELP 0x2000L
#define DS_SHELLFONT (DS_SETFONT | DS_FIXEDSYS)
#endif /* WINVER >= 0x0400 */
#if defined(_WIN32_WCE) && (_WIN32_WCE >= 0x0500)
#define DS_USEPIXELS 0x8000L
#endif
#define DM_GETDEFID (WM_USER+0)
#define DM_SETDEFID (WM_USER+1)
#if(WINVER >= 0x0400)
#define DM_REPOSITION (WM_USER+2)
#endif /* WINVER >= 0x0400 */
/*
* Returned in HIWORD() of DM_GETDEFID result if msg is supported
*/
#define DC_HASDEFID 0x534B
/*
* Dialog Codes
*/
#define DLGC_WANTARROWS 0x0001 /* Control wants arrow keys */
#define DLGC_WANTTAB 0x0002 /* Control wants tab keys */
#define DLGC_WANTALLKEYS 0x0004 /* Control wants all keys */
#define DLGC_WANTMESSAGE 0x0004 /* Pass message to control */
#define DLGC_HASSETSEL 0x0008 /* Understands EM_SETSEL message */
#define DLGC_DEFPUSHBUTTON 0x0010 /* Default pushbutton */
#define DLGC_UNDEFPUSHBUTTON 0x0020 /* Non-default pushbutton */
#define DLGC_RADIOBUTTON 0x0040 /* Radio button */
#define DLGC_WANTCHARS 0x0080 /* Want WM_CHAR messages */
#define DLGC_STATIC 0x0100 /* Static item: don't include */
#define DLGC_BUTTON 0x2000 /* Button item: can be checked */
#define LB_CTLCODE 0L
/*
* Listbox Return Values
*/
#define LB_OKAY 0
#define LB_ERR (-1)
#define LB_ERRSPACE (-2)
/*
** The idStaticPath parameter to DlgDirList can have the following values
** ORed if the list box should show other details of the files along with
** the name of the files;
*/
/* all other details also will be returned */
/*
* Listbox Notification Codes
*/
#define LBN_ERRSPACE (-2)
#define LBN_SELCHANGE 1
#define LBN_DBLCLK 2
#define LBN_SELCANCEL 3
#define LBN_SETFOCUS 4
#define LBN_KILLFOCUS 5
#ifndef NOWINMESSAGES
/*
* Listbox messages
*/
#define LB_ADDSTRING 0x0180
#define LB_INSERTSTRING 0x0181
#define LB_DELETESTRING 0x0182
#define LB_SELITEMRANGEEX 0x0183
#define LB_RESETCONTENT 0x0184
#define LB_SETSEL 0x0185
#define LB_SETCURSEL 0x0186
#define LB_GETSEL 0x0187
#define LB_GETCURSEL 0x0188
#define LB_GETTEXT 0x0189
#define LB_GETTEXTLEN 0x018A
#define LB_GETCOUNT 0x018B
#define LB_SELECTSTRING 0x018C
#define LB_DIR 0x018D
#define LB_GETTOPINDEX 0x018E
#define LB_FINDSTRING 0x018F
#define LB_GETSELCOUNT 0x0190
#define LB_GETSELITEMS 0x0191
#define LB_SETTABSTOPS 0x0192
#define LB_GETHORIZONTALEXTENT 0x0193
#define LB_SETHORIZONTALEXTENT 0x0194
#define LB_SETCOLUMNWIDTH 0x0195
#define LB_ADDFILE 0x0196
#define LB_SETTOPINDEX 0x0197
#define LB_GETITEMRECT 0x0198
#define LB_GETITEMDATA 0x0199
#define LB_SETITEMDATA 0x019A
#define LB_SELITEMRANGE 0x019B
#define LB_SETANCHORINDEX 0x019C
#define LB_GETANCHORINDEX 0x019D
#define LB_SETCARETINDEX 0x019E
#define LB_GETCARETINDEX 0x019F
#define LB_SETITEMHEIGHT 0x01A0
#define LB_GETITEMHEIGHT 0x01A1
#define LB_FINDSTRINGEXACT 0x01A2
#define LB_SETLOCALE 0x01A5
#define LB_GETLOCALE 0x01A6
#define LB_SETCOUNT 0x01A7
#if(WINVER >= 0x0400)
#define LB_INITSTORAGE 0x01A8
#define LB_ITEMFROMPOINT 0x01A9
#endif /* WINVER >= 0x0400 */
#if defined(_WIN32_WCE) && (_WIN32_WCE >= 0x0400)
#define LB_MULTIPLEADDSTRING 0x01B1
#endif
#if(_WIN32_WINNT >= 0x0501)
#define LB_GETLISTBOXINFO 0x01B2
#endif /* _WIN32_WINNT >= 0x0501 */
#if(_WIN32_WINNT >= 0x0501)
#define LB_MSGMAX 0x01B3
#elif defined(_WIN32_WCE) && (_WIN32_WCE >= 0x0400)
#define LB_MSGMAX 0x01B1
#elif(WINVER >= 0x0400)
#define LB_MSGMAX 0x01B0
#else
#define LB_MSGMAX 0x01A8
#endif
#endif /* !NOWINMESSAGES */
#ifndef NOWINSTYLES
/*
* Listbox Styles
*/
#define LBS_NOTIFY 0x0001L
#define LBS_SORT 0x0002L
#define LBS_NOREDRAW 0x0004L
#define LBS_MULTIPLESEL 0x0008L
#define LBS_OWNERDRAWFIXED 0x0010L
#define LBS_OWNERDRAWVARIABLE 0x0020L
#define LBS_HASSTRINGS 0x0040L
#define LBS_USETABSTOPS 0x0080L
#define LBS_NOINTEGRALHEIGHT 0x0100L
#define LBS_MULTICOLUMN 0x0200L
#define LBS_WANTKEYBOARDINPUT 0x0400L
#define LBS_EXTENDEDSEL 0x0800L
#define LBS_DISABLENOSCROLL 0x1000L
#define LBS_NODATA 0x2000L
#if(WINVER >= 0x0400)
#define LBS_NOSEL 0x4000L
#endif /* WINVER >= 0x0400 */
#define LBS_COMBOBOX 0x8000L
#define LBS_STANDARD (LBS_NOTIFY | LBS_SORT | WS_VSCROLL | WS_BORDER)
#endif /* !NOWINSTYLES */
/*
* Combo Box return Values
*/
#define CB_OKAY 0
#define CB_ERR (-1)
#define CB_ERRSPACE (-2)
/*
* Combo Box Notification Codes
*/
#define CBN_ERRSPACE (-1)
#define CBN_SELCHANGE 1
#define CBN_DBLCLK 2
#define CBN_SETFOCUS 3
#define CBN_KILLFOCUS 4
#define CBN_EDITCHANGE 5
#define CBN_EDITUPDATE 6
#define CBN_DROPDOWN 7
#define CBN_CLOSEUP 8
#define CBN_SELENDOK 9
#define CBN_SELENDCANCEL 10
#ifndef NOWINSTYLES
/*
* Combo Box styles
*/
#define CBS_SIMPLE 0x0001L
#define CBS_DROPDOWN 0x0002L
#define CBS_DROPDOWNLIST 0x0003L
#define CBS_OWNERDRAWFIXED 0x0010L
#define CBS_OWNERDRAWVARIABLE 0x0020L
#define CBS_AUTOHSCROLL 0x0040L
#define CBS_OEMCONVERT 0x0080L
#define CBS_SORT 0x0100L
#define CBS_HASSTRINGS 0x0200L
#define CBS_NOINTEGRALHEIGHT 0x0400L
#define CBS_DISABLENOSCROLL 0x0800L
#if(WINVER >= 0x0400)
#define CBS_UPPERCASE 0x2000L
#define CBS_LOWERCASE 0x4000L
#endif /* WINVER >= 0x0400 */
#endif /* !NOWINSTYLES */
/*
* Combo Box messages
*/
#ifndef NOWINMESSAGES
#define CB_GETEDITSEL 0x0140
#define CB_LIMITTEXT 0x0141
#define CB_SETEDITSEL 0x0142
#define CB_ADDSTRING 0x0143
#define CB_DELETESTRING 0x0144
#define CB_DIR 0x0145
#define CB_GETCOUNT 0x0146
#define CB_GETCURSEL 0x0147
#define CB_GETLBTEXT 0x0148
#define CB_GETLBTEXTLEN 0x0149
#define CB_INSERTSTRING 0x014A
#define CB_RESETCONTENT 0x014B
#define CB_FINDSTRING 0x014C
#define CB_SELECTSTRING 0x014D
#define CB_SETCURSEL 0x014E
#define CB_SHOWDROPDOWN 0x014F
#define CB_GETITEMDATA 0x0150
#define CB_SETITEMDATA 0x0151
#define CB_GETDROPPEDCONTROLRECT 0x0152
#define CB_SETITEMHEIGHT 0x0153
#define CB_GETITEMHEIGHT 0x0154
#define CB_SETEXTENDEDUI 0x0155
#define CB_GETEXTENDEDUI 0x0156
#define CB_GETDROPPEDSTATE 0x0157
#define CB_FINDSTRINGEXACT 0x0158
#define CB_SETLOCALE 0x0159
#define CB_GETLOCALE 0x015A
#if(WINVER >= 0x0400)
#define CB_GETTOPINDEX 0x015b
#define CB_SETTOPINDEX 0x015c
#define CB_GETHORIZONTALEXTENT 0x015d
#define CB_SETHORIZONTALEXTENT 0x015e
#define CB_GETDROPPEDWIDTH 0x015f
#define CB_SETDROPPEDWIDTH 0x0160
#define CB_INITSTORAGE 0x0161
#if defined(_WIN32_WCE) &&(_WIN32_WCE >= 0x0400)
#define CB_MULTIPLEADDSTRING 0x0163
#endif
#endif /* WINVER >= 0x0400 */
#if(_WIN32_WINNT >= 0x0501)
#define CB_GETCOMBOBOXINFO 0x0164
#endif /* _WIN32_WINNT >= 0x0501 */
#if(_WIN32_WINNT >= 0x0501)
#define CB_MSGMAX 0x0165
#elif defined(_WIN32_WCE) && (_WIN32_WCE >= 0x0400)
#define CB_MSGMAX 0x0163
#elif(WINVER >= 0x0400)
#define CB_MSGMAX 0x0162
#else
#define CB_MSGMAX 0x015B
#endif
#endif /* !NOWINMESSAGES */
#ifndef NOWINSTYLES
/*
* Scroll Bar Styles
*/
#define SBS_HORZ 0x0000L
#define SBS_VERT 0x0001L
#define SBS_TOPALIGN 0x0002L
#define SBS_LEFTALIGN 0x0002L
#define SBS_BOTTOMALIGN 0x0004L
#define SBS_RIGHTALIGN 0x0004L
#define SBS_SIZEBOXTOPLEFTALIGN 0x0002L
#define SBS_SIZEBOXBOTTOMRIGHTALIGN 0x0004L
#define SBS_SIZEBOX 0x0008L
#if(WINVER >= 0x0400)
#define SBS_SIZEGRIP 0x0010L
#endif /* WINVER >= 0x0400 */
#endif /* !NOWINSTYLES */
/*
* Scroll bar messages
*/
#ifndef NOWINMESSAGES
#define SBM_SETPOS 0x00E0 /*not in win3.1 */
#define SBM_GETPOS 0x00E1 /*not in win3.1 */
#define SBM_SETRANGE 0x00E2 /*not in win3.1 */
#define SBM_SETRANGEREDRAW 0x00E6 /*not in win3.1 */
#define SBM_GETRANGE 0x00E3 /*not in win3.1 */
#define SBM_ENABLE_ARROWS 0x00E4 /*not in win3.1 */
#if(WINVER >= 0x0400)
#define SBM_SETSCROLLINFO 0x00E9
#define SBM_GETSCROLLINFO 0x00EA
#endif /* WINVER >= 0x0400 */
#if(_WIN32_WINNT >= 0x0501)
#define SBM_GETSCROLLBARINFO 0x00EB
#endif /* _WIN32_WINNT >= 0x0501 */
#if(WINVER >= 0x0400)
#define SIF_RANGE 0x0001
#define SIF_PAGE 0x0002
#define SIF_POS 0x0004
#define SIF_DISABLENOSCROLL 0x0008
#define SIF_TRACKPOS 0x0010
#define SIF_ALL (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef struct tagSCROLLINFO
{
UINT cbSize;
UINT fMask;
int nMin;
int nMax;
UINT nPage;
int nPos;
int nTrackPos;
} SCROLLINFO, FAR *LPSCROLLINFO;
typedef SCROLLINFO CONST FAR *LPCSCROLLINFO;
WINUSERAPI
int
WINAPI
SetScrollInfo(
_In_ HWND hwnd,
_In_ int nBar,
_In_ LPCSCROLLINFO lpsi,
_In_ BOOL redraw);
WINUSERAPI
BOOL
WINAPI
GetScrollInfo(
_In_ HWND hwnd,
_In_ int nBar,
_Inout_ LPSCROLLINFO lpsi);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* WINVER >= 0x0400 */
#endif /* !NOWINMESSAGES */
#endif /* !NOCTLMGR */
#ifndef NOMDI
/*
* MDI client style bits
*/
#define MDIS_ALLCHILDSTYLES 0x0001
/*
* wParam Flags for WM_MDITILE and WM_MDICASCADE messages.
*/
#define MDITILE_VERTICAL 0x0000 /*not in win3.1 */
#define MDITILE_HORIZONTAL 0x0001 /*not in win3.1 */
#define MDITILE_SKIPDISABLED 0x0002 /*not in win3.1 */
#if(_WIN32_WINNT >= 0x0500)
#define MDITILE_ZORDER 0x0004
#endif /* _WIN32_WINNT >= 0x0500 */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef struct tagMDICREATESTRUCTA {
LPCSTR szClass;
LPCSTR szTitle;
HANDLE hOwner;
int x;
int y;
int cx;
int cy;
DWORD style;
LPARAM lParam; /* app-defined stuff */
} MDICREATESTRUCTA, *LPMDICREATESTRUCTA;
typedef struct tagMDICREATESTRUCTW {
LPCWSTR szClass;
LPCWSTR szTitle;
HANDLE hOwner;
int x;
int y;
int cx;
int cy;
DWORD style;
LPARAM lParam; /* app-defined stuff */
} MDICREATESTRUCTW, *LPMDICREATESTRUCTW;
#ifdef UNICODE
typedef MDICREATESTRUCTW MDICREATESTRUCT;
typedef LPMDICREATESTRUCTW LPMDICREATESTRUCT;
#else
typedef MDICREATESTRUCTA MDICREATESTRUCT;
typedef LPMDICREATESTRUCTA LPMDICREATESTRUCT;
#endif // UNICODE
typedef struct tagCLIENTCREATESTRUCT {
HANDLE hWindowMenu;
UINT idFirstChild;
} CLIENTCREATESTRUCT, *LPCLIENTCREATESTRUCT;
WINUSERAPI
LRESULT
WINAPI
DefFrameProcA(
_In_ HWND hWnd,
_In_opt_ HWND hWndMDIClient,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam);
WINUSERAPI
LRESULT
WINAPI
DefFrameProcW(
_In_ HWND hWnd,
_In_opt_ HWND hWndMDIClient,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam);
#ifdef UNICODE
#define DefFrameProc DefFrameProcW
#else
#define DefFrameProc DefFrameProcA
#endif // !UNICODE
WINUSERAPI
#ifndef _MAC
LRESULT
WINAPI
#else
LRESULT
CALLBACK
#endif
DefMDIChildProcA(
_In_ HWND hWnd,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam);
WINUSERAPI
#ifndef _MAC
LRESULT
WINAPI
#else
LRESULT
CALLBACK
#endif
DefMDIChildProcW(
_In_ HWND hWnd,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam);
#ifdef UNICODE
#define DefMDIChildProc DefMDIChildProcW
#else
#define DefMDIChildProc DefMDIChildProcA
#endif // !UNICODE
#ifndef NOMSG
WINUSERAPI
BOOL
WINAPI
TranslateMDISysAccel(
_In_ HWND hWndClient,
_In_ LPMSG lpMsg);
#endif /* !NOMSG */
WINUSERAPI
UINT
WINAPI
ArrangeIconicWindows(
_In_ HWND hWnd);
WINUSERAPI
HWND
WINAPI
CreateMDIWindowA(
_In_ LPCSTR lpClassName,
_In_ LPCSTR lpWindowName,
_In_ DWORD dwStyle,
_In_ int X,
_In_ int Y,
_In_ int nWidth,
_In_ int nHeight,
_In_opt_ HWND hWndParent,
_In_opt_ HINSTANCE hInstance,
_In_ LPARAM lParam);
WINUSERAPI
HWND
WINAPI
CreateMDIWindowW(
_In_ LPCWSTR lpClassName,
_In_ LPCWSTR lpWindowName,
_In_ DWORD dwStyle,
_In_ int X,
_In_ int Y,
_In_ int nWidth,
_In_ int nHeight,
_In_opt_ HWND hWndParent,
_In_opt_ HINSTANCE hInstance,
_In_ LPARAM lParam);
#ifdef UNICODE
#define CreateMDIWindow CreateMDIWindowW
#else
#define CreateMDIWindow CreateMDIWindowA
#endif // !UNICODE
#if(WINVER >= 0x0400)
WINUSERAPI
WORD
WINAPI
TileWindows(
_In_opt_ HWND hwndParent,
_In_ UINT wHow,
_In_opt_ CONST RECT * lpRect,
_In_ UINT cKids,
_In_reads_opt_(cKids) const HWND FAR * lpKids);
WINUSERAPI
WORD
WINAPI CascadeWindows(
_In_opt_ HWND hwndParent,
_In_ UINT wHow,
_In_opt_ CONST RECT * lpRect,
_In_ UINT cKids,
_In_reads_opt_(cKids) const HWND FAR * lpKids);
#endif /* WINVER >= 0x0400 */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* !NOMDI */
#endif /* !NOUSER */
/****** Help support ********************************************************/
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#ifndef NOHELP
typedef DWORD HELPPOLY;
typedef struct tagMULTIKEYHELPA {
#ifndef _MAC
DWORD mkSize;
#else
WORD mkSize;
#endif
CHAR mkKeylist;
CHAR szKeyphrase[1];
} MULTIKEYHELPA, *PMULTIKEYHELPA, *LPMULTIKEYHELPA;
typedef struct tagMULTIKEYHELPW {
#ifndef _MAC
DWORD mkSize;
#else
WORD mkSize;
#endif
WCHAR mkKeylist;
WCHAR szKeyphrase[1];
} MULTIKEYHELPW, *PMULTIKEYHELPW, *LPMULTIKEYHELPW;
#ifdef UNICODE
typedef MULTIKEYHELPW MULTIKEYHELP;
typedef PMULTIKEYHELPW PMULTIKEYHELP;
typedef LPMULTIKEYHELPW LPMULTIKEYHELP;
#else
typedef MULTIKEYHELPA MULTIKEYHELP;
typedef PMULTIKEYHELPA PMULTIKEYHELP;
typedef LPMULTIKEYHELPA LPMULTIKEYHELP;
#endif // UNICODE
typedef struct tagHELPWININFOA {
int wStructSize;
int x;
int y;
int dx;
int dy;
int wMax;
CHAR rgchMember[2];
} HELPWININFOA, *PHELPWININFOA, *LPHELPWININFOA;
typedef struct tagHELPWININFOW {
int wStructSize;
int x;
int y;
int dx;
int dy;
int wMax;
WCHAR rgchMember[2];
} HELPWININFOW, *PHELPWININFOW, *LPHELPWININFOW;
#ifdef UNICODE
typedef HELPWININFOW HELPWININFO;
typedef PHELPWININFOW PHELPWININFO;
typedef LPHELPWININFOW LPHELPWININFO;
#else
typedef HELPWININFOA HELPWININFO;
typedef PHELPWININFOA PHELPWININFO;
typedef LPHELPWININFOA LPHELPWININFO;
#endif // UNICODE
/*
* Commands to pass to WinHelp()
*/
#define HELP_CONTEXT 0x0001L /* Display topic in ulTopic */
#define HELP_QUIT 0x0002L /* Terminate help */
#define HELP_INDEX 0x0003L /* Display index */
#define HELP_CONTENTS 0x0003L
#define HELP_HELPONHELP 0x0004L /* Display help on using help */
#define HELP_SETINDEX 0x0005L /* Set current Index for multi index help */
#define HELP_SETCONTENTS 0x0005L
#define HELP_CONTEXTPOPUP 0x0008L
#define HELP_FORCEFILE 0x0009L
#define HELP_KEY 0x0101L /* Display topic for keyword in offabData */
#define HELP_COMMAND 0x0102L
#define HELP_PARTIALKEY 0x0105L
#define HELP_MULTIKEY 0x0201L
#define HELP_SETWINPOS 0x0203L
#if(WINVER >= 0x0400)
#define HELP_CONTEXTMENU 0x000a
#define HELP_FINDER 0x000b
#define HELP_WM_HELP 0x000c
#define HELP_SETPOPUP_POS 0x000d
#define HELP_TCARD 0x8000
#define HELP_TCARD_DATA 0x0010
#define HELP_TCARD_OTHER_CALLER 0x0011
// These are in winhelp.h in Win95.
#define IDH_NO_HELP 28440
#define IDH_MISSING_CONTEXT 28441 // Control doesn't have matching help context
#define IDH_GENERIC_HELP_BUTTON 28442 // Property sheet help button
#define IDH_OK 28443
#define IDH_CANCEL 28444
#define IDH_HELP 28445
#endif /* WINVER >= 0x0400 */
WINUSERAPI
BOOL
WINAPI
WinHelpA(
_In_opt_ HWND hWndMain,
_In_opt_ LPCSTR lpszHelp,
_In_ UINT uCommand,
_In_ ULONG_PTR dwData);
WINUSERAPI
BOOL
WINAPI
WinHelpW(
_In_opt_ HWND hWndMain,
_In_opt_ LPCWSTR lpszHelp,
_In_ UINT uCommand,
_In_ ULONG_PTR dwData);
#ifdef UNICODE
#define WinHelp WinHelpW
#else
#define WinHelp WinHelpA
#endif // !UNICODE
#endif /* !NOHELP */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#if(WINVER >= 0x0500)
#define GR_GDIOBJECTS 0 /* Count of GDI objects */
#define GR_USEROBJECTS 1 /* Count of USER objects */
#endif /* WINVER >= 0x0500 */
#if(WINVER >= 0x0601)
#define GR_GDIOBJECTS_PEAK 2 /* Peak count of GDI objects */
#define GR_USEROBJECTS_PEAK 4 /* Peak count of USER objects */
#endif /* WINVER >= 0x0601 */
#if(WINVER >= 0x0601)
#define GR_GLOBAL ((HANDLE)-2)
#endif /* WINVER >= 0x0601 */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#if(WINVER >= 0x0500)
WINUSERAPI
DWORD
WINAPI
GetGuiResources(
_In_ HANDLE hProcess,
_In_ DWORD uiFlags);
#endif /* WINVER >= 0x0500 */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#ifndef NOSYSPARAMSINFO
/*
* Parameter for SystemParametersInfo.
*/
#define SPI_GETBEEP 0x0001
#define SPI_SETBEEP 0x0002
#define SPI_GETMOUSE 0x0003
#define SPI_SETMOUSE 0x0004
#define SPI_GETBORDER 0x0005
#define SPI_SETBORDER 0x0006
#define SPI_GETKEYBOARDSPEED 0x000A
#define SPI_SETKEYBOARDSPEED 0x000B
#define SPI_LANGDRIVER 0x000C
#define SPI_ICONHORIZONTALSPACING 0x000D
#define SPI_GETSCREENSAVETIMEOUT 0x000E
#define SPI_SETSCREENSAVETIMEOUT 0x000F
#define SPI_GETSCREENSAVEACTIVE 0x0010
#define SPI_SETSCREENSAVEACTIVE 0x0011
#define SPI_GETGRIDGRANULARITY 0x0012
#define SPI_SETGRIDGRANULARITY 0x0013
#define SPI_SETDESKWALLPAPER 0x0014
#define SPI_SETDESKPATTERN 0x0015
#define SPI_GETKEYBOARDDELAY 0x0016
#define SPI_SETKEYBOARDDELAY 0x0017
#define SPI_ICONVERTICALSPACING 0x0018
#define SPI_GETICONTITLEWRAP 0x0019
#define SPI_SETICONTITLEWRAP 0x001A
#define SPI_GETMENUDROPALIGNMENT 0x001B
#define SPI_SETMENUDROPALIGNMENT 0x001C
#define SPI_SETDOUBLECLKWIDTH 0x001D
#define SPI_SETDOUBLECLKHEIGHT 0x001E
#define SPI_GETICONTITLELOGFONT 0x001F
#define SPI_SETDOUBLECLICKTIME 0x0020
#define SPI_SETMOUSEBUTTONSWAP 0x0021
#define SPI_SETICONTITLELOGFONT 0x0022
#define SPI_GETFASTTASKSWITCH 0x0023
#define SPI_SETFASTTASKSWITCH 0x0024
#if(WINVER >= 0x0400)
#define SPI_SETDRAGFULLWINDOWS 0x0025
#define SPI_GETDRAGFULLWINDOWS 0x0026
#define SPI_GETNONCLIENTMETRICS 0x0029
#define SPI_SETNONCLIENTMETRICS 0x002A
#define SPI_GETMINIMIZEDMETRICS 0x002B
#define SPI_SETMINIMIZEDMETRICS 0x002C
#define SPI_GETICONMETRICS 0x002D
#define SPI_SETICONMETRICS 0x002E
#define SPI_SETWORKAREA 0x002F
#define SPI_GETWORKAREA 0x0030
#define SPI_SETPENWINDOWS 0x0031
#define SPI_GETHIGHCONTRAST 0x0042
#define SPI_SETHIGHCONTRAST 0x0043
#define SPI_GETKEYBOARDPREF 0x0044
#define SPI_SETKEYBOARDPREF 0x0045
#define SPI_GETSCREENREADER 0x0046
#define SPI_SETSCREENREADER 0x0047
#define SPI_GETANIMATION 0x0048
#define SPI_SETANIMATION 0x0049
#define SPI_GETFONTSMOOTHING 0x004A
#define SPI_SETFONTSMOOTHING 0x004B
#define SPI_SETDRAGWIDTH 0x004C
#define SPI_SETDRAGHEIGHT 0x004D
#define SPI_SETHANDHELD 0x004E
#define SPI_GETLOWPOWERTIMEOUT 0x004F
#define SPI_GETPOWEROFFTIMEOUT 0x0050
#define SPI_SETLOWPOWERTIMEOUT 0x0051
#define SPI_SETPOWEROFFTIMEOUT 0x0052
#define SPI_GETLOWPOWERACTIVE 0x0053
#define SPI_GETPOWEROFFACTIVE 0x0054
#define SPI_SETLOWPOWERACTIVE 0x0055
#define SPI_SETPOWEROFFACTIVE 0x0056
#define SPI_SETCURSORS 0x0057
#define SPI_SETICONS 0x0058
#define SPI_GETDEFAULTINPUTLANG 0x0059
#define SPI_SETDEFAULTINPUTLANG 0x005A
#define SPI_SETLANGTOGGLE 0x005B
#define SPI_GETWINDOWSEXTENSION 0x005C
#define SPI_SETMOUSETRAILS 0x005D
#define SPI_GETMOUSETRAILS 0x005E
#define SPI_SETSCREENSAVERRUNNING 0x0061
#define SPI_SCREENSAVERRUNNING SPI_SETSCREENSAVERRUNNING
#endif /* WINVER >= 0x0400 */
#define SPI_GETFILTERKEYS 0x0032
#define SPI_SETFILTERKEYS 0x0033
#define SPI_GETTOGGLEKEYS 0x0034
#define SPI_SETTOGGLEKEYS 0x0035
#define SPI_GETMOUSEKEYS 0x0036
#define SPI_SETMOUSEKEYS 0x0037
#define SPI_GETSHOWSOUNDS 0x0038
#define SPI_SETSHOWSOUNDS 0x0039
#define SPI_GETSTICKYKEYS 0x003A
#define SPI_SETSTICKYKEYS 0x003B
#define SPI_GETACCESSTIMEOUT 0x003C
#define SPI_SETACCESSTIMEOUT 0x003D
#if(WINVER >= 0x0400)
#define SPI_GETSERIALKEYS 0x003E
#define SPI_SETSERIALKEYS 0x003F
#endif /* WINVER >= 0x0400 */
#define SPI_GETSOUNDSENTRY 0x0040
#define SPI_SETSOUNDSENTRY 0x0041
#if(_WIN32_WINNT >= 0x0400)
#define SPI_GETSNAPTODEFBUTTON 0x005F
#define SPI_SETSNAPTODEFBUTTON 0x0060
#endif /* _WIN32_WINNT >= 0x0400 */
#if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
#define SPI_GETMOUSEHOVERWIDTH 0x0062
#define SPI_SETMOUSEHOVERWIDTH 0x0063
#define SPI_GETMOUSEHOVERHEIGHT 0x0064
#define SPI_SETMOUSEHOVERHEIGHT 0x0065
#define SPI_GETMOUSEHOVERTIME 0x0066
#define SPI_SETMOUSEHOVERTIME 0x0067
#define SPI_GETWHEELSCROLLLINES 0x0068
#define SPI_SETWHEELSCROLLLINES 0x0069
#define SPI_GETMENUSHOWDELAY 0x006A
#define SPI_SETMENUSHOWDELAY 0x006B
#if (_WIN32_WINNT >= 0x0600)
#define SPI_GETWHEELSCROLLCHARS 0x006C
#define SPI_SETWHEELSCROLLCHARS 0x006D
#endif
#define SPI_GETSHOWIMEUI 0x006E
#define SPI_SETSHOWIMEUI 0x006F
#endif
#if(WINVER >= 0x0500)
#define SPI_GETMOUSESPEED 0x0070
#define SPI_SETMOUSESPEED 0x0071
#define SPI_GETSCREENSAVERRUNNING 0x0072
#define SPI_GETDESKWALLPAPER 0x0073
#endif /* WINVER >= 0x0500 */
#if(WINVER >= 0x0600)
#define SPI_GETAUDIODESCRIPTION 0x0074
#define SPI_SETAUDIODESCRIPTION 0x0075
#define SPI_GETSCREENSAVESECURE 0x0076
#define SPI_SETSCREENSAVESECURE 0x0077
#endif /* WINVER >= 0x0600 */
#if(_WIN32_WINNT >= 0x0601)
#define SPI_GETHUNGAPPTIMEOUT 0x0078
#define SPI_SETHUNGAPPTIMEOUT 0x0079
#define SPI_GETWAITTOKILLTIMEOUT 0x007A
#define SPI_SETWAITTOKILLTIMEOUT 0x007B
#define SPI_GETWAITTOKILLSERVICETIMEOUT 0x007C
#define SPI_SETWAITTOKILLSERVICETIMEOUT 0x007D
#define SPI_GETMOUSEDOCKTHRESHOLD 0x007E
#define SPI_SETMOUSEDOCKTHRESHOLD 0x007F
#define SPI_GETPENDOCKTHRESHOLD 0x0080
#define SPI_SETPENDOCKTHRESHOLD 0x0081
#define SPI_GETWINARRANGING 0x0082
#define SPI_SETWINARRANGING 0x0083
#define SPI_GETMOUSEDRAGOUTTHRESHOLD 0x0084
#define SPI_SETMOUSEDRAGOUTTHRESHOLD 0x0085
#define SPI_GETPENDRAGOUTTHRESHOLD 0x0086
#define SPI_SETPENDRAGOUTTHRESHOLD 0x0087
#define SPI_GETMOUSESIDEMOVETHRESHOLD 0x0088
#define SPI_SETMOUSESIDEMOVETHRESHOLD 0x0089
#define SPI_GETPENSIDEMOVETHRESHOLD 0x008A
#define SPI_SETPENSIDEMOVETHRESHOLD 0x008B
#define SPI_GETDRAGFROMMAXIMIZE 0x008C
#define SPI_SETDRAGFROMMAXIMIZE 0x008D
#define SPI_GETSNAPSIZING 0x008E
#define SPI_SETSNAPSIZING 0x008F
#define SPI_GETDOCKMOVING 0x0090
#define SPI_SETDOCKMOVING 0x0091
#endif /* _WIN32_WINNT >= 0x0601 */
#if(WINVER >= 0x0602)
#define MAX_TOUCH_PREDICTION_FILTER_TAPS 3
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef struct tagTouchPredictionParameters
{
UINT cbSize;
UINT dwLatency; // Latency in millisecs
UINT dwSampleTime; // Sample time in millisecs (used to deduce velocity)
UINT bUseHWTimeStamp; // Use H/W TimeStamps
} TOUCHPREDICTIONPARAMETERS, *PTOUCHPREDICTIONPARAMETERS;
#define TOUCHPREDICTIONPARAMETERS_DEFAULT_LATENCY 8
#define TOUCHPREDICTIONPARAMETERS_DEFAULT_SAMPLETIME 8
#define TOUCHPREDICTIONPARAMETERS_DEFAULT_USE_HW_TIMESTAMP 1
#define TOUCHPREDICTIONPARAMETERS_DEFAULT_RLS_DELTA 0.001f
#define TOUCHPREDICTIONPARAMETERS_DEFAULT_RLS_LAMBDA_MIN 0.9f
#define TOUCHPREDICTIONPARAMETERS_DEFAULT_RLS_LAMBDA_MAX 0.999f
#define TOUCHPREDICTIONPARAMETERS_DEFAULT_RLS_LAMBDA_LEARNING_RATE 0.001f
#define TOUCHPREDICTIONPARAMETERS_DEFAULT_RLS_EXPO_SMOOTH_ALPHA 0.99f
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#define SPI_GETTOUCHPREDICTIONPARAMETERS 0x009C
#define SPI_SETTOUCHPREDICTIONPARAMETERS 0x009D
#define MAX_LOGICALDPIOVERRIDE 2
#define MIN_LOGICALDPIOVERRIDE -2
#define SPI_GETLOGICALDPIOVERRIDE 0x009E
#define SPI_SETLOGICALDPIOVERRIDE 0x009F
#define SPI_GETMOUSECORNERCLIPLENGTH 0x00A0
#define SPI_SETMOUSECORNERCLIPLENGTH 0x00A1
#define SPI_GETMENURECT 0x00A2
#define SPI_SETMENURECT 0x00A3
#endif /* WINVER >= 0x0602 */
#if(WINVER >= 0x0500)
#define SPI_GETACTIVEWINDOWTRACKING 0x1000
#define SPI_SETACTIVEWINDOWTRACKING 0x1001
#define SPI_GETMENUANIMATION 0x1002
#define SPI_SETMENUANIMATION 0x1003
#define SPI_GETCOMBOBOXANIMATION 0x1004
#define SPI_SETCOMBOBOXANIMATION 0x1005
#define SPI_GETLISTBOXSMOOTHSCROLLING 0x1006
#define SPI_SETLISTBOXSMOOTHSCROLLING 0x1007
#define SPI_GETGRADIENTCAPTIONS 0x1008
#define SPI_SETGRADIENTCAPTIONS 0x1009
#define SPI_GETKEYBOARDCUES 0x100A
#define SPI_SETKEYBOARDCUES 0x100B
#define SPI_GETMENUUNDERLINES SPI_GETKEYBOARDCUES
#define SPI_SETMENUUNDERLINES SPI_SETKEYBOARDCUES
#define SPI_GETACTIVEWNDTRKZORDER 0x100C
#define SPI_SETACTIVEWNDTRKZORDER 0x100D
#define SPI_GETHOTTRACKING 0x100E
#define SPI_SETHOTTRACKING 0x100F
#define SPI_GETMENUFADE 0x1012
#define SPI_SETMENUFADE 0x1013
#define SPI_GETSELECTIONFADE 0x1014
#define SPI_SETSELECTIONFADE 0x1015
#define SPI_GETTOOLTIPANIMATION 0x1016
#define SPI_SETTOOLTIPANIMATION 0x1017
#define SPI_GETTOOLTIPFADE 0x1018
#define SPI_SETTOOLTIPFADE 0x1019
#define SPI_GETCURSORSHADOW 0x101A
#define SPI_SETCURSORSHADOW 0x101B
#if(_WIN32_WINNT >= 0x0501)
#define SPI_GETMOUSESONAR 0x101C
#define SPI_SETMOUSESONAR 0x101D
#define SPI_GETMOUSECLICKLOCK 0x101E
#define SPI_SETMOUSECLICKLOCK 0x101F
#define SPI_GETMOUSEVANISH 0x1020
#define SPI_SETMOUSEVANISH 0x1021
#define SPI_GETFLATMENU 0x1022
#define SPI_SETFLATMENU 0x1023
#define SPI_GETDROPSHADOW 0x1024
#define SPI_SETDROPSHADOW 0x1025
#define SPI_GETBLOCKSENDINPUTRESETS 0x1026
#define SPI_SETBLOCKSENDINPUTRESETS 0x1027
#endif /* _WIN32_WINNT >= 0x0501 */
#define SPI_GETUIEFFECTS 0x103E
#define SPI_SETUIEFFECTS 0x103F
#if(_WIN32_WINNT >= 0x0600)
#define SPI_GETDISABLEOVERLAPPEDCONTENT 0x1040
#define SPI_SETDISABLEOVERLAPPEDCONTENT 0x1041
#define SPI_GETCLIENTAREAANIMATION 0x1042
#define SPI_SETCLIENTAREAANIMATION 0x1043
#define SPI_GETCLEARTYPE 0x1048
#define SPI_SETCLEARTYPE 0x1049
#define SPI_GETSPEECHRECOGNITION 0x104A
#define SPI_SETSPEECHRECOGNITION 0x104B
#endif /* _WIN32_WINNT >= 0x0600 */
#if(WINVER >= 0x0601)
#define SPI_GETCARETBROWSING 0x104C
#define SPI_SETCARETBROWSING 0x104D
#define SPI_GETTHREADLOCALINPUTSETTINGS 0x104E
#define SPI_SETTHREADLOCALINPUTSETTINGS 0x104F
#define SPI_GETSYSTEMLANGUAGEBAR 0x1050
#define SPI_SETSYSTEMLANGUAGEBAR 0x1051
#endif /* WINVER >= 0x0601 */
#define SPI_GETFOREGROUNDLOCKTIMEOUT 0x2000
#define SPI_SETFOREGROUNDLOCKTIMEOUT 0x2001
#define SPI_GETACTIVEWNDTRKTIMEOUT 0x2002
#define SPI_SETACTIVEWNDTRKTIMEOUT 0x2003
#define SPI_GETFOREGROUNDFLASHCOUNT 0x2004
#define SPI_SETFOREGROUNDFLASHCOUNT 0x2005
#define SPI_GETCARETWIDTH 0x2006
#define SPI_SETCARETWIDTH 0x2007
#if(_WIN32_WINNT >= 0x0501)
#define SPI_GETMOUSECLICKLOCKTIME 0x2008
#define SPI_SETMOUSECLICKLOCKTIME 0x2009
#define SPI_GETFONTSMOOTHINGTYPE 0x200A
#define SPI_SETFONTSMOOTHINGTYPE 0x200B
/* constants for SPI_GETFONTSMOOTHINGTYPE and SPI_SETFONTSMOOTHINGTYPE: */
#define FE_FONTSMOOTHINGSTANDARD 0x0001
#define FE_FONTSMOOTHINGCLEARTYPE 0x0002
#define SPI_GETFONTSMOOTHINGCONTRAST 0x200C
#define SPI_SETFONTSMOOTHINGCONTRAST 0x200D
#define SPI_GETFOCUSBORDERWIDTH 0x200E
#define SPI_SETFOCUSBORDERWIDTH 0x200F
#define SPI_GETFOCUSBORDERHEIGHT 0x2010
#define SPI_SETFOCUSBORDERHEIGHT 0x2011
#define SPI_GETFONTSMOOTHINGORIENTATION 0x2012
#define SPI_SETFONTSMOOTHINGORIENTATION 0x2013
/* constants for SPI_GETFONTSMOOTHINGORIENTATION and SPI_SETFONTSMOOTHINGORIENTATION: */
#define FE_FONTSMOOTHINGORIENTATIONBGR 0x0000
#define FE_FONTSMOOTHINGORIENTATIONRGB 0x0001
#endif /* _WIN32_WINNT >= 0x0501 */
#if(_WIN32_WINNT >= 0x0600)
#define SPI_GETMINIMUMHITRADIUS 0x2014
#define SPI_SETMINIMUMHITRADIUS 0x2015
#define SPI_GETMESSAGEDURATION 0x2016
#define SPI_SETMESSAGEDURATION 0x2017
#endif /* _WIN32_WINNT >= 0x0600 */
#if(WINVER >= 0x0602)
#define SPI_GETCONTACTVISUALIZATION 0x2018
#define SPI_SETCONTACTVISUALIZATION 0x2019
/* constants for SPI_GETCONTACTVISUALIZATION and SPI_SETCONTACTVISUALIZATION */
#define CONTACTVISUALIZATION_OFF 0x0000
#define CONTACTVISUALIZATION_ON 0x0001
#define CONTACTVISUALIZATION_PRESENTATIONMODE 0x0002
#define SPI_GETGESTUREVISUALIZATION 0x201A
#define SPI_SETGESTUREVISUALIZATION 0x201B
/* constants for SPI_GETGESTUREVISUALIZATION and SPI_SETGESTUREVISUALIZATION */
#define GESTUREVISUALIZATION_OFF 0x0000
#define GESTUREVISUALIZATION_ON 0x001F
#define GESTUREVISUALIZATION_TAP 0x0001
#define GESTUREVISUALIZATION_DOUBLETAP 0x0002
#define GESTUREVISUALIZATION_PRESSANDTAP 0x0004
#define GESTUREVISUALIZATION_PRESSANDHOLD 0x0008
#define GESTUREVISUALIZATION_RIGHTTAP 0x0010
#endif /* WINVER >= 0x0602 */
#if(WINVER >= 0x0602)
#define SPI_GETMOUSEWHEELROUTING 0x201C
#define SPI_SETMOUSEWHEELROUTING 0x201D
#define MOUSEWHEEL_ROUTING_FOCUS 0
#define MOUSEWHEEL_ROUTING_HYBRID 1
#endif /* WINVER >= 0x0602 */
#endif /* WINVER >= 0x0500 */
/*
* Flags
*/
#define SPIF_UPDATEINIFILE 0x0001
#define SPIF_SENDWININICHANGE 0x0002
#define SPIF_SENDCHANGE SPIF_SENDWININICHANGE
#define METRICS_USEDEFAULT -1
#ifdef _WINGDI_
#ifndef NOGDI
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef struct tagNONCLIENTMETRICSA
{
UINT cbSize;
int iBorderWidth;
int iScrollWidth;
int iScrollHeight;
int iCaptionWidth;
int iCaptionHeight;
LOGFONTA lfCaptionFont;
int iSmCaptionWidth;
int iSmCaptionHeight;
LOGFONTA lfSmCaptionFont;
int iMenuWidth;
int iMenuHeight;
LOGFONTA lfMenuFont;
LOGFONTA lfStatusFont;
LOGFONTA lfMessageFont;
#if(WINVER >= 0x0600)
int iPaddedBorderWidth;
#endif /* WINVER >= 0x0600 */
} NONCLIENTMETRICSA, *PNONCLIENTMETRICSA, FAR* LPNONCLIENTMETRICSA;
typedef struct tagNONCLIENTMETRICSW
{
UINT cbSize;
int iBorderWidth;
int iScrollWidth;
int iScrollHeight;
int iCaptionWidth;
int iCaptionHeight;
LOGFONTW lfCaptionFont;
int iSmCaptionWidth;
int iSmCaptionHeight;
LOGFONTW lfSmCaptionFont;
int iMenuWidth;
int iMenuHeight;
LOGFONTW lfMenuFont;
LOGFONTW lfStatusFont;
LOGFONTW lfMessageFont;
#if(WINVER >= 0x0600)
int iPaddedBorderWidth;
#endif /* WINVER >= 0x0600 */
} NONCLIENTMETRICSW, *PNONCLIENTMETRICSW, FAR* LPNONCLIENTMETRICSW;
#ifdef UNICODE
typedef NONCLIENTMETRICSW NONCLIENTMETRICS;
typedef PNONCLIENTMETRICSW PNONCLIENTMETRICS;
typedef LPNONCLIENTMETRICSW LPNONCLIENTMETRICS;
#else
typedef NONCLIENTMETRICSA NONCLIENTMETRICS;
typedef PNONCLIENTMETRICSA PNONCLIENTMETRICS;
typedef LPNONCLIENTMETRICSA LPNONCLIENTMETRICS;
#endif // UNICODE
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* NOGDI */
#endif /* _WINGDI_ */
#define ARW_BOTTOMLEFT 0x0000L
#define ARW_BOTTOMRIGHT 0x0001L
#define ARW_TOPLEFT 0x0002L
#define ARW_TOPRIGHT 0x0003L
#define ARW_STARTMASK 0x0003L
#define ARW_STARTRIGHT 0x0001L
#define ARW_STARTTOP 0x0002L
#define ARW_LEFT 0x0000L
#define ARW_RIGHT 0x0000L
#define ARW_UP 0x0004L
#define ARW_DOWN 0x0004L
#define ARW_HIDE 0x0008L
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef struct tagMINIMIZEDMETRICS
{
UINT cbSize;
int iWidth;
int iHorzGap;
int iVertGap;
int iArrange;
} MINIMIZEDMETRICS, *PMINIMIZEDMETRICS, *LPMINIMIZEDMETRICS;
#ifdef _WINGDI_
#ifndef NOGDI
typedef struct tagICONMETRICSA
{
UINT cbSize;
int iHorzSpacing;
int iVertSpacing;
int iTitleWrap;
LOGFONTA lfFont;
} ICONMETRICSA, *PICONMETRICSA, *LPICONMETRICSA;
typedef struct tagICONMETRICSW
{
UINT cbSize;
int iHorzSpacing;
int iVertSpacing;
int iTitleWrap;
LOGFONTW lfFont;
} ICONMETRICSW, *PICONMETRICSW, *LPICONMETRICSW;
#ifdef UNICODE
typedef ICONMETRICSW ICONMETRICS;
typedef PICONMETRICSW PICONMETRICS;
typedef LPICONMETRICSW LPICONMETRICS;
#else
typedef ICONMETRICSA ICONMETRICS;
typedef PICONMETRICSA PICONMETRICS;
typedef LPICONMETRICSA LPICONMETRICS;
#endif // UNICODE
#endif /* NOGDI */
#endif /* _WINGDI_ */
typedef struct tagANIMATIONINFO
{
UINT cbSize;
int iMinAnimate;
} ANIMATIONINFO, *LPANIMATIONINFO;
typedef struct tagSERIALKEYSA
{
UINT cbSize;
DWORD dwFlags;
LPSTR lpszActivePort;
LPSTR lpszPort;
UINT iBaudRate;
UINT iPortState;
UINT iActive;
} SERIALKEYSA, *LPSERIALKEYSA;
typedef struct tagSERIALKEYSW
{
UINT cbSize;
DWORD dwFlags;
LPWSTR lpszActivePort;
LPWSTR lpszPort;
UINT iBaudRate;
UINT iPortState;
UINT iActive;
} SERIALKEYSW, *LPSERIALKEYSW;
#ifdef UNICODE
typedef SERIALKEYSW SERIALKEYS;
typedef LPSERIALKEYSW LPSERIALKEYS;
#else
typedef SERIALKEYSA SERIALKEYS;
typedef LPSERIALKEYSA LPSERIALKEYS;
#endif // UNICODE
/* flags for SERIALKEYS dwFlags field */
#define SERKF_SERIALKEYSON 0x00000001
#define SERKF_AVAILABLE 0x00000002
#define SERKF_INDICATOR 0x00000004
typedef struct tagHIGHCONTRASTA
{
UINT cbSize;
DWORD dwFlags;
LPSTR lpszDefaultScheme;
} HIGHCONTRASTA, *LPHIGHCONTRASTA;
typedef struct tagHIGHCONTRASTW
{
UINT cbSize;
DWORD dwFlags;
LPWSTR lpszDefaultScheme;
} HIGHCONTRASTW, *LPHIGHCONTRASTW;
#ifdef UNICODE
typedef HIGHCONTRASTW HIGHCONTRAST;
typedef LPHIGHCONTRASTW LPHIGHCONTRAST;
#else
typedef HIGHCONTRASTA HIGHCONTRAST;
typedef LPHIGHCONTRASTA LPHIGHCONTRAST;
#endif // UNICODE
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/* flags for HIGHCONTRAST dwFlags field */
#define HCF_HIGHCONTRASTON 0x00000001
#define HCF_AVAILABLE 0x00000002
#define HCF_HOTKEYACTIVE 0x00000004
#define HCF_CONFIRMHOTKEY 0x00000008
#define HCF_HOTKEYSOUND 0x00000010
#define HCF_INDICATOR 0x00000020
#define HCF_HOTKEYAVAILABLE 0x00000040
#define HCF_LOGONDESKTOP 0x00000100
#define HCF_DEFAULTDESKTOP 0x00000200
/* Flags for ChangeDisplaySettings */
#define CDS_UPDATEREGISTRY 0x00000001
#define CDS_TEST 0x00000002
#define CDS_FULLSCREEN 0x00000004
#define CDS_GLOBAL 0x00000008
#define CDS_SET_PRIMARY 0x00000010
#define CDS_VIDEOPARAMETERS 0x00000020
#if(WINVER >= 0x0600)
#define CDS_ENABLE_UNSAFE_MODES 0x00000100
#define CDS_DISABLE_UNSAFE_MODES 0x00000200
#endif /* WINVER >= 0x0600 */
#define CDS_RESET 0x40000000
#define CDS_RESET_EX 0x20000000
#define CDS_NORESET 0x10000000
#include <tvout.h>
/* Return values for ChangeDisplaySettings */
#define DISP_CHANGE_SUCCESSFUL 0
#define DISP_CHANGE_RESTART 1
#define DISP_CHANGE_FAILED -1
#define DISP_CHANGE_BADMODE -2
#define DISP_CHANGE_NOTUPDATED -3
#define DISP_CHANGE_BADFLAGS -4
#define DISP_CHANGE_BADPARAM -5
#if(_WIN32_WINNT >= 0x0501)
#define DISP_CHANGE_BADDUALVIEW -6
#endif /* _WIN32_WINNT >= 0x0501 */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#ifdef _WINGDI_
#ifndef NOGDI
WINUSERAPI
LONG
WINAPI
ChangeDisplaySettingsA(
_In_opt_ DEVMODEA* lpDevMode,
_In_ DWORD dwFlags);
WINUSERAPI
LONG
WINAPI
ChangeDisplaySettingsW(
_In_opt_ DEVMODEW* lpDevMode,
_In_ DWORD dwFlags);
#ifdef UNICODE
#define ChangeDisplaySettings ChangeDisplaySettingsW
#else
#define ChangeDisplaySettings ChangeDisplaySettingsA
#endif // !UNICODE
WINUSERAPI
LONG
WINAPI
ChangeDisplaySettingsExA(
_In_opt_ LPCSTR lpszDeviceName,
_In_opt_ DEVMODEA* lpDevMode,
_Reserved_ HWND hwnd,
_In_ DWORD dwflags,
_In_opt_ LPVOID lParam);
WINUSERAPI
LONG
WINAPI
ChangeDisplaySettingsExW(
_In_opt_ LPCWSTR lpszDeviceName,
_In_opt_ DEVMODEW* lpDevMode,
_Reserved_ HWND hwnd,
_In_ DWORD dwflags,
_In_opt_ LPVOID lParam);
#ifdef UNICODE
#define ChangeDisplaySettingsEx ChangeDisplaySettingsExW
#else
#define ChangeDisplaySettingsEx ChangeDisplaySettingsExA
#endif // !UNICODE
#define ENUM_CURRENT_SETTINGS ((DWORD)-1)
#define ENUM_REGISTRY_SETTINGS ((DWORD)-2)
WINUSERAPI
BOOL
WINAPI
EnumDisplaySettingsA(
_In_opt_ LPCSTR lpszDeviceName,
_In_ DWORD iModeNum,
_Inout_ DEVMODEA* lpDevMode);
WINUSERAPI
BOOL
WINAPI
EnumDisplaySettingsW(
_In_opt_ LPCWSTR lpszDeviceName,
_In_ DWORD iModeNum,
_Inout_ DEVMODEW* lpDevMode);
#ifdef UNICODE
#define EnumDisplaySettings EnumDisplaySettingsW
#else
#define EnumDisplaySettings EnumDisplaySettingsA
#endif // !UNICODE
#if(WINVER >= 0x0500)
WINUSERAPI
BOOL
WINAPI
EnumDisplaySettingsExA(
_In_opt_ LPCSTR lpszDeviceName,
_In_ DWORD iModeNum,
_Inout_ DEVMODEA* lpDevMode,
_In_ DWORD dwFlags);
WINUSERAPI
BOOL
WINAPI
EnumDisplaySettingsExW(
_In_opt_ LPCWSTR lpszDeviceName,
_In_ DWORD iModeNum,
_Inout_ DEVMODEW* lpDevMode,
_In_ DWORD dwFlags);
#ifdef UNICODE
#define EnumDisplaySettingsEx EnumDisplaySettingsExW
#else
#define EnumDisplaySettingsEx EnumDisplaySettingsExA
#endif // !UNICODE
/* Flags for EnumDisplaySettingsEx */
#define EDS_RAWMODE 0x00000002
#define EDS_ROTATEDMODE 0x00000004
WINUSERAPI
BOOL
WINAPI
EnumDisplayDevicesA(
_In_opt_ LPCSTR lpDevice,
_In_ DWORD iDevNum,
_Inout_ PDISPLAY_DEVICEA lpDisplayDevice,
_In_ DWORD dwFlags);
WINUSERAPI
BOOL
WINAPI
EnumDisplayDevicesW(
_In_opt_ LPCWSTR lpDevice,
_In_ DWORD iDevNum,
_Inout_ PDISPLAY_DEVICEW lpDisplayDevice,
_In_ DWORD dwFlags);
#ifdef UNICODE
#define EnumDisplayDevices EnumDisplayDevicesW
#else
#define EnumDisplayDevices EnumDisplayDevicesA
#endif // !UNICODE
/* Flags for EnumDisplayDevices */
#define EDD_GET_DEVICE_INTERFACE_NAME 0x00000001
#endif /* WINVER >= 0x0500 */
#if(WINVER >= 0x0601)
WINUSERAPI
LONG
WINAPI
GetDisplayConfigBufferSizes(
_In_ UINT32 flags,
_Out_ UINT32* numPathArrayElements,
_Out_ UINT32* numModeInfoArrayElements);
WINUSERAPI
LONG
WINAPI
SetDisplayConfig(
_In_ UINT32 numPathArrayElements,
_In_reads_opt_(numPathArrayElements) DISPLAYCONFIG_PATH_INFO* pathArray,
_In_ UINT32 numModeInfoArrayElements,
_In_reads_opt_(numModeInfoArrayElements) DISPLAYCONFIG_MODE_INFO* modeInfoArray,
_In_ UINT32 flags);
WINUSERAPI
_Success_(return == ERROR_SUCCESS) LONG
WINAPI
QueryDisplayConfig(
_In_ UINT32 flags,
_Inout_ UINT32* numPathArrayElements,
_Out_writes_to_(*numPathArrayElements, *numPathArrayElements) DISPLAYCONFIG_PATH_INFO* pathArray,
_Inout_ UINT32* numModeInfoArrayElements,
_Out_writes_to_(*numModeInfoArrayElements, *numModeInfoArrayElements) DISPLAYCONFIG_MODE_INFO* modeInfoArray,
_When_(!(flags & QDC_DATABASE_CURRENT), _Pre_null_)
_When_(flags & QDC_DATABASE_CURRENT, _Out_)
DISPLAYCONFIG_TOPOLOGY_ID* currentTopologyId);
WINUSERAPI
LONG
WINAPI
DisplayConfigGetDeviceInfo(
_Inout_ DISPLAYCONFIG_DEVICE_INFO_HEADER* requestPacket);
WINUSERAPI
LONG
WINAPI
DisplayConfigSetDeviceInfo(
_In_ DISPLAYCONFIG_DEVICE_INFO_HEADER* setPacket);
#endif /* WINVER >= 0x0601 */
#endif /* NOGDI */
#endif /* _WINGDI_ */
WINUSERAPI
_Success_(return != FALSE)
BOOL
WINAPI
SystemParametersInfoA(
_In_ UINT uiAction,
_In_ UINT uiParam,
_Pre_maybenull_ _Post_valid_ PVOID pvParam,
_In_ UINT fWinIni);
WINUSERAPI
_Success_(return != FALSE)
BOOL
WINAPI
SystemParametersInfoW(
_In_ UINT uiAction,
_In_ UINT uiParam,
_Pre_maybenull_ _Post_valid_ PVOID pvParam,
_In_ UINT fWinIni);
#ifdef UNICODE
#define SystemParametersInfo SystemParametersInfoW
#else
#define SystemParametersInfo SystemParametersInfoA
#endif // !UNICODE
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* !NOSYSPARAMSINFO */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
/*
* Accessibility support
*/
typedef struct tagFILTERKEYS
{
UINT cbSize;
DWORD dwFlags;
DWORD iWaitMSec; // Acceptance Delay
DWORD iDelayMSec; // Delay Until Repeat
DWORD iRepeatMSec; // Repeat Rate
DWORD iBounceMSec; // Debounce Time
} FILTERKEYS, *LPFILTERKEYS;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* FILTERKEYS dwFlags field
*/
#define FKF_FILTERKEYSON 0x00000001
#define FKF_AVAILABLE 0x00000002
#define FKF_HOTKEYACTIVE 0x00000004
#define FKF_CONFIRMHOTKEY 0x00000008
#define FKF_HOTKEYSOUND 0x00000010
#define FKF_INDICATOR 0x00000020
#define FKF_CLICKON 0x00000040
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef struct tagSTICKYKEYS
{
UINT cbSize;
DWORD dwFlags;
} STICKYKEYS, *LPSTICKYKEYS;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* STICKYKEYS dwFlags field
*/
#define SKF_STICKYKEYSON 0x00000001
#define SKF_AVAILABLE 0x00000002
#define SKF_HOTKEYACTIVE 0x00000004
#define SKF_CONFIRMHOTKEY 0x00000008
#define SKF_HOTKEYSOUND 0x00000010
#define SKF_INDICATOR 0x00000020
#define SKF_AUDIBLEFEEDBACK 0x00000040
#define SKF_TRISTATE 0x00000080
#define SKF_TWOKEYSOFF 0x00000100
#if(_WIN32_WINNT >= 0x0500)
#define SKF_LALTLATCHED 0x10000000
#define SKF_LCTLLATCHED 0x04000000
#define SKF_LSHIFTLATCHED 0x01000000
#define SKF_RALTLATCHED 0x20000000
#define SKF_RCTLLATCHED 0x08000000
#define SKF_RSHIFTLATCHED 0x02000000
#define SKF_LWINLATCHED 0x40000000
#define SKF_RWINLATCHED 0x80000000
#define SKF_LALTLOCKED 0x00100000
#define SKF_LCTLLOCKED 0x00040000
#define SKF_LSHIFTLOCKED 0x00010000
#define SKF_RALTLOCKED 0x00200000
#define SKF_RCTLLOCKED 0x00080000
#define SKF_RSHIFTLOCKED 0x00020000
#define SKF_LWINLOCKED 0x00400000
#define SKF_RWINLOCKED 0x00800000
#endif /* _WIN32_WINNT >= 0x0500 */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef struct tagMOUSEKEYS
{
UINT cbSize;
DWORD dwFlags;
DWORD iMaxSpeed;
DWORD iTimeToMaxSpeed;
DWORD iCtrlSpeed;
DWORD dwReserved1;
DWORD dwReserved2;
} MOUSEKEYS, *LPMOUSEKEYS;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* MOUSEKEYS dwFlags field
*/
#define MKF_MOUSEKEYSON 0x00000001
#define MKF_AVAILABLE 0x00000002
#define MKF_HOTKEYACTIVE 0x00000004
#define MKF_CONFIRMHOTKEY 0x00000008
#define MKF_HOTKEYSOUND 0x00000010
#define MKF_INDICATOR 0x00000020
#define MKF_MODIFIERS 0x00000040
#define MKF_REPLACENUMBERS 0x00000080
#if(_WIN32_WINNT >= 0x0500)
#define MKF_LEFTBUTTONSEL 0x10000000
#define MKF_RIGHTBUTTONSEL 0x20000000
#define MKF_LEFTBUTTONDOWN 0x01000000
#define MKF_RIGHTBUTTONDOWN 0x02000000
#define MKF_MOUSEMODE 0x80000000
#endif /* _WIN32_WINNT >= 0x0500 */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef struct tagACCESSTIMEOUT
{
UINT cbSize;
DWORD dwFlags;
DWORD iTimeOutMSec;
} ACCESSTIMEOUT, *LPACCESSTIMEOUT;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* ACCESSTIMEOUT dwFlags field
*/
#define ATF_TIMEOUTON 0x00000001
#define ATF_ONOFFFEEDBACK 0x00000002
/* values for SOUNDSENTRY iFSGrafEffect field */
#define SSGF_NONE 0
#define SSGF_DISPLAY 3
/* values for SOUNDSENTRY iFSTextEffect field */
#define SSTF_NONE 0
#define SSTF_CHARS 1
#define SSTF_BORDER 2
#define SSTF_DISPLAY 3
/* values for SOUNDSENTRY iWindowsEffect field */
#define SSWF_NONE 0
#define SSWF_TITLE 1
#define SSWF_WINDOW 2
#define SSWF_DISPLAY 3
#define SSWF_CUSTOM 4
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef struct tagSOUNDSENTRYA
{
UINT cbSize;
DWORD dwFlags;
DWORD iFSTextEffect;
DWORD iFSTextEffectMSec;
DWORD iFSTextEffectColorBits;
DWORD iFSGrafEffect;
DWORD iFSGrafEffectMSec;
DWORD iFSGrafEffectColor;
DWORD iWindowsEffect;
DWORD iWindowsEffectMSec;
LPSTR lpszWindowsEffectDLL;
DWORD iWindowsEffectOrdinal;
} SOUNDSENTRYA, *LPSOUNDSENTRYA;
typedef struct tagSOUNDSENTRYW
{
UINT cbSize;
DWORD dwFlags;
DWORD iFSTextEffect;
DWORD iFSTextEffectMSec;
DWORD iFSTextEffectColorBits;
DWORD iFSGrafEffect;
DWORD iFSGrafEffectMSec;
DWORD iFSGrafEffectColor;
DWORD iWindowsEffect;
DWORD iWindowsEffectMSec;
LPWSTR lpszWindowsEffectDLL;
DWORD iWindowsEffectOrdinal;
} SOUNDSENTRYW, *LPSOUNDSENTRYW;
#ifdef UNICODE
typedef SOUNDSENTRYW SOUNDSENTRY;
typedef LPSOUNDSENTRYW LPSOUNDSENTRY;
#else
typedef SOUNDSENTRYA SOUNDSENTRY;
typedef LPSOUNDSENTRYA LPSOUNDSENTRY;
#endif // UNICODE
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* SOUNDSENTRY dwFlags field
*/
#define SSF_SOUNDSENTRYON 0x00000001
#define SSF_AVAILABLE 0x00000002
#define SSF_INDICATOR 0x00000004
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#if(_WIN32_WINNT >= 0x0600)
WINUSERAPI
BOOL
WINAPI
SoundSentry(VOID);
#endif /* _WIN32_WINNT >= 0x0600 */
typedef struct tagTOGGLEKEYS
{
UINT cbSize;
DWORD dwFlags;
} TOGGLEKEYS, *LPTOGGLEKEYS;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* TOGGLEKEYS dwFlags field
*/
#define TKF_TOGGLEKEYSON 0x00000001
#define TKF_AVAILABLE 0x00000002
#define TKF_HOTKEYACTIVE 0x00000004
#define TKF_CONFIRMHOTKEY 0x00000008
#define TKF_HOTKEYSOUND 0x00000010
#define TKF_INDICATOR 0x00000020
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#if(_WIN32_WINNT >= 0x0600)
typedef struct tagAUDIODESCRIPTION {
UINT cbSize; // sizeof(AudioDescriptionType)
BOOL Enabled; // On/Off
LCID Locale; // locale ID for language
} AUDIODESCRIPTION, *LPAUDIODESCRIPTION;
#endif /* _WIN32_WINNT >= 0x0600 */
/*
* Set debug level
*/
WINUSERAPI
VOID
WINAPI
SetDebugErrorLevel(
_In_ DWORD dwLevel);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* SetLastErrorEx() types.
*/
#define SLE_ERROR 0x00000001
#define SLE_MINORERROR 0x00000002
#define SLE_WARNING 0x00000003
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
VOID
WINAPI
SetLastErrorEx(
_In_ DWORD dwErrCode,
_In_ DWORD dwType);
WINUSERAPI
int
WINAPI
InternalGetWindowText(
_In_ HWND hWnd,
_Out_writes_to_(cchMaxCount, return + 1) LPWSTR pString,
_In_ int cchMaxCount);
#if defined(WINNT)
WINUSERAPI
BOOL
WINAPI
EndTask(
_In_ HWND hWnd,
_In_ BOOL fShutDown,
_In_ BOOL fForce);
#endif
WINUSERAPI
BOOL
WINAPI
CancelShutdown(
VOID);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#if(WINVER >= 0x0500)
/*
* Multimonitor API.
*/
#define MONITOR_DEFAULTTONULL 0x00000000
#define MONITOR_DEFAULTTOPRIMARY 0x00000001
#define MONITOR_DEFAULTTONEAREST 0x00000002
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
HMONITOR
WINAPI
MonitorFromPoint(
_In_ POINT pt,
_In_ DWORD dwFlags);
WINUSERAPI
HMONITOR
WINAPI
MonitorFromRect(
_In_ LPCRECT lprc,
_In_ DWORD dwFlags);
WINUSERAPI
HMONITOR
WINAPI
MonitorFromWindow(
_In_ HWND hwnd,
_In_ DWORD dwFlags);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#define MONITORINFOF_PRIMARY 0x00000001
#ifndef CCHDEVICENAME
#define CCHDEVICENAME 32
#endif
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef struct tagMONITORINFO
{
DWORD cbSize;
RECT rcMonitor;
RECT rcWork;
DWORD dwFlags;
} MONITORINFO, *LPMONITORINFO;
#ifdef __cplusplus
typedef struct tagMONITORINFOEXA : public tagMONITORINFO
{
CHAR szDevice[CCHDEVICENAME];
} MONITORINFOEXA, *LPMONITORINFOEXA;
typedef struct tagMONITORINFOEXW : public tagMONITORINFO
{
WCHAR szDevice[CCHDEVICENAME];
} MONITORINFOEXW, *LPMONITORINFOEXW;
#ifdef UNICODE
typedef MONITORINFOEXW MONITORINFOEX;
typedef LPMONITORINFOEXW LPMONITORINFOEX;
#else
typedef MONITORINFOEXA MONITORINFOEX;
typedef LPMONITORINFOEXA LPMONITORINFOEX;
#endif // UNICODE
#else // ndef __cplusplus
typedef struct tagMONITORINFOEXA
{
MONITORINFO;
CHAR szDevice[CCHDEVICENAME];
} MONITORINFOEXA, *LPMONITORINFOEXA;
typedef struct tagMONITORINFOEXW
{
MONITORINFO;
WCHAR szDevice[CCHDEVICENAME];
} MONITORINFOEXW, *LPMONITORINFOEXW;
#ifdef UNICODE
typedef MONITORINFOEXW MONITORINFOEX;
typedef LPMONITORINFOEXW LPMONITORINFOEX;
#else
typedef MONITORINFOEXA MONITORINFOEX;
typedef LPMONITORINFOEXA LPMONITORINFOEX;
#endif // UNICODE
#endif
WINUSERAPI
BOOL
WINAPI
GetMonitorInfoA(
_In_ HMONITOR hMonitor,
_Inout_ LPMONITORINFO lpmi);
WINUSERAPI
BOOL
WINAPI
GetMonitorInfoW(
_In_ HMONITOR hMonitor,
_Inout_ LPMONITORINFO lpmi);
#ifdef UNICODE
#define GetMonitorInfo GetMonitorInfoW
#else
#define GetMonitorInfo GetMonitorInfoA
#endif // !UNICODE
typedef BOOL (CALLBACK* MONITORENUMPROC)(HMONITOR, HDC, LPRECT, LPARAM);
WINUSERAPI
BOOL
WINAPI
EnumDisplayMonitors(
_In_opt_ HDC hdc,
_In_opt_ LPCRECT lprcClip,
_In_ MONITORENUMPROC lpfnEnum,
_In_ LPARAM dwData);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#ifndef NOWINABLE
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
/*
* WinEvents - Active Accessibility hooks
*/
WINUSERAPI
VOID
WINAPI
NotifyWinEvent(
_In_ DWORD event,
_In_ HWND hwnd,
_In_ LONG idObject,
_In_ LONG idChild);
typedef VOID (CALLBACK* WINEVENTPROC)(
HWINEVENTHOOK hWinEventHook,
DWORD event,
HWND hwnd,
LONG idObject,
LONG idChild,
DWORD idEventThread,
DWORD dwmsEventTime);
WINUSERAPI
HWINEVENTHOOK
WINAPI
SetWinEventHook(
_In_ DWORD eventMin,
_In_ DWORD eventMax,
_In_opt_ HMODULE hmodWinEventProc,
_In_ WINEVENTPROC pfnWinEventProc,
_In_ DWORD idProcess,
_In_ DWORD idThread,
_In_ DWORD dwFlags);
#if(_WIN32_WINNT >= 0x0501)
WINUSERAPI
BOOL
WINAPI
IsWinEventHookInstalled(
_In_ DWORD event);
#endif /* _WIN32_WINNT >= 0x0501 */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* dwFlags for SetWinEventHook
*/
#define WINEVENT_OUTOFCONTEXT 0x0000 // Events are ASYNC
#define WINEVENT_SKIPOWNTHREAD 0x0001 // Don't call back for events on installer's thread
#define WINEVENT_SKIPOWNPROCESS 0x0002 // Don't call back for events on installer's process
#define WINEVENT_INCONTEXT 0x0004 // Events are SYNC, this causes your dll to be injected into every process
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
UnhookWinEvent(
_In_ HWINEVENTHOOK hWinEventHook);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* idObject values for WinEventProc and NotifyWinEvent
*/
/*
* hwnd + idObject can be used with OLEACC.DLL's OleGetObjectFromWindow()
* to get an interface pointer to the container. indexChild is the item
* within the container in question. Setup a VARIANT with vt VT_I4 and
* lVal the indexChild and pass that in to all methods. Then you
* are raring to go.
*/
/*
* Common object IDs (cookies, only for sending WM_GETOBJECT to get at the
* thing in question). Positive IDs are reserved for apps (app specific),
* negative IDs are system things and are global, 0 means "just little old
* me".
*/
#define CHILDID_SELF 0
#define INDEXID_OBJECT 0
#define INDEXID_CONTAINER 0
/*
* Reserved IDs for system objects
*/
#define OBJID_WINDOW ((LONG)0x00000000)
#define OBJID_SYSMENU ((LONG)0xFFFFFFFF)
#define OBJID_TITLEBAR ((LONG)0xFFFFFFFE)
#define OBJID_MENU ((LONG)0xFFFFFFFD)
#define OBJID_CLIENT ((LONG)0xFFFFFFFC)
#define OBJID_VSCROLL ((LONG)0xFFFFFFFB)
#define OBJID_HSCROLL ((LONG)0xFFFFFFFA)
#define OBJID_SIZEGRIP ((LONG)0xFFFFFFF9)
#define OBJID_CARET ((LONG)0xFFFFFFF8)
#define OBJID_CURSOR ((LONG)0xFFFFFFF7)
#define OBJID_ALERT ((LONG)0xFFFFFFF6)
#define OBJID_SOUND ((LONG)0xFFFFFFF5)
#define OBJID_QUERYCLASSNAMEIDX ((LONG)0xFFFFFFF4)
#define OBJID_NATIVEOM ((LONG)0xFFFFFFF0)
/*
* EVENT DEFINITION
*/
#define EVENT_MIN 0x00000001
#define EVENT_MAX 0x7FFFFFFF
/*
* EVENT_SYSTEM_SOUND
* Sent when a sound is played. Currently nothing is generating this, we
* this event when a system sound (for menus, etc) is played. Apps
* generate this, if accessible, when a private sound is played. For
* example, if Mail plays a "New Mail" sound.
*
* System Sounds:
* (Generated by PlaySoundEvent in USER itself)
* hwnd is NULL
* idObject is OBJID_SOUND
* idChild is sound child ID if one
* App Sounds:
* (PlaySoundEvent won't generate notification; up to app)
* hwnd + idObject gets interface pointer to Sound object
* idChild identifies the sound in question
* are going to be cleaning up the SOUNDSENTRY feature in the control panel
* and will use this at that time. Applications implementing WinEvents
* are perfectly welcome to use it. Clients of IAccessible* will simply
* turn around and get back a non-visual object that describes the sound.
*/
#define EVENT_SYSTEM_SOUND 0x0001
/*
* EVENT_SYSTEM_ALERT
* System Alerts:
* (Generated by MessageBox() calls for example)
* hwnd is hwndMessageBox
* idObject is OBJID_ALERT
* App Alerts:
* (Generated whenever)
* hwnd+idObject gets interface pointer to Alert
*/
#define EVENT_SYSTEM_ALERT 0x0002
/*
* EVENT_SYSTEM_FOREGROUND
* Sent when the foreground (active) window changes, even if it is changing
* to another window in the same thread as the previous one.
* hwnd is hwndNewForeground
* idObject is OBJID_WINDOW
* idChild is INDEXID_OBJECT
*/
#define EVENT_SYSTEM_FOREGROUND 0x0003
/*
* Menu
* hwnd is window (top level window or popup menu window)
* idObject is ID of control (OBJID_MENU, OBJID_SYSMENU, OBJID_SELF for popup)
* idChild is CHILDID_SELF
*
* EVENT_SYSTEM_MENUSTART
* EVENT_SYSTEM_MENUEND
* For MENUSTART, hwnd+idObject+idChild refers to the control with the menu bar,
* or the control bringing up the context menu.
*
* Sent when entering into and leaving from menu mode (system, app bar, and
* track popups).
*/
#define EVENT_SYSTEM_MENUSTART 0x0004
#define EVENT_SYSTEM_MENUEND 0x0005
/*
* EVENT_SYSTEM_MENUPOPUPSTART
* EVENT_SYSTEM_MENUPOPUPEND
* Sent when a menu popup comes up and just before it is taken down. Note
* that for a call to TrackPopupMenu(), a client will see EVENT_SYSTEM_MENUSTART
* followed almost immediately by EVENT_SYSTEM_MENUPOPUPSTART for the popup
* being shown.
*
* For MENUPOPUP, hwnd+idObject+idChild refers to the NEW popup coming up, not the
* parent item which is hierarchical. You can get the parent menu/popup by
* asking for the accParent object.
*/
#define EVENT_SYSTEM_MENUPOPUPSTART 0x0006
#define EVENT_SYSTEM_MENUPOPUPEND 0x0007
/*
* EVENT_SYSTEM_CAPTURESTART
* EVENT_SYSTEM_CAPTUREEND
* Sent when a window takes the capture and releases the capture.
*/
#define EVENT_SYSTEM_CAPTURESTART 0x0008
#define EVENT_SYSTEM_CAPTUREEND 0x0009
/*
* Move Size
* EVENT_SYSTEM_MOVESIZESTART
* EVENT_SYSTEM_MOVESIZEEND
* Sent when a window enters and leaves move-size dragging mode.
*/
#define EVENT_SYSTEM_MOVESIZESTART 0x000A
#define EVENT_SYSTEM_MOVESIZEEND 0x000B
/*
* Context Help
* EVENT_SYSTEM_CONTEXTHELPSTART
* EVENT_SYSTEM_CONTEXTHELPEND
* Sent when a window enters and leaves context sensitive help mode.
*/
#define EVENT_SYSTEM_CONTEXTHELPSTART 0x000C
#define EVENT_SYSTEM_CONTEXTHELPEND 0x000D
/*
* Drag & Drop
* EVENT_SYSTEM_DRAGDROPSTART
* EVENT_SYSTEM_DRAGDROPEND
* Send the START notification just before going into drag&drop loop. Send
* the END notification just after canceling out.
* Note that it is up to apps and OLE to generate this, since the system
* doesn't know. Like EVENT_SYSTEM_SOUND, it will be a while before this
* is prevalent.
*/
#define EVENT_SYSTEM_DRAGDROPSTART 0x000E
#define EVENT_SYSTEM_DRAGDROPEND 0x000F
/*
* Dialog
* Send the START notification right after the dialog is completely
* initialized and visible. Send the END right before the dialog
* is hidden and goes away.
* EVENT_SYSTEM_DIALOGSTART
* EVENT_SYSTEM_DIALOGEND
*/
#define EVENT_SYSTEM_DIALOGSTART 0x0010
#define EVENT_SYSTEM_DIALOGEND 0x0011
/*
* EVENT_SYSTEM_SCROLLING
* EVENT_SYSTEM_SCROLLINGSTART
* EVENT_SYSTEM_SCROLLINGEND
* Sent when beginning and ending the tracking of a scrollbar in a window,
* and also for scrollbar controls.
*/
#define EVENT_SYSTEM_SCROLLINGSTART 0x0012
#define EVENT_SYSTEM_SCROLLINGEND 0x0013
/*
* Alt-Tab Window
* Send the START notification right after the switch window is initialized
* and visible. Send the END right before it is hidden and goes away.
* EVENT_SYSTEM_SWITCHSTART
* EVENT_SYSTEM_SWITCHEND
*/
#define EVENT_SYSTEM_SWITCHSTART 0x0014
#define EVENT_SYSTEM_SWITCHEND 0x0015
/*
* EVENT_SYSTEM_MINIMIZESTART
* EVENT_SYSTEM_MINIMIZEEND
* Sent when a window minimizes and just before it restores.
*/
#define EVENT_SYSTEM_MINIMIZESTART 0x0016
#define EVENT_SYSTEM_MINIMIZEEND 0x0017
#if(_WIN32_WINNT >= 0x0600)
#define EVENT_SYSTEM_DESKTOPSWITCH 0x0020
#endif /* _WIN32_WINNT >= 0x0600 */
#if(_WIN32_WINNT >= 0x0602)
// AppGrabbed: HWND = hwnd of app thumbnail, objectID = 0, childID = 0
#define EVENT_SYSTEM_SWITCHER_APPGRABBED 0x0024
// OverTarget: HWND = hwnd of app thumbnail, objectID =
// 1 for center
// 2 for near snapped
// 3 for far snapped
// 4 for prune
// childID = 0
#define EVENT_SYSTEM_SWITCHER_APPOVERTARGET 0x0025
// Dropped: HWND = hwnd of app thumbnail, objectID = <same as above>, childID = 0
#define EVENT_SYSTEM_SWITCHER_APPDROPPED 0x0026
// Cancelled: HWND = hwnd of app thumbnail, objectID = 0, childID = 0
#define EVENT_SYSTEM_SWITCHER_CANCELLED 0x0027
#endif /* _WIN32_WINNT >= 0x0602 */
#if(_WIN32_WINNT >= 0x0602)
/*
* Sent when an IME's soft key is pressed and should be echoed,
* but is not passed through the keyboard hook.
* Must not be sent when a key is sent through the keyboard hook.
* HWND is the hwnd of the UI containing the soft key
* idChild is the Unicode value of the character entered
* idObject is a bitfield
* 0x00000001: set if a 32-bit Unicode surrogate pair is used
*/
#define EVENT_SYSTEM_IME_KEY_NOTIFICATION 0x0029
#endif /* _WIN32_WINNT >= 0x0602 */
#if(_WIN32_WINNT >= 0x0601)
#define EVENT_SYSTEM_END 0x00FF
#define EVENT_OEM_DEFINED_START 0x0101
#define EVENT_OEM_DEFINED_END 0x01FF
#define EVENT_UIA_EVENTID_START 0x4E00
#define EVENT_UIA_EVENTID_END 0x4EFF
#define EVENT_UIA_PROPID_START 0x7500
#define EVENT_UIA_PROPID_END 0x75FF
#endif /* _WIN32_WINNT >= 0x0601 */
#if(_WIN32_WINNT >= 0x0501)
#define EVENT_CONSOLE_CARET 0x4001
#define EVENT_CONSOLE_UPDATE_REGION 0x4002
#define EVENT_CONSOLE_UPDATE_SIMPLE 0x4003
#define EVENT_CONSOLE_UPDATE_SCROLL 0x4004
#define EVENT_CONSOLE_LAYOUT 0x4005
#define EVENT_CONSOLE_START_APPLICATION 0x4006
#define EVENT_CONSOLE_END_APPLICATION 0x4007
/*
* Flags for EVENT_CONSOLE_START/END_APPLICATION.
*/
#if defined(_WIN64)
#define CONSOLE_APPLICATION_16BIT 0x0000
#else
#define CONSOLE_APPLICATION_16BIT 0x0001
#endif
/*
* Flags for EVENT_CONSOLE_CARET
*/
#define CONSOLE_CARET_SELECTION 0x0001
#define CONSOLE_CARET_VISIBLE 0x0002
#endif /* _WIN32_WINNT >= 0x0501 */
#if(_WIN32_WINNT >= 0x0601)
#define EVENT_CONSOLE_END 0x40FF
#endif /* _WIN32_WINNT >= 0x0601 */
/*
* Object events
*
* The system AND apps generate these. The system generates these for
* real windows. Apps generate these for objects within their window which
* act like a separate control, e.g. an item in a list view.
*
* When the system generate them, dwParam2 is always WMOBJID_SELF. When
* apps generate them, apps put the has-meaning-to-the-app-only ID value
* in dwParam2.
* For all events, if you want detailed accessibility information, callers
* should
* * Call AccessibleObjectFromWindow() with the hwnd, idObject parameters
* of the event, and IID_IAccessible as the REFIID, to get back an
* IAccessible* to talk to
* * Initialize and fill in a VARIANT as VT_I4 with lVal the idChild
* parameter of the event.
* * If idChild isn't zero, call get_accChild() in the container to see
* if the child is an object in its own right. If so, you will get
* back an IDispatch* object for the child. You should release the
* parent, and call QueryInterface() on the child object to get its
* IAccessible*. Then you talk directly to the child. Otherwise,
* if get_accChild() returns you nothing, you should continue to
* use the child VARIANT. You will ask the container for the properties
* of the child identified by the VARIANT. In other words, the
* child in this case is accessible but not a full-blown object.
* Like a button on a titlebar which is 'small' and has no children.
*/
/*
* For all EVENT_OBJECT events,
* hwnd is the dude to Send the WM_GETOBJECT message to (unless NULL,
* see above for system things)
* idObject is the ID of the object that can resolve any queries a
* client might have. It's a way to deal with windowless controls,
* controls that are just drawn on the screen in some larger parent
* window (like SDM), or standard frame elements of a window.
* idChild is the piece inside of the object that is affected. This
* allows clients to access things that are too small to have full
* blown objects in their own right. Like the thumb of a scrollbar.
* The hwnd/idObject pair gets you to the container, the dude you
* probably want to talk to most of the time anyway. The idChild
* can then be passed into the acc properties to get the name/value
* of it as needed.
*
* Example #1:
* System propagating a listbox selection change
* EVENT_OBJECT_SELECTION
* hwnd == listbox hwnd
* idObject == OBJID_WINDOW
* idChild == new selected item, or CHILDID_SELF if
* nothing now selected within container.
* Word '97 propagating a listbox selection change
* hwnd == SDM window
* idObject == SDM ID to get at listbox 'control'
* idChild == new selected item, or CHILDID_SELF if
* nothing
*
* Example #2:
* System propagating a menu item selection on the menu bar
* EVENT_OBJECT_SELECTION
* hwnd == top level window
* idObject == OBJID_MENU
* idChild == ID of child menu bar item selected
*
* Example #3:
* System propagating a dropdown coming off of said menu bar item
* EVENT_OBJECT_CREATE
* hwnd == popup item
* idObject == OBJID_WINDOW
* idChild == CHILDID_SELF
*
* Example #4:
*
* For EVENT_OBJECT_REORDER, the object referred to by hwnd/idObject is the
* PARENT container in which the zorder is occurring. This is because if
* one child is zordering, all of them are changing their relative zorder.
*/
#define EVENT_OBJECT_CREATE 0x8000 // hwnd + ID + idChild is created item
#define EVENT_OBJECT_DESTROY 0x8001 // hwnd + ID + idChild is destroyed item
#define EVENT_OBJECT_SHOW 0x8002 // hwnd + ID + idChild is shown item
#define EVENT_OBJECT_HIDE 0x8003 // hwnd + ID + idChild is hidden item
#define EVENT_OBJECT_REORDER 0x8004 // hwnd + ID + idChild is parent of zordering children
/*
* NOTE:
* Minimize the number of notifications!
*
* When you are hiding a parent object, obviously all child objects are no
* longer visible on screen. They still have the same "visible" status,
* but are not truly visible. Hence do not send HIDE notifications for the
* children also. One implies all. The same goes for SHOW.
*/
#define EVENT_OBJECT_FOCUS 0x8005 // hwnd + ID + idChild is focused item
#define EVENT_OBJECT_SELECTION 0x8006 // hwnd + ID + idChild is selected item (if only one), or idChild is OBJID_WINDOW if complex
#define EVENT_OBJECT_SELECTIONADD 0x8007 // hwnd + ID + idChild is item added
#define EVENT_OBJECT_SELECTIONREMOVE 0x8008 // hwnd + ID + idChild is item removed
#define EVENT_OBJECT_SELECTIONWITHIN 0x8009 // hwnd + ID + idChild is parent of changed selected items
/*
* NOTES:
* There is only one "focused" child item in a parent. This is the place
* keystrokes are going at a given moment. Hence only send a notification
* about where the NEW focus is going. A NEW item getting the focus already
* implies that the OLD item is losing it.
*
* SELECTION however can be multiple. Hence the different SELECTION
* notifications. Here's when to use each:
*
* (1) Send a SELECTION notification in the simple single selection
* case (like the focus) when the item with the selection is
* merely moving to a different item within a container. hwnd + ID
* is the container control, idChildItem is the new child with the
* selection.
*
* (2) Send a SELECTIONADD notification when a new item has simply been added
* to the selection within a container. This is appropriate when the
* number of newly selected items is very small. hwnd + ID is the
* container control, idChildItem is the new child added to the selection.
*
* (3) Send a SELECTIONREMOVE notification when a new item has simply been
* removed from the selection within a container. This is appropriate
* when the number of newly selected items is very small, just like
* SELECTIONADD. hwnd + ID is the container control, idChildItem is the
* new child removed from the selection.
*
* (4) Send a SELECTIONWITHIN notification when the selected items within a
* control have changed substantially. Rather than propagate a large
* number of changes to reflect removal for some items, addition of
* others, just tell somebody who cares that a lot happened. It will
* be faster an easier for somebody watching to just turn around and
* query the container control what the new bunch of selected items
* are.
*/
#define EVENT_OBJECT_STATECHANGE 0x800A // hwnd + ID + idChild is item w/ state change
/*
* Examples of when to send an EVENT_OBJECT_STATECHANGE include
* * It is being enabled/disabled (USER does for windows)
* * It is being pressed/released (USER does for buttons)
* * It is being checked/unchecked (USER does for radio/check buttons)
*/
#define EVENT_OBJECT_LOCATIONCHANGE 0x800B // hwnd + ID + idChild is moved/sized item
/*
* Note:
* A LOCATIONCHANGE is not sent for every child object when the parent
* changes shape/moves. Send one notification for the topmost object
* that is changing. For example, if the user resizes a top level window,
* USER will generate a LOCATIONCHANGE for it, but not for the menu bar,
* title bar, scrollbars, etc. that are also changing shape/moving.
*
* In other words, it only generates LOCATIONCHANGE notifications for
* real windows that are moving/sizing. It will not generate a LOCATIONCHANGE
* for every non-floating child window when the parent moves (the children are
* logically moving also on screen, but not relative to the parent).
*
* Now, if the app itself resizes child windows as a result of being
* sized, USER will generate LOCATIONCHANGEs for those dudes also because
* it doesn't know better.
*
* Note also that USER will generate LOCATIONCHANGE notifications for two
* non-window sys objects:
* (1) System caret
* (2) Cursor
*/
#define EVENT_OBJECT_NAMECHANGE 0x800C // hwnd + ID + idChild is item w/ name change
#define EVENT_OBJECT_DESCRIPTIONCHANGE 0x800D // hwnd + ID + idChild is item w/ desc change
#define EVENT_OBJECT_VALUECHANGE 0x800E // hwnd + ID + idChild is item w/ value change
#define EVENT_OBJECT_PARENTCHANGE 0x800F // hwnd + ID + idChild is item w/ new parent
#define EVENT_OBJECT_HELPCHANGE 0x8010 // hwnd + ID + idChild is item w/ help change
#define EVENT_OBJECT_DEFACTIONCHANGE 0x8011 // hwnd + ID + idChild is item w/ def action change
#define EVENT_OBJECT_ACCELERATORCHANGE 0x8012 // hwnd + ID + idChild is item w/ keybd accel change
#if(_WIN32_WINNT >= 0x0600)
#define EVENT_OBJECT_INVOKED 0x8013 // hwnd + ID + idChild is item invoked
#define EVENT_OBJECT_TEXTSELECTIONCHANGED 0x8014 // hwnd + ID + idChild is item w? test selection change
/*
* EVENT_OBJECT_CONTENTSCROLLED
* Sent when ending the scrolling of a window object.
*
* Unlike the similar event (EVENT_SYSTEM_SCROLLEND), this event will be
* associated with the scrolling window itself. There is no difference
* between horizontal or vertical scrolling.
*
* This event should be posted whenever scroll action is completed, including
* when it is scrolled by scroll bars, mouse wheel, or keyboard navigations.
*
* example:
* hwnd == window that is scrolling
* idObject == OBJID_CLIENT
* idChild == CHILDID_SELF
*/
#define EVENT_OBJECT_CONTENTSCROLLED 0x8015
#endif /* _WIN32_WINNT >= 0x0600 */
#if(_WIN32_WINNT >= 0x0601)
#define EVENT_SYSTEM_ARRANGMENTPREVIEW 0x8016
#endif /* _WIN32_WINNT >= 0x0601 */
#if(_WIN32_WINNT >= 0x0602)
/*
* EVENT_OBJECT_CLOAKED / UNCLOAKED
* Sent when a window is cloaked or uncloaked.
* A cloaked window still exists, but is invisible to
* the user.
*/
#define EVENT_OBJECT_CLOAKED 0x8017
#define EVENT_OBJECT_UNCLOAKED 0x8018
/*
* EVENT_OBJECT_LIVEREGIONCHANGED
* Sent when an object that is part of a live region
* changes. A live region is an area of an application
* that changes frequently and/or asynchronously, so
* that an assistive technology tool might want to pay
* special attention to it.
*/
#define EVENT_OBJECT_LIVEREGIONCHANGED 0x8019
/*
* EVENT_OBJECT_HOSTEDOBJECTSINVALIDATED
* Sent when a window that is hosting other Accessible
* objects changes the hosted objects. A client may
* wish to requery to see what the new hosted objects are,
* especially if it has been monitoring events from this
* window. A hosted object is one with a different Accessibility
* framework (MSAA or UI Automation) from its host.
*
* Changes in hosted objects with the *same* framework
* as the parent should be handed with the usual structural
* change events, such as EVENT_OBJECT_CREATED for MSAA.
* see above.
*/
#define EVENT_OBJECT_HOSTEDOBJECTSINVALIDATED 0x8020
/*
* Drag / Drop Events
* These events are used in conjunction with the
* UI Automation Drag/Drop patterns.
*
* For DRAGSTART, DRAGCANCEL, and DRAGCOMPLETE,
* HWND+objectID+childID refers to the object being dragged.
*
* For DRAGENTER, DRAGLEAVE, and DRAGDROPPED,
* HWND+objectID+childID refers to the target of the drop
* that is being hovered over.
*/
#define EVENT_OBJECT_DRAGSTART 0x8021
#define EVENT_OBJECT_DRAGCANCEL 0x8022
#define EVENT_OBJECT_DRAGCOMPLETE 0x8023
#define EVENT_OBJECT_DRAGENTER 0x8024
#define EVENT_OBJECT_DRAGLEAVE 0x8025
#define EVENT_OBJECT_DRAGDROPPED 0x8026
/*
* EVENT_OBJECT_IME_SHOW/HIDE
* Sent by an IME window when it has become visible or invisible.
*/
#define EVENT_OBJECT_IME_SHOW 0x8027
#define EVENT_OBJECT_IME_HIDE 0x8028
/*
* EVENT_OBJECT_IME_CHANGE
* Sent by an IME window whenever it changes size or position.
*/
#define EVENT_OBJECT_IME_CHANGE 0x8029
#define EVENT_OBJECT_TEXTEDIT_CONVERSIONTARGETCHANGED 0x8030
#endif /* _WIN32_WINNT >= 0x0602 */
#if(_WIN32_WINNT >= 0x0601)
#define EVENT_OBJECT_END 0x80FF
#define EVENT_AIA_START 0xA000
#define EVENT_AIA_END 0xAFFF
#endif /* _WIN32_WINNT >= 0x0601 */
/*
* Child IDs
*/
/*
* System Sounds (idChild of system SOUND notification)
*/
#define SOUND_SYSTEM_STARTUP 1
#define SOUND_SYSTEM_SHUTDOWN 2
#define SOUND_SYSTEM_BEEP 3
#define SOUND_SYSTEM_ERROR 4
#define SOUND_SYSTEM_QUESTION 5
#define SOUND_SYSTEM_WARNING 6
#define SOUND_SYSTEM_INFORMATION 7
#define SOUND_SYSTEM_MAXIMIZE 8
#define SOUND_SYSTEM_MINIMIZE 9
#define SOUND_SYSTEM_RESTOREUP 10
#define SOUND_SYSTEM_RESTOREDOWN 11
#define SOUND_SYSTEM_APPSTART 12
#define SOUND_SYSTEM_FAULT 13
#define SOUND_SYSTEM_APPEND 14
#define SOUND_SYSTEM_MENUCOMMAND 15
#define SOUND_SYSTEM_MENUPOPUP 16
#define CSOUND_SYSTEM 16
/*
* System Alerts (indexChild of system ALERT notification)
*/
#define ALERT_SYSTEM_INFORMATIONAL 1 // MB_INFORMATION
#define ALERT_SYSTEM_WARNING 2 // MB_WARNING
#define ALERT_SYSTEM_ERROR 3 // MB_ERROR
#define ALERT_SYSTEM_QUERY 4 // MB_QUESTION
#define ALERT_SYSTEM_CRITICAL 5 // HardSysErrBox
#define CALERT_SYSTEM 6
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef struct tagGUITHREADINFO
{
DWORD cbSize;
DWORD flags;
HWND hwndActive;
HWND hwndFocus;
HWND hwndCapture;
HWND hwndMenuOwner;
HWND hwndMoveSize;
HWND hwndCaret;
RECT rcCaret;
} GUITHREADINFO, *PGUITHREADINFO, FAR * LPGUITHREADINFO;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#define GUI_CARETBLINKING 0x00000001
#define GUI_INMOVESIZE 0x00000002
#define GUI_INMENUMODE 0x00000004
#define GUI_SYSTEMMENUMODE 0x00000008
#define GUI_POPUPMENUMODE 0x00000010
#if(_WIN32_WINNT >= 0x0501)
#if defined(_WIN64)
#define GUI_16BITTASK 0x00000000
#else
#define GUI_16BITTASK 0x00000020
#endif
#endif /* _WIN32_WINNT >= 0x0501 */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
GetGUIThreadInfo(
_In_ DWORD idThread,
_Inout_ PGUITHREADINFO pgui);
WINUSERAPI
BOOL
WINAPI
BlockInput(
BOOL fBlockIt);
#if(_WIN32_WINNT >= 0x0600)
#define USER_DEFAULT_SCREEN_DPI 96
WINUSERAPI
BOOL
WINAPI
SetProcessDPIAware(
VOID);
WINUSERAPI
BOOL
WINAPI
IsProcessDPIAware(
VOID);
#endif /* _WIN32_WINNT >= 0x0600 */
WINUSERAPI
UINT
WINAPI
GetWindowModuleFileNameA(
_In_ HWND hwnd,
_Out_writes_to_(cchFileNameMax, return) LPSTR pszFileName,
_In_ UINT cchFileNameMax);
WINUSERAPI
UINT
WINAPI
GetWindowModuleFileNameW(
_In_ HWND hwnd,
_Out_writes_to_(cchFileNameMax, return) LPWSTR pszFileName,
_In_ UINT cchFileNameMax);
#ifdef UNICODE
#define GetWindowModuleFileName GetWindowModuleFileNameW
#else
#define GetWindowModuleFileName GetWindowModuleFileNameA
#endif // !UNICODE
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#ifndef NO_STATE_FLAGS
#define STATE_SYSTEM_UNAVAILABLE 0x00000001 // Disabled
#define STATE_SYSTEM_SELECTED 0x00000002
#define STATE_SYSTEM_FOCUSED 0x00000004
#define STATE_SYSTEM_PRESSED 0x00000008
#define STATE_SYSTEM_CHECKED 0x00000010
#define STATE_SYSTEM_MIXED 0x00000020 // 3-state checkbox or toolbar button
#define STATE_SYSTEM_INDETERMINATE STATE_SYSTEM_MIXED
#define STATE_SYSTEM_READONLY 0x00000040
#define STATE_SYSTEM_HOTTRACKED 0x00000080
#define STATE_SYSTEM_DEFAULT 0x00000100
#define STATE_SYSTEM_EXPANDED 0x00000200
#define STATE_SYSTEM_COLLAPSED 0x00000400
#define STATE_SYSTEM_BUSY 0x00000800
#define STATE_SYSTEM_FLOATING 0x00001000 // Children "owned" not "contained" by parent
#define STATE_SYSTEM_MARQUEED 0x00002000
#define STATE_SYSTEM_ANIMATED 0x00004000
#define STATE_SYSTEM_INVISIBLE 0x00008000
#define STATE_SYSTEM_OFFSCREEN 0x00010000
#define STATE_SYSTEM_SIZEABLE 0x00020000
#define STATE_SYSTEM_MOVEABLE 0x00040000
#define STATE_SYSTEM_SELFVOICING 0x00080000
#define STATE_SYSTEM_FOCUSABLE 0x00100000
#define STATE_SYSTEM_SELECTABLE 0x00200000
#define STATE_SYSTEM_LINKED 0x00400000
#define STATE_SYSTEM_TRAVERSED 0x00800000
#define STATE_SYSTEM_MULTISELECTABLE 0x01000000 // Supports multiple selection
#define STATE_SYSTEM_EXTSELECTABLE 0x02000000 // Supports extended selection
#define STATE_SYSTEM_ALERT_LOW 0x04000000 // This information is of low priority
#define STATE_SYSTEM_ALERT_MEDIUM 0x08000000 // This information is of medium priority
#define STATE_SYSTEM_ALERT_HIGH 0x10000000 // This information is of high priority
#define STATE_SYSTEM_PROTECTED 0x20000000 // access to this is restricted
#define STATE_SYSTEM_VALID 0x3FFFFFFF
#endif
#define CCHILDREN_TITLEBAR 5
#define CCHILDREN_SCROLLBAR 5
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
/*
* Information about the global cursor.
*/
typedef struct tagCURSORINFO
{
DWORD cbSize;
DWORD flags;
HCURSOR hCursor;
POINT ptScreenPos;
} CURSORINFO, *PCURSORINFO, *LPCURSORINFO;
#define CURSOR_SHOWING 0x00000001
#if(WINVER >= 0x0602)
#define CURSOR_SUPPRESSED 0x00000002
#endif /* WINVER >= 0x0602 */
WINUSERAPI
BOOL
WINAPI
GetCursorInfo(
_Inout_ PCURSORINFO pci);
/*
* Window information snapshot
*/
typedef struct tagWINDOWINFO
{
DWORD cbSize;
RECT rcWindow;
RECT rcClient;
DWORD dwStyle;
DWORD dwExStyle;
DWORD dwWindowStatus;
UINT cxWindowBorders;
UINT cyWindowBorders;
ATOM atomWindowType;
WORD wCreatorVersion;
} WINDOWINFO, *PWINDOWINFO, *LPWINDOWINFO;
#define WS_ACTIVECAPTION 0x0001
WINUSERAPI
BOOL
WINAPI
GetWindowInfo(
_In_ HWND hwnd,
_Inout_ PWINDOWINFO pwi);
/*
* Titlebar information.
*/
typedef struct tagTITLEBARINFO
{
DWORD cbSize;
RECT rcTitleBar;
DWORD rgstate[CCHILDREN_TITLEBAR + 1];
} TITLEBARINFO, *PTITLEBARINFO, *LPTITLEBARINFO;
WINUSERAPI
BOOL
WINAPI
GetTitleBarInfo(
_In_ HWND hwnd,
_Inout_ PTITLEBARINFO pti);
#if(WINVER >= 0x0600)
typedef struct tagTITLEBARINFOEX
{
DWORD cbSize;
RECT rcTitleBar;
DWORD rgstate[CCHILDREN_TITLEBAR + 1];
RECT rgrect[CCHILDREN_TITLEBAR + 1];
} TITLEBARINFOEX, *PTITLEBARINFOEX, *LPTITLEBARINFOEX;
#endif /* WINVER >= 0x0600 */
/*
* Menubar information
*/
typedef struct tagMENUBARINFO
{
DWORD cbSize;
RECT rcBar; // rect of bar, popup, item
HMENU hMenu; // real menu handle of bar, popup
HWND hwndMenu; // hwnd of item submenu if one
BOOL fBarFocused:1; // bar, popup has the focus
BOOL fFocused:1; // item has the focus
} MENUBARINFO, *PMENUBARINFO, *LPMENUBARINFO;
WINUSERAPI
BOOL
WINAPI
GetMenuBarInfo(
_In_ HWND hwnd,
_In_ LONG idObject,
_In_ LONG idItem,
_Inout_ PMENUBARINFO pmbi);
/*
* Scrollbar information
*/
typedef struct tagSCROLLBARINFO
{
DWORD cbSize;
RECT rcScrollBar;
int dxyLineButton;
int xyThumbTop;
int xyThumbBottom;
int reserved;
DWORD rgstate[CCHILDREN_SCROLLBAR + 1];
} SCROLLBARINFO, *PSCROLLBARINFO, *LPSCROLLBARINFO;
WINUSERAPI
BOOL
WINAPI
GetScrollBarInfo(
_In_ HWND hwnd,
_In_ LONG idObject,
_Inout_ PSCROLLBARINFO psbi);
/*
* Combobox information
*/
typedef struct tagCOMBOBOXINFO
{
DWORD cbSize;
RECT rcItem;
RECT rcButton;
DWORD stateButton;
HWND hwndCombo;
HWND hwndItem;
HWND hwndList;
} COMBOBOXINFO, *PCOMBOBOXINFO, *LPCOMBOBOXINFO;
WINUSERAPI
BOOL
WINAPI
GetComboBoxInfo(
_In_ HWND hwndCombo,
_Inout_ PCOMBOBOXINFO pcbi);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* The "real" ancestor window
*/
#define GA_PARENT 1
#define GA_ROOT 2
#define GA_ROOTOWNER 3
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
HWND
WINAPI
GetAncestor(
_In_ HWND hwnd,
_In_ UINT gaFlags);
/*
* This gets the REAL child window at the point. If it is in the dead
* space of a group box, it will try a sibling behind it. But static
* fields will get returned. In other words, it is kind of a cross between
* ChildWindowFromPointEx and WindowFromPoint.
*/
WINUSERAPI
HWND
WINAPI
RealChildWindowFromPoint(
_In_ HWND hwndParent,
_In_ POINT ptParentClientCoords);
/*
* This gets the name of the window TYPE, not class. This allows us to
* recognize ThunderButton32 et al.
*/
WINUSERAPI
UINT
WINAPI
RealGetWindowClassA(
_In_ HWND hwnd,
_Out_writes_to_(cchClassNameMax, return) LPSTR ptszClassName,
_In_ UINT cchClassNameMax);
/*
* This gets the name of the window TYPE, not class. This allows us to
* recognize ThunderButton32 et al.
*/
WINUSERAPI
UINT
WINAPI
RealGetWindowClassW(
_In_ HWND hwnd,
_Out_writes_to_(cchClassNameMax, return) LPWSTR ptszClassName,
_In_ UINT cchClassNameMax);
#ifdef UNICODE
#define RealGetWindowClass RealGetWindowClassW
#else
#define RealGetWindowClass RealGetWindowClassA
#endif // !UNICODE
/*
* Alt-Tab Switch window information.
*/
typedef struct tagALTTABINFO
{
DWORD cbSize;
int cItems;
int cColumns;
int cRows;
int iColFocus;
int iRowFocus;
int cxItem;
int cyItem;
POINT ptStart;
} ALTTABINFO, *PALTTABINFO, *LPALTTABINFO;
WINUSERAPI
BOOL
WINAPI
GetAltTabInfoA(
_In_opt_ HWND hwnd,
_In_ int iItem,
_Inout_ PALTTABINFO pati,
_Out_writes_opt_(cchItemText) LPSTR pszItemText,
_In_ UINT cchItemText);
WINUSERAPI
BOOL
WINAPI
GetAltTabInfoW(
_In_opt_ HWND hwnd,
_In_ int iItem,
_Inout_ PALTTABINFO pati,
_Out_writes_opt_(cchItemText) LPWSTR pszItemText,
_In_ UINT cchItemText);
#ifdef UNICODE
#define GetAltTabInfo GetAltTabInfoW
#else
#define GetAltTabInfo GetAltTabInfoA
#endif // !UNICODE
/*
* Listbox information.
* Returns the number of items per row.
*/
WINUSERAPI
DWORD
WINAPI
GetListBoxInfo(
_In_ HWND hwnd);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* NOWINABLE */
#endif /* WINVER >= 0x0500 */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#if(_WIN32_WINNT >= 0x0500)
WINUSERAPI
BOOL
WINAPI
LockWorkStation(
VOID);
#endif /* _WIN32_WINNT >= 0x0500 */
#if(_WIN32_WINNT >= 0x0500)
WINUSERAPI
BOOL
WINAPI
UserHandleGrantAccess(
_In_ HANDLE hUserHandle,
_In_ HANDLE hJob,
_In_ BOOL bGrant);
#endif /* _WIN32_WINNT >= 0x0500 */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#if(_WIN32_WINNT >= 0x0501)
/*
* Raw Input Messages.
*/
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
DECLARE_HANDLE(HRAWINPUT);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* WM_INPUT wParam
*/
/*
* Use this macro to get the input code from wParam.
*/
#define GET_RAWINPUT_CODE_WPARAM(wParam) ((wParam) & 0xff)
/*
* The input is in the regular message flow,
* the app is required to call DefWindowProc
* so that the system can perform clean ups.
*/
#define RIM_INPUT 0
/*
* The input is sink only. The app is expected
* to behave nicely.
*/
#define RIM_INPUTSINK 1
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
/*
* Raw Input data header
*/
typedef struct tagRAWINPUTHEADER {
DWORD dwType;
DWORD dwSize;
HANDLE hDevice;
WPARAM wParam;
} RAWINPUTHEADER, *PRAWINPUTHEADER, *LPRAWINPUTHEADER;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* Type of the raw input
*/
#define RIM_TYPEMOUSE 0
#define RIM_TYPEKEYBOARD 1
#define RIM_TYPEHID 2
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
/*
* Raw format of the mouse input
*/
typedef struct tagRAWMOUSE {
/*
* Indicator flags.
*/
USHORT usFlags;
/*
* The transition state of the mouse buttons.
*/
union {
ULONG ulButtons;
struct {
USHORT usButtonFlags;
USHORT usButtonData;
};
};
/*
* The raw state of the mouse buttons.
*/
ULONG ulRawButtons;
/*
* The signed relative or absolute motion in the X direction.
*/
LONG lLastX;
/*
* The signed relative or absolute motion in the Y direction.
*/
LONG lLastY;
/*
* Device-specific additional information for the event.
*/
ULONG ulExtraInformation;
} RAWMOUSE, *PRAWMOUSE, *LPRAWMOUSE;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* Define the mouse button state indicators.
*/
#define RI_MOUSE_LEFT_BUTTON_DOWN 0x0001 // Left Button changed to down.
#define RI_MOUSE_LEFT_BUTTON_UP 0x0002 // Left Button changed to up.
#define RI_MOUSE_RIGHT_BUTTON_DOWN 0x0004 // Right Button changed to down.
#define RI_MOUSE_RIGHT_BUTTON_UP 0x0008 // Right Button changed to up.
#define RI_MOUSE_MIDDLE_BUTTON_DOWN 0x0010 // Middle Button changed to down.
#define RI_MOUSE_MIDDLE_BUTTON_UP 0x0020 // Middle Button changed to up.
#define RI_MOUSE_BUTTON_1_DOWN RI_MOUSE_LEFT_BUTTON_DOWN
#define RI_MOUSE_BUTTON_1_UP RI_MOUSE_LEFT_BUTTON_UP
#define RI_MOUSE_BUTTON_2_DOWN RI_MOUSE_RIGHT_BUTTON_DOWN
#define RI_MOUSE_BUTTON_2_UP RI_MOUSE_RIGHT_BUTTON_UP
#define RI_MOUSE_BUTTON_3_DOWN RI_MOUSE_MIDDLE_BUTTON_DOWN
#define RI_MOUSE_BUTTON_3_UP RI_MOUSE_MIDDLE_BUTTON_UP
#define RI_MOUSE_BUTTON_4_DOWN 0x0040
#define RI_MOUSE_BUTTON_4_UP 0x0080
#define RI_MOUSE_BUTTON_5_DOWN 0x0100
#define RI_MOUSE_BUTTON_5_UP 0x0200
/*
* If usButtonFlags has RI_MOUSE_WHEEL, the wheel delta is stored in usButtonData.
* Take it as a signed value.
*/
#define RI_MOUSE_WHEEL 0x0400
/*
* Define the mouse indicator flags.
*/
#define MOUSE_MOVE_RELATIVE 0
#define MOUSE_MOVE_ABSOLUTE 1
#define MOUSE_VIRTUAL_DESKTOP 0x02 // the coordinates are mapped to the virtual desktop
#define MOUSE_ATTRIBUTES_CHANGED 0x04 // requery for mouse attributes
#if(WINVER >= 0x0600)
#define MOUSE_MOVE_NOCOALESCE 0x08 // do not coalesce mouse moves
#endif /* WINVER >= 0x0600 */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
/*
* Raw format of the keyboard input
*/
typedef struct tagRAWKEYBOARD {
/*
* The "make" scan code (key depression).
*/
USHORT MakeCode;
/*
* The flags field indicates a "break" (key release) and other
* miscellaneous scan code information defined in ntddkbd.h.
*/
USHORT Flags;
USHORT Reserved;
/*
* Windows message compatible information
*/
USHORT VKey;
UINT Message;
/*
* Device-specific additional information for the event.
*/
ULONG ExtraInformation;
} RAWKEYBOARD, *PRAWKEYBOARD, *LPRAWKEYBOARD;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* Define the keyboard overrun MakeCode.
*/
#define KEYBOARD_OVERRUN_MAKE_CODE 0xFF
/*
* Define the keyboard input data Flags.
*/
#define RI_KEY_MAKE 0
#define RI_KEY_BREAK 1
#define RI_KEY_E0 2
#define RI_KEY_E1 4
#define RI_KEY_TERMSRV_SET_LED 8
#define RI_KEY_TERMSRV_SHADOW 0x10
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
/*
* Raw format of the input from Human Input Devices
*/
typedef struct tagRAWHID {
DWORD dwSizeHid; // byte size of each report
DWORD dwCount; // number of input packed
BYTE bRawData[1];
} RAWHID, *PRAWHID, *LPRAWHID;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* RAWINPUT data structure.
*/
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef struct tagRAWINPUT {
RAWINPUTHEADER header;
union {
RAWMOUSE mouse;
RAWKEYBOARD keyboard;
RAWHID hid;
} data;
} RAWINPUT, *PRAWINPUT, *LPRAWINPUT;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#ifdef _WIN64
#define RAWINPUT_ALIGN(x) (((x) + sizeof(QWORD) - 1) & ~(sizeof(QWORD) - 1))
#else // _WIN64
#define RAWINPUT_ALIGN(x) (((x) + sizeof(DWORD) - 1) & ~(sizeof(DWORD) - 1))
#endif // _WIN64
#define NEXTRAWINPUTBLOCK(ptr) ((PRAWINPUT)RAWINPUT_ALIGN((ULONG_PTR)((PBYTE)(ptr) + (ptr)->header.dwSize)))
/*
* Flags for GetRawInputData
*/
#define RID_INPUT 0x10000003
#define RID_HEADER 0x10000005
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
UINT
WINAPI
GetRawInputData(
_In_ HRAWINPUT hRawInput,
_In_ UINT uiCommand,
_Out_writes_bytes_to_opt_(*pcbSize, return) LPVOID pData,
_Inout_ PUINT pcbSize,
_In_ UINT cbSizeHeader);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* Raw Input Device Information
*/
#define RIDI_PREPARSEDDATA 0x20000005
#define RIDI_DEVICENAME 0x20000007 // the return valus is the character length, not the byte size
#define RIDI_DEVICEINFO 0x2000000b
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef struct tagRID_DEVICE_INFO_MOUSE {
DWORD dwId;
DWORD dwNumberOfButtons;
DWORD dwSampleRate;
BOOL fHasHorizontalWheel;
} RID_DEVICE_INFO_MOUSE, *PRID_DEVICE_INFO_MOUSE;
typedef struct tagRID_DEVICE_INFO_KEYBOARD {
DWORD dwType;
DWORD dwSubType;
DWORD dwKeyboardMode;
DWORD dwNumberOfFunctionKeys;
DWORD dwNumberOfIndicators;
DWORD dwNumberOfKeysTotal;
} RID_DEVICE_INFO_KEYBOARD, *PRID_DEVICE_INFO_KEYBOARD;
typedef struct tagRID_DEVICE_INFO_HID {
DWORD dwVendorId;
DWORD dwProductId;
DWORD dwVersionNumber;
/*
* Top level collection UsagePage and Usage
*/
USHORT usUsagePage;
USHORT usUsage;
} RID_DEVICE_INFO_HID, *PRID_DEVICE_INFO_HID;
typedef struct tagRID_DEVICE_INFO {
DWORD cbSize;
DWORD dwType;
union {
RID_DEVICE_INFO_MOUSE mouse;
RID_DEVICE_INFO_KEYBOARD keyboard;
RID_DEVICE_INFO_HID hid;
};
} RID_DEVICE_INFO, *PRID_DEVICE_INFO, *LPRID_DEVICE_INFO;
WINUSERAPI
UINT
WINAPI
GetRawInputDeviceInfoA(
_In_opt_ HANDLE hDevice,
_In_ UINT uiCommand,
_Inout_updates_bytes_to_opt_(*pcbSize, *pcbSize) LPVOID pData,
_Inout_ PUINT pcbSize);
WINUSERAPI
UINT
WINAPI
GetRawInputDeviceInfoW(
_In_opt_ HANDLE hDevice,
_In_ UINT uiCommand,
_Inout_updates_bytes_to_opt_(*pcbSize, *pcbSize) LPVOID pData,
_Inout_ PUINT pcbSize);
#ifdef UNICODE
#define GetRawInputDeviceInfo GetRawInputDeviceInfoW
#else
#define GetRawInputDeviceInfo GetRawInputDeviceInfoA
#endif // !UNICODE
/*
* Raw Input Bulk Read: GetRawInputBuffer
*/
WINUSERAPI
UINT
WINAPI
GetRawInputBuffer(
_Out_writes_bytes_opt_(*pcbSize) PRAWINPUT pData,
_Inout_ PUINT pcbSize,
_In_ UINT cbSizeHeader);
/*
* Raw Input request APIs
*/
typedef struct tagRAWINPUTDEVICE {
USHORT usUsagePage; // Toplevel collection UsagePage
USHORT usUsage; // Toplevel collection Usage
DWORD dwFlags;
HWND hwndTarget; // Target hwnd. NULL = follows keyboard focus
} RAWINPUTDEVICE, *PRAWINPUTDEVICE, *LPRAWINPUTDEVICE;
typedef CONST RAWINPUTDEVICE* PCRAWINPUTDEVICE;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#define RIDEV_REMOVE 0x00000001
#define RIDEV_EXCLUDE 0x00000010
#define RIDEV_PAGEONLY 0x00000020
#define RIDEV_NOLEGACY 0x00000030
#define RIDEV_INPUTSINK 0x00000100
#define RIDEV_CAPTUREMOUSE 0x00000200 // effective when mouse nolegacy is specified, otherwise it would be an error
#define RIDEV_NOHOTKEYS 0x00000200 // effective for keyboard.
#define RIDEV_APPKEYS 0x00000400 // effective for keyboard.
#if(_WIN32_WINNT >= 0x0501)
#define RIDEV_EXINPUTSINK 0x00001000
#define RIDEV_DEVNOTIFY 0x00002000
#endif /* _WIN32_WINNT >= 0x0501 */
#define RIDEV_EXMODEMASK 0x000000F0
#define RIDEV_EXMODE(mode) ((mode) & RIDEV_EXMODEMASK)
#if(_WIN32_WINNT >= 0x0501)
/*
* Flags for the WM_INPUT_DEVICE_CHANGE message.
*/
#define GIDC_ARRIVAL 1
#define GIDC_REMOVAL 2
#endif /* _WIN32_WINNT >= 0x0501 */
#if (_WIN32_WINNT >= 0x0601)
#define GET_DEVICE_CHANGE_WPARAM(wParam) (LOWORD(wParam))
#elif (_WIN32_WINNT >= 0x0501)
#define GET_DEVICE_CHANGE_LPARAM(lParam) (LOWORD(lParam))
#endif /* (_WIN32_WINNT >= 0x0601) */
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
RegisterRawInputDevices(
_In_reads_(uiNumDevices) PCRAWINPUTDEVICE pRawInputDevices,
_In_ UINT uiNumDevices,
_In_ UINT cbSize);
WINUSERAPI
UINT
WINAPI
GetRegisteredRawInputDevices(
_Out_writes_opt_( *puiNumDevices) PRAWINPUTDEVICE pRawInputDevices,
_Inout_ PUINT puiNumDevices,
_In_ UINT cbSize);
typedef struct tagRAWINPUTDEVICELIST {
HANDLE hDevice;
DWORD dwType;
} RAWINPUTDEVICELIST, *PRAWINPUTDEVICELIST;
WINUSERAPI
UINT
WINAPI
GetRawInputDeviceList(
_Out_writes_opt_(*puiNumDevices) PRAWINPUTDEVICELIST pRawInputDeviceList,
_Inout_ PUINT puiNumDevices,
_In_ UINT cbSize);
WINUSERAPI
LRESULT
WINAPI
DefRawInputProc(
_In_reads_(nInput) PRAWINPUT* paRawInput,
_In_ INT nInput,
_In_ UINT cbSizeHeader);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* _WIN32_WINNT >= 0x0501 */
#if(WINVER >= 0x0602)
#define POINTER_DEVICE_PRODUCT_STRING_MAX 520
/*
* wParam values for WM_POINTERDEVICECHANGE
*/
#define PDC_ARRIVAL 0x001
#define PDC_REMOVAL 0x002
#define PDC_ORIENTATION_0 0x004
#define PDC_ORIENTATION_90 0x008
#define PDC_ORIENTATION_180 0x010
#define PDC_ORIENTATION_270 0x020
#define PDC_MODE_DEFAULT 0x040
#define PDC_MODE_CENTERED 0x080
#define PDC_MAPPING_CHANGE 0x100
#define PDC_RESOLUTION 0x200
#define PDC_ORIGIN 0x400
#define PDC_MODE_ASPECTRATIOPRESERVED 0x800
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef enum tagPOINTER_DEVICE_TYPE {
POINTER_DEVICE_TYPE_INTEGRATED_PEN = 0x00000001,
POINTER_DEVICE_TYPE_EXTERNAL_PEN = 0x00000002,
POINTER_DEVICE_TYPE_TOUCH = 0x00000003,
#if(WINVER >= 0x0603)
POINTER_DEVICE_TYPE_TOUCH_PAD = 0x00000004,
#endif /* WINVER >= 0x0603 */
POINTER_DEVICE_TYPE_MAX = 0xFFFFFFFF
} POINTER_DEVICE_TYPE;
typedef struct tagPOINTER_DEVICE_INFO {
DWORD displayOrientation;
HANDLE device;
POINTER_DEVICE_TYPE pointerDeviceType;
HMONITOR monitor;
ULONG startingCursorId;
USHORT maxActiveContacts;
WCHAR productString[POINTER_DEVICE_PRODUCT_STRING_MAX];
} POINTER_DEVICE_INFO;
typedef struct tagPOINTER_DEVICE_PROPERTY {
INT32 logicalMin;
INT32 logicalMax;
INT32 physicalMin;
INT32 physicalMax;
UINT32 unit;
UINT32 unitExponent;
USHORT usagePageId;
USHORT usageId;
} POINTER_DEVICE_PROPERTY;
typedef enum tagPOINTER_DEVICE_CURSOR_TYPE {
POINTER_DEVICE_CURSOR_TYPE_UNKNOWN = 0x00000000,
POINTER_DEVICE_CURSOR_TYPE_TIP = 0x00000001,
POINTER_DEVICE_CURSOR_TYPE_ERASER = 0x00000002,
POINTER_DEVICE_CURSOR_TYPE_MAX = 0xFFFFFFFF
} POINTER_DEVICE_CURSOR_TYPE;
typedef struct tagPOINTER_DEVICE_CURSOR_INFO {
UINT32 cursorId;
POINTER_DEVICE_CURSOR_TYPE cursor;
} POINTER_DEVICE_CURSOR_INFO;
WINUSERAPI
BOOL
WINAPI
GetPointerDevices(
_Inout_ UINT32* deviceCount,
_Out_writes_opt_(*deviceCount) POINTER_DEVICE_INFO *pointerDevices);
WINUSERAPI
BOOL
WINAPI
GetPointerDevice(
_In_ HANDLE device,
_Out_writes_(1) POINTER_DEVICE_INFO *pointerDevice);
WINUSERAPI
BOOL
WINAPI
GetPointerDeviceProperties(
_In_ HANDLE device,
_Inout_ UINT32* propertyCount,
_Out_writes_opt_(*propertyCount) POINTER_DEVICE_PROPERTY *pointerProperties);
WINUSERAPI
BOOL
WINAPI
RegisterPointerDeviceNotifications(
_In_ HWND window,
_In_ BOOL notifyRange);
WINUSERAPI
BOOL
WINAPI
GetPointerDeviceRects(
_In_ HANDLE device,
_Out_writes_(1) RECT* pointerDeviceRect,
_Out_writes_(1) RECT* displayRect);
WINUSERAPI
BOOL
WINAPI
GetPointerDeviceCursors(
_In_ HANDLE device,
_Inout_ UINT32* cursorCount,
_Out_writes_opt_(*cursorCount) POINTER_DEVICE_CURSOR_INFO *deviceCursors);
WINUSERAPI
BOOL
WINAPI
GetRawPointerDeviceData(
_In_ UINT32 pointerId,
_In_ UINT32 historyCount,
_In_ UINT32 propertiesCount,
_In_reads_(propertiesCount) POINTER_DEVICE_PROPERTY* pProperties,
_Out_writes_(historyCount * propertiesCount) LONG* pValues);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* WINVER >= 0x0602 */
#if(WINVER >= 0x0600)
/*
* Message Filter
*/
#define MSGFLT_ADD 1
#define MSGFLT_REMOVE 2
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
ChangeWindowMessageFilter(
_In_ UINT message,
_In_ DWORD dwFlag);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* WINVER >= 0x0600 */
#if(WINVER >= 0x0601)
/*
* Message filter info values (CHANGEFILTERSTRUCT.ExtStatus)
*/
#define MSGFLTINFO_NONE (0)
#define MSGFLTINFO_ALREADYALLOWED_FORWND (1)
#define MSGFLTINFO_ALREADYDISALLOWED_FORWND (2)
#define MSGFLTINFO_ALLOWED_HIGHER (3)
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
typedef struct tagCHANGEFILTERSTRUCT {
DWORD cbSize;
DWORD ExtStatus;
} CHANGEFILTERSTRUCT, *PCHANGEFILTERSTRUCT;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* Message filter action values (action parameter to ChangeWindowMessageFilterEx)
*/
#define MSGFLT_RESET (0)
#define MSGFLT_ALLOW (1)
#define MSGFLT_DISALLOW (2)
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
ChangeWindowMessageFilterEx(
_In_ HWND hwnd, // Window
_In_ UINT message, // WM_ message
_In_ DWORD action, // Message filter action value
_Inout_opt_ PCHANGEFILTERSTRUCT pChangeFilterStruct); // Optional
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* WINVER >= 0x0601 */
#if(WINVER >= 0x0601)
#endif /* WINVER >= 0x0601 */
#if(WINVER >= 0x0601)
/*
* Gesture defines and functions
*/
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
/*
* Gesture information handle
*/
DECLARE_HANDLE(HGESTUREINFO);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* Gesture flags - GESTUREINFO.dwFlags
*/
#define GF_BEGIN 0x00000001
#define GF_INERTIA 0x00000002
#define GF_END 0x00000004
/*
* Gesture IDs
*/
#define GID_BEGIN 1
#define GID_END 2
#define GID_ZOOM 3
#define GID_PAN 4
#define GID_ROTATE 5
#define GID_TWOFINGERTAP 6
#define GID_PRESSANDTAP 7
#define GID_ROLLOVER GID_PRESSANDTAP
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
/*
* Gesture information structure
* - Pass the HGESTUREINFO received in the WM_GESTURE message lParam into the
* GetGestureInfo function to retrieve this information.
* - If cbExtraArgs is non-zero, pass the HGESTUREINFO received in the WM_GESTURE
* message lParam into the GetGestureExtraArgs function to retrieve extended
* argument information.
*/
typedef struct tagGESTUREINFO {
UINT cbSize; // size, in bytes, of this structure (including variable length Args field)
DWORD dwFlags; // see GF_* flags
DWORD dwID; // gesture ID, see GID_* defines
HWND hwndTarget; // handle to window targeted by this gesture
POINTS ptsLocation; // current location of this gesture
DWORD dwInstanceID; // internally used
DWORD dwSequenceID; // internally used
ULONGLONG ullArguments; // arguments for gestures whose arguments fit in 8 BYTES
UINT cbExtraArgs; // size, in bytes, of extra arguments, if any, that accompany this gesture
} GESTUREINFO, *PGESTUREINFO;
typedef GESTUREINFO const * PCGESTUREINFO;
/*
* Gesture notification structure
* - The WM_GESTURENOTIFY message lParam contains a pointer to this structure.
* - The WM_GESTURENOTIFY message notifies a window that gesture recognition is
* in progress and a gesture will be generated if one is recognized under the
* current gesture settings.
*/
typedef struct tagGESTURENOTIFYSTRUCT {
UINT cbSize; // size, in bytes, of this structure
DWORD dwFlags; // unused
HWND hwndTarget; // handle to window targeted by the gesture
POINTS ptsLocation; // starting location
DWORD dwInstanceID; // internally used
} GESTURENOTIFYSTRUCT, *PGESTURENOTIFYSTRUCT;
/*
* Gesture argument helpers
* - Angle should be a double in the range of -2pi to +2pi
* - Argument should be an unsigned 16-bit value
*/
#define GID_ROTATE_ANGLE_TO_ARGUMENT(_arg_) ((USHORT)((((_arg_) + 2.0 * 3.14159265) / (4.0 * 3.14159265)) * 65535.0))
#define GID_ROTATE_ANGLE_FROM_ARGUMENT(_arg_) ((((double)(_arg_) / 65535.0) * 4.0 * 3.14159265) - 2.0 * 3.14159265)
/*
* Gesture information retrieval
* - HGESTUREINFO is received by a window in the lParam of a WM_GESTURE message.
*/
WINUSERAPI
BOOL
WINAPI
GetGestureInfo(
_In_ HGESTUREINFO hGestureInfo,
_Out_ PGESTUREINFO pGestureInfo);
/*
* Gesture extra arguments retrieval
* - HGESTUREINFO is received by a window in the lParam of a WM_GESTURE message.
* - Size, in bytes, of the extra argument data is available in the cbExtraArgs
* field of the GESTUREINFO structure retrieved using the GetGestureInfo function.
*/
WINUSERAPI
BOOL
WINAPI
GetGestureExtraArgs(
_In_ HGESTUREINFO hGestureInfo,
_In_ UINT cbExtraArgs,
_Out_writes_bytes_(cbExtraArgs) PBYTE pExtraArgs);
/*
* Gesture information handle management
* - If an application processes the WM_GESTURE message, then once it is done
* with the associated HGESTUREINFO, the application is responsible for
* closing the handle using this function. Failure to do so may result in
* process memory leaks.
* - If the message is instead passed to DefWindowProc, or is forwarded using
* one of the PostMessage or SendMessage class of API functions, the handle
* is transfered with the message and need not be closed by the application.
*/
WINUSERAPI
BOOL
WINAPI
CloseGestureInfoHandle(
_In_ HGESTUREINFO hGestureInfo);
/*
* Gesture configuration structure
* - Used in SetGestureConfig and GetGestureConfig
* - Note that any setting not included in either GESTURECONFIG.dwWant or
* GESTURECONFIG.dwBlock will use the parent window's preferences or
* system defaults.
*/
typedef struct tagGESTURECONFIG {
DWORD dwID; // gesture ID
DWORD dwWant; // settings related to gesture ID that are to be turned on
DWORD dwBlock; // settings related to gesture ID that are to be turned off
} GESTURECONFIG, *PGESTURECONFIG;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
/*
* Gesture configuration flags - GESTURECONFIG.dwWant or GESTURECONFIG.dwBlock
*/
/*
* Common gesture configuration flags - set GESTURECONFIG.dwID to zero
*/
#define GC_ALLGESTURES 0x00000001
/*
* Zoom gesture configuration flags - set GESTURECONFIG.dwID to GID_ZOOM
*/
#define GC_ZOOM 0x00000001
/*
* Pan gesture configuration flags - set GESTURECONFIG.dwID to GID_PAN
*/
#define GC_PAN 0x00000001
#define GC_PAN_WITH_SINGLE_FINGER_VERTICALLY 0x00000002
#define GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY 0x00000004
#define GC_PAN_WITH_GUTTER 0x00000008
#define GC_PAN_WITH_INERTIA 0x00000010
/*
* Rotate gesture configuration flags - set GESTURECONFIG.dwID to GID_ROTATE
*/
#define GC_ROTATE 0x00000001
/*
* Two finger tap gesture configuration flags - set GESTURECONFIG.dwID to GID_TWOFINGERTAP
*/
#define GC_TWOFINGERTAP 0x00000001
/*
* PressAndTap gesture configuration flags - set GESTURECONFIG.dwID to GID_PRESSANDTAP
*/
#define GC_PRESSANDTAP 0x00000001
#define GC_ROLLOVER GC_PRESSANDTAP
#define GESTURECONFIGMAXCOUNT 256 // Maximum number of gestures that can be included
// in a single call to SetGestureConfig / GetGestureConfig
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
SetGestureConfig(
_In_ HWND hwnd, // window for which configuration is specified
_In_ DWORD dwReserved, // reserved, must be 0
_In_ UINT cIDs, // count of GESTURECONFIG structures
_In_reads_(cIDs) PGESTURECONFIG pGestureConfig, // array of GESTURECONFIG structures, dwIDs will be processed in the
// order specified and repeated occurances will overwrite previous ones
_In_ UINT cbSize); // sizeof(GESTURECONFIG)
#define GCF_INCLUDE_ANCESTORS 0x00000001 // If specified, GetGestureConfig returns consolidated configuration
// for the specified window and it's parent window chain
WINUSERAPI
BOOL
WINAPI
GetGestureConfig(
_In_ HWND hwnd, // window for which configuration is required
_In_ DWORD dwReserved, // reserved, must be 0
_In_ DWORD dwFlags, // see GCF_* flags
_In_ PUINT pcIDs, // *pcIDs contains the size, in number of GESTURECONFIG structures,
// of the buffer pointed to by pGestureConfig
_Inout_updates_(*pcIDs) PGESTURECONFIG pGestureConfig,
// pointer to buffer to receive the returned array of GESTURECONFIG structures
_In_ UINT cbSize); // sizeof(GESTURECONFIG)
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* WINVER >= 0x0601 */
#if(WINVER >= 0x0601)
/*
* GetSystemMetrics(SM_DIGITIZER) flag values
*/
#define NID_INTEGRATED_TOUCH 0x00000001
#define NID_EXTERNAL_TOUCH 0x00000002
#define NID_INTEGRATED_PEN 0x00000004
#define NID_EXTERNAL_PEN 0x00000008
#define NID_MULTI_INPUT 0x00000040
#define NID_READY 0x00000080
#endif /* WINVER >= 0x0601 */
#define MAX_STR_BLOCKREASON 256
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
ShutdownBlockReasonCreate(
_In_ HWND hWnd,
_In_ LPCWSTR pwszReason);
WINUSERAPI
BOOL
WINAPI
ShutdownBlockReasonQuery(
_In_ HWND hWnd,
_Out_writes_opt_(*pcchBuff) LPWSTR pwszBuff,
_Inout_ DWORD *pcchBuff);
WINUSERAPI
BOOL
WINAPI
ShutdownBlockReasonDestroy(
_In_ HWND hWnd);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#if(WINVER >= 0x0601)
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
/*
* Identifiers for message input source device type.
*/
typedef enum tagINPUT_MESSAGE_DEVICE_TYPE {
IMDT_UNAVAILABLE = 0x00000000, // not specified
IMDT_KEYBOARD = 0x00000001, // from keyboard
IMDT_MOUSE = 0x00000002, // from mouse
IMDT_TOUCH = 0x00000004, // from touch
IMDT_PEN = 0x00000008, // from pen
#if(WINVER >= 0x0603)
IMDT_TOUCHPAD = 0x00000010, // from touchpad
#endif /* WINVER >= 0x0603 */
} INPUT_MESSAGE_DEVICE_TYPE;
typedef enum tagINPUT_MESSAGE_ORIGIN_ID {
IMO_UNAVAILABLE = 0x00000000, // not specified
IMO_HARDWARE = 0x00000001, // from a hardware device or injected by a UIAccess app
IMO_INJECTED = 0x00000002, // injected via SendInput() by a non-UIAccess app
IMO_SYSTEM = 0x00000004, // injected by the system
} INPUT_MESSAGE_ORIGIN_ID;
/*
* Input source structure.
*/
typedef struct tagINPUT_MESSAGE_SOURCE {
INPUT_MESSAGE_DEVICE_TYPE deviceType;
INPUT_MESSAGE_ORIGIN_ID originId;
} INPUT_MESSAGE_SOURCE;
/*
* API to determine the input source of the current messsage.
*/
WINUSERAPI
BOOL
WINAPI
GetCurrentInputMessageSource(
_Out_ INPUT_MESSAGE_SOURCE *inputMessageSource);
WINUSERAPI
BOOL
WINAPI
GetCIMSSM(
_Out_ INPUT_MESSAGE_SOURCE *inputMessageSource);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* WINVER >= 0x0601 */
#if(WINVER >= 0x0601)
#pragma region Application Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
/*
* AutoRotation state structure
*/
typedef enum tagAR_STATE {
AR_ENABLED = 0x0,
AR_DISABLED = 0x1,
AR_SUPPRESSED = 0x2,
AR_REMOTESESSION = 0x4,
AR_MULTIMON = 0x8,
AR_NOSENSOR = 0x10,
AR_NOT_SUPPORTED = 0x20,
AR_DOCKED = 0x40,
AR_LAPTOP = 0x80
} AR_STATE, *PAR_STATE;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) */
#pragma endregion
#ifndef MIDL_PASS
// Dont define this for MIDL compiler passes over winuser.h. Some of them
// dont include winnt.h (where DEFINE_ENUM_FLAG_OPERATORS is defined and
// get compile errors.
DEFINE_ENUM_FLAG_OPERATORS(AR_STATE);
#endif
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
/*
* Orientation preference structure. This is used by applications to specify
* their orientation preferences to windows.
*/
typedef enum ORIENTATION_PREFERENCE {
ORIENTATION_PREFERENCE_NONE = 0x0,
ORIENTATION_PREFERENCE_LANDSCAPE = 0x1,
ORIENTATION_PREFERENCE_PORTRAIT = 0x2,
ORIENTATION_PREFERENCE_LANDSCAPE_FLIPPED = 0x4,
ORIENTATION_PREFERENCE_PORTRAIT_FLIPPED = 0x8
} ORIENTATION_PREFERENCE;
#ifndef MIDL_PASS
// Dont define this for MIDL compiler passes over winuser.h. Some of them
// dont include winnt.h (where DEFINE_ENUM_FLAG_OPERATORS is defined and
// get compile errors.
DEFINE_ENUM_FLAG_OPERATORS(ORIENTATION_PREFERENCE);
#endif
WINUSERAPI
BOOL
WINAPI
GetAutoRotationState(
_Out_ PAR_STATE pState);
WINUSERAPI
BOOL
WINAPI
GetDisplayAutoRotationPreferences(
_Out_ ORIENTATION_PREFERENCE *pOrientation);
WINUSERAPI
BOOL
WINAPI
GetDisplayAutoRotationPreferencesByProcessId(
_In_ DWORD dwProcessId,
_Out_ ORIENTATION_PREFERENCE *pOrientation,
_Out_ BOOL *fRotateScreen);
WINUSERAPI
BOOL
WINAPI
SetDisplayAutoRotationPreferences(
_In_ ORIENTATION_PREFERENCE orientation);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* WINVER >= 0x0601 */
#if(WINVER >= 0x0601)
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
WINUSERAPI
BOOL
WINAPI
IsImmersiveProcess(
_In_ HANDLE hProcess);
WINUSERAPI
BOOL
WINAPI
SetProcessRestrictionExemption(
_In_ BOOL fEnableExemption);
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif /* WINVER >= 0x0601 */
#if !defined(RC_INVOKED) /* RC complains about long symbols in #ifs */
#if defined(ISOLATION_AWARE_ENABLED) && (ISOLATION_AWARE_ENABLED != 0)
#include "winuser.inl"
#endif /* ISOLATION_AWARE_ENABLED */
#endif /* RC */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* !_WINUSER_ */
↧
window消息定义代码
↧
键盘鼠标模拟全知道
本文目录如下
一、基于windows 消息机制的鼠标键盘模拟
(一)、应用程序级模拟
(二)、系统级模拟
1、 用API函数keybd_event 模拟键盘事件
2、 SendInput函数模拟全局键盘鼠标事件
3、用全局钩子模拟键盘消息
二、驱动级模拟
*******************************************************************************************
一、基于windows 消息机制的鼠标键盘模拟
我们怎样才能用Delphi来写一个程序,用来代替人们按键的方法呢?那就让我们来先了解一下windows中响应键盘事件的机制。
当用户按下键盘上的一个键时,键盘内的芯片会检测到这个动作,并把这个信号传送到计算机。如何区别是哪一个键被按下了呢?键盘上的所有按键都有一个编码,称作键盘扫描码。当你按下一个键时,这个键的扫描码就被传给系统。扫描码是跟具体的硬件相关的,同一个键,在不同键盘上的扫描码有可能不同。键盘控制器就是将这个扫描码传给计算机,然后交给键盘驱动程序。键盘驱动程序会完成相关的工作,并把这个扫描码转换为键盘虚拟码。什么是虚拟码呢?因为扫描码与硬件相关,不具有通用性,为了统一键盘上所有键的编码,于是就提出了虚拟码概念。无论什么键盘,同一个按键的虚拟码总是相同的,这样程序就可以识别了。简单点说,虚拟码就是我们经常可以看到的像VK_A,VK_B这样的常数,比如键A的虚拟码是65,写成16进制就是&H41,注意,人们经常用16进制来表示虚拟码。当键盘驱动程序把扫描码转换为虚拟码后,会把这个键盘操作的扫描码和虚拟码还有其它信息一起传递给操作系统。然后操作系统则会把这些信息封装在一个消息中,并把这个键盘消息插入到消息列队。最后,要是不出意外的话,这个键盘消息最终会被送到当前的活动窗口那里,活动窗口所在的应用程序接收到这个消息后,就知道键盘上哪个键被按下,也就可以决定该作出什么响应给用户了。
这个过程可以简单的如下表示:
用户按下键盘上的一个键 >>>>> 键盘控制器就把这个键的扫描码传给计算机,然后交给键盘驱动程序 >>>>> 键盘驱动程序会把这个扫描码转换为键盘虚拟码(VK_A,VK_B这样的常数,比如键A的虚拟码是65,写成16进制就是&H41)传给操作系统 >>>>> 操操作系统则会把这些信息封装在一个消息中,并把这个键盘消息插入到消息列队 >>>>> 键盘消息被发送到当前活动窗口
明白了这个过程,我们就可以编程实现在其中的某个环节来模拟键盘操作了。在Delphi中,有多种方法可以实现键盘模拟,我们就介绍几种比较典型的。
(一)、应用程序级模拟(只针对某个程序,我称之为局部模拟)
windows提供了几个这样的API函数可以实现直接向目标程序发送消息的功能,常用的有SendMessage和PostMessage,它们的区别是PostMessage函数直接把消息仍给目标程序就不管了,而SendMessage把消息发出去后,还要等待目标程序返回些什么东西才好。这里要注意的是,模拟键盘消息一定要用PostMessage函数才好,用SendMessage是不正确的(因为模拟键盘消息是不需要返回值的,不然目标程序会没反应),切记切记!
PostMessage函数的delphi声明如下:
PostMessage(
hWnd: HWND; {目标程序上某个控件的句柄}
Msg: UINT; {消息的类型}
wParam: WPARAM; {32位指定附加的消息特定的信息}
lParam: LPARAM {32位指定附加的消息特定的信息}
): BOOL;
参数hwnd 是你要发送消息的目标程序上某个控件的句柄,参数Msg 是消息的类型,表示你要发送什么样的消息,最后wParam 和lParam这两个参数是随消息附加的数据,具体内容要由消息决定。
再来看看Msg 这个参数,要模拟按键就靠这个了。
键盘消息常用的有如下几个:
WM_KEYDOWN 表示一个普通键被按下
WM_KEYUP 表示一个普通键被释放
WM_SYSKEYDOWN 表示一个系统键被按下,比如Alt键
WM_SYSKEYUP 表示一个系统键被释放,比如Alt键
如果你确定要发送以上几个键盘消息,那么再来看看如何确定键盘消息中的wParam 和lParam 这两个参数。在一个键盘消息中,wParam 参数的含义较简单,它表示你要发送的键盘事件的按键虚拟码,比如你要对目标程序模拟按下A键,那么wParam 参数的值就设为VK_A ,至于lParam 这个参数就比较复杂了,因为它包含了多个信息,一般可以把它设为0。即
PostMessage (MyHwnd, WM_KEYDOWN, key, 0);
但是如果你想要你的模拟更真实一些,那么建议你还是设置一下这个参数。那么我们就详细了解一下lParam 吧。
lParam 是一个32 bit的参数,它在内存中占4个字节,写成二进制就是
00000000 00000000 00000000 00000000
一共是32位,我们从右向左数,假设最右边那位为第0位(注意是从0而不是从1开始计数),最左边的就是第31位。那么该参数的
0-15位表示键的发送次数等扩展信息,
16-23位为按键的扫描码,
24-31位表示是按下键还是释放键。
大家一般习惯写成16进制的,那么就应该是
&H00 00 00 00 ,
第0-15位一般为&H0001,如果是按下键,那么24-31位为&H00,释放键则为&HC0,
那么16-23位的扫描码怎么会得呢?这需要用到一个API函数MapVirtualKey,这个函数可以将虚拟码转换为扫描码,或将扫描码转换为虚拟码,还可以把虚拟码转换为对应字符的ASCII码。它的delphi 声明如下:
MapVirtualKey(
uCode: UINT; {key code, scan code or virtual key}
uMapType: UINT {flags for translation mode}
): UINT; {returns translated key code}
参数uCode 表示待转换的码,参数uMapType 表示从什么转换为什么,如果是虚拟码转扫描码,则uMapType 设置为0,如果是虚拟扫描码转虚拟码,则wMapType 设置为1,如果是虚拟码转ASCII码,则uMapType 设置为2.相信有了这些,我们就可以构造键盘事件的lParam参数了。
下面给出一个构造lParam参数的函数:
function VKB_param(VirtualKey:Integer;flag:Integer):Integer; //函数名
var
s,Firstbyte,Secondbyte:String;
S_code:Integer;
Begin
if flag=1 then //按下键
begin
Firstbyte :='00'
end
else //弹起键
begin
Firstbyte :='C0'
end;
S_code:= MapVirtualKey(VirtualKey, 0);
Secondbyte:='00'+inttostr(s_code);
Secondbyte:=copy(Secondbyte,Length(Secondbyte)-1,2);
s:='$'+Firstbyte + Secondbyte + '0001';
Result:=strtoint(s);
End;
使用按键的方法:
说明:key为键值,如1键[不是数字键的1]的值是$31,flag传递的是按键状态,1是按下,0是弹起。
lparam := VKB_param(key, 1); {按下键}
PostMessage (MyHwnd, WM_KEYDOWN, key, lParam);
lParam := VKB_param(key, 0); {松开键}
PostMessage (MyHwnd, WM_KEYUP, key, lParam);
var
hwnd, lparam:Cardinal;
begin
hwnd:=FindWindowEx(FindWindow(nil,'无标题 - 记事本'),0,'edit',nil);
lparam := VKB_param(97, 1); {按下键}
PostMessage (hwnd,WM_KEYDOWN,vk_F3,lparam) ; //按下F3键
//PostMessage (hwnd,WM_CHAR,97,lparam); //输入字符A (edit控件接收字符)
lParam := VKB_param(key, 0); {松开键}
PostMessage (hwnd,WM_KEYUP,vk_F3,lparam); //释放F3键
end;
模拟鼠标点击
Var
P1:Tpoint;
Lparam:integer;
begin
GetCursorPos(P1); // 获取屏幕坐标
P1.X:= P1.X+100;
P1.Y:=P1.Y+100;
lparam:=p1.X+ p1.Y shl 16;
sendmessage(h,messages.WM_LBUTTONDOWN ,0,lparam);// 按下鼠标左键
sendmessage(h,messages.WM_LBUTTONUP ,0, lparam); //抬起鼠标左键
End;
(二)、系统级模拟(针对所有程序的窗口,我称之为全局模拟)
模拟全局键盘消息常见的可以有以下一些方法:
1、 用API函数keybd_event,这个函数可以用来模拟一个键盘事件
keybd_event(
bVk: Byte; {virtual-key code}
bScan: Byte; {scan-code}
dwFlags: DWORD; {option flags}
dwExtraInfo: DWORD {additional information about the key}
); {this procedure does not return a value}
keybd_event(VK_A, 0, 0, 0) '按下A键
keybd_event (VK_A, 0, KEYEVENTF_KEYUP, 0) '释放A键
注意有时候按键的速度不要太快,否则会出问题,可以用API函数Sleep来进行延时,delphi声明如下:
Sleep(
dwMilliseconds: DWORD {specifies the number of milliseconds to pause}
);
参数dwMilliseconds表示延时的时间,以毫秒为单位。
那么如果要模拟按下功能键怎么做呢?比如要按下Ctrl+C实现拷贝这个功能,可以这样:
keybd_event (VK_Ctrl, 0, 0, 0 ); //按下Ctrl键
keybd_event (VK_C, 0, 0, 0); //按下C键
Sleep(500 ); //延时500毫秒
keybd_event (VK_C, 0, KEYEVENTF_KEYUP, 0 ); //释放C键
keybd_event (VK_Ctrl, 0, KEYEVENTF_KEYUP, 0 ); //释放Ctrl键
好了,现在你可以试试是不是可以骗过目标程序了,这个函数对大部分的窗口程序都有效,可是仍然有一部分游戏对它产生的键盘事件熟视无睹,这时候,你就要用上bScan这个参数了。一般的,bScan都传0,但是如果目标程序是一些DirectX游戏,那么你就需要正确使用这个参数传入扫描码,用了它可以产生正确的硬件事件消息,以被游戏识别。这样的话,就可以写成这样:
keybd_event (VK_A, MapVirtualKey(VK_A, 0), 0, 0); //按下A键
keybd_event (VK_A, MapVirtualKey(VK_A, 0), KEYEVENTF_KEYUP, 0 ); //释放A键
以上就是用keybd_event函数来模拟键盘事件。
模拟按下鼠标左键
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);//鼠标左键按下mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);//鼠标左键弹起
2、 SendInput函数也可以模拟全局键盘鼠标事件。 SendInput可以直接把一条消息插入到消息队列中,算是比较底层的了。 SendInput的参数其实很简单,在Windows.pas就有函数的声明如下: function SendInput ( cInputs: UINT; pInputs中记录数组的元素数目 var pInputs: TInput; TInput类型记录数组的第1个元素 cbSize: Integer 定义TInput的大小,一般为SizeOf(TInput) ): UINT; stdcall; cInputs:定义pInputs中记录数组的元素数目。pInputs:TInput类型记录数组的第1个元素。每个元素代表插人到系统消息队列的键盘或鼠标事件。cbSize:定义TInput的大小,一般为SizeOf(TInput)。函数返回成功插入系统消息队列中事件的数目,失败返回0。调用SendInput关键的就是要搞清楚它的几个记录结构的意思,在Windows.pas中对TInput的声明如下: tagINPUT = packed record Itype: DWORD; case Integer of 0: (mi: TMouseInput); 1: (ki: TKeybdInput); 2: (hi: THardwareInput); end; TInput = tagINPUT; 其中mi、ki、hi是3个共用型的记录结构,Itype指出记录结构中所使用的类型,它有3个值。INPUT_MOUSE:表示使用mi记录结构,忽略ki和hi;INPUT_KEYBOARD:表示使用ki记录结构,忽略mi和hi。 (1)、键盘模拟 TKeybdInput记录结构的声明如下: tagKEYBDINPUT = packed record wVk: WORD; 是将要操作的按键的虚键码 wScan: WORD; 是安全码,一般不用 dwFlags: DWORD; 指定键盘所进行的操作,为0时表示按下某键,KEYEVENTF_KEYUP表示放开某键 time: DWORD; dwExtraInfo: DWORD; 是扩展信息,可以使用API函数GetMessageExtraInfo的返回值 end; TKeybdInput = tagKEYBDINPUT; 其中wVk是将要操作的按键的虚键码。wScan是安全码,一般不用。dwFlags指定键盘所进行的操作,为0时表示按下某键,KEYEVENTF_KEYUP表示放开某键。time是时间戳,可以使用API函数GetTickCount的返回值。dwExtraInfo是扩展信息,可以使用API函数GetMessageExtraInfo的返回值。例如击键“A”的程序如下: procedure KeyPressA; var Inputs : array [0..1] of TInput; begin Inputs[0].Itype:=INPUT_KEYBOARD; with Inputs[0].ki do begin wVk:=VK_A; wScan:=0; dwFlags:=0; time:=GetTickCount; dwExtraInfo:=GetMessageExtraInfo; end; Inputs[1].Itype:=INPUT_KEYBOARD; with Inputs[1].ki do begin wVk:=VK_A; wScan:=0; dwFlags:=KEYEVENTF_KEYUP; time:=GetTickCount; dwExtraInfo:=GetMessageExtraInfo; end; SendInput(2,Inputs[0],SizeOf(TInput)); end; 注意:在Windows.pas单元中并没有字母和数字的虚键码的声明,在我写的SIMouseKeyboard.pas单元文件中对所有的虚键码进行了重新声明,包含了字母、数字和标点符号。 (2)、鼠标模拟 TMouseInput记录结构的声明如下: tagMOUSEINPUT = packed record dx: Longint; dy: Longint; mouseData: DWORD; dwFlags: DWORD; time: DWORD; dwExtraInfo: DWORD; end; TMouseInput = tagMOUSEINPUT; 其中dx、dy是鼠标移动时的坐标差(不是象素单位),在鼠标移动时有效。mouseData是鼠标滚轮滚动值,在滚动鼠标滚轮时有效。当mouseData小于0时向下滚动,当mouseData大于0时向上滚动,mouseData的绝对值一般设为120。dwFlags指定鼠标所进行的操作,例如,MOUSEEVENTF_MOVE表示移动鼠标,MOUSEEVENTF_LEFTDOWN表示按下鼠标左键,MOUSEEVENTF_LEFTUP表示放开鼠标左键。time是时间戳,可以使用API函数GetTickCount的返回值。dwExtraInfo是扩展信息,可以使用API函数GetMessageExtraInfo的返回值。例如单击鼠标左键的程序如下: procedure MouseClick; var Inputs : array [0..1] of TInput; begin Inputs[0].Itype:=INPUT_MOUSE; with Inputs[0].mi do begin dx:=0; dy:=0; mouseData:=0; dwFlags:=MOUSEEVENTF_LEFTDOWN; time:=GetTickCount; dwExtraInfo:=GetMessageExtraInfo; end; Inputs[1].Itype:=INPUT_MOUSE; with Inputs[1].mi do begin dx:=0; dy:=0; mouseData:=0; dwFlags:=MOUSEEVENTF_LEFTUP; time:=GetTickCount; dwExtraInfo:=GetMessageExtraInfo; end; SendInput(2,Inputs[0],SizeOf(TInput)); end; 鼠标的移动总是很麻烦,上面的dx、dy不是以象素为单位的,而是以鼠标设备移动量为单位的,它们之间的比值受鼠标移动速度设置的影响。具体的解决方法我已经在《Delphi下利用WinIo模拟鼠标键盘详解》一文中进行了讨论,这里不再重复。dwFlags可以设置一个MOUSEEVENTF_ABSOLUTE标志,这使得可以用另外一种方法移动鼠标。当dwFlags设置了MOUSEEVENTF_ABSOLUTE标志,dx、dy为屏幕坐标值,表示将鼠标移动到dx,dy的位置。但是这个坐标值也不是以象素为单位的。这个值的范围是0到65535($FFFF),当dx等于0、dy等于0时表示屏幕的最左上角,当dx等于65535、dy等于65535时表示屏幕的最右下角,相当于将屏幕的宽和高分别65536等分。API函数GetSystemMetrics(SM_CXSCREEN)可以返回屏幕的宽度,函数GetSystemMetrics(SM_CYSCREEN)可以返回屏幕的高度,利用屏幕的宽度和高度就可以将象素坐标换算成相应的dx、dy。注意:这种换算最多会出现1象素的误差。例如:将鼠标指针移动到屏幕150,120坐标处的程序如下: procedure MouseMove; var Input : TInput; begin Input.Itype:=INPUT_MOUSE; with Input.mi do begin dx:=($FFFF div (GetSystemMetrics(SM_CXSCREEN)-1)) * 150; dy:=($FFFF div (GetSystemMetrics(SM_CYSCREEN)-1)) * 120; mouseData:=0; dwFlags:=MOUSEEVENTF_MOVE or MOUSEEVENTF_ABSOLUTE; time:=GetTickCount; dwExtraInfo:=GetMessageExtraInfo; end; SendInput(1,Input,SizeOf(TInput)); end; (3)、SendInput与WInIo的对比 在《Delphi下利用WinIo模拟鼠标键盘详解》一文中我已经说了WinIo的很多缺点,SendInput几乎没有这些缺点。SendInput的模拟要比WinIo简单的多。事件是被直接插入到系统消息队列的,所以它的速度比WinIo要快。系统也会保证数据的完整性,不会出现数据包混乱的情况。利用“绝对移动”可以将鼠标指针移动到准确的位置,同鼠标的配置隔离不会出现兼容性的问题。SendInput的缺点也是最要命的,它会被一些程序屏蔽。所以说在SendInput与WInIo都可以使用的情况下优先考虑SendInput。另外SendInput与WInIo可以接合使用,一些程序对鼠标左键单击敏感,可以使用WinIo模拟鼠标左键单击,其它操作由SendInput模拟。 3、用全局钩子也可以模拟键盘消息。如果你对windows中消息钩子的用法已经有所了解,那么你可以通过设置一个全局HOOK来模拟键盘消息,比如,你可以用WH_JOURNALPLAYBACK这个钩子来模拟按键。WH_JOURNALPLAYBACK是一个系统级的全局钩子,它和WH_JOURNALRECORD的功能是相对的,常用它们来记录并回放键盘鼠标操作。WH_JOURNALRECORD钩子用来将键盘鼠标的操作忠实地记录下来,记录下来的信息可以保存到文件中,而WH_JOURNALPLAYBACK则可以重现这些操作。当然亦可以单独使用WH_JOURNALPLAYBACK来模拟键盘操作。 SetWindowsHookEx函数,它可以用来安装消息钩子: SetWindowsHookEx( idHook: Integer; {hook type flag} lpfn: TFNHookProc; {a pointer to the hook function} hmod: HINST; {a handle to the module containing the hook function} dwThreadId: DWORD {the identifier of the associated thread} ): HHOOK; 先安装WH_JOURNALPLAYBACK这个钩子,然后你需要自己写一个钩子函数,在系统调用它时,把你要模拟的事件传递给钩子参数lParam所指向的EVENTMSG区域,就可以达到模拟按键的效果。不过用这个钩子模拟键盘事件有一个副作用,就是它会锁定真实的鼠标键盘,不过如果你就是想在模拟的时候不会受真实键盘操作的干扰,那么用用它倒是个不错的主意。 在不需要监视系统消息时需要调用提供UnHookWindowsHookEx来解除对消息的监视。 下面来建立程序,在Delphi中建立一个工程,在Form1上添加3个按钮用于程序操作。另外再添加一个按钮控件和一个Edit控件用于验证操作。 下面是Form1的全部代码 unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; Button3: TButton; Edit1: TEdit; Button4: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; EventArr:array[0..1000]of EVENTMSG; EventLog:Integer; PlayLog:Integer; hHook,hPlay:Integer; recOK:Integer; canPlay:Integer; bDelay:Bool; implementation {$R *.DFM} Function PlayProc(iCode:Integer;wParam:wParam;lParam:lParam):LRESULT;stdcall; begin canPlay:=1; Result:=0; if iCode < 0 then // 必须将消息传递到消息链的下一个接受单元 Result := CallNextHookEx(hPlay,iCode,wParam,lParam) else if iCode = HC_SYSMODALON then canPlay:=0 else if iCode = HC_SYSMODALOFF then canPlay:=1 else if ((canPlay =1 )and(iCode=HC_GETNEXT)) then begin if bDelay then begin bDelay:=False; Result:=50; end; pEventMSG(lParam)^:=EventArr[PlayLog]; end else if ((canPlay = 1)and(iCode = HC_SKIP))then begin bDelay := True; PlayLog:=PlayLog+1; end; if PlayLog>=EventLog then begin UNHookWindowsHookEx(hPlay); end; end; function HookProc(iCode:Integer;wParam:wParam;lParam:lParam):LRESULT;stdcall; begin recOK:=1; Result:=0; if iCode < 0 then Result := CallNextHookEx(hHook,iCode,wParam,lParam) else if iCode = HC_SYSMODALON then recOK:=0 else if iCode = HC_SYSMODALOFF then recOK:=1 else if ((recOK>0) and (iCode = HC_ACTION)) then begin EventArr[EventLog]:=pEventMSG(lParam)^; EventLog:=EventLog+1; if EventLog>=1000 then begin UnHookWindowsHookEx(hHook); end; end; end; procedure TForm1.FormCreate(Sender: TObject); begin Button1.Caption:= '纪录'; Button2.Caption:= '停止'; Button3.Caption:= '回放'; Button4.Caption:= '范例'; Button2.Enabled:=False; Button3.Enabled:=False; end; procedure TForm1.Button1Click(Sender: TObject); begin EventLog:=0; // 建立键盘鼠标操作消息纪录链 hHook:=SetwindowsHookEx(WH_JOURNALRECORD,HookProc,HInstance,0); Button2.Enabled:=True; Button1.Enabled:=False; end; procedure TForm1.Button2Click(Sender: TObject); begin UnHookWindowsHookEx(hHook); hHook:=0; Button1.Enabled:=True; Button2.Enabled:=False; Button3.Enabled:=True; end; procedure TForm1.Button3Click(Sender: TObject); begin PlayLog:=0; //建立键盘鼠标操作消息纪录回放链 hPlay:=SetwindowsHookEx(WH_JOURNALPLAYBACK,PlayProc, HInstance,0); Button3.Enabled:=False; end; end. 二、驱动级模拟 (绕过了windows消息) 有一些使用DirectX接口的游戏程序,它们在读取键盘操作时绕过了windows的消息机制,而使用DirectInput.这是因为有些游戏对实时性控制的要求比较高,比如赛车游戏,要求以最快速度响应键盘输入。而windows消息由于是队列形式的,消息在传递时会有不少延迟,有时1秒钟也就传递十几条消息,这个速度达不到游戏的要求。而DirectInput则绕过了windows消息,直接与键盘驱动程序打交道,效率当然提高了不少。因此也就造成,对这样的程序无论用PostMessage或者是keybd_event都不会有反应,因为这些函数都在较高层。对于这样的程序,只好用直接读写键盘端口的方法来模拟硬件事件了。要用这个方法来模拟键盘,需要先了解一下键盘编程的相关知识。 在DOS时代,当用户按下或者放开一个键时,就会产生一个键盘中断(如果键盘中断是允许的),这样程序会跳转到BIOS中的键盘中断处理程序去执行。打开windows的设备管理器,可以查看到键盘控制器由两个端口控制。其中&H60是数据端口,可以读出键盘数据,而&H64是控制端口,用来发出控制信号。也就是,从&H60号端口可以读此键盘的按键信息,当从这个端口读取一个字节,该字节的低7位就是按键的扫描码,而高1位则表示是按下键还是释放键。当按下键时,最高位为0,称为通码,当释放键时,最高位为1,称为断码。既然从这个端口读数据可以获得按键信息,那么向这个端口写入数据就可以模拟按键了!用过QbASIC4.5的朋友可能知道,QB中有个OUT命令可以向指定端口写入数据,而INP函数可以读取指定端口的数据。那我们先看看如果用QB该怎么写代码: 假如你想模拟按下一个键,这个键的扫描码为&H50,那就这样 OUT &H64,&HD2 '把数据&HD2发送到&H64端口。这是一个KBC指令,表示将要向键盘写入数据 OUT &H60,&H50 '把扫描码&H50发送到&H60端口,表示模拟按下扫描码为&H50的这个键 那么要释放这个键呢?像这样,发送该键的断码: OUT &H64,&HD2 '把数据&HD2发送到&H64端口。这是一个KBC指令,表示将要向键盘写入数据 OUT &H60,(&H50 or &H80) '把扫描码&H50与数据&H80进行或运算,可以把它的高位置1,得到断码,表示释放这个键 好了,现在的问题就是在delphi中如何向端口写入数据了。因为在windows中,普通应用程序是无权操作端口的,于是我们就需要一个驱动程序来帮助我们实现。在这里我们可以使用一个组件WINIO来完成读写端口操作。什么是WINIO?WINIO是一个全免费的、无需注册的、含源程序的WINDOWS2000端口操作驱动程序组件(可以到http://www.internals.com/上去下载)。它不仅可以操作端口,还可以操作内存;不仅能在VB下用,还可以在DELPHI、VC等其它环境下使用,性能特别优异。下载该组件,解压缩后可以看到几个文件夹,其中Release文件夹下的3个文件就是我们需要的,这3个文件是WinIo.sys(用于win xp下的驱动程序),WINIO.VXD(用于win 98下的驱动程序),WinIo.dll(封装函数的动态链接库),我们只需要调用WinIo.dll中的函数,然后WinIo.dll就会安装并调用驱动程序来完成相应的功能。值得一提的是这个组件完全是绿色的,无需安装,你只需要把这3个文件复制到与你的程序相同的文件夹下就可以使用了。用法很简单,先用里面的InitializeWinIo函数安装驱动程序,然后就可以用GetPortVal来读取端口或者用SetPortVal来写入端口了。好,让我们来做一个驱动级的键盘模拟吧。先把winio的3个文件拷贝到你的程序的文件夹下。 下面给出使用WINIO模拟按键的单元和使用方法: {****************************************************************************} unit MNwinio; interface const KBC_KEY_CMD = $64; //键盘命令端口 KBC_KEY_DATA = $60; //键盘数据端口 implementation function InitializeWinIo: Boolean; stdcall; external 'WinIo.dll' name 'InitializeWinIo'; { 本函数初始化WioIO函数库。 必须在调用所有其它功能函数之前调用本函数。 如果函数调用成功,返回值为非零值。 如果调用失败,则返回值为0。 procedure TForm1.FormActivate(Sender: TObject); //通常在程序启动时调用 begin if InitializeWinIo = False then begin Messagebox(handle, '初始化失败!', '提示', MB_OK + MB_IconError) end; end; } function InstallWinIoDriver(pszWinIoDriverPath: PString; IsDemandLoaded: boolean = false): Boolean; stdcall; external 'WinIo.dll' name 'InstallWinIoDriver'; function RemoveWinIoDriver: Boolean; stdcall; external 'WinIo.dll' name 'RemoveWinIoDriver'; function GetPortVal(PortAddr: Word; PortVal: PDWord; bSize: Byte): Boolean; stdcall; external 'WinIo.dll' name 'GetPortVal'; function SetPortVal(PortAddr: Word; PortVal: DWord; bSize: Byte): Boolean; stdcall; external 'WinIo.dll' name 'SetPortVal'; function GetPhysLong(PhysAddr: PByte; PhysVal: PDWord): Boolean; stdcall; external 'WinIo.dll' name 'GetPhysLong'; function SetPhysLong(PhysAddr: PByte; PhysVal: DWord): Boolean; stdcall; external 'WinIo.dll' name 'SetPhysLong'; function MapPhysToLin(PhysAddr: PByte; PhysSize: DWord; PhysMemHandle: PHandle): PByte; stdcall; external 'WinIo.dll' name 'MapPhysToLin'; function UnMapPhysicalMemory(PhysMemHandle: THandle; LinAddr: PByte): Boolean; stdcall; external 'WinIo.dll' name 'UnmapPhysicalMemory'; procedure ShutdownWinIo; stdcall; external 'WinIo.dll' name 'ShutdownWinIo'; { 本函数在内存中清除WinIO库 本函数必须在中止应用函数之前或者不再需要WinIO库时调用 procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); //通常在程序关闭时调用 begin ShutdownWinIo; end; } {**********以上为WINIO.dll中API函数的调用***************} procedure KBCWait4IBE; //等待键盘缓冲区为空 var dwVal: DWord; begin repeat GetPortVal($64, @dwVal, 1); {这句表示从&H64端口读取一个字节并把读出的数据放到变量dwVal中. GetPortVal函数的用法是 GetPortVal (端口号,存放读出数据的变量地址,读入的长度} until (dwVal and $2) = 0; {上面的是一个根据KBC规范写的过程,它的作用是在向键盘端口写入数据前等待一段时间,后面将会用到。} end; procedure MyKeyDown(vKeyCoad: Integer); // 这个用来模拟按下键,参数vKeyCoad传入按键的虚拟码 var btScancode: DWord; begin btScancode := MapVirtualKey(vKeyCoad, 0); KBCWait4IBE; // 发送数据前应该先等待键盘缓冲区为空 SetPortVal($64, $D2, 1); // 发送键盘写入命令 {SetPortVal函数用于向端口写入数据,它的用法是:SetPortVal(端口号,欲写入的数据,写入数据的长度)} KBCWait4IBE; SetPortVal($60, btScancode, 1); //写入按键信息,按下键 end; procedure MyKeyUp(vKeyCoad: Integer); //这个用来模拟释放键,参数vKeyCoad传入按键的虚拟码 var btScancode: DWord; begin btScancode := MapVirtualKey(vKeyCoad, 0); KBCWait4IBE; SetPortVal($64, $D2, 1); KBCWait4IBE; SetPortVal($64, (btScancode or $80), 1); end; end. { 使用方法: 如模拟按键 1 MyKeyDown($31); Sleep(50); MyKeyUp($31); }↧
↧
Marshal.GetDelegateForFunctionPointer
原来是为了在游戏外挂中发送键盘鼠标消息,自己写个sendmessage或者是postmessage又比较麻烦。于是google了一下,发现现在很多脚本工具都有这个功能,其中按键精灵的一个叫361度的插件已经有这个的实现,还验证过了。为什么不拿来己用呢?
首先分析一下按键精灵插件的接口,发现:
插件的功能函数没有直接暴露出来,而是通过一个GetCommand的函数返回一个函数描述结构。
接下来看看这个结构:
上面这个结构我已经是转换成C#的对应结构了,原结构可以查看按键精灵提供的插件C++接口源代码。
这个结构里面的 handlerFunction 实际上是指向函数的入口点,也就是一个函数指针,每个函数都一样是2个参数:
好了,方便哇?这样一来,我们可以在.net上面实现动态加载和卸载Win32 dll. 具体思路就是:(还是代码来得方便)
typedef int (*QMPLUGIN_HANDLER)(char *lpszParamList, char *lpszRetVal);
转换为C#中相应的委托为:
delegate void Invoker(string parameters, StringBuilder returnValue);
大家注意到,有两个参数,c++原型中都是char*类型,转换为C#的delegate后第一个为string,第二个为StringBuilder。这是因为parameters是in的,dll中不会对这个参数做修改,而returnValue是out的,dll返回时候要把返回值写入这个 StringBuilder的缓冲区。
原本的想法是用C++写一个桥来调用dll,不过在.net 2.0 中,框架直接提供了 Marshal.GetDelegateForFunctionPointer 来转换一个函数指针为一个委托,这就方便多拉。请看下面代码,注意看 BGKM_ExecuteCommand 这个函数里面的东西。
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace WJsHome.Game.Utility
{
public class QMacro
{
[DllImport("BGKM5.dll", EntryPoint = "GetCommand")]
static extern IntPtr BGKM_GetCommand(int commandNum);
[StructLayout(LayoutKind.Sequential)]
class QMPLUGIN_CMD_INFO
{
public string commandName;
public string commandDescription;
public IntPtr handlerFunction;
public uint paramNumber;
}
delegate void Invoker(string parameters, StringBuilder returnValue);
static string BuildParameters(params object[] parameters)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < parameters.Length; i++)
{
sb.Append(parameters[i].ToString());
if (i != parameters.Length - 1)
{
sb.Append(',');
}
}
return sb.ToString();
}
static void BGKM_ExecuteCommand(int cmdNum, string parameters, StringBuilder retVal)
{
IntPtr pCmdInfo = BGKM_GetCommand(cmdNum);
QMPLUGIN_CMD_INFO cmdInfo = new QMPLUGIN_CMD_INFO();
Marshal.PtrToStructure(pCmdInfo, cmdInfo);
Invoker invoker = Marshal.GetDelegateForFunctionPointer(cmdInfo.handlerFunction, typeof(Invoker)) as Invoker;
invoker(parameters, retVal);
}
public static void BGKM_KeyClick(IntPtr hWnd, int key)
{
BGKM_ExecuteCommand(0, BuildParameters(hWnd, key), null);
}
public static void BGKM_KeyDown(IntPtr hWnd, int key)
{
BGKM_ExecuteCommand(1, BuildParameters(hWnd, key), null);
}
![]()
public static void BGKM_Mouse(IntPtr hWnd, int code, int x, int y)
{
BGKM_ExecuteCommand(15, BuildParameters(hWnd, code, x, y), null);
}
public static WinApi.POINT BGKM_ScrToCli(IntPtr hWnd, int x, int y)
{
StringBuilder retVal = new StringBuilder();
BGKM_ExecuteCommand(16, BuildParameters(hWnd, x, y), retVal);
string[] tmp = retVal.ToString().Split('|');
return new WinApi.POINT(int.Parse(tmp[0]), int.Parse(tmp[1]));
}
}
}


好了,方便哇?这样一来,我们可以在.net上面实现动态加载和卸载Win32 dll. 具体思路就是:(还是代码来得方便)
public delegate int MsgBox(int hwnd,string msg,string cpp,int ok);
[DllImport("Kernel32")]
public static extern int GetProcAddress(int handle, String funcname);
[DllImport("Kernel32")]
public static extern int LoadLibrary(String funcname);
[DllImport("Kernel32")]
public static extern int FreeLibrary(int handle);
private static Delegate GetAddress(int dllModule, string functionname, Type t)
{
int addr = GetProcAddress(dllModule, functionname);
if (addr == 0)
return null;
else
return Marshal.GetDelegateForFunctionPointer(new IntPtr(addr), t);
}
private void button1_Click(object sender, EventArgs e)
{
int huser32 = 0;
huser32 = LoadLibrary("user32.dll");
MsgBox mymsg = (MsgBox)GetAddress(huser32, "MessageBoxA", typeof(MsgBox));
mymsg(this.Handle.ToInt32(), txtmsg.Text, txttitle.Text , 64);
FreeLibrary(huser32);
}
↧
C#读取Excel的其中一种方式OleDb读取(100万条)–快速大量插入SQL中
主要运用表类型
C#端读取Excel
C#端插入到sql表中

1 Create table BulkTestTable( 2 Id nvarchar(32), 3 UserName nvarchar(32), 4 Pwd nvarchar(32) 5 ) 6 Go 7 CREATE TYPE BulkUdt AS TABLE 8 (Id nvarchar(32), 9 UserName nvarchar(32), 10 Pwd nvarchar(32) )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 |
/// <summary> /// 读取Excel中数据 /// </summary> /// <param name="strExcelPath"></param> /// <param name="tableName"></param> /// <returns></returns> public DataTable GetExcelTableByOleDB( string strExcelPath, string tableName) { try { DataTable dtExcel = new DataTable(); //数据表 DataSet ds = new DataSet(); //获取文件扩展名 string strExtension = System.IO.Path.GetExtension(strExcelPath); string strFileName = System.IO.Path.GetFileName(strExcelPath); //Excel的连接 OleDbConnection objConn = null ; switch (strExtension) { case ".xls" : objConn = new OleDbConnection( "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + strExcelPath + ";" + "Extended Properties=\"Excel 8.0;HDR=NO;IMEX=1;\"" ); break ; case ".xlsx" : objConn = new OleDbConnection( "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + strExcelPath + ";" + "Extended Properties=\"Excel 12.0;HDR=NO;IMEX=1;\"" ); break ; default : objConn = null ; break ; } if (objConn == null ) { return null ; } objConn.Open(); //获取Excel中所有Sheet表的信息 //System.Data.DataTable schemaTable = objConn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, null); //获取Excel的第一个Sheet表名 // string tableName1 = schemaTable.Rows[0][2].ToString().Trim(); string strSql = "select * from [" + tableName + "$]" ; //获取Excel指定Sheet表中的信息 OleDbCommand objCmd = new OleDbCommand(strSql, objConn); OleDbDataAdapter myData = new OleDbDataAdapter(strSql, objConn); myData.Fill(ds, tableName); //填充数据 objConn.Close(); //dtExcel即为excel文件中指定表中存储的信息 dtExcel = ds.Tables[tableName]; return dtExcel; } catch (Exception ex) { MessageBox.Show(ex.Message); return null ; } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 |
/// <summary> /// 导入msSql /// </summary> /// <param name="?"></param> /// <returns></returns> public int ExcelToMsSQL( string tablename,DataTable dt) { int count = 0; string Connstr = "Data Source=;Initial Catalog=;Persist Security Info=True;User ID=;Password=" ; SqlConnection sqlConn = new SqlConnection(Connstr); const string TSqlStatement = "insert into BulkTestTable (Id,UserName,Pwd)" + " SELECT nc.Id, nc.UserName,nc.Pwd" + " FROM @NewBulkTestTvp AS nc" ; SqlCommand cmd = new SqlCommand(TSqlStatement, sqlConn); SqlParameter catParam = cmd.Parameters.AddWithValue( "@NewBulkTestTvp" , dt); catParam.SqlDbType = SqlDbType.Structured; //表值参数的名字叫BulkUdt,在上面的建立测试环境的SQL中有。 catParam.TypeName = "dbo.BulkUdt" ; try { sqlConn.Open(); if (dt != null && dt.Rows.Count != 0) { count = cmd.ExecuteNonQuery(); } } catch (Exception ex) { throw ex; } finally { sqlConn.Close(); } return count ; } |
↧
Office Web Apps安装部署(一)
Office Web Apps安装部署(一)
系统要求为Windows Server 2012,
注意:安装Office Web Apps的服务器除了Office Web Apps之外,不能安装其他应用。包括不能安装Office,lync,,sharepoint等应用,即要单独部署。
打开服务器管理器
添加角色和功能
打开“添加角色和功能向导”界面,点击下一步
因为是基于本机安装,所以要选择“基于角色或者基于功能安装”
点击“下一步”
在服务器角色列表上选择“Web服务器”
“下一步”,安装。
注意,在安装IIS的时候要安装Web服务器下面的“管理服务”,
或者按以下操作顺序运行命令:
以管理员身份运行PowerShell
View Code
这段PowerShell的意思 是启用 Windows的相关的角色和功能,如墨迹手写服务,ASP.NET 4.5,IIS服务等。
同意协议,点击“继续”
选择安装位置,点击“立即安装”。
安装完成之后,点击“关闭”
勾选许可条款,继续安装。
安装完成界面。
点击接受协议,继续。以完成安装。
安装之后重启。否则接下来的操作中,PowerShell识别不了相关的cmdlet命令。
如果不想重启的话,可以在PowerShell中键入如下命令
以加载Office Web Apps管理命令集
注意:如果是给Office Web Apps服务器场安装语言包,请将单个服务器先单独从服务器场隔离开来,然后单个安装。
(其中http://OfficeWebApps.veekee.cn 的OfficeWebApps.veekee.cn 为OfficeWebApps服务器的计算机全名。这个名称根据具体环境而设)。
如图所示
回车以确定。
会出现提示
输入”y”,回车。
成功的话,会返回列表信息
我们可以在服务器的浏览器中输入下列Url以求证
http://OfficeWebApps.veekee.cn/hosting/discovery
(其中http://OfficeWebApps.veekee.cn 的OfficeWebApps.veekee.cn 为OfficeWebApps服务器的计算机全名。这个名称根据具体环境而设)
安装成功的话,会显示下图信息:
至此Office Web Apps布署成功。
一般情况下,Office Web Apps要与其他应用配合使用,如下图所示:
从上图可知,如果自己开发一个系统的话,实际上也是可以调用Office web Apps。
安装IIS 7.0








安装Office Web Apps
从http://www.microsoft.com/zh-cn/download/confirmation.aspx?id=35489 链接下载 Microsoft Office Web Apps Server 点击安装。 打开安装文件,界面如下:



安装Office Web Apps补丁文件
从http://www.microsoft.com/zh-cn/download/confirmation.aspx?id=38378 下载补丁文件进行安装 如下图:

安装Office Web Apps语言包
Office Web Apps的语言包可以让用户的Office文档在sharepoint网站中以Web方式打开时,如果文档内包含有多种语言时,可以正常查看。语言包可以在以下链接打开: http://www.microsoft.com/zh-cn/download/confirmation.aspx?id=35490 下图是它的安装界面
Import-Module OfficeWebApps
布署Office Web Apps
在OfficeWebApps服务器上,以管理员身份打开PowerShell,键入命令New-OfficeWebAppsFarm –InternalURL "http://OfficeWebApps.veekee.cn" –AllowHttp –EditingEnabled





↧
↧
让服务器能支持10万并发数秘诀,亲身经历,站在巨人的肩膀上创造
由于一个项目的访问量越来越大,从原来的几百个,增加到现在50多万个每天,所以阿里的服务器也扛不住了,于是就想办法,查了N多资料,总结了以下方法,才解决这问题,每天一共访问量50多万,并不是同时访问,所以,提高并发数才是关键。
由于网站一再打不开,按照排除原因来看,数据库连接、进程池满了、iis并发数太高,我能想到的就只有这三种情况,于是就一个一个排除,当项目网站打不开时,同服务器其他网站都正常,内存不到30%,CUP不到20%,怎么可能打不开呢,于是我先重启数据库,发现仍然打不开,然后重启进程池,还是打不开,最后我重启iis,这次好了,秒开。看来是iis并发数搞得鬼,于是就查微软资料,发现,win2008默认的并发数是5000,我想这哪够啊,就想到如下方法,按步骤来:
步骤一:
首先设置进程池
要点:把队列长度调整到65535,禁止重叠回收,最大故障数改成65530,这三点必须要改,不然实现不了10万并发效果
步骤二:
调整IIS 的appConcurrentRequestLimit设置
在开始--》运行--》输入:c:\windows\system32\inetsrv\appcmd.exe set config /section:serverRuntime /appConcurrentRequestLimit:100000--》回车
即可,然后可通过在运行中输入%systemroot%\System32\inetsrv\config\applicationHost.config回车查询设置结果,设置后就会出现下面代码:
步骤三:
调整machine.config中的processModel>requestQueueLimit的设置
在开始-->运行--》输入:%systemroot%\Microsoft.Net\Framework64\v2.0.50727\CONFIG\machine.config
打开后搜索找到: ,将此替换成
步骤四:
在开始--》运行--》输入下面三句代码,然后回车,分别输入
reg add HKLM\System\CurrentControlSet\Services\HTTP\Parameters /v MaxConnections /t REG_DWORD /d 100000
reg add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP\Parameters /v MaxFieldLength /t REG_DWORD /d 32768
reg add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP\Parameters /v MaxRequestBytes /t REG_DWORD /d 32768
第一句将tcp并发数提高到10万,第二和第三句防止出现解决Bad Request - Request Too Long问题,三句分别输入,分别回车
步骤五:
启动cmd,然后先输入net stop http,等待完成,再输入 net start http,等待完成,再输入 iisreset
完成以上5步后,再重启服务器,即可达到并发数10万,无压力
如果访问量再大的话,就需要使用负载均衡、图片和网站分离、CDN等方法。
↧
IIS处理并发请求时出现的问题及解决
一个ASP.NET项目在部署到生产环境时,当用户并发量达到200左右时,IIS出现了明显的请求排队现象,发送的请求都进入等待,无法及时响应,系统基本处于不可用状态。因经验不足,花了很多时间精力解决这个问题,本文记录了我查找问题的过程和最后解决方案,供大家参考。
软硬件环境:
IBM刀片服务器,Intel至强处理器,4物理核,16个逻辑核心,内存32G
Windows Server2008 Enterprise R2, ASP.net 4.0 Webform IIS7.5 集成模式
当发现请求明显延迟,没有被即时处理的现象,首先就要查看Windows自带的性能日志Performance Monitor。
由于我注意到只有对于.aspx或.ashx的请求才会延迟,而.htm或.jpg文件都是即时响应的,所以很明显问题出在ASP.Net上,于是我选择了性能监视器中的ASP.NET 4.0中的2个主要计数器:Requests Current(当前请求数), Requests Queued(被排队的请求数)进行观察。通过观察发现,当前请求数达到200左右时,被排队的请求数就从0开始上升,一直到50左右,如果请求数继续上升,则被排队数也随之上升。当被排队的请求数>0时,就意味着这个时候去访问任何.aspx页面,页面都会处于长时间等待中,没有任何响应,直到IIS处理完了其他请求,才会开始处理队列中的请求。也就是说,当排队数长期>0时,系统基本处于不可用的状态。
由于这个系统的页面布局比较复杂,采用了大量的Ajax+.ashx的方式,将内容分批展示在页面上,所以对服务器的请求总数会比传统aspx模式来的多一些,一个页面全部加载完毕可能需要5-10秒,但我想这不应该是造成问题的主要原因,就算系统性能较差,IIS也应该足以承受这么小的并发量的。
为探究到底是系统写的有问题,还是IIS本身的问题,我抛开我们的系统,写了一个简单的页面,就一个aspx文件,page_load里sleep 10秒。假设这就是一个性能比较差的网站,每个页面都要10秒才能展现,我将其部署在IIS上测试其性能,我使用的是Microsoft Web Application Stress Tool,模拟发起80个线程,每个连接有4个Socket,总共相当于320个并发请求。
测试开始后,可以从下图中看到,当前请求数立刻攀升到300左右(图中红线),然后队列中的请求数也上升到300左右(图中绿线),就是说在300个并发请求下,几乎所有的请求都被排队了,系统基本不可用,通过简单的测试,这个问题已经得以重现了。
随着时间推移,发现绿线慢慢减少,从300下降到100多,就是系统可用性渐渐提高,有一部分用户可以正常使用,但大部分还在排队。
过了6,7分钟,队列中的请求数下降到0左右,并有一些小幅波动。这个时候大部分请求可以被正常处理了。 按照这个现象分析的话,应该是IIS发现有大量请求在队列中,就会试图增加处理线程数以满足要求,但是增长速度有些缓慢。
那是不是系统经过了6,7分钟的适应期之后,以后就一直可以在这个并发量下稳定运作了呢?事实并非如此。我将压力测试停了几秒,当服务器的请求数降为0以后,再重新开启320个请求的测试,IIS如何表现?从下图可以看到,只要请求数有明显上升,则等待队列又开始达到最高值,然后缓慢下降,重复上面的过程。总结下来就是,当出现较大并发时,IIS的处理请求能力完全跟不上,需要很长时间才能开出足够的线程。
然后我做了一个测试,看看IIS默认情况到底能承受多少请求而不排队?似乎是在100个并发左右,表现尚可,未出现排队。
当200个左右就不行了。
然后我将测试程序从sleep10秒改成3秒,对于一个应用系统来说,页面平均3秒处理时间的性能该还算比较正常了。但可惜的是,排队现象与处理时间并无太大关系,排队仍然很严重。
针对以上问题,查阅了相关资料,是否出现排队是和应用程序池的可用线程有关,通过2个方法可以查看系统总线程数和当前可用线程数。
ThreadPool.GetAvailableThreads( out availableWorker, out availableIO);
ThreadPool.GetMaxThreads(out maxWorker, out maxIO);
在队列请求数达到120左右时,通过此方法,得到maxWorker=1600,而availableWorker=1472
因为服务器是16核的,ASP.NET4.0默认每核可以使用100个线程,所以maxWorker是1600,1600-120=1480,大致相等。
就是说当前有120个线程被用来处理请求,还有1400多个处于空闲。关键问题就是为什么这些空闲线程没有被及时启用?
ASP.NET提供的线程配置参数中,有一个参数是非常重要,但是可能被大家忽略的,就是minWorkerThreads。
意指最小工作线程,根据我们以上的测试结果,IIS托管线程启动非常慢,微软也认识到了这个问题,所以提供此参数用于设置正常情况下的最小工作线程数。比如我们系统白天的并发在200-300之间,则可以设置最小线程为300,这样系统响应速度可以大幅提高。
据此,我对配置文件(machine.config)进行了如下修改。注意都是针对单个CPU的,系统会自动乘以逻辑CPU的数量。
相当于最小工作线程设置成了50*16=800。
重启IIS后进行测试,我们得到了以下结果:
可以看到,由于设置了合理的最小工作线程数,使得IIS无需不断创建新线程来处理请求,系统的响应能力已可以满足并发要求。
除此之外,在IIS6之后引入了一个新功能叫Web Garden,其设计目的是为了在CPU占用较低,但是并发请求数比较多的情况下,提升服务器性能。这正符合我当前的情况,于是我启用了Web Garden,将工作进程数从1调整到5,在任务管理器中可以看到w3wp进程从原来的1增加到了5,然后重新测试。
同样的320个请求下,可以看到除了一开始的几秒出现了一些排队,后面基本上表现良好,没有请求进入队列。
通过以上两种方式,都可以有效解决本文开头提出的问题。但Web Garden是工作在多进程模式下,如果应用中用到了依赖进程的Session和Cache等对象都必须另想办法,不能保存在服务器内存中,而且Web Garden的多个进程切换时会有上下文复制,其资源消耗相对单进程要大,这些是需要考虑的因素。
↧
IIS 之 在IIS7、IIS7.5中应用程序池最优配置方案
找到Web站点对应的应用程序池,“应用程序池” → 找到对应的“应用程序池” → 右键“高级设置...”
一、一般优化方案
1、基本设置
[1] 队列长度: 默认值1000,将原来的队列长度改为 65535。
[2] 启动32位应用程序:默认值False,改为True, 否则安装一些32的组建或32位的php都会出错。
[3] 托管管道模式:Integrated 或 Classsic。
2、高级设置
[1] 闲置超时(分钟):默认20分钟,修改设长。
[2] 快速故障防护 → 已启用 :默认True,改为False。
3、解决PEP第一次打开PEP速度慢
回收间隔时间
使用windows server 2008 r2解决回收假死的问题
打开应用程序池 -> 高级设置 ->在“禁止重叠回收”里选择“true”,这样就有效避免了应用程序池回收假死问题。
二、支持同时10万个请求
通过对IIS7的配置进行优化,调整IIS7应用池的队列长度,请求数限制,TCPIP连接数等方面,从而使WEB服务器的性能得以提升,保证WEB访问的访问流畅。
站点碰到如下问题:
Error Summary:
HTTP Error 503.2 - Service Unavailable
The serverRuntime@appConcurrentRequestLimit setting is being exceeded.
Detailed Error Information:
Module IIS Web Core
Notification BeginRequest
Handler StaticFile
Error Code 0x00000000
由于之前使用的是默认配置,服务器最多只能处理5000个同时请求,今天下午由于某种情况造成同时请求超过5000,从而出现了上面的错误。
为了避免这样的错误,我们根据相关文档调整了设置,让服务器从设置上支持10万个并发请求。
具体设置如下:
1. 调整IIS 7应用程序池队列长度
将原来的队列长度由默认值 1000 改为 65535。当然这里的队列长度你可以根据自己的 访问用户*1.5 来设置,例如:有2000用户,此处就可以设置为3000(3000=2000用户数*1.5)。
2. 调整IIS 7的appConcurrentRequestLimit设置
由原来的默认5000改为100000。
[1] 在cmd中执行:
c:\windows\system32\inetsrv\appcmd.exe set config /section:serverRuntime /appConcurrentRequestLimit:100000
[2] 在%systemroot%\System32\inetsrv\config\applicationHost.config中可以查看到该设置:
3. 调整machine.config中的processModel>requestQueueLimit的设置
[1] 单击“开始”,然后单击“运行”,或者 windows + R。
[2] 在“运行”对话框中,键入 notepad %systemroot%\Microsoft.Net\Framework64\v4.0.30319\CONFIG\machine.config,然后单击“确定”。(不同的.NET版本路径不一样,可以选择你自己当前想设置的.NET版本的config)
[3] 找到如下所示的 processModel 元素:
[4] 将 processModel 元素替换为以下值:
[5] 保存并关闭 Machine.config 文件。
由原来的默认5000改为100000。
参考文章:http://technet.microsoft.com/en-us/library/dd425294(office.13).aspx
4. 修改注册表,调整IIS 7支持的同时TCPIP连接数
由原来的默认5000改为100000。在cmd中执行:
reg add HKLM\System\CurrentControlSet\Services\HTTP\Parameters /v MaxConnections /t REG_DWORD /d 100000
可在注册表中查看
5. 运行命令使用设置生效
net stop http & net start http & iisreset
完成上述5个设置,就可以支持10万个并发请求,博客园博客服务器已经启用上述设置。
为了方法大家与自己使用,我把上面能用bat操作简单放到一个bat文件里面了。将下面的内容保存为do.bat文件运行就可以了,需要手工的自己操作
三、支持高并发的IIS Web服务器常用设置
适用的IIS版本:IIS 7.0, IIS 7.5, IIS 8.0
适用的Windows Server版本:Windows Server 2008, Windows Server 2008 R2, Windows Server 2012
1、应用程序池(Application Pool)的设置:
[1] General->Queue Length设置为65535(队列长度所支持的最大值)
[2] Process Model->Idle Time-out设置为0(不让应用程序池因为没有请求而回收)
[3] Recycling->Regular Time Interval设置为0(禁用应用程序池定期自动回收)
2、.Net Framework相关设置
[1] 在machine.config中将
< processModel autoConfig="true" />
改为
(保存后该设置立即生效)
[2] 打开C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\Browsers\Default.browser,找到,注释部分,然后在命令行中运行aspnet_regbrowsers -i。以解决text/vnd.wap.wml问题。
设置命令:
c:\windows\system32\inetsrv\appcmd.exe set config /section:serverRuntime /appConcurrentRequestLimit:100000
设置结果:
< serverRuntime appConcurrentRequestLimit="100000" />
(保存后该设置立即生效)
4、http.sys的设置
注册表设置命令1(将最大连接数设置为10万):
reg add HKLM\System\CurrentControlSet\Services\HTTP\Parameters /v MaxConnections /t REG_DWORD /d 100000
注册表设置命令2(解决Bad Request - Request Too Long问题):
reg add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP\Parameters /v MaxFieldLength /t REG_DWORD /d 32768
reg add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP\Parameters /v MaxRequestBytes /t REG_DWORD /d 32768
(需要在命令行运行 net stop http & net start http & iisreset 使设置生效)
5、针对负载均衡场景的设置
在Url Rewrite Module中增加如下的规则:
注意事项:添加该URL重写规则会造成IIS内核模式缓存不工作,详见微软的坑:Url重写竟然会引起IIS内核模式缓存不工作。
6、 设置Cache-Control为public
在web.config中添加如下配置:
复制代码
复制代码
在machine.config的中添加如下设置:
< processModel enable="true" maxWorkerThreads="100" maxIoThreads="100" minWorkerThreads="50" minIoThreads="50"/>
↧
一个IO的传奇一生
一个IO的传奇一生
前言
前几天同事提议写一篇文章来仔细分析一下一个IO从创建到消亡的整个过程,我觉得这个想法很好,一个IO从创建到消亡经历了千山万水,从软件到硬件涉及到很多很多的技术。一个看似简单的IO读写操作,其实汇集了从计算机软件技术、硬件技术、电子技术、信号处理等各个方面的内容。所以,我想把IO的一生通过自己的认识把他描述一下,让世人看清在执行一个简单的IO操作究竟汇集了多少的智慧!汇集了工程师、科学家多少的心血!在此,将此系列文章定名为《一个IO的传奇一生》,与大家一起分享。
针对不同的操作系统,IO历程是有所差别的,但是很多基本思想是相同的。在此,我想以Linux操作系统为样本,对整个IO历程进行深入分析,最主要的是设计思想方面的考虑。
1.jpg
上图描述了IO操作中所涉及到的软硬件模块,从这张图中我们可以一窥整个系统还是很庞大的,主要涉及了文件系统、块设备层、SCSI层、PCI层、SAS/Ethernet网络以及磁盘/U盘。本文会根据作者的理解对IO在上述各个层次的游历过程进行详细阐述。
文件基本操作
如果你想保存你的Word资料至本地硬盘,你就会触发一个文件系统写操作。如果你想将一个文件从本地电脑拷贝到U盘时,你会触发一次文件系统的读写过程。大家知道,为了简化用户对文件的管理,操作系统提供了文件系统对数据资料进行了管理,文件系统是操作系统最为重要的组成部分。一旦你想往文件系统写入数据时,一个新的IO请求就会在用户态诞生,但是,其绝大部分的人生旅程都会在内核空间。对于不同的应用类型,IO请求的属性会大相径庭。除了文件本身应该具备的基本属性(读写权限等)之外,我们还需要考虑文件的访问模式:异步IO还是同步IO?对文件系统的Cache是如何控制的?应用程序和内核程序之间是如何交互的?所以,在创建一个IO时,我们需要考虑很多这样的因素。
我们知道,当我们需要进行文件操作的时候,5个API函数是必不可少的。Create,Open,Close,Write和Read函数实现了对文件的所有操作。Create函数用来打开一个文件,如果该文件不存在,那么需要在磁盘上创建该文件。Open函数用于打开一个指定的文件。如果在Open函数中指定O_CREATE标记,那么Open函数同样可以实现Create函数的功能。Close函数用于释放文件句柄。Write和Read函数用于实现文件的读写过程。举个例子,如果用户需要对一个文件进行写操作,那么首先调用Open函数打开想要操作的文件,函数完成之后获取所要操作文件的句柄;然后调用Write函数将数据写入文件;最后采用Close函数释放文件句柄,结束文件写入过程。上述过程大家应该都非常的熟悉,在上述过程中,整个系统到底发生了哪些操作呢?
打开文件
众所周知,用户态的API函数通过系统调用陷入内核。对于Open函数对应了sys_open函数例程。该函数的主要职责是查找指定文件的inode,然后在内核中生成对应的文件对象。在Linux中,Sys_open函数调用do_sys_open完成具体功能。在do_sys_open中通过do_filp_open函数完成文件名解析、inode对象查找,然后创建file对象,最后执行特定文件对应的file->open函数。Do_filp_open过程中的核心处理函数是link_path_walk。该函数完成了基本的文件路径的解析功能,是名字字符串解析处理实现的核心。该函数的实现基于分级解析处理的思想。例如,当需要解析“/dev/mapper/map0”字符串时,其首先需要判断从何处开始解析,根目录还是当前目录?这个例子是从根目录开始解析的,那么首先获取根目录的dentry对象并开始分析后继字符串。处理过程是以‘/’字符为界按序提取字符串。根据规则,首先我们可以提取“dev”字符串,并且计算该字符串的Hash值,通过该Hash值查找dentry下的inode Hash表,就可以很快的找到/dev/目录下的inode对象。Hash值的计算是比较简单的,把所有字符对应的值累加起来就可以得到一个Hash值。根据规则,依此类推,最后解析得到”/dev/mapper/”目录的inode对象以及文件名字符串“map0”。到这一步为止,link_path_walk函数的使命完成,最后可以通过do_last函数获取或者创建文件inode。如果用户态程序设置了O_CREATE标记,那么系统如果找不到用户指定的inode,do_last会创建一个新的文件inode,并且把这些信息以元数据的形式写入磁盘。当指定文件的inode找到之后,另一件很重要的事情就是初始化file文件对象。初始化文件对象通过__dentry_open函数来实现。文件对象通过inode参数进行初始化,并且把inode的操作方法函数集告诉给file对象。一旦file对象初始化成功之后,调用文件对象的open函数执行进一步的初始化工作。
通过上述分析,整个过程看似比较复杂,涉及到dentry,inode以及file对象。其实这个模型还是很简单的。Dentry用来描述文件目录,在磁盘上会采用元数据的方式存储在一个block中,文件目录本身在Linux中也是一个文件。Inode描述一个具体的文件,也通过元数据的方式在磁盘上保存。如果对一个文件系统从根目录开始往下看,整个文件系统是一颗庞大的inode树:
2.jpg
在打开一个文件的过程中,文件系统所要做的事情就是找到指定文件的inode,所以在这个过程中会有磁盘元数据读操作。一旦文件所属的inode被找到,那么需要在内存中初始化一个描述被打开文件的对象,这个对象就是file。所以,dentry,inode之类的信息在磁盘上是永久存储的,file对象是在内存中是临时存在的,它会随着文件的创建而生成,随着文件的关闭而消亡。
在Linux系统中文件类型是多种多样的,一个USB设备也是一个文件,一个普通的Word文档也是一个文件,一个RAID设备也是一个文件。虽然他们在系统中都是文件,但是,他们的操作方式是截然不同的。USB设备可能需要采用字符设备的方式和设备驱动交互;RAID设备可能需要采用块设备的方式和设备驱动进行交互;普通Word文件需要通过cache机制进行性能优化。所以,虽然都是文件,但是,文件表面下的这些设备是不相同的,需要采用的操作方法显然是截然不同的。作为一个通用的文件系统,如何封装不同的底层设备是需要考虑的问题。在Linux中,为了达到这个目的,推出了VFS概念。在VFS层次对用户接口进行了统一封装,并且实现了通用的文件操作功能。例如打开一个文件和关闭一个文件的操作都是相同的。在VFS下面会有针对不同需求的具体文件系统,例如针对Word文档可以采用EXT3文件系统进行操作,对于磁盘设备可以采用bdev块设备文件系统进行操作。在打开一个文件,对文件对象file进行初始化的时候,会将具体的文件系统操作方法关联到file->f_op和file->f_mapping对象。在后面的读写过程中,我们将会看到针对不同的文件类型,会采用不同的f_op和f_mapping方法。
读写文件
当一个文件被打开之后,用户态程序就可以得到一个文件对象,即文件句柄。一旦获取文件句柄之后就可以对其进行读写了。用户态的读写函数write对应内核空间的sys_write例程。通过系统调用可以陷入sys_write。Sys_write函数在VFS层做的工作及其有限,其会调用文件对象中指定的操作函数file->f_op->write。对于不同的文件系统,file->f_op->write指向的操作函数是不同的。对于EXT3文件系统而言,在文件inode初始化的时候会指定ext3_file_operations操作方法集。该方法集说明了EXT3文件系统的读写操作方法,说明如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const struct file_operations ext3_file_operations = {
.llseek= generic_file_llseek,
.read= do_sync_read,
.write= do_sync_write,
.aio_read= generic_file_aio_read,
.aio_write= ext3_file_write,
.ioctl= ext3_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl= ext3_compat_ioctl,
#endif
.mmap= generic_file_mmap,
.open= generic_file_open,
.release= ext3_release_file,
.fsync= ext3_sync_file,
.splice_read= generic_file_splice_read,
.splice_write= generic_file_splice_write,
};
如果文件设备是一个USB设备,并且采用的是字符设备的接口,那么在初始化文件inode的时候会调用init_special_inode初始化这些特殊的设备文件。对于字符设备会采用默认的def_chr_fops方法集,对于块设备会采用def_blk_fops方法集。不同的文件类型会调用各自的方法集。下面章节会对EXT3文件写和块设备文件写进行详细阐述。由于字符设备类型比较简单,在此进行简单说明。
Def_chr_fops方法集其实就定义了open方法,其它的方法都没有定义。其实字符设备的操作方法都需要字符设备驱动程序自己定义,每个设备驱动程序都需要定义自己的write、read、open和close方法,这些方法保存在字符设备对象中。当用户调用文件系统接口open函数打开指定字符设备文件时,VFS会通过上述讲述的sys_open函数找到设备文件inode中保存的def_chr_fops方法,并且执行该方法中的open函数(chrdev_open),chrdev_open函数完成的一个重要功能就是将文件对象file中采用的方法替换成驱动程序设定的设备操作方法。完成这个偷梁换柱的代码是:
1
filp->f_op = fops_get(p->ops)
一旦这个过程完成,后继用户程序通过文件系统的write方法都将会调用字符设备驱动程序设定的write方法。即对于字符设备文件而言,在VFS的sys_write函数将直接调用字符设备驱动程序的write方法。所以,对于字符设备驱动程序而言,整个过程很简单,用户态程序可以直接通过系统调用执行字符设备驱动程序的代码。而对于块设备和普通文件,这个过程将会复杂的多。
在用户程序发起写请求的时候,通常会考虑如下三个问题:第一个问题是用户态数据如何高效传递给内核?第二个问题是采用同步或者异步的方式执行IO请求。第三个问题是如果执行普通文件操作,需不需要文件Cache?
第一个问题是数据拷贝的问题。对于普通文件,如果采用了page cache机制,那么这种拷贝合并在很大程度上是避免不了的。但是对于网卡之类的设备,我们在读写数据的时候,需要避免这样的数据拷贝,否则数据传输效率将会变的很低。我第一次关注这个问题是在做本科毕业设计的时候,那时候我设计了一块PCI数据采集卡。在PCI采集卡上集成了4KB的FIFO,数据采集电路会将数据不断的压入FIFO,当FIFO半满的时候会对PCI主控芯片产生一个中断信号,通知PCI主控制器将FIFO中的2KB数据DMA至主机内存。CPU接收到这个中断信号之后,分配DMA内存,初始化DMA控制器,并且启动DMA操作,将2KB数据传输至内存。并且当DMA完成操作之后,会对CPU产生一个中断。板卡的设备驱动程序在接收到这个中断请求之后,面临一个重要的问题:如何将内核空间DMA过来的数据传输给用户空间?通常有两种方法:一种是直接将内核内存映射给用户程序;另一种是进行数据拷贝的方式。对于PCI数据采集卡而言,一个很重要的特性是实时数据采集,在板卡硬件FIFO很小的情况下,如果主机端的数据传输、处理耗费太多的时间,那么整条IO流水线将无法运转,导致FIFO溢出,数据采集出现漏点的情况。所以,为了避免这样的情况,在这些很严格应用的场合只能采用内存映射的方法,从而实现数据在操作系统层面的零拷贝。在Linux中,我们可以采用memory map的方法将内核空间内存映射给用户程序,从而实现用户程序对内核内存的直接访问。在Windows操作系统中,这种内核空间和用户空间的数据交互方式定义成两种:Map IO和Direct IO。Map IO就是采用内存拷贝的方式,Direct IO就是采用MDL内存映射的方式。在编写WDM Windows设备驱动程序的时候经常会用到这两种数据传输模式。值得注意的是,Windows中的Direct IO和Linux中的Direct IO是完全不同的两个概念。在Linux中Direct IO是指写穿page cache的一种IO方法。
第二个问题是异步IO和同步IO的问题。对于普通文件而言,为了提高效率,通常会采用page cache对文件数据在内存进行缓存。Cache虽然提高了效率,但是有些应用一旦发出写请求,并且执行完毕之后,其期望是将数据写入磁盘,而不是内存。例如,有些应用会有一些元数据操作,在元数据操作的过程中,通常期望将数据直接刷新至磁盘,而不是Cache在内存。这就提出了同步IO的需求。为了达到这个效果,可以在打开文件的时候设置O_SYNC标记。当数据在page cache中聚合之后,如果发现O_SYNC标记被设置,那么就会将page cache中的数据强制的刷新到磁盘。对于EXT3文件系统,该过程在ext3_file_write函数中实现。
第三个问题是普通文件的cache问题。对于普通文件,由于磁盘性能比较低,为了提高读写性能,通常会采用内存作为磁盘的cache。文件系统会采用预读等机制对文件读写性能进行优化,避免磁盘随机IO性能过低对文件读写性能造成影响。但是,page cache虽然提高了性能,但是也会对文件系统的可靠性造成一定影响。例如,当数据已经被写入内存之后,系统Crash,内存中的磁盘数据将会遭到破坏。为了避免这种情况,Linux文件系统提供了Direct IO的IO方式。该方式就是让一次IO过程绕过page cache机制,直接将文件内容刷新到磁盘。与上面的同步IO相比,Direct IO达到的效果似乎有点类似。其实,同步IO是一种write through的Cache机制,而Direct IO是完全把Cache抛弃了。同步IO的数据在内存还是有镜像的,而Direct IO是没有的,这是两者的区别。在Linux中的__generic_file_aio_write_nolock函数中,会判断O_DIRECT标记是否被设置,如果该标记被设置,那么调用generic_file_direct_write函数完成数据磁盘写入过程。如果该标记不存在,那么调用generic_file_buffered_write函数将数据写入page cache。
↧
↧
TCP连接的状态详解以及故障排查
我们通过了解TCP各个状态,可以排除和定位网络或系统故障时大有帮助。(总结网络上的内容)
1、TCP状态
了解TCP之前,先了解几个命令:
linux查看tcp的状态命令:
1)、netstat -nat 查看TCP各个状态的数量
2)、lsof -i:port 可以检测到打开套接字的状况
3)、 sar -n SOCK 查看tcp创建的连接数
4)、tcpdump -iany tcp port 9000 对tcp端口为9000的进行抓包
网络测试常用命令;
1)ping:检测网络连接的正常与否,主要是测试延时、抖动、丢包率。
但是很多服务器为了防止攻击,一般会关闭对ping的响应。所以ping一般作为测试连通性使用。ping命令后,会接收到对方发送的回馈信息,其中记录着对方的IP地址和TTL。TTL是该字段指定IP包被路由器丢弃之前允许通过的最大网段数量。TTL是IPv4包头的一个8 bit字段。例如IP包在服务器中发送前设置的TTL是64,你使用ping命令后,得到服务器反馈的信息,其中的TTL为56,说明途中一共经过了8道路由器的转发,每经过一个路由,TTL减1。
2)traceroute:raceroute 跟踪数据包到达网络主机所经过的路由工具
traceroute hostname
3)pathping:是一个路由跟踪工具,它将 ping 和 tracert 命令的功能与这两个工具所不提供的其他信息结合起来,综合了二者的功能
pathping www.baidu.com
4)mtr:以结合ping nslookup tracert 来判断网络的相关特性
5) nslookup:用于解析域名,一般用来检测本机的DNS设置是否配置正确。
LISTENING:侦听来自远方的TCP端口的连接请求.
首先服务端需要打开一个socket进行监听,状态为LISTEN。
有提供某种服务才会处于LISTENING状态,TCP状态变化就是某个端口的状态变化,提供一个服务就打开一个端口,例如:提供www服务默认开的是80端口,提供ftp服务默认的端口为21,当提供的服务没有被连接时就处于LISTENING状态。FTP服务启动后首先处于侦听(LISTENING)状态。处于侦听LISTENING状态时,该端口是开放的,等待连接,但还没有被连接。就像你房子的门已经敞开的,但还没有人进来。
看LISTENING状态最主要的是看本机开了哪些端口,这些端口都是哪个程序开的,关闭不必要的端口是保证安全的一个非常重要的方面,服务端口都对应一个服务(应用程序),停止该服务就关闭了该端口,例如要关闭21端口只要停止IIS服务中的FTP服务即可。关于这方面的知识请参阅其它文章。
如果你不幸中了服务端口的木马,木马也开个端口处于LISTENING状态。
SYN-SENT:客户端SYN_SENT状态:
再发送连接请求后等待匹配的连接请求:客户端通过应用程序调用connect进行active open.于是客户端tcp发送一个SYN以请求建立一个连接.之后状态置为SYN_SENT. /*The socket is actively attempting to establish a connection. 在发送连接请求后等待匹配的连接请求 */
当请求连接时客户端首先要发送同步信号给要访问的机器,此时状态为SYN_SENT,如果连接成功了就变为ESTABLISHED,正常情况下SYN_SENT状态非常短暂。例如要访问网站http://www.baidu.com,如果是正常连接的话,用TCPView观察IEXPLORE.EXE(IE)建立的连接会发现很快从SYN_SENT变为ESTABLISHED,表示连接成功。SYN_SENT状态快的也许看不到。
如果发现有很多SYN_SENT出现,那一般有这么几种情况,一是你要访问的网站不存在或线路不好,二是用扫描软件扫描一个网段的机器,也会出出现很多SYN_SENT,另外就是可能中了病毒了,例如中了"冲击波",病毒发作时会扫描其它机器,这样会有很多SYN_SENT出现。
SYN-RECEIVED:服务器端状态SYN_RCVD
再收到和发送一个连接请求后等待对方对连接请求的确认
当服务器收到客户端发送的同步信号时,将标志位ACK和SYN置1发送给客户端,此时服务器端处于SYN_RCVD状态,如果连接成功了就变为ESTABLISHED,正常情况下SYN_RCVD状态非常短暂。
如果发现有很多SYN_RCVD状态,那你的机器有可能被SYN Flood的DoS(拒绝服务攻击)攻击了。
SYN Flood的攻击原理是:
在进行三次握手时,攻击软件向被攻击的服务器发送SYN连接请求(握手的第一步),但是这个地址是伪造的,如攻击软件随机伪造了51.133.163.104、65.158.99.152等等地址。服务器在收到连接请求时将标志位ACK和SYN置1发送给客户端(握手的第二步),但是这些客户端的IP地址都是伪造的,服务器根本找不到客户机,也就是说握手的第三步不可能完成。
这种情况下服务器端一般会重试(再次发送SYN+ACK给客户端)并等待一段时间后丢弃这个未完成的连接,这段时间的长度我们称为SYN Timeout,一般来说这个时间是分钟的数量级(大约为30秒-2分钟);一个用户出现异常导致服务器的一个线程等待1分钟并不是什么很大的问题,但如果有一个恶意的攻击者大量模拟这种情况,服务器端将为了维护一个非常大的半连接列表而消耗非常多的资源----数以万计的半连接,即使是简单的保存并遍历也会消耗非常多的CPU时间和内存,何况还要不断对这个列表中的IP进行SYN+ACK的重试。此时从正常客户的角度看来,服务器失去响应,这种情况我们称做:服务器端受到了SYN Flood攻击(SYN洪水攻击)
ESTABLISHED:代表一个打开的连接。
ESTABLISHED状态是表示两台机器正在传输数据,观察这个状态最主要的就是看哪个程序正在处于ESTABLISHED状态。
服务器出现很多ESTABLISHED状态: netstat -nat |grep 9502或者使用lsof -i:9502可以检测到。
当客户端未主动close的时候就断开连接:即客户端发送的FIN丢失或未发送。
这时候若客户端断开的时候发送了FIN包,则服务端将会处于CLOSE_WAIT状态;
这时候若客户端断开的时候未发送FIN包,则服务端处还是显示ESTABLISHED状态;
结果客户端重新连接服务器。
而新连接上来的客户端(也就是刚才断掉的重新连上来了)在服务端肯定是ESTABLISHED; 如果客户端重复的上演这种情况,那么服务端将会出现大量的假的ESTABLISHED连接和CLOSE_WAIT连接。
最终结果就是新的其他客户端无法连接上来,但是利用netstat还是能看到一条连接已经建立,并显示ESTABLISHED,但始终无法进入程序代码。
FIN-WAIT-1:等待远程TCP连接中断请求,或先前的连接中断请求的确认
主动关闭(active close)端应用程序调用close,于是其TCP发出FIN请求主动关闭连接,之后进入FIN_WAIT1状态./* The socket is closed, and the connection is shutting down. 等待远程TCP的连接中断请求,或先前的连接中断请求的确认 */
如果服务器出现shutdown再重启,使用netstat -nat查看,就会看到很多FIN-WAIT-1的状态。就是因为服务器当前有很多客户端连接,直接关闭服务器后,无法接收到客户端的ACK。
FIN-WAIT-2:从远程TCP等待连接中断请求
主动关闭端接到ACK后,就进入了FIN-WAIT-2 ./* Connection is closed, and the socket is waiting for a shutdown from the remote end. 从远程TCP等待连接中断请求 */
这就是著名的半关闭的状态了,这是在关闭连接时,客户端和服务器两次握手之后的状态。在这个状态下,应用程序还有接受数据的能力,但是已经无法发送数据,但是也有一种可能是,客户端一直处于FIN_WAIT_2状态,而服务器则一直处于WAIT_CLOSE状态,而直到应用层来决定关闭这个状态。
CLOSE-WAIT:等待从本地用户发来的连接中断请求
被动关闭(passive close)端TCP接到FIN后,就发出ACK以回应FIN请求(它的接收也作为文件结束符传递给上层应用程序),并进入CLOSE_WAIT. /* The remote end has shut down, waiting for the socket to close. 等待从本地用户发来的连接中断请求 */
CLOSING:等待远程TCP对连接中断的确认
比较少见./* Both sockets are shut down but we still don't have all our data
sent. 等待远程TCP对连接中断的确认 */
LAST-ACK:等待原来的发向远程TCP的连接中断请求的确认
被动关闭端一段时间后,接收到文件结束符的应用程序将调用CLOSE关闭连接。这导致它的TCP也发送一个 FIN,等待对方的ACK.就进入了LAST-ACK
. /* The remote end has shut down, and the socket is closed. Waiting for acknowledgement. 等待原来发向远程TCP的连接中断请求的确认
*/
使用并发压力测试的时候,突然断开压力测试客户端,服务器会看到很多LAST-ACK。
TIME-WAIT:等待足够的时间以确保远程TCP接收到连接中断请求的确认
在主动关闭端接收到FIN后,TCP就发送ACK包,并进入TIME-WAIT状态。/*
The socket is waiting after close to handle
packets still in the network.等待足够的时间以确保远程TCP接收到连接中断请求的确认 */
TIME_WAIT等待状态,这个状态又叫做2MSL状态,说的是在TIME_WAIT2发送了最后一个ACK数据报以后,要进入TIME_WAIT状态,这个状态是防止最后一次握手的数据报没有传送到对方那里而准备的(注意这不是四次握手,这是第四次握手的保险状态)。这个状态在很大程度上保证了双方都可以正常结束,但是,问题也来了。
由于插口的2MSL状态(插口是IP和端口对的意思,socket),使得应用程序在2MSL时间内是无法再次使用同一个插口的,对于客户程序还好一些,但是对于服务程序,例如httpd,它总是要使用同一个端口来进行服务,而在2MSL时间内,启动httpd就会出现错误(插口被使用)。为了避免这个错误,服务器给出了一个平静时间的概念,这是说在2MSL时间内,虽然可以重新启动服务器,但是这个服务器还是要平静的等待2MSL时间的过去才能进行下一次连接。
详情请看:TIME_WAIT引起Cannot assign requested address报错
CLOSED:没有任何连接状态
被动关闭端在接受到ACK包后,就进入了closed的状态。连接结束./* The socket is not being used. 没有任何连接状态
*/
2、TCP状态迁移路线图
client/server两条路线讲述TCP状态迁移路线图:
这是一个看起来比较复杂的状态迁移图,因为它包含了两个部分---服务器的状态迁移和客户端的状态迁移,如果从某一个角度出发来看这个图,就会清晰许多,这里面的服务器和客户端都不是绝对的,发送数据的就是客户端,接受数据的就是服务器。
客户端应用程序的状态迁移图
客户端的状态可以用如下的流程来表示:
CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED
以上流程是在程序正常的情况下应该有的流程,从书中的图中可以看到,在建立连接时,当客户端收到SYN报文的ACK以后,客户端就打开了数据交互地连接。而结束连接则通常是客户端主动结束的,客户端结束应用程序以后,需要经历FIN_WAIT_1,FIN_WAIT_2等状态,这些状态的迁移就是前面提到的结束连接的四次握手。
服务器的状态迁移图
服务器的状态可以用如下的流程来表示:
CLOSED->LISTEN->SYN收到->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED
在建立连接的时候,服务器端是在第三次握手之后才进入数据交互状态,而关闭连接则是在关闭连接的第二次握手以后(注意不是第四次)。而关闭以后还要等待客户端给出最后的ACK包才能进入初始的状态。
其他状态迁移
还有一些其他的状态迁移,这些状态迁移针对服务器和客户端两方面的总结如下
LISTEN->SYN_SENT,对于这个解释就很简单了,服务器有时候也要打开连接的嘛。
SYN_SENT->SYN收到,服务器和客户端在SYN_SENT状态下如果收到SYN数据报,则都需要发送SYN的ACK数据报并把自己的状态调整到SYN收到状态,准备进入ESTABLISHED
SYN_SENT->CLOSED,在发送超时的情况下,会返回到CLOSED状态。
SYN_收到->LISTEN,如果受到RST包,会返回到LISTEN状态。
SYN_收到->FIN_WAIT_1,这个迁移是说,可以不用到ESTABLISHED状态,而可以直接跳转到FIN_WAIT_1状态并等待关闭。
怎样牢牢地将这张图刻在脑中呢?那么你就一定要对这张图的每一个状态,及转换的过程有深刻的认识,不能只停留在一知半解之中。下面对这张图的11种状态详细解析一下,以便加强记忆!不过在这之前,先回顾一下TCP建立连接的三次握手过程,以及关闭连接的四次握手过程。
3、TCP连接建立三次握手
TCP是一个面向连接的协议,所以在连接双方发送数据之前,都需要首先建立一条连接。
Client连接Server:
当Client端调用socket函数调用时,相当于Client端产生了一个处于Closed状态的套接字。
( 1) 第一次握手:Client端又调用connect函数调用,系统为Client随机分配一个端口,连同传入connect中的参数(Server的IP和端口),这就形成了一个连接四元组,客户端发送一个带SYN标志的TCP报文到服务器。这是三次握手过程中的报文1。connect调用让Client端的socket处于SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。
( 2)第二次握手: 服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
( 3) 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户器和客务器进入ESTABLISHED状态,完成三次握手。连接已经可以进行读写操作。
一个完整的三次握手也就是: 请求---应答---再次确认。
TCP协议通过三个报文段完成连接的建立,这个过程称为三次握手(three-way handshake),过程如下图所示。
对应的函数接口:
2)Server
当Server端调用socket函数调用时,相当于Server端产生了一个处于Closed状态的监听套接字
Server端调用bind操作,将监听套接字与指定的地址和端口关联,然后又调用listen函数,系统会为其分配未完成队列和完成队列,此时的监听套接字可以接受Client的连接,监听套接字状态处于LISTEN状态。
当Server端调用accept操作时,会从完成队列中取出一个已经完成的client连接,同时在server这段会产生一个会话套接字,用于和client端套接字的通信,这个会话套接字的状态是ESTABLISH。
从图中可以看出,当客户端调用connect时,触发了连接请求,向服务器发送了SYN J包,这时connect进入阻塞状态;服务器监听到连接请求,即收到SYN J包,调用accept函数接收请求向客户端发送SYN K ,ACK J+1,这时accept进入阻塞状态;客户端收到服务器的SYN K ,ACK J+1之后,这时connect返回,并对SYN K进行确认;服务器收到ACK K+1时,accept返回,至此三次握手完毕,连接建立。
我们可以通过网络抓包的查看具体的流程:
比如我们服务器开启9502的端口。使用tcpdump来抓包:
tcpdump -iany tcp port 9502
然后我们使用telnet 127.0.0.1 9502开连接.:
telnet 127.0.0.1 9502
14:12:45.104687 IP localhost.39870 > localhost.9502: Flags [S], seq 2927179378, win 32792, options [mss 16396,sackOK,TS val 255474104 ecr 0,nop,wscale 3], length 0(1)
14:12:45.104701 IP localhost.9502 > localhost.39870: Flags [S.], seq 1721825043, ack 2927179379, win 32768, options [mss 16396,sackOK,TS val 255474104 ecr 255474104,nop,wscale 3], length 0 (2)
14:12:45.104711 IP localhost.39870 > localhost.9502: Flags [.], ack 1, win 4099, options [nop,nop,TS val 255474104 ecr 255474104], length 0 (3)
14:13:01.415407 IP localhost.39870 > localhost.9502: Flags [P.], seq 1:8, ack 1, win 4099, options [nop,nop,TS val 255478182 ecr 255474104], length 7
14:13:01.415432 IP localhost.9502 > localhost.39870: Flags [.], ack 8, win 4096, options [nop,nop,TS val 255478182 ecr 255478182], length 0
14:13:01.415747 IP localhost.9502 > localhost.39870: Flags [P.], seq 1:19, ack 8, win 4096, options [nop,nop,TS val 255478182 ecr 255478182], length 18
14:13:01.415757 IP localhost.39870 > localhost.9502: Flags [.], ack 19, win 4097, options [nop,nop,TS val 255478182 ecr 255478182], length 0
我们看到 (1)(2)(3)三步是建立tcp:
第一次握手:
14:12:45.104687 IP localhost.39870 > localhost.9502: Flags [S], seq 2927179378
客户端IP localhost.39870 (客户端的端口一般是自动分配的) 向服务器localhost.9502 发送syn包(syn=j)到服务器》
syn的seq= 2927179378
第二次握手:
14:12:45.104701 IP localhost.9502 > localhost.39870: Flags [S.], seq 1721825043, ack 2927179379,
服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包
SYN(ack=j+1)=ack 2927179379 服务器主机SYN包(syn=seq 1721825043)
第三次握手:
14:12:45.104711 IP localhost.39870 > localhost.9502: Flags [.], ack 1,
客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1)
客户端和服务器进入ESTABLISHED状态后,可以进行通信数据交互。此时和accept接口没有关系,即使没有accepte,也进行3次握手完成。
连接出现连接不上的问题,一般是网路出现问题或者网卡超负荷或者是连接数已经满啦。
紫色背景的部分:
IP localhost.39870 > localhost.9502: Flags [P.], seq 1:8, ack 1, win 4099, options [nop,nop,TS val 255478182 ecr 255474104], length 7
客户端向服务器发送长度为7个字节的数据,
IP localhost.9502 > localhost.39870: Flags [.], ack 8, win 4096, options [nop,nop,TS val 255478182 ecr 255478182], length 0
服务器向客户确认已经收到数据
IP localhost.9502 > localhost.39870: Flags [P.], seq 1:19, ack 8, win 4096, options [nop,nop,TS val 255478182 ecr 255478182], length 18
然后服务器同时向客户端写入数据。
IP localhost.39870 > localhost.9502: Flags [.], ack 19, win 4097, options [nop,nop,TS val 255478182 ecr 255478182], length 0
客户端向服务器确认已经收到数据
这个就是tcp可靠的连接,每次通信都需要对方来确认。
4. TCP连接的终止(四次握手释放)
由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
建立一个连接需要三次握手,而终止一个连接要经过四次握手,这是由TCP的半关闭(half-close)造成的,如图:
(1)客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送(报文段4)。
(2)服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1(报文段5)。和SYN一样,一个FIN将占用一个序号。
(3)服务器B关闭与客户端A的连接,发送一个FIN给客户端A(报文段6)。
(4)客户端A发回ACK报文确认,并将确认序号设置为收到序号加1(报文段7)。
对应函数接口如图:
调用过程如下:
1) 当client想要关闭它与server之间的连接。client(某个应用进程)首先调用close主动关闭连接,这时TCP发送一个FIN M;client端处于FIN_WAIT1状态。
2) 当server端接收到FIN M之后,执行被动关闭。对这个FIN进行确认,返回给client ACK。当server端返回给client ACK后,client处于FIN_WAIT2状态,server处于CLOSE_WAIT状态。它的接收也作为文件结束符传递给应用进程,因为FIN的接收 意味着应用进程在相应的连接上再也接收不到额外数据;
3) 一段时间之后,当server端检测到client端的关闭操作(read返回为0)。接收到文件结束符的server端调用close关闭它的socket。这导致server端的TCP也发送一个FIN N;此时server的状态为LAST_ACK。
4) 当client收到来自server的FIN后 。 client端的套接字处于TIME_WAIT状态,它会向server端再发送一个ack确认,此时server端收到ack确认后,此套接字处于CLOSED状态。
这样每个方向上都有一个FIN和ACK。
1.为什么建立连接协议是三次握手,而关闭连接却是四次握手呢?
这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的建连请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。
2.为什么TIME_WAIT状态还需要等2MSL后才能返回到CLOSED状态?
这是因为虽然双方都同意关闭连接了,而且握手的4个报文也都协调和发送完毕,按理可以直接回到CLOSED状态(就好比从SYN_SEND状态到ESTABLISH状态那样):
一方面是可靠的实现TCP全双工连接的终止,也就是当最后的ACK丢失后,被动关闭端会重发FIN,因此主动关闭端需要维持状态信息,以允许它重新发送最终的ACK。
另一方面,但是因为我们必须要假想网络是不可靠的,你无法保证你最后发送的ACK报文会一定被对方收到,因此对方处于LAST_ACK状态下的SOCKET可能会因为超时未收到ACK报文,而重发FIN报文,所以这个TIME_WAIT状态的作用就是用来重发可能丢失的ACK报文。
TCP在2MSL等待期间,定义这个连接(4元组)不能再使用,任何迟到的报文都会丢弃。设想如果没有2MSL的限制,恰好新到的连接正好满足原先的4元组,这时候连接就可能接收到网络上的延迟报文就可能干扰最新建立的连接。
3、发现系统存在大量TIME_WAIT状态的连接,可以通过调整内核参数解决:vi /etc/sysctl.conf 加入以下内容:
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30
然后执行 /sbin/sysctl -p 让参数生效。
net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
net.ipv4.tcp_fin_timeout 修改系統默认的 TIMEOUT 时间
5、同时打开
两个应用程序同时执行主动打开的情况是可能的,虽然发生的可能性较低。每一端都发送一个SYN,并传递给对方,且每一端都使用对端所知的端口作为本地端口。例如:
主机a中一应用程序使用7777作为本地端口,并连接到主机b 8888端口做主动打开。
主机b中一应用程序使用8888作为本地端口,并连接到主机a 7777端口做主动打开。
tcp协议在遇到这种情况时,只会打开一条连接。
这个连接的建立过程需要4次数据交换,而一个典型的连接建立只需要3次交换(即3次握手)
但多数伯克利版的tcp/ip实现并不支持同时打开。
6、同时关闭
如果应用程序同时发送FIN,则在发送后会首先进入FIN_WAIT_1状态。在收到对端的FIN后,回复一个ACK,会进入CLOSING状态。在收到对端的ACK后,进入TIME_WAIT状态。这种情况称为同时关闭。
同时关闭也需要有4次报文交换,与典型的关闭相同。
7. TCP通信中服务器处理客户端意外断开
引用地址:http://blog.csdn.net/kkkkkxiaofei/article/details/12966407
如果TCP连接被对方正常关闭,也就是说,对方是正确地调用了closesocket(s)或者shutdown(s)的话,那么上面的Recv或Send调用就能马上返回,并且报错。这是由于close socket(s)或者shutdown(s)有个正常的关闭过程,会告诉对方“TCP连接已经关闭,你不需要再发送或者接受消息了”。
但是,如果意外断开,客户端(3g的移动设备)并没有正常关闭socket。双方并未按照协议上的四次挥手去断开连接。
那么这时候正在执行Recv或Send操作的一方就会因为没有任何连接中断的通知而一直等待下去,也就是会被长时间卡住。
像这种如果一方已经关闭或异常终止连接,而另一方却不知道,我们将这样的TCP连接称为半打开的。
解决意外中断办法都是利用保活机制。而保活机制分又可以让底层实现也可自己实现。
1、自己编写心跳包程序
简单的说也就是在自己的程序中加入一条线程,定时向对端发送数据包,查看是否有ACK,如果有则连接正常,没有的话则连接断开
2、启动TCP编程里的keepAlive机制
一、双方拟定心跳(自实现)
一般由客户端发送心跳包,服务端并不回应心跳,只是定时轮询判断一下与上次的时间间隔是否超时(超时时间自己设定)。服务器并不主动发送是不想增添服务器的通信量,减少压力。
但这会出现三种情况:
情况1.
客户端由于某种网络延迟等原因很久后才发送心跳(它并没有断),这时服务器若利用自身设定的超时判断其已经断开,而后去关闭socket。若客户端有重连机制,则客户端会重新连接。若不确定这种方式是否关闭了原本正常的客户端,则在ShutDown的时候一定要选择send,表示关闭发送通道,服务器还可以接收一下,万一客户端正在发送比较重要的数据呢,是不?
情况2.
客户端很久没传心跳,确实是自身断掉了。在其重启之前,服务端已经判断出其超时,并主动close,则四次挥手成功交互。
情况3.
客户端很久没传心跳,确实是自身断掉了。在其重启之前,服务端的轮询还未判断出其超时,在未主动close的时候该客户端已经重新连接。
这时候若客户端断开的时候发送了FIN包,则服务端将会处于CLOSE_WAIT状态;
这时候若客户端断开的时候未发送FIN包,则服务端处还是显示ESTABLISHED状态;
而新连接上来的客户端(也就是刚才断掉的重新连上来了)在服务端肯定是ESTABLISHED;这时候就有个问题,若利用轮询还未检测出上条旧连接已经超时(这很正常,timer总有个间隔吧),而在这时,客户端又重复的上演情况3,那么服务端将会出现大量的假的ESTABLISHED连接和CLOSE_WAIT连接。
最终结果就是新的其他客户端无法连接上来,但是利用netstat还是能看到一条连接已经建立,并显示ESTABLISHED,但始终无法进入程序代码。个人最初感觉导致这种情况是因为假的ESTABLISHED连接和CLOSE_WAIT连接会占用较大的系统资源,程序无法再次创建连接(因为每次我发现这个问题的时候我只连了10个左右客户端却已经有40多条无效连接)。而最近几天测试却发现有一次程序内只连接了2,3个设备,但是有8条左右的虚连接,此时已经连接不了新客户端了。这时候我就觉得我想错了,不可能这几条连接就占用了大量连接把,如果说几十条还有可能。但是能肯定的是,这个问题的产生绝对是设备在不停的重启,而服务器这边又是简单的轮询,并不能及时处理,暂时还未能解决。
二、利用KeepAlive
其实keepalive的原理就是TCP内嵌的一个心跳包,
以服务器端为例,如果当前server端检测到超过一定时间(默认是 7,200,000 milliseconds,也就是2个小时)没有数据传输,那么会向client端发送一个keep-alive packet(该keep-alive packet就是ACK和当前TCP序列号减一的组合),此时client端应该为以下三种情况之一:
1. client端仍然存在,网络连接状况良好。此时client端会返回一个ACK。server端接收到ACK后重置计时器(复位存活定时器),在2小时后再发送探测。如果2小时内连接上有数据传输,那么在该时间基础上向后推延2个小时。
2. 客户端异常关闭,或是网络断开。在这两种情况下,client端都不会响应。服务器没有收到对其发出探测的响应,并且在一定时间(系统默认为1000 ms)后重复发送keep-alive packet,并且重复发送一定次数(2000 XP 2003 系统默认为5次, Vista后的系统默认为10次)。
3. 客户端曾经崩溃,但已经重启。这种情况下,服务器将会收到对其存活探测的响应,但该响应是一个复位,从而引起服务器对连接的终止。
对于应用程序来说,2小时的空闲时间太长。因此,我们需要手工开启Keepalive功能并设置合理的Keepalive参数。
全局设置可更改/etc/sysctl.conf,加上:
net.ipv4.tcp_keepalive_intvl = 20
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_time = 60
在程序中设置如下:
[cpp] view plain copy print?
#include
#include
#include
#include
#include
int keepAlive = 1; // 开启keepalive属性
int keepIdle = 60; // 如该连接在60秒内没有任何数据往来,则进行探测
int keepInterval = 5; // 探测时发包的时间间隔为5 秒
int keepCount = 3; // 探测尝试的次数.如果第1次探测包就收到响应了,则后2次的不再发.
setsockopt(rs, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive));
setsockopt(rs, SOL_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle));
setsockopt(rs, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));
setsockopt(rs, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));
在程序中表现为,当tcp检测到对端socket不再可用时(不能发出探测包,或探测包没有收到ACK的响应包),select会返回socket可读,并且在recv时返回-1,同时置上errno为ETIMEDOUT.
8. Linux错误信息(errno)列表
经常出现的错误:
22:参数错误,比如ip地址不合法,没有目标端口等
101:网络不可达,比如不能ping通
111:链接被拒绝,比如目标关闭链接等
115:当链接设置为非阻塞时,目标没有及时应答,返回此错误,socket可以继续使用。比如socket连接
附录:Linux的错误码表(errno table)
_ 124 EMEDIUMTYPE_ Wrong medium type
_ 123 ENOMEDIUM__ No medium found
_ 122 EDQUOT___ Disk quota exceeded
_ 121 EREMOTEIO__ Remote I/O error
_ 120 EISNAM___ Is a named type file
_ 119 ENAVAIL___ No XENIX semaphores available
_ 118 ENOTNAM___ Not a XENIX named type file
_ 117 EUCLEAN___ Structure needs cleaning
_ 116 ESTALE___ Stale NFS file handle
_ 115 EINPROGRESS +Operation now in progress
操作正在进行中。一个阻塞的操作正在执行。
_ 114 EALREADY__ Operation already in progress
_ 113 EHOSTUNREACH No route to host
_ 112 EHOSTDOWN__ Host is down
_ 111 ECONNREFUSED Connection refused
1、拒绝连接。一般发生在连接建立时。
拔服务器端网线测试,客户端设置keep alive时,recv较快返回0, 先收到ECONNREFUSED (Connection refused)错误码,其后都是ETIMEOUT。
2、an error returned from connect(), so it can only occur in a client (if a client is defined as the party that initiates the connection
_ 110 ETIMEDOUT_ +Connection timed out
_ 109 ETOOMANYREFS Too many references: cannot splice
_ 108 ESHUTDOWN__ Cannot send after transport endpoint shutdown
_ 107 ENOTCONN__ Transport endpoint is not connected
在一个没有建立连接的socket上,进行read,write操作会返回这个错误。出错的原因是socket没有标识地址。Setsoc也可能会出错。
还有一种情况就是收到对方发送过来的RST包,系统已经确认连接被断开了。
_ 106 EISCONN___ Transport endpoint is already connected
一般是socket客户端已经连接了,但是调用connect,会引起这个错误。
_ 105 ENOBUFS___ No buffer space available
_ 104 ECONNRESET_ Connection reset by peer
连接被远程主机关闭。有以下几种原因:远程主机停止服务,重新启动;当在执行某些操作时遇到失败,因为设置了“keep alive”选项,连接被关闭,一般与ENETRESET一起出现。
1、在客户端服务器程序中,客户端异常退出,并没有回收关闭相关的资源,服务器端会先收到ECONNRESET错误,然后收到EPIPE错误。
2、连接被远程主机关闭。有以下几种原因:远程主机停止服务,重新启动;当在执行某些操作时遇到失败,因为设置了“keep alive”选项,连接被关闭,一般与ENETRESET一起出现。
3、远程端执行了一个“hard”或者“abortive”的关闭。应用程序应该关闭socket,因为它不再可用。当执行在一个UDP socket上时,这个错误表明前一个send操作返回一个ICMP“port unreachable”信息。
4、如果client关闭连接,server端的select并不出错(不返回-1,使用select对唯一一个socket进行non- blocking检测),但是写该socket就会出错,用的是send.错误号:ECONNRESET.读(recv)socket并没有返回错误。
5、该错误被描述为“connection reset by peer”,即“对方复位连接”,这种情况一般发生在服务进程较客户进程提前终止。
主动关闭调用过程如下:
服务器端主动关闭:
1)当服务器的服务因为某种原因,进程提前终止时会向客户 TCP 发送 FIN 分节,服务器端处于FIN_WAIT1状态。
2)客户TCP回应ACK后,服务TCP将转入FIN_WAIT2状态。
3)此时如果客户进程没有处理该 FIN (如阻塞在其它调用上而没有关闭 Socket 时),则客户TCP将处于CLOSE_WAIT状态。
4)当客户进程再次向 FIN_WAIT2 状态的服务 TCP 发送数据时,则服务 TCP 将立刻响应 RST。
一般来说,这种情况还可以会引发另外的应用程序异常,客户进程在发送完数据后,往往会等待从网络IO接收数据,很典型的如 read 或 readline 调用,此时由于执行时序的原因,如果该调用发生在RST分节收到前执行的话,那么结果是客户进程会得到一个非预期的 EOF 错误。此时一般会输出“server terminated prematurely”-“服务器过早终止”错误。
_ 103 ECONNABORTED Software caused connection abort
1、软件导致的连接取消。一个已经建立的连接被host方的软件取消,原因可能是数据传输超时或者是协议错误。
2、该错误被描述为“software caused connection abort”,即“软件引起的连接中止”。原因在于当服务和客户进程在完成用于 TCP 连接的“三次握手”后,客户 TCP 却发送了一个 RST (复位)分节,在服务进程看来,就在该连接已由 TCP 排队,等着服务进程调用 accept 的时候 RST 却到达了。POSIX 规定此时的 errno 值必须 ECONNABORTED。源自 Berkeley 的实现完全在内核中处理中止的连接,服务进程将永远不知道该中止的发生。服务器进程一般可以忽略该错误,直接再次调用accept。
当TCP协议接收到RST数据段,表示连接出现了某种错误,函数read将以错误返回,错误类型为ECONNERESET。并且以后所有在这个套接字上的读操作均返回错误。错误返回时返回值小于0。
_ 102 ENETRESET__ Network dropped connection on reset
网络重置时丢失连接。
由于设置了"keep-alive"选项,探测到一个错误,连接被中断。在一个已经失败的连接上试图使用setsockopt操作,也会返回这个错误。
_ 101 ENETUNREACH_ Network is unreachable
网络不可达。Socket试图操作一个不可达的网络。这意味着local的软件知道没有路由到达远程的host。
_ 100 ENETDOWN__ Network is down
_ 99 EADDRNOTAVAIL Cannot assign requested address
_ 98 EADDRINUSE_ Address already in use
_ 97 EAFNOSUPPORT Address family not supported by protocol
_ 96 EPFNOSUPPORT Protocol family not supported
_ 95 EOPNOTSUPP_ Operation not supported
_ 94 ESOCKTNOSUPPORT Socket type not supported
Socket类型不支持。指定的socket类型在其address family中不支持。如可选选中选项SOCK_RAW,但实现并不支持SOCK_RAW sockets。
_ 93 EPROTONOSUPPORT Protocol not supported
不支持的协议。系统中没有安装标识的协议,或者是没有实现。如函数需要SOCK_DGRAM socket,但是标识了stream protocol.。
_ 92 ENOPROTOOPT_ Protocol not available
该错误不是一个 Socket 连接相关的错误。errno 给出该值可能由于,通过 getsockopt 系统调用来获得一个套接字的当前选项状态时,如果发现了系统不支持的选项参数就会引发该错误。
_ 91 EPROTOTYPE_ Protocol wrong type for socket
协议类型错误。标识了协议的Socket函数在不支持的socket上进行操作。如ARPA Internet
UDP协议不能被标识为SOCK_STREAM socket类型。
_ 90 EMSGSIZE__ +Message too long
消息体太长。
发送到socket上的一个数据包大小比内部的消息缓冲区大,或者超过别的网络限制,或是用来接收数据包的缓冲区比数据包本身小。
_ 89 EDESTADDRREQ Destination address required
需要提供目的地址。
在一个socket上的操作需要提供地址。如往一个ADDR_ANY 地址上进行sendto操作会返回这个错误。
_ 88 ENOTSOCK__ Socket operation on non-socket
在非socket上执行socket操作。
_ 87 EUSERS___ Too many users
_ 86 ESTRPIPE__ Streams pipe error
_ 85 ERESTART__ Interrupted system call should be restarted
_ 84 EILSEQ___ Invalid or incomplete multibyte or wide character
_ 83 ELIBEXEC__ Cannot exec a shared library directly
_ 82 ELIBMAX___ Attempting to link in too many shared libraries
_ 81 ELIBSCN___ .lib section in a.out corrupted
_ 80 ELIBBAD___ Accessing a corrupted shared library
_ 79 ELIBACC___ Can not access a needed shared library
_ 78 EREMCHG___ Remote address changed
_ 77 EBADFD___ File descriptor in bad state
_ 76 ENOTUNIQ__ Name not unique on network
_ 75 EOVERFLOW__ Value too large for defined data type
_ 74 EBADMSG__ +Bad message
_ 73 EDOTDOT___ RFS specific error
_ 72 EMULTIHOP__ Multihop attempted
_ 71 EPROTO___ Protocol error
_ 70 ECOMM____ Communication error on send
_ 69 ESRMNT___ Srmount error
_ 68 EADV____ Advertise error
_ 67 ENOLINK___ Link has been severed
_ 66 EREMOTE___ Object is remote
_ 65 ENOPKG___ Package not installed
_ 64 ENONET___ Machine is not on the network
_ 63 ENOSR____ Out of streams resources
_ 62 ETIME____ Timer expired
_ 61 ENODATA___ No data available
_ 60 ENOSTR___ Device not a stream
_ 59 EBFONT___ Bad font file format
_ 57 EBADSLT___ Invalid slot
_ 56 EBADRQC___ Invalid request code
_ 55 ENOANO___ No anode
_ 54 EXFULL___ Exchange full
_ 53 EBADR____ Invalid request descriptor
_ 52 EBADE____ Invalid exchange
_ 51 EL2HLT___ Level 2 halted
_ 50 ENOCSI___ No CSI structure available
_ 49 EUNATCH___ Protocol driver not attached
_ 48 ELNRNG___ Link number out of range
_ 47 EL3RST___ Level 3 reset
_ 46 EL3HLT___ Level 3 halted
_ 45 EL2NSYNC__ Level 2 not synchronized
_ 44 ECHRNG___ Channel number out of range
_ 43 EIDRM____ Identifier removed
_ 42 ENOMSG___ No message of desired type
_ 40 ELOOP____ Too many levels of symbolic links
_ 39 ENOTEMPTY_ +Directory not empty
_ 38 ENOSYS___ +Function not implemented
_ 37 ENOLCK___ +No locks available
_ 36 ENAMETOOLONG +File name too long
_ 35 EDEADLK__ +Resource deadlock avoided
_ 34 ERANGE___ +Numerical result out of range
_ 33 EDOM____ +Numerical argument out of domain
_ 32 EPIPE___ +Broken pipe
接收端关闭(缓冲中没有多余的数据),但是发送端还在write:
1、Socket 关闭,但是socket号并没有置-1。继续在此socket上进行send和recv,就会返回这种错误。这个错误会引发SIGPIPE信号,系统会将产生此EPIPE错误的进程杀死。所以,一般在网络程序中,首先屏蔽此消息,以免发生不及时设置socket进程被杀死的情况。
2、write(..) on a socket that has been closed at the other end will cause a SIGPIPE.
3、错误被描述为“broken pipe”,即“管道破裂”,这种情况一般发生在客户进程不理会(或未及时处理)Socket 错误,继续向服务 TCP 写入更多数据时,内核将向客户进程发送 SIGPIPE 信号,该信号默认会使进程终止(此时该前台进程未进行 core dump)。结合上边的 ECONNRESET 错误可知,向一个 FIN_WAIT2 状态的服务 TCP(已 ACK 响应 FIN 分节)写入数据不成问题,但是写一个已接收了 RST 的 Socket 则是一个错误。
_ 31 EMLINK___ +Too many links
_ 30 EROFS___ +Read-only file system
_ 29 ESPIPE___ +Illegal seek
_ 28 ENOSPC___ +No space left on device
_ 27 EFBIG___ +File too large
_ 26 ETXTBSY___ Text file busy
_ 25 ENOTTY___ +Inappropriate ioctl for device
_ 24 EMFILE___ +Too many open files
打开了太多的socket。对进程或者线程而言,每种实现方法都有一个最大的可用socket数目处理,或者是全局的,或者是局部的。
_ 23 ENFILE___ +Too many open files in system
_ 22 EINVAL___ +Invalid argument
无效参数。提供的参数非法。有时也会与socket的当前状态相关,如一个socket并没有进入listening状态,此时调用accept,就会产生EINVAL错误。
_ 21 EISDIR___ +Is a directory
_ 20 ENOTDIR__ +Not a directory
_ 19 ENODEV___ +No such device
_ 18 EXDEV___ +Invalid cross-device link
_ 17 EEXIST___ +File exists
_ 16 EBUSY___ +Device or resource busy
_ 15 ENOTBLK___ Block device required
_ 14 EFAULT___ +Bad address地址错误
_ 13 EACCES___ +Permission denied
_ 12 ENOMEM___ +Cannot allocate memory
_ 11 EAGAIN___ +Resource temporarily unavailable
在读数据的时候,没有数据在底层缓冲的时候会遇到,一般的处理是循环进行读操作,异步模式还会等待读事件的发生再读
1、Send返回值小于要发送的数据数目,会返回EAGAIN和EINTR。
2、recv 返回值小于请求的长度时说明缓冲区已经没有可读数据,但再读不一定会触发EAGAIN,有可能返回0表示TCP连接已被关闭。
3、当socket是非阻塞时,如返回此错误,表示写缓冲队列已满,可以做延时后再重试.
4、在Linux进行非阻塞的socket接收数据时经常出现Resource temporarily unavailable,errno代码为11(EAGAIN),表明在非阻塞模式下调用了阻塞操作,在该操作没有完成就返回这个错误,这个错误不会破坏socket的同步,不用管它,下次循环接着recv就可以。对非阻塞socket而言,EAGAIN不是一种错误。
_ 10 ECHILD___ +No child processes
__ 9 EBADF___ +Bad file descriptor
__ 8 ENOEXEC__ +Exec format error
__ 7 E2BIG___ +Argument list too long
__ 6 ENXIO___ +No such device or address
__ 5 EIO____ +Input/output error
__ 4 EINTR___ +Interrupted system call
阻塞的操作被取消阻塞的调用打断。如设置了发送接收超时,就会遇到这种错误。
只能针对阻塞模式的socket。读,写阻塞的socket时,-1返回,错误号为INTR。另外,如果出现EINTR即errno为4,错误描述Interrupted system call,操作也应该继续。如果recv的返回值为0,那表明连接已经断开,接收操作也应该结束。
__ 3 ESRCH___ +No such process
__ 2 ENOENT___ +No such file or directory
__ 1 EPERM___ +Operation not permitted
↧
Native Application 开发详解(直接在程序中调用 ntdll.dll 中的 Native API,有内存小、速度快、安全、API丰富等8大优点)
文章目录:
1. 引子:
2. Native Application Demo 展示:
3. Native Application 简介:
4. Native Application 有何妙用:
5. MJ0011 关于 Native Application 的文章整理:
6. 互联网上其他关于 Native Application 的文章整理:
7. 小结:
1. 引子:
其实在好久以前就看了 MJ0011 翻译的那个《Native 应用程序详细》系列的文章,
(PS: MJ0011 为 360 的首席技术执行官,技术是没的说,不过貌似有点狂妄之说 ~ )
而且看完后对这一系列文章也很感兴趣的,所以又去 Google 上找了几个小资料学习了一下,
而这篇文章呢,则是将我前阵子的所谓的学习给总结出来也顺道给大伙分享一下。
虽然这里是说的总结 Native Application,但最早出现 Native Application 应该是 06 年的事了,
(当然,Native Application 这个技术是一直存在的,只是在 06 年后有了下面这篇文章后就稍微火了点)
其是 Sysinternals 上的一篇由 Mark Russinovich 发表的文章《Inside Native Applications》,
文章地址如下:http://technet.microsoft.com/en-us/sysinternals/bb897447
而我却在 2011 年才得以来总结这个技术,所以我确是属于研究这些东西的落后者啊 ~
下面我给出一副截图来看一下 Windows 操作系统下的程序的类型:
image
在 Windows 最初设计的时候考虑到了兼容各种系统的应用程序,所以有了环境子系统之说,
其中一开始的时候考虑到了子系统,POSIX 子系统和 OS/2 子系统,
但是随着历史的发展,现在也就剩下个 Windows 子系统了,
我们日常使用的 Windows 操作系统的上层其实也就是指的这个 Windows 子系统了,
至于这里为何要扯到 Windows 子系统的话,就看下文介绍了。
很多朋友都知道有 Windows 应用程序和 Windows 内核驱动程序之说,
却很少有知道在 Windows 中还有 Native Application 一说了,
但是这类程序确实是存在的 ~只不过这类程序应用比较窄,也没有被很好的推广开来,
当然还有一点就是 Microsoft 自然不希望你随随便便的使用 Native API。
2. Native Application Demo 展示:
首先你需要将下载(博文的最后面附上 Demo 的下载地址)的 EXE 文件拷贝一份到 system32 目录下,
(博文的 Demo 只是拿了网上的代码然后自行使用 DDK 编译了而已,Demo 并非笔者原创)
然后再在注册表以下路径中修改 BootExecute,
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager
在其中添加 NativeApp_01 Hello World ! 这个字符串,
image
image
重启电脑,然后就可以看到下面的效果图了(仅在 XP SP3 上进行了测试)
2011-09-18_111934
3. Native Application 简介:
何为 Native API ?
Native API 就是你 system32 目录下的那个 ntdll.dll 中所公开的 API(大部分为 Undocument)~
如果读者看过我前面的《进程隐藏与进程保护(SSDT Hook 实现)》系列文章的话,
相信肯定会知道在 Windows 中 kernel32.dll 中的 API 的调用都会经过转换,
也就是跳转到 ntdll.dll 中,并且在 ntdll.dll 中也有与之相对于的 API 调用,
(比如 Kernel32.dll 中的 CreateProcess 在 ntdll.dll 中有 NtCreateProcess 与之对应)
那么什么称之为 Native 应用程序呢 ?
下面给出一副截图:
image
从上面的截图可以看出,在一开始的 Windows NT 内核中是支持三个环境子系统的,
即 POSIX,WINDOWS,OS/2,这些子系统属于同一层,它们共用了 Windows NT 所提供的 API,
即每一个子系统中的 API 的调用都会转换到下一层的相同调用上,
在 Windows 环境子系统(有 Windows,Posix,OS/2)中的程序,
都会调用其相对于的子系统下的 API,比如 Windows 子系统中的程序有可能会调用 Win32 API CreateProcess,
而 Posix 子系统中的程序也有可能会调用 Posix API CreateProcess(当然有可能在 POSIX 下创建进程不是这个名称),
但是终归来说,这两个 CreateProcess 的调用都会转换到 Ntdll.dll 中的 NtCreateProcess 中,
也就是上面的三个子系统最后的调用都会回归到 ntdll.dll 上,
而我们的 Native Application 则是绕过 Windows 子系统,
直接自己调用 Native API,比如创建进程的话,我就不再通过子系统中的神马 CreateProcess 来完成了,
而是直接在程序中调用 ntdll.dll 中的 Native API NtCreateProcess 来完成,
而这类程序即称之为 Native Application !
Native Application 的运行环境:
上面也说了,Native Application 是只能够访问 ntdll.dll 中的内容的,
而如果是在子系统下运行一个程序的话,必然会加载其他的 DLL,
比如在 Windows 子系统下一个 kernel32.dll 是必不可少的吧,
如果 Native Application 能够运行在 Windows 子系统下的话,必然也会加载到 Kernel32.dll,
这样不就和上面相违背了嘛 ~
总之:Native Application 是不能够运行在任何子系统下的 !
比如在 Windows 子系统下运行 Native Application 会弹出如下错误对话框:
image
Native Application 的启动时机:
对于 Windows 操作系统的引导过程,这里需要带一笔的,Windows 操作系统启动时,
当 Windows 内核的引导完成以后,就会启动会话管理器 smss.exe 进程了,
smss.exe 进程虽然是一个用户模式的进程,但是这个进程相对于其他用户模式进程是具有一定特殊性的,
首先 smss.exe 进程是直接建立在 Windows NT 内核上的,其不依赖于任何一个环境子系统,
至于不依赖于任何一个环境子系统这一说的话,还是可以很好的解释的,
因为当环境子系统进程(Windows 子系统进程为 csrss.exe)就是由 smss.exe 进程启动的,
然后 smss.exe 是 Windows 操作系统启动的第一个用户态进程,
而 Native Application 也属于用户态程序,自然 Native Application 的启动是在 smss.exe 之后,
而后前面也说过,Native Application 运行时,子系统进程还尚未启动,
所以 Native Application 的启动则是在 csrss.exe 之前的,
而话又说回来,csrss.exe 就是由会话管理器(smss.exe)启动的,
所以 Native Application 的启动时机也就只有一种可能了,
即 smss.exe 先启动 Native Application,然后 Native Application 开始执行,
等到 Native Application 都给执行完了后 smss.exe 再启动 csrss.exe 进程。
(事实上,Win32 应用程序环境子系统 csrss.exe 本质上也是一个 Native Application ~)
下面给出一副截图以说明 SMSS.EXE 的在启动过程中所完成的工作:
运行启动时执行的程序即是执行 Native Application
image
4. Native Application 有何妙用:
前面也提到过,Native Application 的应用范围比较窄,这主要受以下几点约束:
首先,Native Application 是直接调用 Native API 来完成任务的,
而在 Windows 中,Native API 绝大部分都是 Undocument 的,这样开发起来自然难度会大很多了。
然后,由于 Native Application 是调用的 Undocument API,
说不准那一天 Microsoft 就在下一代 Windows 中修改了这个 API,这样的话,你程序的可移植性也就完全没了。
最后的话,Native Application 的执行环境并非是在 Windows 子系统中,
事实上,当 Native Application 开始执行的时候,Windows 子系统进程(csrss.exe)进程都还没有启动的 ~
所以 Native Application 的执行是受限制的,其不能够执行子系统中的任何东西,
说白一点的话就是 Native Application 只能够调用 ntdll.dll 中的 API,
其他 DLL 中的 API 一律不得调用,这样也就注定 Native Application 的应用范围不会很广泛了。
应用范围比较窄并不等于说没有应用价值,
也还是有蛮多的软件,包括一些商业软件也都是用了 Native Application,
下面来看一些 Native Application 的应用(我也只是从网上道听途说,不过有些也确实是自己也用过的):
最典型的应用自然是属于 Windows 操作系统自带的磁盘自检程序了;
然后比较典型的商业应用是瑞星的开机杀毒,即实现让病毒在你还没有完全开机之前死掉;
然后就是可以通过 Native Application 来实现接管 Windows 的开机启动界面和密码输入界;
还可以通过 Native Application 来实现开机前的磁盘修复(Windows 自带了这款工具也是这样实现的);
5. MJ0011 关于 Native Application 的文章整理:
这一小节里面主要是整理一下关于 MJ0011 的 Native Application 的博文,
也就是说我这里纯粹是将他的东西给贴出来瞧瞧,关于 MJ0011 博文的原地址为:
《NATIVE应用程序详细之一》:
http://hi.baidu.com/mj0011/blog/item/7ee496d67a4d4d2f07088bc7.html
《NATIVE应用程序详细之2 NATIVE应用程序的优势和劣势》
http://hi.baidu.com/mj0011/blog/item/f8108f2f5890fb381e30896d.html
《native应用程序详细之三 构建native应用程序》:
http://hi.baidu.com/mj0011/blog/item/725b4882042b03a20df4d269.html
《深入Native应用程序》(该文翻译自《Inside Native Application》):
http://hi.baidu.com/mj0011/blog/item/85c0b50f80b1baedab6457de.html
《native app GUI界面的实现》:
http://hi.baidu.com/mj0011/blog/item/6e5a22fa214c8116a9d3115b.html
Native 应用程序简介:
NT 系统被设计成为支持子系统(封装),它可以执行在不同平台上的代码。包括但不限于:POSIX、OS/2和Win32,
为了管理这些子系统,NT内核输出了大量名为 Native API的API函数,子系统服务将这些函数包装为他们自己的函数。
例如:CreateFile和fopen都被映射到NtCreateFile.那么子系统管理程序运行在哪个子系统中?
为了避免先有鸡还是先有蛋的问题,NT系统同样支持原生的Native应用程序。
这些Native应用程序是独立于子系统的。现在,所有的子系统应用程序都需要注册它们自己的子系统服务,
显然,Kernel32是一个Win32应用程序,csrss注册WIN32子系统,然后通知子系统管理器SMSS,
因此,一个Native应用程序是无法调用其中数千种API的,
同时它也无法使用一些基本的DLL中的函数例如kernel32、user32、gdi32等,
其它任何调用了这三者的DLL中的函数的DLL也无法被使用。
事实上,加载者在其入口点没有被加载前,并不允许加载决大多数的Win32 DLL。
因此,native应用程序被限制只许使用一个DLL:ntdll.dll,这个DLL供应所有Native和运行函数。
但是想想,既然所有Win32函数最后都是去调用Ntdll.dll中的函数来实现的(除了GUI部分),
这些函数就已经足够了,不是吗?
Native应用程序优势:
(一) 内存使用和大小:因为Native应用程序并不需要加载90多个DLL到内存中去,因此其使用的内存是很小的。
(二) 速度:Native API比Win32对应的函数要更快(通常会快很多),
尽管实际上很多时间都被消耗在Win32 API的封装上,这些包括修改、兼容性选项,和其他的代码部分,
这些都会在执行真正的Native调用前执行。如果你知道如何去做而且希望它运行得更快,Native是一个很好的方法。
因为不需要加载那90多个DLL,kernel32不需要到csrss和smss做lpc注册,因此启动也是非常快速和直接的。
(三) 熟悉程度和特性:Native应用程序并没有古怪的入口点或者奇怪的Hack,就象读命令行一样简单使用,
而事实上将在后面介绍,Native应用程序和Console程序一样启动与_main函数,
通过一组简单的char*[]队列来接受命令行参数和环境变量,就象一个典型的Win32 Console程序一样,
一些特性例如缓冲区溢出保护(/GS)、Safe SEH(/SAFESEH)、hotpathing(/HOTPATCH),
以及其他的特性都被支持。
(四) 丰富:Native API非常丰富,它们提供的特性和功能性要远远超越Win32函数所能达到的程度。
这并不是说Win32无法做到Native API那样的更困难和更复杂的工作,而是Win32太过简单而已,
比如Win32函数中,无法远程注入一个Section到一个进程中,因为MapViewOfFileEx不提供进程句柄接口,
而Native API则可以实现这个功能。
(五) 安全:但是Native应用程序有这样一个特点:人们对于Native API不是十分熟悉,
他们需要花费更多的时间才能理解你的代码,而更重要的是,无法使用一个用户模式的debugger来调试Native应用程序,
只有SoftIce和使用内核模式远程连接的WinDbg才可以对其进行调试,这足以让那些废物脚本小子去死了,
再说一遍,这并不意味着Native 应用程序是“不可调试的,安全的”,只是它更模糊更难被破解。
(六) 同内核模式的连接:因为Native应用程序只使用Native API,这些函数在内核模式仍然可用,
这样,一个Native程序只需少量修改就可修改为内核驱动,而Win32程序则需要几乎重写所有代码。
(七) 运行在独立于子系统的环境中:因为Native应用程序并不依赖与任何子系统,
它运行于一个正常应用永远无法再次得到的环境中,比如autochk.exe,它运行与任何子系统加载之前,
并负责显示'press any key to scan your hard disk"信息,并扫描你的硬盘是否有错误。
在这个模式运行允许你显示信息到启动屏幕上,以及很多增强特性。
(八) 标准性:不象Win32函数有一个正常版本,一个"Ex"版本,以及经常有一个"扩展其他功能"的版本,
以及经常返回0,1,-1或一些随机的数值来表示成功,并且要使用SetLastError来设置返回错误,
在Native应用程序中,这些垃圾都是不存在的,所有的Native API都有统一的标准,
所有都返回NTSTAUS(除非明确表示会返回一个特定的值),NTSTAUS是一个标准的错误码定义,
而且使用它们时你也不需要考虑该死的Ex版本。
Native 应用程序劣势:
(一) 和Win32开发的差异较大:如果你以前从来没有进行过Native API或内核驱动的相关开发,
你可能需要学习所有的API相关知识,当然,他们的名字是相似的,但是他们的标志经常是完全不同的,
而且他们的返回值,很可能使你感到迷惑。
(二) 缺少文档:虽然所有的Rtl*函数都是有文档的,数百个其他的Native API仍是无文档的。
(三) 缺少商业价值:虽然Native程序如此美好,但是建议你不要在商业产品中使用 Native API 或着使用Native应用程序,
Native API是可能改变的,虽然它们通常没有改变,但是他们很可能变得不再有用,不要拿你的客户的钱冒险。
(四) 没有GUI、及输入/输出接口:没有"Native控制台程序",你无法简单地从用户那里接受到输入或显示些什么到屏幕上,
因为那些接口都无法再使用(控制台API都是Win32 API)。
Native 应用程序构建:
你需要这两者或两者之一来创建你的 native 应用程序:
(1)Visual C++ 2005 Express(or higher)
(2)Windows Driver Kit
我们将从基础开始,首先你需要创建你的应用程序的头文件,precomp.h,ntddk.h
1: #include "ntddk.h"
Now that that's done, create your main initialization file,
which we will call init.c. In this file, add precomp.h like this:
1: #include "precomp.h"
And define your entrypoint:
1: NTSTATUS __cdeclmain(
2:
3: INT argc,
4:
5: PCHAR argv[],
6:
7: PCHAR envp[],
8:
9: ULONG DebugFlag OPTIONAL)
10:
11: {
12:
13: // Entry code here
14:
15: }
Hopefully you are familiar with this entrypoint, it's the typical one used by C programs,
except with an addon: the "DebugFlag". Right now, we don't need to care about this.
We'll keep this entry simple, and turn this into a "Hello World":
1: NTSTATUS __cdecl main(
2:
3: INT argc,
4:
5: PCHAR argv[],
6:
7: PCHAR envp[],
8:
9: ULONG DebugFlag OPTIONAL)
10:
11: {
12:
13: UNICODE_STRING HelloMsg = RTL_CONSTANT_STRING(L"Hello World!\n");
14:
15: //Say hello
16:
17: NtDisplayString(&HelloMsg);
18:
19: }
20:
Now, if you're wondering what NTSTATUS is,
what NtDisplayString is or what
RTL_CONSTANT_STRING and UNICODE_STRINGs are,
then you'll need to read all the DDK documentation you can swallow,
as well as Nebett's Undocumented Native API book.
Although it's outdated, the information about the APIs is still pretty valid.
I also plan to possibly give a fully-fledged lesson on this if lots of
people are interested.So now that we have our simple program, we need to build it.
I prefer using the WDK myself,
because it's much simpler and doesn't require changing 100 of MSVC's default settings.
Assuming you've properly installed the WDK and entered the Windows build environment for
your OS (from the Start Menu),
you'll need to create two files in the directory where init.c and precomp.h are:
sources and makefile.
Sources should look something like this:
--
1: TARGETNAME=native
2:
3: TARGETTYPE=PROGRAM
4:
5: UMTYPE=nt
6:
7: INCLUDES=\
8:
9: $(DDK_INC_PATH); \
10:
11: $(NDK_INC_PATH);
12:
13: SOURCES=init.c
14:
15: PRECOMPILED_INCLUDE=precomp.h
16:
--
that you'll have to set NDK_INC_PATH as an environment variable yourself,
to where the NDK is installed (DDK_INC_PATH is already setup by the WDK).
Finally, you'll need a makefile:
--
1: INCLUDE $(NTMAKEENV)\makefile.def
--
That's all you really need for our purposes.
So now you should have init.c, precomp.h, sources and makefile.
The only thing left is to write "build",
and the WDK should do the magic and create your first native application.
Unforunately, you can't really test it for now,
unless you do the following:Open registry editor and browse to
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager
Edit the "BootExecute" key and write "native" instead of what's currently in it,
then copy native.exe to your system32 directory and restart the computer.
You should see the message appear on the screen for a little while.
Make sure that you do NOT boot with /NOGUIBOOT, or else you will never see it.
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
/////////////////MJ0011 翻译《Inside Native Application》//////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
导言
如果你对Windows Nt结构有一定的了解,你可能会知道,Win32 应用程序所使用的API,
并非是"真正"的NT API,POSIX、OS/2和Win32这些Windows NT 操作系统环境,
使用他们自己的 API 同他们的客户应用程序进行交流,但却使用Windows NT的"Native" API同Windows NT交流,
这些Native API大都是未公开UnDocumented 的。
大约只有25个API(包含250种功能)在Windows NT设备驱动开发工具包(DDK)里有所描述。
尽管绝大多数人都不知道,但"Native"应用程序的确存在与Windows NT上,他们在操作环境上没有任何客户程序,
这些程序交流着Native NT API并且不能使用任何操作环境API比如 Win32,为什么这样一种程序是必须的呢?
因为在Win32子系统启动之前(大约在登陆对话框出现时)只可以运行Native应用程序,
最常见的Native应用程序的例子是"autochk"程序,他在初始化蓝色登陆屏幕前运行chkdsk(程序在屏幕上打印一串".")。
当然,Win32应用程序环境服务程序:CSRSS.exe(客户-服务运行时间子系统),也是一个Native应用程序。
在这篇文章里,我将会讲述如何构造一个Native应用程序以及它们是如何工作的,
同时我也会提供一个Native应用程序的示例源代码。
这个示例很容易安装,它会在启动时的蓝色屏幕打印一段你指定的字符串。
Autochk是如何被执行的
Autochk在当内存分页被打开,Windows启动和系统开始驱动被载入之间的时间内运行,
在这个时间点会启动会话管理器(smss.exe)进入Windows NT用户模式,并且没有任何程序被启动。
注册表中:HKLM\System\CurrentControlSet\Control\Session Manager\BootExecute
一个MULTI_SZ类型的键值,这里存放着将被会话管理器所执行的程序名称和参数,通常是Autochk后加*号作为其参数
Autocheck Autochk *
;名称 程序名 参数
会话管理器在\system32目录下查找该值列出的可执行程序,当Autochk运行时,没有任何文件被打开,
所以Autochk可以用raw模式打开任何一个驱动器卷(包括根驱动器),并操作其磁盘数据结构,
之后的任何时间点都无法进行类似这样的操作。
编译Native应用程序
1. 微软没有提供相应的文档,但是NT DDK构建器知道如何去生成一个Native应用程序,
而且它可以被用来编译autochk程序,和编写设备驱动程序一样,你必须指定SOURCE文件中的信息来定义应用程序,
然而和编写驱动不同的时,你在SOURCE文件中要求生成一个Native应用程序需要这样定义:
TARGETTYPE=PROGRAM
2. 构建器使用一个标准的makefile来进行向导:\ddk\inc\makefile.def 在编译Native应用程序时,
会查找名为nt.lib的运行库。不幸的是,微软并没在DDK上装载这个文件(在Windows Server 2003 DDK里包括了这个文件,
但是我怀疑你用这个版本来连接你的Native应用程序是无法运行在Windows XP或Windows 2000上的)不管怎样,
你可以忽略这个错误,方法是加入一行不考虑nt.lib,而指定Visual C++ 的运行库msvcrt.lib到makefile.lib中。
3. 如果你在DDK的"Checked Build"环境下进行编译,
将会在%BASEDIR%\lib\%CPU%\ Checked(例如c:\ddk\lib\i386\checked\ native.exe)
产生一个包含了全部调试信息的Native应用程序。
4. 如果在"Free Build"环境中编译,你会在%BASEDIR%\lib\%CPU%\Free得到一个释出版本的程序,
这些和构造设备驱动程序放置的位置是一样的。
5. Native应用程序有着".exe"的扩展名,但是你不能像 Win32的.exe文件那样去运行它,
如果你在Win32环境下运行下,将会得到如下提示:"<应用程序名> 应用程序无法在Win32模式中运行。"
深入学习Native应用程序
1. Native应用程序的入口点是NtProcessStartup,类似WinMain或Main,不同于其他的 Win32入口点的是,
Native应用程序提供一个数据结构来存放它的唯一的参数来定位命令行参数。
2. 大多数的Native应用程序的运行环境是由Windows Nt的Native API输出库 - NTDLL.DLL提供的。
3. Native应用程序必须使用RtlCreateHeap(一个ntdll函数)来创建他们自己的堆来分配存储,
使用RtlAllocateHeap来分配内存以及用RtlFreeHeap来释放内存。
4. Native应用程序需要使用NtDisplayString 函数才可以打印想要的内容到屏幕上(将被输出到初始化时的蓝色屏幕上)。
5. Native应用程序不像Win32程序那样简单地从他们的启动函数返回,你需要调用NtProcessTerminate函数来结束它的进程。
6. NTDLL运行包含了数百个函数允许Native应用程序执行文件I/O,与设备驱动进行相连,并执行进程间通讯。
不幸的是,他们大部分都是未公开的。
Native应用程序实例
1. 我创建一个Native应用程序用来演示Native应用程序是如何构建的以及他们是如何工作的。
运行install.bat来安装Native程序。
2. 批处理程序复制Native.exe到你的\system32目录,
并在注册表中增加一个BootExecute的入口点: native Hello World!
3. 当你重新启动时,会话管理器运行完autochk后就会执行Native,Native分配一些堆,
定位它的命令行参数并打印参数("Hello world!")到蓝色屏幕上,它所使用的函数上面已说过了。
如果你想要打印其他的简单内容,可以编辑BootExecute值使用regedit或regedit32,
修改"Hello world"为你想要的信息。
4. 运行uinstall.bat可以卸载这个Native执行程序。它从\system32 目录删除 Native.exe,
并修改BootExecute值为通常的值。
5. 如果你想要构建native程序你必须要用Windows设备驱动工具包(DDK),
复制makefile.def到 \ddk\inc然后你可以运行构建。
Native.H
1: //Environment information, which includes command line and image file name
2: typedef struct
3: {
4: ULONG Unknown[21];
5: UNICODE_STRING CommandLine;
6: UNICODE_STRING ImageFile;
7: } ENVIRONMENT_INFORMATION, *PENVIRONMENT_INFORMATION;
8:
9: // This structure is passed as NtProcessStartup's parameter
10: typedef struct
11: {
12: ULONG Unknown[3];
13: PENVIRONMENT_INFORMATION Environment;
14: } STARTUP_ARGUMENT, *PSTARTUP_ARGUMENT;
15:
16: // Data structure for heap definition.
17: // This includes various sizing parameters and callback routines,
18: // which, if left NULL, result in default behavior
19: typedef struct
20: {
21: ULONG Length;
22: ULONG Unknown[11];
23: } RTL_HEAP_DEFINITION, *PRTL_HEAP_DEFINITION;
24:
25: // Native NT api function to write something to the boot-time
26: // blue screen
27: NTSTATUS NTAPI NtDisplayString(
28: PUNICODE_STRING String
29: );
30:
31: // Native applications must kill themselves when done -
32: // the job of this native API
33: NTSTATUS NTAPI NtTerminateProcess(
34: HANDLE ProcessHandle,
35: LONG ExitStatus
36: );
37:
38: // Definition to represent current process
39: #define NtCurrentProcess() ( (HANDLE) -1 )
40:
41: // Heap creation routine
42: HANDLE NTAPI RtlCreateHeap(
43: ULONG Flags,
44: PVOID BaseAddress,
45: ULONG SizeToReserve,
46: ULONG SizeToCommit,
47: PVOID Unknown,
48: PRTL_HEAP_DEFINITION Definition
49: );
50:
51: // Heap allocation function (ala "malloc")
52: PVOID NTAPI RtlAllocateHeap(
53: HANDLE Heap,
54: ULONG Flags,
55: ULONG Size
56: );
57:
58: // Heap free function (ala "free")
59: BOOLEAN NTAPI RtlFreeHeap(
60: HANDLE Heap,
61: ULONG Flags,
62: PVOID Address
63: );
Native.C
1: //======================================================================
2: //
3: // This is a demonstration of a Native NT program. These programs
4: // run outside of the Win32 environment and must rely on the raw
5: // services provided by NTDLL.DLL. AUTOCHK (the program that executes
6: // a chkdsk activity during the system boot) is an example of a
7: // native NT application.
8: //
9: // This example is a native 'hello world' program. When installed with
10: // the regedit file associated with it, you will see it print
11: // "hello world" on the initialization blue screen during the system
12: // boot. This program cannot be run from inside the Win32 environment.
13: //
14: //======================================================================
15: #include "ntddk.h"
16: #include "stdio.h"
17: #include "native.h"
18:
19: // Our heap
20: HANDLE Heap;
21: //----------------------------------------------------------------------
22: // NtProcessStartup
23: // Instead of a 'main', NT applications are entered via this entry point.
24: //----------------------------------------------------------------------
25: void NtProcessStartup( PSTARTUP_ARGUMENT Argument )
26: {
27: PUNICODE_STRING commandLine;
28: PWCHAR stringBuffer;
29: PWCHAR argPtr;
30: UNICODE_STRING helloWorld;
31: RTL_HEAP_DEFINITION heapParams;
32:
33: // Initialize some heap
34: memset( &heapParams, 0, sizeof( RTL_HEAP_DEFINITION ));
35: heapParams.Length = sizeof( RTL_HEAP_DEFINITION );
36: Heap = RtlCreateHeap( 2, 0, 0x100000, 0x1000, 0, &heapParams );
37:
38: // Point at command line
39: commandLine = &Argument->Environment->CommandLine;
40: // Locate the argument
41: argPtr = commandLine->Buffer;
42: while( *argPtr != L' ' )
43: {
44: argPtr++;
45: }
46: argPtr++;
47:
48: // Print out the argument
49: stringBuffer = RtlAllocateHeap( Heap, 0, 256 );
50: swprintf( stringBuffer, L"\n%s", argPtr );
51:
52: helloWorld.Buffer = stringBuffer;
53: helloWorld.Length = wcslen( stringBuffer ) * sizeof(WCHAR);
54: helloWorld.MaximumLength = helloWorld.Length + sizeof(WCHAR);
55:
56: NtDisplayString( &helloWorld );
57:
58: // Free heap
59: RtlFreeHeap( Heap, 0, stringBuffer );
60:
61: // Terminate
62: NtTerminateProcess( NtCurrentProcess(), 0 );
63: }
Install.bat:
1: @echo off
2: copy native.exe %systemroot%\system32\.
3: regedit /s add.reg
4: echo Native Example Installed
UnInstall.bat:
1: @echo off
2: del %systemroot%\system32\native.exe
3: regedit /s remove.reg
4: echo Native Example Uninstalled
6. 互联网上其他关于 Native Application 的文章整理:
下面给出的则是我在互联网上其他地方找到的关于 Native Application 的比较好的资料,
这里也只是将这些资料进行一个整理。
《native app 开发小结(一)》:
http://hi.baidu.com/316526334/blog/item/32823e8a83d87b1fc9fc7a0f.html
《native app 开发小结(二)》:
http://hi.baidu.com/316526334/blog/item/43a21061ad619cd28cb10d08.html
《Native Application 应用之开机杀毒》:
http://www.cublog.cn/u/8754/showart_447592.html
程序类型
关于程序级别的分类,大概可以分为三层:应用层程序,即普通的APP程序;Native App程序,如常见的chkdsk工具,PQ分区工具等,都属于这类,它是在win子系统未启动起来就执行的程序,执行环境比较纯净,只能调用ntdll.dll导出的函数;
Driver 内核驱动程序,因功能不同也分为若干类,如设备驱动程序,内核扩展程序,文件系统驱动,过滤驱动等,
同属于内核态程序;其中,native app在项目开发中用的较少,所用的函数接口MS也均未公开,
开发难度和驱动相当,所以很少有人问津。但是,事实上,在某些应用场景下,用native app来实现是非常完美的,
比如:接管winodws的开机启动界面和密码输入界面,需要native app;
在开机前,执行磁盘修复,需要native app;开机前,执行杀毒,或者磁盘整理,
因为此时环境比较纯净,需要native app。诸如此类~ 最近,开发一个Native App项目,其规模和复杂度也不一般。
期间遇到很多问题,在逐一解决的时候也收获了很多东西。现在略作整理,以备将来查用,二来与大家分享之~
Native app 基本工作原理
这里,只想简单的描述下。
Windows的设计是基于分层模型的,在设计之初,内核NT支持三个子系统,OS/2,posix,win32,
这些子系统同属于一个层面上,它们公用windows nt提供的系统API和例程。其中,在某一个子系统上的API调用,
都会经过NT”native”API同windowsNT进行通信。这些native API就是ntdll.dll导出的函数,
因为它导出的大部分函数都只是起一个从子系统到NT内核的转发传递作用,所以也成为stub函数,
这些函数的原型大多是未公开的,在早期的DDK里会有相关的描述,但是现在没了,
取而代之的是内核实现的zw*,nt*开头的驱动函数。这里表明了MS的一个态度,
不希望第三方在native app上干涉windows的太多工作,比如,接管了开机启动系统,接管了登录密码界面:D.
后来,因为种种历史原因,对OS/2和posix子系统的支持逐渐被淡忘。但是这种分层模型仍然存在,
native app就是工作在子系统未启动之前,此时的系统环境很纯净,权限也相对较高;
另外,对操作系统来说,支持native app也是一种必须,因为在子系统启动之前,
很多功能的程序只能以native app来呈现,比如登录界面,CSRSS~
具体的启动时机:
Native app由启动会话管理器(smss.exe)来启动,如果想通知smss来执行一个native app程序,
只需要修改一个注册表项,smss在每次启动的时候会去检查该项,确保该项下面的每个native app程序依次执行。
注册表项为:HKLM\System\CurrentControlSet\Control\Session Manager\BootExecute ,
其类型为MULTI_SZ, 又是MS玩的一种字符串类型—多字符串类型,也就是说,
这个MULTI_SZ字符串包含多个以\0结尾的子字符串,而整个字符串以\0\0结尾。
在该注册表项后面添加要注册的native 程序名和参数就可以了。
关于native app的更多详细介绍,可以参考Mark Russinovich的一篇关于native的文章。
Native app程序结构
Native app程序结构很简单,就好像我们写hello world,需要写一个main函数入口一样,
native app的入口函数是NtProcessStartup,形如:
1: void NtProcessStartup( PSTARTUP_ARGUMENT Argument )
其中,参数PSTARTUP_ARGUMENT是一个结构体,用来存放传入参数。
程序退出时,主动调用函数NtProcessTerminate退出,它不会像普通应用程序一样一个返回return就退出了。
基本的结构就是这样了:
1: void NtProcessStartup( PSTARTUP_ARGUMENT Argument )
2:
3: {
4:
5: // do something else
6:
7: NtProcessTerminate( NtCurrentProcess(), 0 );
8:
9: }
10:
当然现在还没有包含头文件之类的。
开发语言及第三方的库
Native app支持的开发语言有C/ASM/C++,并且完美的支持C++的类特性,不过要像编写驱动一样,
需要重载new,delete等内存分配函数。在内存使用上,可以使用两套接口:堆函数接口,以及虚拟内存函数接口,
但是根据我的经验,使用堆函数接口,更高效并且内存bug出现的频率会大大降低。
举个例子:我在调试native app的时候,一切正常,且全部通过,但是双机调试的时候,
功能代码都运行完了,在子系统起来的时候,提示memory_corruption错误,
这个问题整整找了好几天都没有找到,到最后,无意间屏蔽掉了系统的DbgPrint函数,memory错误才解决。
其原因是,native gui图形模块的debug消息打印的太快太频繁,导致调试缓冲被溢出,
当屏蔽了系统DbgPrint的时候,也就是在windbg 下bp DbgPrint,然后a eip,ret后,就正常了。
虽然这个现象和程序无关,但是,用了虚拟内存的话,这个问题会更加容易重现。关于这个问题的重现很容易,
就是在native 环境下双机调试,target机器一直打印消息,当打印到10W条以上时,调试缓冲就“爆”了。
这真不知道是ms的bug,还是自己~~
关于 new, delete 的重载。
使用堆函数过程如下:首先创建一个全局堆,然后在这个全局堆上分配和释放局部堆。
1: HANDLE hGlobalHeap = NULL; // for globle call
2:
3: void* __cdecl operator new(size_t size)
4:
5: {
6: if(hGlobalHeap == NULL)
7: return NULL;
8: return RtlAllocateHeap(hGlobalHeap,0/*HEAP_ZERO_MEMORY*/,size);
9: }
10:
11: void __cdecl operator delete(void* addr)
12:
13: {
14: if(hGlobalHeap && addr) (void)RtlFreeHeap(hGlobalHeap,0,addr);
15: }
16:
关于 NDK:前面说到,native app用的是ntdll.dll的导出函数,而这些函数MS并没有公开接口声明,
那么我们使用的时候,首先必须要自己定义函数声明。
NDK就是这样的一个类库,它几乎定义了ntdll.dll导出的全部函数的声明以及一些常用的数据结构的定义,
我们只需要包含相应的头文件,导入ntdll.lib库,就可以像使用普通的API函数一样开发native app了。
关于DLL:native app可以调用同一级别的DLL,使大型的项目开发更加容易,更加容易划分模块。
注意,DLL的编译环境要和native app一致。
关于native app的编译:可以选择用vs环境,也可以用DDK/WDK,但是推荐使用WDK。
用VS环境的话,需要简单的设置下,随意创建一个类型的工程,然后修改Linker->system->Native,
就可以了。如果用WDK编译,需要写一个SOURCE模板,如:
1: TARGETNAME=defrag
2:
3: TARGETPATH=obj
4:
5: TARGETTYPE=PROGRAM
6:
7: INCLUDES=$(PUBLIC_ROOT)\inc\ddk
8:
9: SOURCES=defrag.cpp
10:
注意:上面说的DLL的编译环境和native app的编译环境要一致,
指的是不要用WDK编译的native去尝试链接VS编译的DLL,反之亦然。
1: //NTSTATUS NTAPI NtDisplayString( PUNICODE_STRING String);
Native GUI
在native app执行环境下画界面是不可行的,但是不是说做不到。
前面说了,可以写一个native app来接管windows的启动界面和密码输入界面,那么这个界面是如何画的呢?
也有从驱动里实现的。但是,事实上,MS提供了一个native级别的动态库,名为:Bootvid.dll,
用来实现GUI启动屏幕的引导视频驱动,这个dll导出了一些函数,可以实现画图,贴图功能,
当然,这些函数接口仍然是未公开的。呵呵~
另外,在native app程序,可以利用一个函数向屏幕打印输出字符串,名为:
但是,事实上,这个函数已经不推荐使用了,
在用WDK编译native app的时候,会提示一个警告信息,deprecated~~
Native app的灵活性
native app由于受到调用函数接口未公开,以及开发难度和调试难度不小的原因,很少有项目问津,
但是,事实上,它仍然是一种工作于ring3的用户态程序,只是在子系统启动之前运行,
所以,native app程序一般不会引起系统蓝屏的问题。
也正是如此,native 程序工作在一个相对纯净的环境下,可以访问任何文件,甚至搬移MFT,系统元文件等。
Ntdll.dll为native app导出的函数虽少,但是可以完成很多的功能。
这些导出函数,基本上和内核的系统例程都是一一对应的。结合其他的模块,driver,应用程app,
在加之native独特的运行环境和执行能力,往往会达到一个良好的效果。在这里,仅仅是一个普及~
具体应用及实例
在开发native app之前,我想,最好有开发驱动的基础。因为native app程序的编写规范基本上和驱动一样,
除了入口函数,调试方法也一样,必须要双机调试。当然,只是说编写规则一样,驱动特有的函数例程以及工作原理,
二者是毫不相干的。举个例子,操作注册表,文件IO,线程创建,内存使用,二者基本上是一致的,具体的在使用中自己体会吧。
作为入门例子
作为入门我想还是用Mark Russinovich的例子吧,就好像Hello World的作用一样,
让你真切的感受下native app程序。该程序在系统启动时,蓝屏界面上输出一行字符串信息。
程序在附件,没什么过多的需要解释的。
实际开发
实际开发中,有不少的应用例子。比如,影子系统的启动界面,PQ分区工具,
win系统自带的chkdsk工具,都属于这类程序。下面说下自己的一些经历吧:
项目中有个需要,对特定文件进行磁盘整理。我们知道,文件系统导出了一组函数接口,
用于对磁盘上的文件进行搬移操作,使文件内碎片和外碎片减少,提高IO吞吐率和磁盘访问率。
唯一的限制是,pagefile.sys和日志文件不能整理,其他的文件,如MFT,系统元文件都可以整理。
对于文件整理,更重要的是算法和稳定法,当然,这是另外一个话题了。
根据prefreth原理,一个应用程序的工作集页面在运行时基本上是趋于稳定的,
那么这些稳定的页面如果位于不同的文件(可能是链接库之类),且这些文件在磁盘上比较分散,
那么就会影响程序的启动时间了,虽然prefretch做了改善,会自动的激发系统的磁盘整理来对“相关”的文件紧密排放,
但仍然是不够的。所以,关于这种性能的改善看起来微乎其微,但是做好了,价值是不可估量的。
这仅仅是一个方面,当然,项目中的主要目的并不是这个,虽然也是为了提高性能。
在native app下操作文件,考虑的情况是比较单一的,不会担心文件或目录被锁,
从而出现不能访问的情况,也不会考虑过多的并发问题。
所以,功能会更加集中,运行效率会更高,操作的空间和权限也更大。
仅限于此,就到这吧 ~
7. 小结:
上面的文字呢就大体的把 Native Application 给介绍的差不多了,
主要是总结了一下自己关于 Native Application 的理解,
然后再将 MJ0011 和互联网上的几位博主的文章给整理了一下(原博文排版不怎么好),
这里对 MJ0011 以及所整理的文章的博主表示感谢 ~
博文中的 Demo 我是采用的 DDK 2600.1106 编译的,至于 WDK 7 的话,我没有去试哦 ~
有兴趣的可以直接下载了 Demo 进行测试的,代码什么的都在里面,
source 和 makefile 我也都整理好了放在 Demo 中 ~
最后还是和以往一样,给出些我近来的一些疑问:
我曾经从一台电脑 A 上下载了卡巴斯基的试用版,然后我将这个试用版的安装文件拷贝到了电脑 B 上,
这时我发现卡巴斯基的这个安装文件在电脑 B 上是无法运行的 ~ 直接报错,
当然,这个安装文件在电脑 A 上是可以运行安装的,
我想应该是卡巴斯基的这个安装文件在拷贝的过程中还是下载的过程中记录下了我的电脑 A,
然后在安装的时候,其自动判断是否是在电脑 A 上安装运行,
如果是的话,则可以成功安装,如果不是,则直接报错 ~
我想知道上面是怎么来实现的呢 ? 我只是下载和拷贝了一下哦 ~
还有就是貌似要考个微软的 MCTS 证书,
应该是 Windows 方向的 71-511 或者 Web 方向的 71-515 这两门考试,
不晓得大伙有什么好建议或者好的资料没有哦 ~ 可否提供一些呢 ~ 谢谢咯 ~
然后再问一下哦,有没有湖南娄底的啊 ? 国庆组队回去否 ?(我在深圳 ~)
下载 Demo Source Code
版权所有,欢迎转载,但转载请注明: 转载自 Zachary.XiaoZhen - 梦想的天空
http://www.cnblogs.com/BoyXiao/archive/2011/09/21/2183059.html
↧
SQL Server · 最佳实践 · 参数嗅探问题
摘要: 摘要 MSSQL Server参数嗅探既是一个涉及知识面非常广泛,又是一个比较难于解决的课题,即使对于数据库老手也是一个比较头痛的问题。这篇文章从参数嗅探是什么,如何产生,表象是什么,会带来哪些问题,如何解决这五个方面来探讨参数嗅探的来龙去脉,期望能够将SQL Server参数嗅探问题理清楚,道明白。 什么参数嗅探 当SQL Server第一次执行查询语句或存储过程(或者查询语句与存储过程被强制
摘要
MSSQL Server参数嗅探既是一个涉及知识面非常广泛,又是一个比较难于解决的课题,即使对于数据库老手也是一个比较头痛的问题。这篇文章从参数嗅探是什么,如何产生,表象是什么,会带来哪些问题,如何解决这五个方面来探讨参数嗅探的来龙去脉,期望能够将SQL Server参数嗅探问题理清楚,道明白。
什么参数嗅探
当SQL Server第一次执行查询语句或存储过程(或者查询语句与存储过程被强制重新编译)的时候,SQL Server会有一个进程来评估传入的参数,并根据传入的参数生成对应的执行计划缓存,然后参数的值会伴随查询语句或存储过程执行计划一并保存在执行计划缓存里。这个评估的过程就叫做参数嗅探。
参数嗅探是如何产生的
SQL Server对查询语句编译和缓存机制是SQL语句执行过程中非常重要的环节,也是SQLOS内存管理非常重要的一环。理由是SQL Server对查询语句编译过程是非常消耗系统性能,代价昂贵的。因为它需要从成百上千条执行路径中选择一条最优的执行计划方案。所以,查询语句可以重用执行计划的缓存,避免重复编译,以此来节约系统开销。这种编译查询语句,选择最优执行方案,缓存执行计划的机制就是参数嗅探问题产生的理论基础。
参数嗅探的表象
以上是比较枯燥的理论解释,这里我们来看看两个实际的例子。在此,我们以AdventureWorks2008R2数据库中的Sales.SalesOrderDetail表做为我们测试的数据源,我们挑选其中三个典型的产品,ProductID分别为897,945和870,分别对应的订单总数为2,257和4688。
挑选的方法如下:
use AdventureWorks2008R2
GO
;WITH DATA
AS(
select ProductID, COUNT(1) as order_count, rowid = ROW_NUMBER() OVER(ORDER BY COUNT(1) asc)
from Sales.SalesOrderDetail with(nolock)
group by ProductID
)
SELECT *
FROM DATA
WHERE rowid in (1, 266, 133)
得到如下结果:
01__Product
查询语句的参数嗅探表象
接下来,我们看三个非常相似的查询语句(仅传入的参数值不同)的执行计划有什么差异。
三个查询语句:
use AdventureWorks2008R2
GO
SELECT SalesOrderDetailID, OrderQty
FROM Sales.SalesOrderDetail WITH(NOLOCK)
WHERE ProductID = 897;
SELECT SalesOrderDetailID, OrderQty
FROM Sales.SalesOrderDetail WITH(NOLOCK)
WHERE ProductID = 945;
SELECT SalesOrderDetailID, OrderQty
FROM Sales.SalesOrderDetail WITH(NOLOCK)
WHERE ProductID = 870;
分别的执行计划:
02__
从这个执行计划对比来看,ProductID为945和897的两条语句执行计划一致,因为满足条件的记录数非常少,分别为257条和2条,所以SQL Server均选择走最优执行计划Index Seek + Key Lookup。但是与ProductID为870的查询语句执行计划完全不同,这条语句SQL Server选择走的是Clustered Index Scan,几乎等价于Table Scan的性能消耗。这是因为,SQL Server认为满足条件ProductID = 870的记录数太多,达到了4688条记录,与其走Index Seek + Key Lookup,还不如走Clustered Index Scan顺序IO的效率高。从这里可以看出,SQL Server会因为传入参数值的不同而选择走不同的执行计划,执行效率也大不相同。确切的说,这个就是属于查询语句的参数嗅探问题范畴。
存储过程的参数嗅探表象
上一小节,我们看了查询语句的参数嗅探表象,这一小节我们来看看存储过程参数嗅探的表象又是如何的呢?
首先,我们创建如下存储过程:
USE AdventureWorks2008R2
GO
CREATE PROCEDURE UP_GetOrderIDAndOrderQtyByProductID(
@ProductID INT
)
AS
BEGIN
SET NOCOUNT ON
SELECT
SalesOrderDetailID
, OrderQty
FROM Sales.SalesOrderDetail WITH(NOLOCK)
WHERE ProductID = @ProductID;
END
GO
接下来,我们执行两次这个存储过程,传入不同的参数:
EXEC dbo.UP_GetOrderIDAndOrderQtyByProductID 870
EXEC dbo.UP_GetOrderIDAndOrderQtyByProductID 945
从这个执行计划来看,ProductID为870和945走的相同的执行计划Clustered Index Scan,这个和上一小节得到的结果是不一样的。上一节中ProductID = 945的查询语句执行计划走的是Index Seek + Key Lookup。
03_SP_
当我们选择第二个执行计划的Clustered Index Scan的时候,我们观察Properties中的Estimated Number of Rows,这里显示的是4668,但实际上正确得行数应该是257。如下如所示:
04_SP_
这到底是为什么呢?从另外一个角度来讲,这个不正确的统计估值甚至会导致SQL Server走到一个不是最优的执行计划上来(根据上一小节,ProductID = 945的最优执行计划其实是Index Seek + Key Lookup)。
答案其实就是存储过程的参数嗅探问题。这是因为,我们在首次执行这个存储过程的时候,传入的参数ProductID = 870对应的订单总数为4668,SQL Server在编译,缓存执行计划的时候,连同这个值一起记录到执行计划缓存中了。从而影响到存储过程的第二次及以后的执行计划方案,进而影响到存储过程的执行效率。
我们可以通过如下方法来查看执行计划中传入参数的值,右键 => Show Execution Plan XML => 搜索 ParameterCompiledValue
05__
在此例中,我们很清楚的发现传入参数值是870,同时也很清楚得看到了参数嗅探对于执行计划的影响:
...
...
至此,我们分别从查询语句和存储过程两个方便看到了参数嗅探的表象。
参数嗅探导致的问题
从参数嗅探的表象这一章节,我们可以对此参数嗅探的问题窥探一二。但是,参数嗅探可能会导致哪些常见的问题呢?根据我们的经验,如果你遭遇了MSSQL Server以下奇怪问题,你可能就遇到参数嗅探这个“大魔头”了。
ALTER PROCEDURE解决性能问题
某些传入参数导致存储过程执行非常缓慢,但是ALTER PROCDURE(所有代码没做任何改动)后,性能恢复正常。这个场景是我们之前经常遇到的,原因是当你ALTER PROCEDURE后,MSSQL Server会主动清除对应的存储过程执行计划缓存,然后再次执行该存储过程的时候,系统会重新编译并缓存该存储过程执行计划。
相同的存储过程,相同的传入参数,执行时快时慢
这个听起来非常奇怪吧,当我们执行相同的存储过程,传入相同的参数值,但是执行效率时快时慢,请注意下面例子中的注释部分。
USE AdventureWorks2008R2
GO
--SQL Server 创建执行计划,优化ProductID = 870对应的大量订单量,运行时间500毫秒
EXEC dbo.UP_GetOrderIDAndOrderQtyByProductID 870
--SQL Server直接获取缓存中的执行计划,对于小量订单来说可能不是最好的执行计划,不过没关系,执行时间450毫秒
EXEC dbo.UP_GetOrderIDAndOrderQtyByProductID 945
现在我们清空了执行计划缓存,为了方便,我直接清除所有的执行计划缓存。
DBCC FREEPROCCACHE
再次执行存储过程,这次我们交换了执行顺序,先执行ProductID 945,然后执行ProductID 870。
USE AdventureWorks2008R2
GO
--SQL Server 创建执行计划,优化ProductID = 945,对应于小量订单的最优执行计划,运行时间100毫秒
EXEC dbo.UP_GetOrderIDAndOrderQtyByProductID 945
--SQL Server直接获取缓存中的执行计划,对于大量订单的ProductID 870来说,可能是很差的执行计划,执行时间60秒
EXEC dbo.UP_GetOrderIDAndOrderQtyByProductID 870
从这两个批次执行的时间对比来看,ProductID 945和870执行时间有比较大的差异,特别是ProductID = 870。这种相同的存储过程,相同的传入参数,执行时快时慢的问题,也是由于参数嗅探导致的。
注意:这里只是为了描述这种现象,由于表数据量本来不大的原因,可能实际上执行时间可能没有那么大的差异。
查询语句放在存储过程中和单独执行效率差异大
某一个查询语句,放在存储过程中执行和拿出来单独执行,时间消耗差异大,一般情况是拿出来单独执行的语句很快,放到存储过程中执行很慢。这个情况也是我们在产品环境常见的一种典型参数嗅探导致的问题。
参数嗅探的解决方法
上一节,我们探讨了参数嗅探可能会导致的问题。当发现这些问题的时候,我们来看看两类人的不同解决方法。请允许我将这两类人分别命名为菜鸟和老鸟,没有任何歧视,只是一个名字代号而已。
菜鸟的解决方法
菜鸟的理论很简单粗暴,既然参数嗅探是因为查询语句或者存储过程的执行计划缓存导致,那么我只需要清空内存就可以解决这个问题了嘛。嗯,来看看菜鸟很傻很天真的做法吧。
方法一:重启Windows OS。果然很黄很暴力,重启Windows操作系统,彻底清空Windows所有内存内容。
方法二:重启SQL Server Service。稍微温柔一点点啦,重启SQL Server Service,彻底清空SQL Server占用的所有内存,当然执行计划缓存也被清空了。
方法三:DBCC命令清空SQL Server执行计划缓存。又温柔了不少吧,彻底清空了SQL Server所有的执行计划缓存,包含有问题的和没有问题的缓存。
DBCC FREEPROCCACHE
老鸟的解决方法
当菜鸟还在为自己的解决方法解决了参数嗅探问题而沾沾自喜的时候,老鸟的思维已经走得很远很远了,老鸟就是老鸟,是菜鸟所望尘莫及的。老鸟的思维逻辑其实也很简单,既然是某个或者某些查询语句或存储过程的执行计划缓存有问题,那么,我们只需要重新编译缓存这些害群之马就好了。
方法一:创建存储过程使用WITH RECOMPILE
USE AdventureWorks2008R2
GO
ALTER PROCEDURE dbo.UP_GetOrderIDAndOrderQtyByProductID(
@ProductID INT
)
WITH RECOMPILE
AS
BEGIN
SET NOCOUNT ON
SELECT
SalesOrderDetailID
, OrderQty
FROM Sales.SalesOrderDetail WITH(NOLOCK)
WHERE ProductID = @ProductID;
END
GO
再重新执行两次存储过程,传入不同的参数值,我们可以看到均走到最优的执行计划上来了,说明参数嗅探的问题已经解决。这个方法带来的一个问题就是每次执行这个存储过程系统都会重新编译,无法使用执行计划缓存。但是相对来说,重新编译的系统开销要远远小于参数嗅探导致的系统性能消耗,所以,两害取其轻。
06__WITH_RECOMPILE
方法二:查询语句使用Query Hits
如果我们知道ProductID对应的订单总数分布,认为ProductID = 945为最好的执行计划,那么我们可以强制SQL Server按照参数输入945来执行存储过程,我们可以添加Query Hits来实现。这种方法的难点在于对表中数据分布有着精细的认识,可操作性不强,因为表中数据分布是随时在改变的。
USE AdventureWorks2008R2
GO
ALTER PROCEDURE dbo.UP_GetOrderIDAndOrderQtyByProductID(
@ProductID INT
)
AS
BEGIN
SET NOCOUNT ON
SELECT
SalesOrderDetailID
, OrderQty
FROM Sales.SalesOrderDetail WITH(NOLOCK)
WHERE ProductID = @ProductID
--OPTION (RECOMPILE);
OPTION (OPTIMIZE FOR (@ProductID=945));
--OPTION (OPTIMIZE FOR (@ProductID UNKNOWN));
END
GO
方法三:DBCC清除特定语句或存储过程缓存
当清除执行计划缓存后,SQL Server再次执行会重新编译对应语句或者存储过程,以获得最好的执行计划。在此以清除特定存储过程执行计划缓存为例。
USE AdventureWorks2008R2
GO
declare
@plan_id varbinary(64)
;
SELECT TOP 1 @plan_id = cache.plan_handle
FROM sys.dm_exec_cached_plans cache
CROSS APPLY sys.dm_exec_query_plan(cache.plan_handle) AS pla
CROSS APPLY sys.dm_exec_sql_text(cache.plan_handle) AS txt
WHERE pla.objectid = object_id(N'UP_GetOrderIDAndOrderQtyByProductID','P')
and txt.objectid = object_id(N'UP_GetOrderIDAndOrderQtyByProductID','P')
DBCC FREEPROCCACHE (@plan_id);
GO
方法四:更新表对象统计信息
表统计信息过时导致执行计划评估不准确,进而影响查询语句执行效率。这个也是导致参数嗅探问题另一个重要原因。这种情况,我们只需要手动更新表统计信息。这个解决方法的难点在于找到有问题的查询语句和对应有问题的表。统计信息更新方法如下,如果发现StatsUpdated时间太过久远就应该是被怀疑的对象:
USE AdventureWorks2008R2
GO
UPDATE STATISTICS Sales.SalesOrderDetail WITH FULLSCAN;
SELECT
name AS index_name
, STATS_DATE(OBJECT_ID, index_id) AS StatsUpdated
FROM sys.indexes
WHERE OBJECT_ID = OBJECT_ID('Sales.SalesOrderDetail')
GO
方法五:重整表对象索引
另外一个导致执行计划评估不准确的重要原因是索引碎片过高(超过30%),这个也会导致参数嗅探问题的重要原因。这种情况我们需要手动重整索引碎片,方法如下:
USE AdventureWorks2008R2
GO
select
DB_NAME = DB_NAME(database_id)
,SCHEMA_NAME = SCHEMA_NAME(schema_id)
,OBJECT_NAME = tb.name
,ix.name
,avg_fragmentation_in_percent
from sys.dm_db_index_physical_stats(db_id(),object_id('Sales.SalesOrderDetail','U'),NULL,NULL,'LIMITED') AS fra
CROSS APPLY sys.indexes AS ix WITH (NOLOCK)
INNER JOIN sys.tables as tb WITH(NOLOCK)
ON ix.object_id = tb.object_id
WHERE ix.object_id = fra.object_id
and ix.index_id = fra.index_id
USE AdventureWorks2008R2
GO
ALTER INDEX PK_SalesOrderDetail_SalesOrderID_SalesOrderDetailID
ON Sales.SalesOrderDetail REBUILD;
方法六:创建缺失的索引
还有一个重要的导致执行计划评估不准确的因素是表缺失索引,这个也是会导致参数嗅探的问题。查找缺失索引的方法如下:
USE AdventureWorks2008R2
GO
SELECT TOP 10
database_name = db_name(details.database_id)
, schema_name = SCHEMA_NAME(tb.schema_id)
, object_name = tb.name
, avg_estimated_impact = dm_migs.avg_user_impact*(dm_migs.user_seeks+dm_migs.user_scans)
, last_user_seek = dm_migs.last_user_seek
, create_index =
'CREATE INDEX [IX_' + OBJECT_NAME(details.OBJECT_ID,details.database_id) + '_'
+ REPLACE(REPLACE(REPLACE(ISNULL(details.equality_columns,''),', ','_'),'[',''),']','')
+ CASE
WHEN details.equality_columns IS NOT NULL
AND details.inequality_columns IS NOT NULL THEN '_'
ELSE ''
END
+ REPLACE(REPLACE(REPLACE(ISNULL(details.inequality_columns,''),', ','_'),'[',''),']','')
+ ']'
+ ' ON ' + details.statement
+ ' (' + ISNULL (details.equality_columns,'')
+ CASE WHEN details.equality_columns IS NOT NULL AND details.inequality_columns
IS NOT NULL THEN ',' ELSE
'' END
+ ISNULL (details.inequality_columns, '')
+ ')'
+ ISNULL (' INCLUDE (' + details.included_columns + ')', '')
FROM sys.dm_db_missing_index_groups AS dm_mig WITH(NOLOCK)
INNER JOIN sys.dm_db_missing_index_group_stats AS dm_migs WITH(NOLOCK)
ON dm_migs.group_handle = dm_mig.index_group_handle
INNER JOIN sys.dm_db_missing_index_details AS details WITH(NOLOCK)
ON dm_mig.index_handle = details.index_handle
INNER JOIN sys.tables AS tb WITH(NOLOCK)
ON details.object_id = tb.object_id
WHERE details.database_ID = DB_ID()
ORDER BY Avg_Estimated_Impact DESC
GO
方法七:使用本地变量
这是一个非常奇怪的解决方法,使用这种方法的原因是,对于本地变量SQL Server使用统计密度来代替统计直方图,它会认为所有的本地变量均拥有相同的统计密度,即对应于相同的记录数。这样可以避免因为数据分布不均匀导致的参数嗅探问题。
USE AdventureWorks2008R2
GO
ALTER PROCEDURE dbo.UP_GetOrderIDAndOrderQtyByProductID(
@ProductID INT
)
AS
BEGIN
SET NOCOUNT ON
DECLARE
@Local_ProductID INT
;
SET
@Local_ProductID = @ProductID
;
SELECT
SalesOrderDetailID
, OrderQty
FROM Sales.SalesOrderDetail WITH(NOLOCK)
WHERE ProductID = @Local_ProductID
END
GO
至此结束,本节分享了菜鸟和老鸟关于参数嗅探问题的解决方法,我相信大家应该可以轻松的做出正确选择适合自己的解决方法。
补充说明
以上所有代码的测试环境是在MSSQL Server 2008R2 Enterprise中完成。
Microsoft SQL Server 2008 R2 (SP2) - 10.50.4000.0 (X64) Jun 28 2012 08:36:30 Copyright (c) Microsoft Corporation Enterprise Edition (64-bit) on Windows NT 6.1 (Build 7601: Service Pack 1) (Hypervisor)
本文为云栖社区原创内容,未经允许不得转载,如需转载请发送邮件至yqeditor@list.alibaba-inc.com;如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:yqgroup@service.aliyun.com 进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
↧
微软MS17-010补丁下载直链地址
↧
↧
关于Class对象、类加载机制、虚拟机运行时的内存布局的全面解析和推测
简介:
本文是对Java的类加载机制,Class对象,反射原理等相关概念的理解、验证和Java虚拟机中内存布局的一些推测。本文重点讲述了如何理解Class对象以及Class对象的作用。
欢迎探讨,如有错误敬请指正
如需转载,请注明出处 http://www.cnblogs.com/nullzx/
(图片来自于http://blog.csdn.net/u011080472/article/details/51332866)
当一个ClassLoader对象需要加载某个类时,在它试图亲自搜索某个类之前,先把这个任务委托给它的父类加载器,父类加载器继续向上委托,直到BootstrapClassLoader类加载器为止。即,首先由最顶层的类加载器BootstrapClassLoader在指定目录试图加载目标类,如果没加载到,则把任务回退给ExtensionClassLoader,让它在指定目录进行加载,如果它也没加载到,则继续回退给App ClassLoader 进行加载,以此类推。如果所有的加载器都没有找到该类,则抛出ClassNotFoundException异常。否则将这个找到的“*.class”文件进行解析,最后返回表示该类的Class对象。
java代码中我们只能使用ExtensionClassLoader和AppClassLoader的实例,这两种类加载器分别有且只有一个实例。我们无法通过任何方法创建这两个类的额外的实例,可以理解为设计模式中的单例模式。
1.3 为什么要使用双亲委托这种模型呢?
1)这样可以避免重复加载,当父亲已经加载了该类的时候,就没有必要子加载器再加载一次。
2)核心类通过Java自带的加载器加载,可以确保这些类的字节码没有被篡改,保证代码的安全性。
JVM在判定两个Class对象是否相同时,不仅要满足两个类名相同,而且要满足由同一个类加载器加载。只有两者同时满足的情况下,JVM才认为这两个Class对象是相同的。
1.4 自定义类加载器
除了Java默认提供的三个类加载器之外,用户还可以根据需要定义自已的类加载器,自定义的类加载器都必须继承自java.lang.ClassLoader类。
既然JVM已经提供了默认的类加载器,为什么还要定义自已的类加载器呢?
1)因为Java中提供的默认ClassLoader,只加载指定目录下的jar和class,如果我们想加载其它位置的class文件或jar时就需要定义自己的ClassLoader。
2)对于那些已经加密过的Class文件,自定义ClassLoader可以在解析Class文件前,进行解密操作。这样相互配合的方式保证了代码的安全性。
1.5 定义自已的类加载器的步骤
主要分为两步
1)继承java.lang.ClassLoader
2)重写父类的findClass方法
下面是API文档中给出的自定义加载器的实现模型
下面的代码是一个类加载器的具体实现。MyClassLoader类加载器主要加载任意指定目录下的“*.class”文件,而这个指定的目录又不在环境变量ClassPath所表示的目录中。
通过代码实现可以看出,自定义类加载器的核心精髓是调用ClassLoader类中的defineClass方法。
下面是运行结果
从运行结果看出,MyClassLoader的父加载器是AppClassLoader(这是在ClassLoader的构造函数中实现的)。Person.Class由MyClassLoader加载(父类加载器都没有加载成功),而当MyClassLoader加载String.class时,委托到BootstrapClassLoader加载,发现BootstrapClassLoader已加载完毕,结果null表示String类的加载器是BootstrapClassLoader。
Person类
运行结果
4.3 Class对象有哪些功能?
1)反射(关于反射的使用会在后续博客中讲解)
2)多态的实现。
我们通过以下代码来讲解Class对象在多态中的应用
运行结果
我们定义的静态方法speakByType,显然编译器在编译这个方法的时候不能确定到底调用哪一个speak方法,需要依据对象的具体类型才能确定符号引用。
现在我们通过工具重点查看一下speakByType的字节码
我们发现里面出现了一条字节码调用语句 invokevirtual方法。而invokevirtual指令在执行时,首先会找到当前对象的类的Class对象,然后通过该Class对象查找sepak方法,如果通过该Class对象查找到了签名一致的的sepak方法就会调用它。每个Class对象都会持有表示父类的Class对象的引用(通过Class的getSuperClass方法获取),Object.class除外,自己想想为啥?否则从其父类的Class对象中继续查找签名一致的speak方法。显然如果没有找到,会沿着有继承关系的Class的路径继续向下查找,如果直到Object.class对象中还未找到就会抛出异常。
3)instace of和向上转型
当我们判断某个对象是否属于某个类时,比如 a instance of A,显然只要判断
a.getClass() == A.class && a.getClass().classLoader() == A.classLoader()即可,如果不满足就沿着getSuperClass的路径继续向下找,如果直到Object.class还不满足条件就返回false。同理在运行时,我们还能依据Class对象判断向上转型是否正确。
4.4 Class.class对象存在的意义是什么?
我们通常不会通过Class.class对象来间接访问forName方法和其它相应方法,而是直接使用该类的方法。所以一种可能的情况就是利用Class对象进行类型判断,即判断一个对象是不是Class对象还是普通对象(判断obj.getClass() == Class.class是否成立)。另一种可能就是保持概念的完整性,每一个类都有一个Class对象与之对应。
4.5 假设B类继承了A类,那么B类的实例在内存中应该是什么样子的?
java语言的设计者考虑到对象向上转型等问题,每一个类的数据成员显然要按照继承关系的先后顺序排列,同时考虑执行效率,还存在数据对齐等问题。
4.6 Java在运行时的内存布局
用一个例子来看看javaVM运行时,类、对象、Class对象、ClassLoader的关系
运行结果
通过上面的结果,我们可以推测这些对象,方法,加载器等在堆和栈中布局的一种可能。
在堆区中,我们一般的对象我们用浅黄色表示,Class对象用浅蓝色表示(原谅我的辨色能力,什么颜色请自行体会)。
在堆区中,绿色箭头表示getClass方法返回的对象。显然,非Class对象的getClass方法返回这个类对应的Class对象。Class类继承Object类,Object类定义了getClass方法,所有的Class对象也有getClass方法。如果把Class对象看成普通对象,那么它的getClass方法就会返回表示整个Class类的Class对象,即Class.class。而Class.class对象的getClass方法返回它本身。
堆区中,每个Class对象的黑色虚线都指向了方法区中表示该类的全部信息,所以我们能够通过Class对象进行反射操作。
堆区中的黑色实线表示Class对象的getSupperClass方法返回的对象,由于所有的类都继承于Object类,所以有的Class对象最终都指向于Object.clss,而Object.class没有父类。
我们想要实现反射,一般使用Class.forName方法进行类加载,forName方法本质上就是调用ClassLoadr实例的loadClass方法。推测,为了方便每个加载器查找某个类是否已加载器过,每个类加载器可能都有一张表,记录每个已加载的类和对应Class对象的地址。
4.7 数组与Class对象
不同数据类型,不同维度的数组都对应不同的Class对象
所有具有相同元素类型和维数的数组都共享该 Class 对象。
由于数组没有构造函数,我们也就没有办法通过它的Class对象直接创建数组对象。为了实现这个功能,JDK中就提供了Array类(java.lang.reflect.Array)来弥补这个缺陷。有关Array类的功能和使用,请参考Java的API文档,注意区分java.util.Arrays类。
1. 类加载机制
当我们编写好一个“.java”文件,通过javac编译器编译后会形成一个“.class”文件。当我们运行该文件时,Java虚拟机就通过类加载器(类加载器本质就是一段程序)把“.class”文件加载到内存,在方法区形成该类各方法的代码段和描述该类细节信息的常量池,同时在堆区形成一个表示该类的Class对象(java.lang.Class类的实例)。Class对象中存储了指向了该类的属性和方法的所有详细信息的指针(同时,还存储了指向该类的父类的Class对象的指针)。我们能够通过Class对象直接创建该类的实例,并调用该类的所有方法,这就是我们所说的反射。 类加载器不仅仅可以加载本地文件系统中的“.class”文件,还可以通过各种形式进行加载,比如通过网络上的获取的数据流作为 “.class”。 类加载器本质上是实现一个解析的工作,把表示该类的字节数据变成方法区中的字节码和并在堆区产生表示该类的Class对象。 1.1 类加载器(ClassLoader)的层次结构 Java默认提供的三个ClassLoader(JAVA_HOME表示JDK的安装目录) BootStrapClassLoader:称为启动类加载器,是Java类加载层次中最顶层的类加载器,负责加载JAVA_HOME\jre\lib目录下JDK中的核心类库,如:rt.jar、resources.jar、charsets.jar等。该加载器不是ClassLoader的子类,由C/C++语言实现其功能。 ExtensionClassLoader:称为扩展类加载器,负责加载Java的扩展类库,默认加载JAVA_HOME\jre\lib\ext目下的所有jar。它是ClassLoader的子类,由Java语言实现。 AppClassLoader:称为应用程序类加载器,负责加载当前应用程序目录下的所有jar和class文件以及环境变量CLASSPATH指定的jar(即JAVA_HOME/lib/dt.jar和JAVA_HOME/lib/tools.jar)和第三方jar。AppClassLoader是ClassLoader的子类,由Java语言实现。 注意JDK中有两个lib目录,一个是JAVA_HOME/lib,另一个是JAVA_HOME/jre/lib。 在java中,还存在两个概念,分别是系统类加载器和线程上下文类加载器,其实都是指是AppClassLoader加载器。 1.2 类加载器双亲委派模型 ClassLoader使用的是双亲委托来搜索类的。每个ClassLoader实例都有一个父类加载器的引用(不是继承的关系,是一个包含的关系)。 AppClassLoader的父加载器是ExtensionClassLoader,而Extension ClassLoader的父加载器是BootstrapClassLoader,而Bootstrap ClassLoader是虚拟机内置的类加载器,本身没有父加载器。
1
2
3
4
5
6
7
8
9
10
11
12
13
14 |
class NetworkClassLoader extends ClassLoader { String host; int port; public Class findClass(String name) { byte [] b = loadClassData(name); return defineClass(name, b, 0 , b.length); } private byte [] loadClassData(String name) { // load the class data from the connection . . . } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 |
package demo; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; public class MyClassLoader extends ClassLoader { private String path; @Override public Class<?> findClass(String name){ byte [] data = null ; try { data = loadClassData(path); } catch (IOException e) { e.printStackTrace(); } return defineClass(name, data, 0 , data.length); } private byte [] loadClassData(String path) throws IOException{ File f = new File(path); FileInputStream fis = new FileInputStream(f); byte [] data = new byte [( int ) f.length()]; fis.read(data); fis.close(); return data; } /* * 定义了带两个参数的loadClass方法,为了多传递一个path参数 * 内部一定要调用父类的loadClass方法,因为该方法内实现了双亲委派模型 */ public Class<?> loadClass(String path, String name) throws ClassNotFoundException{ this .path = path; return super .loadClass(name); } public static void main(String[] args) throws ClassNotFoundException{ MyClassLoader mcl = new MyClassLoader(); /*打印当前类加载器的父加载器*/ System.out.println(mcl.getParent()); System.out.println( "==========" ); Class<?> cls1 = mcl.loadClass( "D:/用户目录/我的文档/Eclipse/Person.class" , "javalearning.Person" ); System.out.println(cls1.getClassLoader()); System.out.println( "==========" ); Class<?> cls2 = mcl.loadClass( null , "java.lang.Thread" ); System.out.println(cls2.getClassLoader()); System.out.println( "==========" ); } } |
1
2
3
4
5
6 |
sun.misc.Launcher$AppClassLoader @4e0e2f2a ========== demo.MyClassLoader @2a139a55 ========== null ========== |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 |
package javalearning; public class Person{ public int age; public String name; public Person(){ name = "zx" ; age = 18 ; } @Override public String toString(){ return name + " " + age; } } |
2. 谈谈java.lang.Class和java.lang.Object之间的悖论
通过java的语法学习,我们知道以下三点 1)java.lang.Class类继承java.lang.Object类 2)按照语法规则,创建一个java.lang.Class对象必须先创建它的父类(java.lang.Object)的一个对象 3)按照语法规则,创建一个类的对象,必须先存在表示该类的java.lang.Class对象 但是这三点又是矛盾的。这两个对象的创建没有办法顺序实现。所以不是先创建好一个,再创建另一个,而是通过自举实现的,也就是说是两个对象同时创建好。自举程序本身不是由Java语言实现的,而是由C和C++实现的。 所有的java.lang.Class对象的创建不是通过构造函数创建的,而是通过加载器生成的。每个类都有对应的用于反射该类的Class对象,每个类有且只对应一个Class对象。 每一个类都从Object类中继承了一个getClass的实例方法,返回该类对应的Class对象。 Class.class对象有两层含义。第一,它是一个Class类的实例。第二,它又又表示是Class类本身用于反射的对象,所以该对象的getClass方法返回它本身。我们不能通过Class.class的newInstance方法产生Class类的实例,如果这么做,会抛出异常。另一个方面,假设能够产生这样的对象,我们怎么知道这个对象应该对应哪一个类呢?3. 谈谈java.lang.Class和类加载器之间的悖论
类加载器也是一个类,也有对应的Class对象,但是Class对象又必须通过加载器的实例产生,显然这两点又是矛盾的。 三个默认的类加载器中ExtensionClassLoader和AppClassLoader是由java代码实现的,而BootstrapClassLoader是由C/C++实现的。也就是说BootstrapClassLoader没有,不需要有,也不可能有对应Class对象。ExtensionClassLoader类的实例和它对应ExtensionClassLoader.class对象都是由BootstrapClassLoader一并加载创建完成。然后再由ExtensionClassLoader对象加载AppClassLoader.class。4 java.lang.Class对象和对象的内存布局
4.1 Class对象中到底存了什么? 从已有资料来看,Class对象在不同的虚拟机在实现上存储的内容都不一致,但是理论上来讲, Class对象内部一定存储了方法区中该类的所有方法签名,属性签名,和每个方法对应的字节码的地址。 4.2 实例和实例方法之间的关系? obj.setName(“zhang san”) 在实际执行过程中等价于 setName(obj, “zhang san”) 也就是对象时作为参数传递到实例方法里面的,对象本身不含指向方法的指针(这里说的是非Class对象)。方法的具体实现都位于方法区中相应的代码段中。当虚拟机调用该方法时,只要将虚拟机执行引擎的PC(程序计数器)指向该方法的地址,然后将实例对象传递给该方法即可。通过实例直接调用方法时,实际上没有,也没有必要通过Class对象。 下面的示例表示了,锁住Person.Class对象不能阻止其它线程的代码创建该对象的实例,并调用实例方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 |
package javalearning; public class ClassLockTest { public static class T1 extends Thread{ private Class<?> cls; private boolean done; public T1(Class<?> cls){ this .cls = cls; } @Override public void run() { synchronized (cls){ while (!done){ } } } public void done(){ done = true ; } } public static void main(String[] args) throws InterruptedException{ /*我们先让线程t1锁住Person.class对象,然后在主线程中创建该对象的实例,并调用toString方法*/ Class<?> cls = Person. class ; T1 t1 = new T1(cls); t1.start(); while (!t1.isAlive()){ System.out.println( "t1 is not alive" ); Thread.sleep( 500 ); } Person p = new Person(); System.out.println(p); t1.done(); System.out.println( "over" ); } } |
1
2 |
zx 18 over |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 |
package demo; public class ClassObjectDemo1 { /*定义两个具有继承关系的类,两个类内部有同一个方法的不同实现*/ public static class Person{ public void speak(){ System.out.println( "i am a person" ); } } public static class Coder extends Person{ public void speak(){ System.out.println( "i am a coder" ); } } /*定义了一个静态方法,静态方法会调用对应类型的speak方法*/ public static void speakByType(Person p){ p.speak(); } public static void main(String[] args) { Person p0 = new Coder(); speakByType(coder); Person p1 = new Person(); speakByType(person); } } |
1
2 |
i am a coder i am a person |
1
2
3
4
5
6
7 |
public static void speakByType(demo.ClassObjectDemo1$Person p) { /* L20 */ 0 aload_0; /* p */ 1 invokevirtual 16 ; /* void speak() */ /* L21 */ 4 return ; } |

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 |
package demo; import java.lang.reflect.InvocationTargetException; public class ClassObjectDemo0 { /*定义两个具有继承关系的类,两个类内部都为空*/ public static class Person{ } public static class Coder extends Person{ } /*哈哈,main函数抛出的异常似乎有点多*/ public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InterruptedException{ /*通过对象找到该类的Class对象*/ Coder coder = new Coder(); System.out.println(coder.getClass()); System.out.println( "========================" ); /*通过Class对象可以看出继承关系*/ System.out.println(Coder. class ); System.out.println(Coder. class .getSuperclass()); System.out.println(Coder. class .getSuperclass().getSuperclass()); System.out.println( "========================" ); /*查看每个Class对象的类加载器*/ System.out.println(Coder. class .getClassLoader()); System.out.println(Person. class .getClassLoader()); System.out.println(Object. class .getClassLoader()); System.out.println( "========================" ); /*每个Class对象都是Class类的实例*/ System.out.println(Coder. class .getClass()); System.out.println(Person. class .getClass()); System.out.println(Object. class .getClass()); System.out.println( "========================" ); /*Class.class的getClass方法会返回它本身*/ System.out.println(Class. class .getClass()); /*产看Class对象的的父类*/ System.out.println(Class. class .getSuperclass()); } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 |
/*通过对象找到该类的Class对象*/ class demo.ClassObjectDemo$Coder ======================== /*通过Class对象可以看出继承关系*/ class demo.ClassObjectDemo$Coder class demo.ClassObjectDemo$Person class java.lang.Object ======================== /*查看每个Class对象的类加载器*/ sun.misc.Launcher$AppClassLoader @4e0e2f2a sun.misc.Launcher$AppClassLoader @4e0e2f2a null /*说明Object类的加载器是BootstrapClassLoader*/ ======================== /*每个Class对象都是Class类的实例*/ class java.lang.Class class java.lang.Class class java.lang.Class ======================== /*Class.class的getClass方法会返回它本身*/ class java.lang.Class ======================== /*查看Class.class对象的父类*/ class java.lang.Object |

1
2
3
4
5
6
7
8
9
10
11
12 |
package javalearning; public class ArrayTest { public static void main(String[] args){ int [] a1 = new int [ 10 ]; int [][] a2 = new int [ 5 ][ 3 ]; Class<?> c1 = a1.getClass(); Class<?> c2 = a2.getClass(); System.out.println(c1 == c2); /*结果false*/ System.out.println(c2.getComponentType() == c1); /*结果true*/ } } |
5 参考内容
[1]. classpath、path、JAVA_HOME的作用及JAVA环境变量配置 [2]. 深入分析Java ClassLoader原理 [3]. Java魔法堂:类加载器入了个门↧
Timeout expired 超时时间已到. 达到了最大池大小 错误及Max Pool Size设置
参考数据库链接串:
查看应用程序池占用数量:
Max Pool Size:如果未设置则默认为100,理论最大值为32767。最大连接数是连接池能申请的最大连接数,如果数据库连接请求超过此数,后面的数据库连接请求将被加入到等待队列中,这会影响之后的数据库操作。在等待队列中,默认等待与服务器的连接的时间为15秒。
中文错误:
超时时间已到。超时时间已到,但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大小。
英文错误:
Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
问题描述:我们获取连接超过连接池最大值时产生如上异常。通常连接池最大值为100。当我们获取连接超过最大值时,ADO.NET等待连接池返回连接而超时,这样将抛出如上异常
解决办法:首先要做的是在我们使用连接后立即关闭连接。如果没有关闭连接那么连接将保存到连接池中知道GC来销毁。这种情况下你以为连接池没有到达最大值但实际上连接池已经到达了最大值 其次我们可以通过连接字符串中的Max Pool Size = N;来动态扩大连接池中的连接最大数量。
说明:
也就是在connectionString中如果未指定max pool size的值,则max pool size=100,当访问人员同时连接数据库的数量为101人时,则等待SqlConnection.ConnectionTimeout设置的时间(默认是15 秒)后,还是没有可用的Connection则会出现上面的错误。
当我们设置为:
"Server=(local); Integrated Security=SSPI; Database=Northwind; Max Pool Size=512; Min Pool Size=5" 时。则访问人员同时连接数据库的数量为513时,则等待SqlConnection.ConnectionTimeout设置的时间(默认是15 秒)后,还是没有可用的Connection则 就会出现上面的错误。
<add key="data" value="server=192.168.1.123; Port=3306; uid=root; pwd=root;database=data;pooling=true;min pool size=5;max pool size=512;connect timeout = 20; "/>
select * from sysprocesses where dbid= db_id('数据库名')
- Connection Pool 是什么呢 ?
每当程序需要读写数据库的时候。Connection.Open()会使用ConnectionString连接到数据库,数据库会为程序建立 一个连接,并且保持打开状态,此后程序就可以使用T-SQL语句来查询/更新数据库。当执行到Connection.Close()后,数据库就会关闭当 前的连接。很好,一切看上去都是如此有条不紊。
但是如果我的程序需要不定时的打开和关闭连接,(比如说 ASP.Net 或是 Web Service ),例如当Http Request发送到服务器的时候、,我们需要打开Connection 然后使用Select* from Table 返回一个DataTable/DataSet给客户端/浏览器,然后关闭当前的Connection。那每次都Open/Close Connection 如此的频繁操作对于整个系统无疑就成了一种浪费。
ADO.Net Team就给出了一个比较好地解决方法。将先前的Connection保存起来,当下一次需要打开连接的时候就将先前的Connection 交给下一个连接。这就是Connection Pool。
- Connection Pool 如何工作的?
首先当一个程序执行Connection.open()时候,ADO.net就需要判断,此连接是否支持Connection Pool (Pooling 默认为True),如果指定为False, ADO.net就与数据库之间创建一个连接(为了避免混淆,所有数据库中的连接,都使用”连接”描述),然后返回给程序。
如果指定为 True,ADO.net就会根据ConnectString创建一个Connection Pool,然后向Connection Pool中填充Connection(所有.net程序中的连接,都使用”Connection”描述)。填充多少个Connection由Min Pool Size (默认为0)属性来决定。例如如果指定为5,则ADO.net会一次与SQL数据库之间打开5个连接,然后将4个Connection,保存在 Connection Pool中,1个Connection返回给程序。
当程序执行到Connection.close() 的时候。如果Pooling 为True,ADO.net 就把当前的Connection放到Connection Pool并且保持与数据库之间的连接。
同时还会判断Connection Lifetime(默认为0)属性,0代表无限大,如果Connection存在的时间超过了Connection LifeTime,ADO.net就会关闭的Connection同时断开与数据库的连接,而不是重新保存到Connection Pool中。
(这个设置主要用于群集的SQL 数据库中,达到负载平衡的目的)。如果Pooling指定为False,则直接断开与数据库之间的连接。
然后当下一次Connection.Open() 执行的时候,ADO.Net就会判断新的ConnectionString与之前保存在Connection Pool中的Connection的connectionString是否一致。
(ADO.Net会将ConnectionString转成二进制流,所 以也就是说,新的ConnectionString与保存在Connection Pool中的Connection的ConnectionString必须完全一致,即使多加了一个空格,或是修改了Connection String中某些属性的次序都会让ADO.Net认为这是一个新的连接,而从新创建一个新的连接。所以如果您使用的UserID,Password的认 证方式,修改了Password也会导致一个Connection,如果使用的是SQL的集成认证,就需要保存两个连接使用的是同一个)。
然后 ADO.net需要判断当前的Connection Pool中是否有可以使用的Connection(没有被其他程序所占用),如果没有的话,ADO.net就需要判断ConnectionString设 置的Max Pool Size (默认为100),如果Connection Pool中的所有Connection没有达到Max Pool Size,ADO.net则会再次连接数据库,创建一个连接,然后将Connection返回给程序。
如果已经达到了 MaxPoolSize,ADO.net就不会再次创建任何新的连接,而是等待Connection Pool中被其他程序所占用的Connection释放,这个等待时间受SqlConnection.ConnectionTimeout(默认是15 秒)限制,也就是说如果时间超过了15秒,SqlConnection就会抛出超时错误(所以有时候如果SqlConnection.open()方法抛 出超时错误,一个可能的原因就是没有及时将之前的Connnection关闭,同时Connection Pool数量达到了MaxPoolSize。)
如果有可用的Connection,从Connection Pool 取出的Connection也不是直接就返回给程序,ADO.net还需要检查ConnectionString的ConnectionReset属性 (默认为True)是否需要对Connection 最一次reset。这是由于,之前从程序中返回的Connection可能已经被修改过,比如说使用 SqlConnection.ChangeDatabase method 修改当前的连接,此时返回的Connection可能就已经不是连接当前的Connection String指定的Initial Catalog数据库了。所以需要reset一次当前的连接。但是由于所有的额外检查都会增大ADO.net Connection Pool 对系统的开销。
↧
C# 连接池(Connection Pool)的一些个人见解
原文标题:关于ADO.Net连接池(Connection Pool)的一些个人见解
一下是原文:
建立池连接可以显著提高应用程序的性能和可缩放性。SQL Server .NET Framework 数据提供程序自动为 ADO.NET 客户端应用程序提供连接池(MSDN)。
Opening a database connection is a resource intensive and time consuming operation. Connection pooling increases the performance of Web/windows applications by reusing active database connections instead of creating a new connection with every request. Connection pool manager maintains a pool of open database connections. When a new connection requests come in, the pool manager checks if the pool contains any unused connections and returns one if available. If all connections currently in the pool are busy and the maximum pool size has not been reached, the new connection is created and added to the pool. When the pool reaches its maximum size all new connection requests are being queued up until a connection in the pool becomes available or the connection attempt times out.
Connection pooling behavior is controlled by the connection string parameters. Please look into MSDN documents in the reference link if you want to know further information.
前面是关于连接池知识的一些基本介绍,下面的内容是重点,也是个人见解。因为没有这方面的文档资料参考或者佐证,所以请各位仔细思考和讨论(我不想误导大家)。
下面分2种情况进行讨论。
1,Client端的windows form application通过ADO.Net直接访问后台Database。
查看大图
SqlServer DirectConnection
我认为在这种情况下,每一个Client端和Database之间都存在一个连接池。通过设置ConnectiongString的Max Pool Size和Min Pool Size属性来验证。
如Max Pool Size = 5, Min Pool Size = 3, 通过SQL Server的SP_WHO2可以检测导如下结果:
启动1个Client端的Windows form application:application和SQL Server之间存在3个connection。
启动2个Client端的Windows form application:application和SQL Server之间存在6个connection。
启动3个Client端的Windows form application:application和SQL Server之间存在9个connection。
由此可见,每一个Client端和SQL Server之间都存在一个连接池,否则9个connection已经超出了Max Pool Size的设定。
2,Client端的application不直接通过ADO.Net来访问后台Database,而是通过IIS Server来同后台Database Server打交道。
至少有如下2种情况:
(1)Client通过IE访问部署在IIS中的web application,web application中的Data Access Class进一步访问后台Database Server.
(2)Client端的windows form application访问部署在IIS中的Remote Object,Remote Object进一步访问后台Database Server.
查看大图
SqlServer InDirectConnection
下面进行同样的测试:通过设置ConnectiongString的Max Pool Size和Min Pool Size属性来验证。
如Max Pool Size = 5, Min Pool Size = 3, 通过SQL Server的SP_WHO2可以检测导如下结果:
启动1个Client端的Web form application:application和SQL Server之间存在3个connection。
启动2个Client端的Web form application:application和SQL Server之间存在3个connection。
启动3个Client端的Web form application:application和SQL Server之间存在3个connection。
调用由IIS承载的Remote Object,结果类似。只是在未启动Client端之前,发现在Remote Object与Database Server之间已经存在一个connection。
由此可见,对同一个application而言,IIS Server与Database Server之间只有存在一个连接池,与Client端的多少没有关系。
3,连接池小节
根据上面的测试结果,显然第二种情况更有利于减少无用的连接数量,提高Database Server的性能。关于.Net Remoting技术及其性能问题,可以参考如下的Reference连接,这里就不讨论了。
另外,本文是个人关于连接池的一些见解,如果观点有不正确之处,希望不要误导各位。欢迎各位在此发表意见。同意的说赞同,不同意的请提出您的看法。谢谢。
Reference Links:
(1) MSDN, ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/cpguide/html/cpconconnectionpoolingforsqlservernetdataprovider.htm
(2) Microsoft .NET Remoting:技术概述,http://www.microsoft.com/china/MSDN/library/NetFramework/default.mspx
(3) 性能比较:.NET Remoting 与 ASP.NET Web 服务,http://www.microsoft.com/china/msdn/archives/library/dnbda/html/bdadotnetarch14.asp
========================原文结束,开可以参考另外一篇文章:NET 连接池救生员
原文的一些补充观点:
连接的创建和获取:
Q: 如果我最大连接池是5个,那么,在我的程序中,每次访问,我都会使用New一个连接,然后Open,使用以后,然后Close,那么在每次New的时候,会不会创建连接,?
A: 在每次New的时候,如果connection pool中有空闲的连接,则不会创建新连接,否则会创建。
如果超过最多连接数,还能发出New的请求,但是该请求会放入队列,直到connection pool中有空闲连接或连接请求超时。
连接的效率问题:
Q: 要是可以对连接进行控制的话,应该怎么控制,很简单,我现在每次使用数据库访问时,都会New并close,我是担心这样的效率是不是会很低啊,想在连接上提高效率,要怎么操作呢?
A: 使用connection pool时,New并不一定会创建新的连接,如果connection pool中有空闲连接,直接拿来就用。
close也只是将连接放入connection pool,供后续请求使用。因此不会有效率问题。
连接的存活时间:
当连接返回到池中时,将对它的创建时间和当前时间进行比较,如果时间间隔超过由 Connection Lifetime 指定的值(以秒为单位),则会毁坏该连接。在聚集配置中可以使用它来强制在运行服务器和刚联机的服务器之间达到负载平衡。
如果值为零 (0),则将使池连接具有最大的超时期限。默认值为0
SqlConnection.Close和.Dispose的比较:
sqlconnection.close和.dispose的相同地方是:
dispose肯定调用了close,所以close里面有做的事情,dispose都包括
dispose还做了其他的资源的释放,这样在GC第一次回收的时候,省却了dispose的步骤,加快了内存资源的回收速度。
如果没有调用dispose,GC将在第一次回收先做dispose。
如果程序频繁做new sqlconnection(),然后很快就做close并且不再使用这个connection(例如一些com+/asp.net/web service的程序),而且又不做dispose,那么随着这个程序被多次调用,被分配但未能尽快释放的系统资源(通常是内存)会有很多,GC被迫回收的次数也相应增多,系统的整体效率就会变低(GC回收的时候是所有.net程序都暂停,等GC回收跑完才可以继续,造成其他程序也受到影响)。所以对于这种情况,做dispose好。
但如果其他情况,例如Winforms的client,那么没有所谓。
最近发现本站有时候会出现连接不上服务器的现象,通过sp_who查看数据库连接时,发现网站应用程序占用了比较多的连接数,当连接数达到一定数量后,网站就会出现连接不上数据库的错误。那么可以肯定,网站出现错误的原因,是数据库连接没有及时释放的缘故——或者是开辟了太多的连接。网站的数据库访问逻辑没有集中在一个数据库访问类中,而是在用到的时候建立,用完了关闭。那么这种情况是否跟上文讲的第一种情况相同呢?上文的第一种情况应该是针对winform应用程序来说的。但是本站的程序没有想上文说的第二种情况,把数据访问集中在一个数据访问类中。这个问题有待实践来验证。
来源:http://blogs.msdn.com/angelsb/archive/2004/08/25/220333.aspx
作者:angelsb
System.InvalidOperationException: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
Timeout expired 异常是个很棘手的异常,想必几乎每个人都碰到过。有时可真是对它咬牙切齿,拿它没办法。 angelsb这篇文章很好,希望对大家有用。我也是看到他讲得很好,才翻译过来的,水平有限,请多多指教.
System.InvalidOperationException: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
哎!在另一个进程中,又出现了连接池已满的问题,这是个最让人头痛却又是最常出现的连接池问题之一.原因是在开发过程中很少碰到这个头痛的问题,但在部署APP到客户端时,却总是不经意地跑出来了.我想,我应该花些许时间对这个问题进行一次完整的总结吧.
发生的本质是什么?
我们来认真看一下可能会发生这种异常的两种情况
1) 你使用了超过最大的连接池连接数(默认的最大连接数是100)
在大部分应用程序中,这种情况是很少出现的. 毕竟当你使用连接池时,100个并行连接是一个非常大的数字.根据我的经验,会造成这种异常的原因的最大可能,应该是在一个纯种下打开了100个连接.
程序代码
解决方案:如果你确定你将会使用超过100个并行连接(在同一连接字符串上),你可以增加最大连接数.
2) 连接泄漏
我个人认为的连接泄漏定义是你打开了一个连接但你没有在你的代码中执行close()或dispose().这范围不仅仅是你忘记了在connection后连接后使用dispose()或close()对期进行关闭,还包括一些你已经在相关connection后写好了close()却根本没有起作用的情況.我们来看看下面的代码:
程序代码
这就是一个典型的例子,将这段代码复制到visual Studio中,在 sqlconnection1.close()中设置一个断点,编译时可以看到他永远没有执行,因为ExecuteNonQurery抛出了一个异常.之后你应该可以看到恐怖的超时异常了. 在我的机子上,大约有170个连接被打开. 我曾想让其在每次调用的时候将异常抛出来达到降低连接超时出现的机率,但当你考虑到将其部署到一个ASP.NET的应用程序的时候,任何一个泄漏都将让你处于麻烦之中.
3)你是通过visual Studio中的sql debugging 来打开或关闭连接的
这是一个众所周知的Bug,可以看一下下面这个链接
http://support.microsoft.com/default.aspx?scid=kb;en-us;830118
如何在ADO.NET2.0中判断是否是连接泄漏
在1.0或1.1中,我们很难去判断是否是连接泄漏,至多可以通过一些性能指标或诸如此类的工作去实现.但在ADO.NET2.0中,如果你注意到NumberOfReclaimedConnections这个玩艺儿,就可以知道你的应用程序是否是连接泄漏了.
时刻注意修复相关的连接字符串
修改相关的连接字符串可以让你暂时翻译”逃过”一些异常,这是非常诱人的.特别是在一个高性能消耗时,修改它就显示更为必要了.
这里是一些让你的应用程序能”运行良好”的非正常行为(搬起石头砸自己的脚)
不要把Poooling=False
坦白的说,如果你将pooling设为关闭状态,你当然不会再碰到超时异常,可怕的是你的应用程序性能将大大降低,而你的连接仍然处于泄漏状态.
不要把Connection LifeTime=1
这不是一个能清除异常的方法,但它可能是最接近的一个解决方法.你想告诉我们的是将所有的连接超过一秒钟的连接都通通抛弃(正常的生命周期结束应该是在connetcio.close()后).我个人认为这种方法上关闭连接池没什么两样.除非你是在使用数据库的集群,否则你不应设置连接周期来达到目的.
不要将 Connection TimeOut=40000
非常愚蠢的选择,你这是在告诉我们在抛出一个超时异常之前,你在无限地等待一个连接转变为可用的.幸亏在ASP.NET中将会在三分钟之后取消一个进程.
不要将Max PoolSize=4000;
如果你将连接池的最大数设置到足够大的时候,你最终会将这异常停止.但在另一方面,你将占用了你的应用程序中才是真正需要的巨大的连接资源,这种做法只能饮鸠止渴.
解决方案:
你需要保证你每次调用连接的同时都在使用过后通过close()或dispose()对其执行了关闭.最简单的办法就是使用using,将你的连接泄漏方法修改成如下面的代码样式:
public void DoesNotLeakConnections()
{
Using (SqlConnection sqlconnection1 = new SqlConnection("Server=.//SQLEXPRESS ;Integrated security=sspi;connection timeout=5")) {
sqlconnection1.Open();
SqlCommand sqlcommand1 = sqlconnection1.CreateCommand();
sqlcommand1.CommandText = "raiserror ('This is a fake exception', 17,1)";
sqlcommand1.ExecuteNonQuery(); //this throws a SqlException every time it is called.
sqlconnection1.Close(); //Still never gets called.
} // Here sqlconnection1.Dispose is _guaranteed_
}
FAQ:
Q:为什么要这样做
A:使用using结构等同于Try/…/Finally{ <using object>.Dispose() ) 即使当ExecuteNonQuery会抛出一个执行错误时,我们都可以保证finally模块将会执行
Q:我上面的代码中如果没有异常抛出的话,我可以使用close()或dispose()吗
A:我们毫无顾忌地用他们中的任意一个,或两个同时使用.在一个已经close或dipose()的连接中使用close()或dispose()是不会影响的
Q:Close()和Dispose()有什么不同,我应该用哪一个好?
A:它们做的是同一件事,你可以调用他们中的任意一个,或两个同时使用.
Q:你所说的"practically the same thing”是什么意思?
A:Dispose()将会通过sqlConnection来清理相关的连接,之后执行close().它们没有什么本质的区别,你可以通过reflector来证明这点
Q:与close()相比,connection.dispose()会将连接些移除吗?
A:不会
---------------------------------------------------------------
我的分享:
针对"Timeout expired"这个异常,我也查阅了很多资料。在国内我们很多project都会采用MS提供的sqlhelper这个封装类。因为这个类中有本身的缺陷所致,所以出现的"Timeout expiered"异常机率大。我在国外的一篇文章中看到的解决方案是:
将SqlHelper中的cmd.CommandTimeout="你要设置的秒数"加上去,重新编译.
if (trans != null)
cmd.Transaction = trans;
cmd.CommandType = cmdType;
cmd.CommandTimeout = 240;
通过搜索,我找到了相关的一个代码.
这个代码是摘自国人的某位同行的,感谢
http://blog.csdn.net/long2006sky/archive/2007/07/09/1683459.aspx
eg:
**//// <summary>
/// 执行查询语句,返回DataTable
/// </summary>
/// <param name="SQLString">查询语句</param>
/// <param name="commTime">设置查询Timeout</param>
/// <returns>用于复杂查询</returns>
public static DataTable GetDataTable(string SQLString,int commTime)
...{
string connectionString = System.Configuration.ConfigurationManager.AppSettings["connectionString"];
using (System.Data.SqlClient.SqlConnection connection = new System.Data.SqlClient.SqlConnection(connectionString))
...{
DataTable dt = new DataTable();
try
...{
connection.Open();
System.Data.SqlClient.SqlDataAdapter da = new System.Data.SqlClient.SqlDataAdapter();
System.Data.SqlClient.SqlCommand comm = new System.Data.SqlClient.SqlCommand(SQLString, connection);
comm.CommandTimeout = commTime;
da.SelectCommand = comm;
da.Fill(dt);
}
catch (System.Data.SqlClient.SqlException ex)
...{
throw new Exception(ex.Message);
}
return dt;
}
}
asp.net如何设置数据库连接池的数量?

SqlConnection[] connectionArray = new SqlConnection[101];
for (int i = 0; i <= 100; i++)
{
connectionArray[i] = new SqlConnection("Server=.//SQLEXPRESS ;Integrated security=sspi;connection timeout=5");
connectionArray[i].Open();
}

using System;
using System.Data;
using System.Data.SqlClient;
public class Repro
{
public static int Main(string[] args)
{
Repro repro = new Repro();
for (int i = 0; i <= 5000; i++)
{
try{ Console.Write(i+" "); repro.LeakConnections(); }
catch (SqlException){}
}
return 1;
}
public void LeakConnections()
{
SqlConnection sqlconnection1 = new SqlConnection("Server=.//SQLEXPRESS ;Integrated security=sspi;connection timeout=5");
sqlconnection1.Open();
SqlCommand sqlcommand1 = sqlconnection1.CreateCommand();
sqlcommand1.CommandText = "raiserror ('This is a fake exception', 17,1)";
sqlcommand1.ExecuteNonQuery(); //this throws a SqlException every time it is called.
sqlconnection1.Close(); //We are calling connection close, and we are still leaking connections (see above comment for explanation)
}
}
使用一组名称-值对以链接字符串的形式配置链接池。例如,可以配置池是否有效(默认是有效的),池的最大、最小容量,用于打
开链接的排队请求被阻断的时间。下面的示例字符串配置了池的最大和最小容量。
"Server=(local); Integrated Security=SSPI; Database=Northwind;
Max Pool Size=75; Min Pool Size=5"
摘要
连接池允许应用程序从连接池中获得一个连接并使用这个连接,而不需要为每一个连接请求重新建立一个连接。一旦一个新的连接被创建
并且放置在连接池中,应用程序就可以重复使用这个连接而不必实施整个数据库连接创建过程。
当应用程序请求一个连接时,连接池为该应用程序分配一个连接而不是重新建立一个连接;当应用程序使用完连接后,该连接被归还给连接
池而不是直接释放。
如何实现连接池
确保你每一次的连接使用相同的连接字符串(和连接池相同);只有连接字符串相同时连接池才会工作。如果连接字符串不相同,应用程序
就不会使用连接池而是创建一个新的连接。
优点
使用连接池的最主要的优点是性能。创建一个新的数据库连接所耗费的时间主要取决于网络的速度以及应用程序和数据库服务器的
(网络)距离,而且这个过程通常是一个很耗时的过程。而采用数据库连接池后,数据库连接请求可以直接通过连接池满足而不需要为该请
求重新连接、认证到数据库服务器,这样就节省了时间。
缺点
数据库连接池中可能存在着多个没有被使用的连接一直连接着数据库(这意味着资源的浪费)。
技巧和提示
1. 当你需要数据库连接时才去创建连接池,而不是提前建立。一旦你使用完连接立即关闭它,不要等到垃圾收集器来处理它。
2. 在关闭数据库连接前确保关闭了所有用户定义的事务。
3. 不要关闭数据库中所有的连接,至少保证连接池中有一个连接可用。如果内存和其他资源是你必须首先考虑的问题,可以关闭所有的连
接,然后在下一个请求到来时创建连接池。
连接池FAQ
1. 何时创建连接池?
当第一个连接请求到来时创建连接池;连接池的建立由数据库连接的连接字符创来决定。每一个连接池都与一个不同的连接字符串相关。
当一个新的连接请求到来时如果连接字符串和连接池使用的字符串相同,就从连接池取出一个连接;如果不相同,就新建一个连接池。
2. 何时关闭连接池?
当连接池中的所有连接都已经关闭时关闭连接池。
3. 当连接池中的连接都已经用完,而有新的连接请求到来时会发生什么?
当连接池已经达到它的最大连接数目时,有新的连接请求到来时,新的连接请求将放置到连接队列中。当有连接释放给连接池时,连接池将
新释放的连接分配给在队列中排队的连接请求。你可以调用close和dispose将连接归还给连接池。
4. 我应该如何允许连接池?
对于.NET应用程序而言,默认为允许连接池。(这意味着你可以不必为这件事情做任何的事情)当然,如果你可以在SQLConnection对象的连
接字符串中加进Pooling=true;确保你的应用程序允许连接池的使用。
5. 我应该如何禁止连接池?
ADO.NET默认为允许数据库连接池,如果你希望禁止连接池,可以使用如下的方式:
1) 使用SQLConnection对象时,往连接字符串加入如下内容:Pooling=False;
2) 使用OLEDBConnection对象时,往连接字符串加入如下内容:OLE DB Services=-4;
↧
office mime
What are the Microsoft Office MIME Types?
FILExt does not presently have a search capability for MIME types however, in the interest of helping, this FAQ contains a complete list of the official Microsoft Office MIME types for the newest version of Microsoft Office (2007+). To fully support the new types, web server administrators should add the MIME types for the Open XML formats to their Web server metabase settings so as to add the correct MIME type header in documents saved directly on the server and sent back. The following table documents the HTTP MIME types that are available when working with Office 2007 documents:Ext | MIME Type |
.doc | application/msword |
.dot | application/msword |
.docx | application/vnd.openxmlformats-officedocument.wordprocessingml.document |
.dotx | application/vnd.openxmlformats-officedocument.wordprocessingml.template |
.docm | application/vnd.ms-word.document.macroEnabled.12 |
.dotm | application/vnd.ms-word.template.macroEnabled.12 |
.xls | application/vnd.ms-excel |
.xlt | application/vnd.ms-excel |
.xla | application/vnd.ms-excel |
.xlsx | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet |
.xltx | application/vnd.openxmlformats-officedocument.spreadsheetml.template |
.xlsm | application/vnd.ms-excel.sheet.macroEnabled.12 |
.xltm | application/vnd.ms-excel.template.macroEnabled.12 |
.xlam | application/vnd.ms-excel.addin.macroEnabled.12 |
.xlsb | application/vnd.ms-excel.sheet.binary.macroEnabled.12 |
.ppt | application/vnd.ms-powerpoint |
.pot | application/vnd.ms-powerpoint |
.pps | application/vnd.ms-powerpoint |
.ppa | application/vnd.ms-powerpoint |
.pptx | application/vnd.openxmlformats-officedocument.presentationml.presentation |
.potx | application/vnd.openxmlformats-officedocument.presentationml.template |
.ppsx | application/vnd.openxmlformats-officedocument.presentationml.slideshow |
.ppam | application/vnd.ms-powerpoint.addin.macroEnabled.12 |
.pptm | application/vnd.ms-powerpoint.presentation.macroEnabled.12 |
.potm | application/vnd.ms-powerpoint.template.macroEnabled.12 |
.ppsm | application/vnd.ms-powerpoint.slideshow.macroEnabled.12 |
↧
↧
Log Parser Studio
windows管理员利器之用Log Parser Studio分析IIS日志(附逐浪CMS官方命令集)
Log Parser Studio是一个强大的IIS图形分析工具,值得推荐。
1. 安装Log Parser Studio
a) 需要先安装Log Parser,下载地址:http://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=24659
b) 安装Log Parser Studio,下载地址:http://gallery.technet.microsoft.com/Log-Parser-Studio-cd458765,下载之后解压即可。
2. 运行Log Parser Studio
在之前解压的LPSV2.D1文件夹中运行LPS.exe。
3. 指定IIS日志文件路径
4. 创建查询
a) 点击“Create a new queyr”按钮
b) 在查询窗口输入查询语句(SQL语法),比如:
c) 设置Log Type,比如这里用的是IISW3CLOG
5. 执行查询
a) 点击“Execute active query”按钮
b) 执行结果如下:
真的很方便!
【参考资料】
Introducing: Log Parser Studio
附:

- SELECT TOP 100 cs-uri-stem,time-taken,TO_TIMESTAMP(date, time) AS TimestampFROM '[LOGFILEPATH]' WHERE time-taken > 2000


- /*加载最慢的2000个记录*/
- SELECT TOP 100 cs-uri-stem,time-taken,TO_TIMESTAMP(date, time) AS Timestamp
- FROM '[LOGFILEPATH]'
- WHERE time-taken > 2000
- order by time-taken desc
- /*特定时间内的请求数倒序列表*/
- SELECT TOP 100 cs-uri-stem,time-taken,c-ip,TO_TIMESTAMP(date, time) AS Timestamp
- FROM '[LOGFILEPATH]'
- WHERE time-taken > 2000 and to_time(time) > '00:00:05' and to_time(time) < '23:00:15'
- order by time-taken desc
版权声明:本文为博主原创文章,未经博主允许不得转载。
↧
四种Sandcastle方法生成c#.net帮助类帮助文档
方法一、Visual Studio新建documentation生成帮助文档
前段时间在网上收集和自己平时工作总结整理了《干货,比较全面的c#.net公共帮助类》,整理完成上传github之后我又想,既然是帮助类,总得有个帮助文档于是乎想到了Sandcastle,Sandcastle是微软官方生成帮助文档这发面的工具。 它可以配合Microsoft Visual Studio生成的dll和xml注释文件生成完整的帮助文档。 结合可视化工具Sandcastle Help File Builder,简单直接,还能生成各种属性的说明。 支持Helpe1x:chm, Helper2x:Hxs, Website,HelperView等多种格式而且扩展灵活功能强大,下面我们就看一下怎样用Sandcastle生成chm文档。一、下载
首先我们前往CodePlex下载Sandcastle,地址:http://sandcastle.codeplex.com/ 然后下载Sandcastle Help File Builder,地址:http://shfb.codeplex.com/,点击右边download下载即可。二、安装
Sandcastle,直接Next就可以了,Sandcastle Help File Builder要说一下的是,在MAML Schema IntelliSense for Visual Studio为vs安装插件的时候一定要勾选上,不然新建项目的时候会没有这个选项。


三、设置

四、新建项目documentation




五、生成
如果没有报错,直接生成,然后我们项目目录的Help就可以看到生成的帮助文档了
方法二、cmd生成帮助文档
在Sandcastle和Sandcastle Help File Builder都安装好的前提下, 在我们将步骤三生成的Common.Utility.dll 和Common.Utility.xml 拷贝至C:\Program Files (x86)\Sandcastle\Examples\Sandcastle(Sandcastle安装路径)下面。 这种方法是一种批处理的方法,然后我们打开cmd,输入build_sandcastle.bat vs2005 Common.Utility 回车,然后进行批处理。 我们会看到这目录下生成很多文件夹,如果过程没有报错,我们在chm 文件夹就会看到我们生成的帮助文档了。方法三、SandcastleBuilderGUI


方法四、Sandcastle Help File Builder可视化工具
通过Sandcastle的图形操作界面。在C:\Program Files (x86)\Sandcastle\Examples\Generic\SandcastleGui.exe下打开如下界面。
↧
sqlplus连接数据库几种方式
第一种:通过标准连接字符串来连接。
1) sqlplus test/123@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=10.68.4.68)(PORT=1521))(CONNECT_DATA=(SID=ORCL)))
2)sqlplus test/123@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=10.68.4.68)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=orcltest)))
第二种:通过数据库服务名 连接 sqlplus test/123@10.68.4.68:1521/orcl
第三种:通过TNS文件链接 sqlplus test/123@orcl
第四种:通过操作系统认证连接:
1)直接连接默认实例 sqlplus / as sysdba
2)连接指定实例先执行 SET ORACLE_SID=ORCL 再第一步
↧