• C#中使用 SendMessage 向非顶端窗体发送组合键


    开门见山,不废话了, 直接举例说明一下:

    比如发送ALT + F

    以下是 用spy++截取的消息内容


    <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 是这么说的:

    Parameters

    nVirtKey 
    Value of wParam. Specifies the virtual-key code of the key being pressed. 
    lKeyData 
    Value of lParam. Specifies the repeat count, scan code, extended-key flag, context code, previous key-state flag, and transition-state flag, as shown in the following table. 
    ValueDescription
    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 就可以了表示按键的次数

    lParam资讯

      在四个按键讯息(WM_KEYDOWN、WM_KEYUP、WM_SYSKEYDOWN和WM_SYSKEYUP)中,wParam讯息参数含有上面所讨论的虚拟键码,而lParam讯息参数则含有对了解按键非常有用的其他资讯。lParam的32位分为6个栏位,如图所示。
      在Win 3.x中,WPARAM是16位的,而LPARAM是32位的,两者有明显的区别。因为地址通常是32位的,所以LPARAM被用来传递地址,这个习惯在Win32 API中仍然能够看到。在Win32 API中,WPARAM和LPARAM都是32位,所以没有什么本质的区别。Windows的消息必须参考帮助文件才能知道具体的含义。如果是你定义的消息,愿意怎么使这两个参数都行。但是习惯上,我们愿意使用LPARAM传递地址,而WPARAM传递其他参数。
  • 相关阅读:
    bootStrap-treeview插件
    UML常用图的几种关系的总结
    RFC中文文档
    继承:重新使用接口
    Java8向后兼容
    Java8 时间调节器
    Java8 ChronoUnits枚举
    BigDecimal.divide方法
    java.lang.Double.byteValue() 方法
    事件处理是什么?
  • 原文地址:https://www.cnblogs.com/MaxWoods/p/3969537.html
Copyright © 2020-2023  润新知