有时需要出发菜单功能,例如发送ALT + F打开应用程序的文件菜单,如何使用SendMessage实现呢?
使用用spy++截取的ALT+F的消息内容(如何使用spy++,请熟悉的高手指点下,我使用spy++ lite没有得到):
<00001> 000310DC P WM_SYSKEYDOWN nVirtKey:VK_MENU cRepeat:1 ScanCode:38 fExtended:0 fAltDown:1 fRepeat:0 fUp:0
<00002> 000310DC P WM_SYSKEYDOWN nVirtKey:'F' cRepeat:1 ScanCode:21 fExtended:0 fAltDown:1 fRepeat:0 fUp:0
<00003> 000310DC P WM_SYSCHAR chCharCode:'102' (102) cRepeat:1 ScanCode:21 fExtended:0 fAltDown:1 fRepeat:0 fUp:0
<00004> 000310DC P WM_SYSKEYUP nVirtKey:'F' cRepeat:1 ScanCode:21 fExtended:0 fAltDown:1 fRepeat:1 fUp:1
<00005> 000310DC P WM_KEYUP nVirtKey:VK_MENU cRepeat:1 ScanCode:38 fExtended:0 fAltDown:0 fRepeat:1 fUp:1
转换为 SendMessage
[DllImport("user32.dll", EntryPoint = "SendMessage")]
public static extern int SendMessage(IntPtr hwnd, int wMsg, uint wParam, uint lParam);
SendMessage(hwnd, 0x0104, 0x00000012, 0x20380001);//(0x00000012 == VK_MENU(ALT键))
SendMessage(hwnd, 0x0104, 0x00000046, 0x20210001);//这一行可以省略(0x00000046 == 'F')
SendMessage(hwnd, 0x0106, 0x00000066, 0x20210001);//发送一个char 'f'
SendMessage(hwnd, 0x0105, 0x00000046, 0xE0210001);//这一行可以省略(0x00000046 == 'F')
SendMessage(hwnd, 0x0105, 0x00000012, 0xC0380001);//(0x00000012 == VK_MENU(ALT键))
过程是这样的:
首先 发送了一个 ALT按下 //(WM_SYSKEYDOWN == 0x0104)
然后 发送了一个 'F'键 //这里省略可以实现同样功能 系统兼容性问题 建议发送这个键
然后 发送了一个 字符'f' //(WM_SYSCHAR == 0x0106)
然后 抬起按键 'F'键 //这里省略可以实现同样功能 系统兼容性问题 建议发送这个键
最后 抬起按键 ALT键 //(WM_SYSKEYUP == 0x0105)
要实现类似功能 比如 ALT + a 可以这么写
SendMessage(hwnd, 0x0104, 0x00000012, 0x20380001);//0x00000012可以写成0x12
SendMessage(hwnd, 0x0104, 0x00000041, 0x201E0001);//0x00000041可以写成0x41
SendMessage(hwnd, 0x0106, (int)'a', 0x20210001);// (把char转换为 int 或者API声明时传递参数wParam为char)
SendMessage(hwnd, 0x0105, 0x00000041, 0xE01E0001);//0x00000041 == 'A'
SendMessage(hwnd, 0x0105, 0x00000012, 0xC0380001);//
下面列举一下键盘按键对应值:
//Windows 使用的256个虚拟键码
public const int VK_LBUTTON = 0x1
public const int VK_RBUTTON = 0x2
public const int VK_CANCEL = 0x3
public const int VK_MBUTTON = 0x4
public const int VK_BACK = 0x8
public const int VK_TAB = 0x9
public const int VK_CLEAR = 0xC
public const int VK_RETURN = 0xD
public const int VK_SHIFT = 0x10
public const int VK_CONTROL = 0x11
public const int VK_MENU = 0x12
public const int VK_PAUSE = 0x13
public const int VK_CAPITAL = 0x14
public const int VK_ESCAPE = 0x1B
public const int VK_SPACE = 0x20
public const int VK_PRIOR = 0x21
public const int VK_NEXT = 0x22
public const int VK_END = 0x23
public const int VK_HOME = 0x24
public const int VK_LEFT = 0x25
public const int VK_UP = 0x26
public const int VK_RIGHT = 0x27
public const int VK_DOWN = 0x28
public const int VK_Select = 0x29
public const int VK_PRINT = 0x2A
public const int VK_EXECUTE = 0x2B
public const int VK_SNAPSHOT = 0x2C
public const int VK_Insert = 0x2D
public const int VK_Delete = 0x2E
public const int VK_HELP = 0x2F
public const int VK_0 = 0x30
public const int VK_1 = 0x31
public const int VK_2 = 0x32
public const int VK_3 = 0x33
public const int VK_4 = 0x34
public const int VK_5 = 0x35
public const int VK_6 = 0x36
public const int VK_7 = 0x37
public const int VK_8 = 0x38
public const int VK_9 = 0x39
public const int VK_A = 0x41
public const int VK_B = 0x42
public const int VK_C = 0x43
public const int VK_D = 0x44
public const int VK_E = 0x45
public const int VK_F = 0x46
public const int VK_G = 0x47
public const int VK_H = 0x48
public const int VK_I = 0x49
public const int VK_J = 0x4A
public const int VK_K = 0x4B
public const int VK_L = 0x4C
public const int VK_M = 0x4D
public const int VK_N = 0x4E
public const int VK_O = 0x4F
public const int VK_P = 0x50
public const int VK_Q = 0x51
public const int VK_R = 0x52
public const int VK_S = 0x53
public const int VK_T = 0x54
public const int VK_U = 0x55
public const int VK_V = 0x56
public const int VK_W = 0x57
public const int VK_X = 0x58
public const int VK_Y = 0x59
public const int VK_Z = 0x5A
public const int VK_STARTKEY = 0x5B
public const int VK_CONTEXTKEY = 0x5D
public const int VK_NUMPAD0 = 0x60
public const int VK_NUMPAD1 = 0x61
public const int VK_NUMPAD2 = 0x62
public const int VK_NUMPAD3 = 0x63
public const int VK_NUMPAD4 = 0x64
public const int VK_NUMPAD5 = 0x65
public const int VK_NUMPAD6 = 0x66
public const int VK_NUMPAD7 = 0x67
public const int VK_NUMPAD8 = 0x68
public const int VK_NUMPAD9 = 0x69
public const int VK_MULTIPLY = 0x6A
public const int VK_ADD = 0x6B
public const int VK_SEPARATOR = 0x6C
public const int VK_SUBTRACT = 0x6D
public const int VK_DECIMAL = 0x6E
public const int VK_DIVIDE = 0x6F
public const int VK_F1 = 0x70
public const int VK_F2 = 0x71
public const int VK_F3 = 0x72
public const int VK_F4 = 0x73
public const int VK_F5 = 0x74
public const int VK_F6 = 0x75
public const int VK_F7 = 0x76
public const int VK_F8 = 0x77
public const int VK_F9 = 0x78
public const int VK_F10 = 0x79
public const int VK_F11 = 0x7A
public const int VK_F12 = 0x7B
public const int VK_F13 = 0x7C
public const int VK_F14 = 0x7D
public const int VK_F15 = 0x7E
public const int VK_F16 = 0x7F
public const int VK_F17 = 0x80
public const int VK_F18 = 0x81
public const int VK_F19 = 0x82
public const int VK_F20 = 0x83
public const int VK_F21 = 0x84
public const int VK_F22 = 0x85
public const int VK_F23 = 0x86
public const int VK_F24 = 0x87
public const int VK_NUMLOCK = 0x90
public const int VK_OEM_SCROLL = 0x91
public const int VK_OEM_1 = 0xBA
public const int VK_OEM_PLUS = 0xBB
public const int VK_OEM_COMMA = 0xBC
public const int VK_OEM_MINUS = 0xBD
public const int VK_OEM_PERIOD = 0xBE
public const int VK_OEM_2 = 0xBF
public const int VK_OEM_3 = 0xC0
public const int VK_OEM_4 = 0xDB
public const int VK_OEM_5 = 0xDC
public const int VK_OEM_6 = 0xDD
public const int VK_OEM_7 = 0xDE
public const int VK_OEM_8 = 0xDF
public const int VK_ICO_F17 = 0xE0
public const int VK_ICO_F18 = 0xE1
public const int VK_OEM102 = 0xE2
public const int VK_ICO_HELP = 0xE3
public const int VK_ICO_00 = 0xE4
public const int VK_ICO_CLEAR = 0xE6
public const int VK_OEM_RESET = 0xE9
public const int VK_OEM_JUMP = 0xEA
public const int VK_OEM_PA1 = 0xEB
public const int VK_OEM_PA2 = 0xEC
public const int VK_OEM_PA3 = 0xED
public const int VK_OEM_WSCTRL = 0xEE
public const int VK_OEM_CUSEL = 0xEF
public const int VK_OEM_ATTN = 0xF0
public const int VK_OEM_FINNISH = 0xF1
public const int VK_OEM_COPY = 0xF2
public const int VK_OEM_AUTO = 0xF3
public const int VK_OEM_ENLW = 0xF4
public const int VK_OEM_BACKTAB = 0xF5
public const int VK_ATTN = 0xF6
public const int VK_CRSEL = 0xF7
public const int VK_EXSEL = 0xF8
public const int VK_EREOF = 0xF9
public const int VK_PLAY = 0xFA
public const int VK_ZOOM = 0xFB
public const int VK_NONAME = 0xFC
public const int VK_PA1 = 0xFD
public const int VK_OEM_CLEAR = 0xFE
按照以上对照表 写快捷键 CTRL + F :
SendMessage(hwnd, 0x0104, 0x11, 0x20380001);//0x11 == VK_CONTROL == ALT键
SendMessage(hwnd, 0x0104, (int)'F', 0x20210001);//
SendMessage(hwnd, 0x0106, (int)'f', 0x20210001);//
SendMessage(hwnd, 0x0105, (int)'F', 0xE0210001);//
SendMessage(hwnd, 0x0105, 0x11, 0xC0380001);//
忘记说了 关于参数 lParam 是这么说的:
Value | Description |
---|---|
0–15 | Specifies the repeat count for the current message. The value is the number of times the keystroke is auto-repeated as a result of the user holding down the key. If the keystroke is held long enough, multiple messages are sent. However, the repeat count is not cumulative. |
16–23 | Specifies the scan code. The value depends on the original equipment manufacturer (OEM). |
24 | Specifies whether the key is an extended key, such as the right-hand alt and ctrl keys that appear on an enhanced 101- or 102-key keyboard. The value is 1 if it is an extended key; otherwise, it is 0. |
25–28 | Reserved; do not use. |
29 | Specifies the context code. The value is 1 if the ALT key is down while the key is pressed; it is 0 if the WM_SYSKEYDOWN message is posted to the active window because no window has the keyboard focus. |
30 | Specifies the previous key state. The value is 1 if the key is down before the message is sent, or it is 0 if the key is up. |
31 | Specifies the transition state. The value is always 0 for a WM_SYSKEYDOWN message. |
0-15位:指定当前消息的重复次数。其值就是用户按下该键后自动重复的次数,但是重复次数不累积
16-23位:指定其扫描码,其值依赖于OEM厂商
24位:指定该按键是否为扩展按键,所谓扩展按键就是Ctrl,Alt之类的,如果是扩展按键,其值为1,否则为0
25-28位:保留字段,暂时不可用
29位:指定按键时的上下文,其值为1时表示在按键时Alt键被按下,其值为0表示WM_SYSKEYDOWN消息因没有任何窗口有键盘焦点而被发送到当前活动窗口。
30位:指定该按键之前的状态,其值为1时表示该消息发送前,该按键是被按下的,其值为0表示该消息发送前该按键是抬起的。
31位:指定其转换状态,对WM_SYSKEYDOWN消息而言,其值总为0。
具体可以参考 http://msdn.microsoft.com/zh-cn/library/ms646286(en-us,VS.85).aspx
如果你想知道这些参数的含义 你可以直接输入1 就可以了表示按键的次数
联系客服