请教如何得到按键的硬件扫描码(hardware scan code)

publicsub 2005-01-11 02:31:27
我在 http://search.csdn.net/Expert/topic/2454/2454973.xml?temp=6.72549E-03 看到一段代码
-------------------------------------------------------------
keybd_event( VK_NUMLOCK,
0x45,
KEYEVENTF_EXTENDEDKEY | 0,
0 );

// Simulate a key release
keybd_event( VK_NUMLOCK,
0x45,
KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,
0);
}
-------------------------------------------------------------
请问下这里keybd_event函数的第二个参数 0x45是怎么来的啊?(不要告诉我设为0就可以了)
有什么函数或方法可以得到它么?
...全文
1563 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
MuseIn 2005-01-12
  • 打赏
  • 举报
回复
MapVirtualKey




本文作者:alpha
文章出处:cnwill.com
文章性质:原创
阅读次数:99
发布时间:2004-12-27
此文发于csdn:http://blog.csdn.net/netsh/archive/2004/07/31/57103.aspx

在我们编写远程控制软件的时候,我们会发现要想解锁server端我们就得发送这三个键的虚拟。

下面我说一下解决过程


1.一开始,决定通过keybd_event()来模拟键盘

keybd_event(VK_CONTROL,MapVirtualKey(VK_CONTROL,0),0,0);
keybd_event(VK_MENU,MapVirtualKey(VK_MENU,0),0,0);
keybd_event(VK_DELETE,MapVirtualKey(VK_DELETE,0),0,0);
keybd_event(VK_DELETE,MapVirtualKey(VK_DELETE,0),KEYEVENTF_KEYUP,0);
keybd_event(VK_MENU,MapVirtualKey(VK_MENU,0),KEYEVENTF_KEYUP,0);
keybd_event(VK_CONTROL,MapVirtualKey(VK_CONTROL,0),KEYEVENTF_KEYUP,0);
发现只能模拟ctrl+alt两个键的效果,然而其他的两个键的都可以模拟比如win+d。不知道是不是keybd_event()只能模拟两键还是因为
ctrl+alt+delete的特殊性,望高手告之,在此谢过。

2.运用PostMessage(HWND_BROADCAST, WM_HOTKEY, 0, MAKELONG(MOD_ALT | MOD_CONTROL, VK_DELETE));来发送虚拟键盘,但是在winNT以后的系统里我们还有很多事情要做,比如:OpenDesktop()、OpenInputDesktop()、GetThreadDesktop()、SetThreadDesktop()、CloseDesktop()、GetUserObjectInformation()

代码如下:


#include "windows.h"
BOOL simulateAltControlDel();
void main()
{
simulateAltControlDel();
}
BOOL simulateAltControlDel()
{
HDESK hdeskCurrent;
HDESK hdesk;
HWINSTA hwinstaCurrent;
HWINSTA hwinsta;
//
// Save the current Window station
//
hwinstaCurrent = GetProcessWindowStation();
if (hwinstaCurrent == NULL)
return FALSE;
//
// Save the current desktop
//
hdeskCurrent = GetThreadDesktop(GetCurrentThreadId());
if (hdeskCurrent == NULL)
return FALSE;
//
// Obtain a handle to WinSta0 - service must be running
// in the LocalSystem account
//
hwinsta = OpenWindowStation("winsta0", FALSE,
WINSTA_ACCESSCLIPBOARD |
WINSTA_ACCESSGLOBALATOMS |
WINSTA_CREATEDESKTOP |
WINSTA_ENUMDESKTOPS |
WINSTA_ENUMERATE |
WINSTA_EXITWINDOWS |
WINSTA_READATTRIBUTES |
WINSTA_READSCREEN |
WINSTA_WRITEATTRIBUTES);
if (hwinsta == NULL)
return FALSE;
//
// Set the windowstation to be winsta0
//
if (!SetProcessWindowStation(hwinsta))
return FALSE;

//
// Get the default desktop on winsta0
//
hdesk = OpenDesktop("Winlogon", 0, FALSE,
DESKTOP_CREATEMENU |
DESKTOP_CREATEWINDOW |
DESKTOP_ENUMERATE |
DESKTOP_HOOKCONTROL |
DESKTOP_JOURNALPLAYBACK |
DESKTOP_JOURNALRECORD |
DESKTOP_READOBJECTS |
DESKTOP_SWITCHDESKTOP |
DESKTOP_WRITEOBJECTS);
if (hdesk == NULL)
return FALSE;

//
// Set the desktop to be "default"
//
if (!SetThreadDesktop(hdesk))
return FALSE;
PostMessage(HWND_BROADCAST,WM_HOTKEY,0,MAKELPARAM(MOD_ALT|MOD_CONTROL,VK_DELETE));


//
// Reset the Window station and desktop
//
if (!SetProcessWindowStation(hwinstaCurrent))
return FALSE;

if (!SetThreadDesktop(hdeskCurrent))
return FALSE;

//
// Close the windowstation and desktop handles
//
if (!CloseWindowStation(hwinsta))
return FALSE;
if (!CloseDesktop(hdesk))
return FALSE;
return TRUE;
}

偶一开始试验了发现不成功,后来冰河大哥告诉我说OpenDesktop("Winlogon", ......)本身需要LocalSystem权限,
果然如此,把它注册成服务,然后效果实现。相信如何注册成服务不用我说了吧。ok,我们想要的功能实现了。

3.还有一种方法
Dos下键盘的完全控制 ------- 一系列的BIOS级别的键盘控制函数!
http://dev.csdn.net/develop/article/7/7181.shtm


hyamw 2005-01-12
  • 打赏
  • 举报
回复
具体的结果应该是什么我倒是,没怎么注意 :)
但是,直接那样写,也能成功 ^_^
至于参数uMapType取0还是2,其实都是转换成扫描码。只不过有点差别
0 uCode is a virtual-key code and is translated into a scan code. If it is a virtual-key code that does not distinguish between left- and right-hand keys, the left-hand scan code is returned. If there is no translation, the function returns 0.
2 uCode is a virtual-key code and is translated into an unshifted character value in the low-order word of the return value. Dead keys (diacritics) are indicated by setting the top bit of the return value. If there is no translation, the function returns 0.
publicsub 2005-01-12
  • 打赏
  • 举报
回复
将MapVirtualKey的uMapType指定为0 ,取最低字节传递给keybd_event函数。 测试显示结果正确。

MuseIn(air supply * 学好Linux)
MapVirtualKey返回的是四字节整型,而keybd_event接收的单字节整型。 不需要转型么?


谢谢 hyamw(林锋)和MuseIn(air supply * 学好Linux)提供的帮助。
谢谢 kingzai(stevenzhu)的参与。
:))))
publicsub 2005-01-11
  • 打赏
  • 举报
回复
kingzai(stevenzhu) 你是什么意思?
谢谢 hyamw(林锋), MapVirtualKey()可以得到扫描码。

我看了文档然后自己试了一下,mapVirtualKey的uMapType好像要指定为0,而且传递给keybd_event时应该取最低位的一个字节。

请大家来看看 证实一下以上想法。
hyamw 2005-01-11
  • 打赏
  • 举报
回复
上面的程序这样写:
keybd_event(VK_NUMLOCK,MapVirtualKey(VK_NUMLOCK,2),0,0);
kingzai 2005-01-11
  • 打赏
  • 举报
回复
Virtual-Key Codes
The following table shows the symbolic constant names, hexadecimal values, and mouse or keyboard equivalents for the virtual-key codes used by the system. The codes are listed in numeric order.

0x45转换成十进制是69,是数字9
VK_NUMPAD9 69 Numeric keypad 9 key
hyamw 2005-01-11
  • 打赏
  • 举报
回复
MapVirtualKey
The MapVirtualKey function translates (maps) a virtual-key code into a scan code or character value, or translates a scan code into a virtual-key code.

UINT MapVirtualKey(
UINT uCode, // virtual-key code or scan code
UINT uMapType // translation to perform
);

Parameters
uCode
Specifies the virtual-key code or scan code for a key. How this value is interpreted depends on the value of the uMapType parameter.
uMapType
Specifies the translation to perform. The value of this parameter depends on the value of the uCode parameter: Value Meaning
0 uCode is a virtual-key code and is translated into a scan code. If it is a virtual-key code that does not distinguish between left- and right-hand keys, the left-hand scan code is returned. If there is no translation, the function returns 0.
1 uCode is a scan code and is translated into a virtual-key code that does not distinguish between left- and right-hand keys. If there is no translation, the function returns 0.
2 uCode is a virtual-key code and is translated into an unshifted character value in the low-order word of the return value. Dead keys (diacritics) are indicated by setting the top bit of the return value. If there is no translation, the function returns 0.
3 uCode is a scan code and is translated into a virtual-key code that distinguishes between left- and right-hand keys. If there is no translation, the function returns 0.


Return Values
The return value is either a scan code, a virtual-key code, or a character value, depending on the value of uCode and uMapType. If there is no translation, the return value is zero.

Remarks
An application can use MapVirtualKey to translate scan codes to the virtual-key code constants VK_SHIFT, VK_CONTROL, and VK_MENU, and vice versa. These translations do not distinguish between the left and right instances of the shift, ctrl, or alt keys. An application can get the scan code corresponding to the left or right instance of one of these keys by calling MapVirtualKey with uCode set to one of the following virtual-key code constants.

VK_LSHIFT VK_RSHIFT
VK_LCONTROL VK_RCONTROL
VK_LMENU VK_RMENU


These left- and right-distinguishing constants are available to an application only through the GetKeyboardState, SetKeyboardState, GetAsyncKeyState, GetKeyState, and MapVirtualKey functions.

hyamw 2005-01-11
  • 打赏
  • 举报
回复
MapVirtualKey

2,640

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 硬件/系统
社区管理员
  • 硬件/系统社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧