Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

我用 RegisterHotKey 注册一个热键,Ctrl + Pause ...

70 views
Skip to first unread message

acc

unread,
Oct 8, 2009, 9:10:02 AM10/8/09
to
Ϊ�߳�ע��һ���ȼ�������д��
RegisterHotKey(NULL, 1, MOD_CONTROL, VK_PAUSE);

��������û�а취������ȼ������


Cen

unread,
Oct 8, 2009, 10:34:07 AM10/8/09
to
Pause
Alt + Pause
Shift + Pause 锟斤拷锟斤拷锟斤拷
唯锟斤拷 Ctrl + Pause 锟斤拷锟揭碉拷XPsp3锟斤拷没锟斤拷应

"acc" <jo...@sina.com> wrote:
> 为锟竭筹拷注锟斤拷一锟斤拷锟饺硷拷锟斤拷锟斤拷锟斤拷写锟斤拷
> RegisterHotKey(NULL, 1, MOD_CONTROL, VK_PAUSE);
>
> 锟斤拷锟斤拷锟斤拷锟斤拷没锟叫办法锟斤拷锟斤拷锟斤拷燃锟斤拷锟斤拷锟斤拷

hotkey.cpp

Cen

unread,
Oct 8, 2009, 10:58:41 AM10/8/09
to
锟揭碉拷原锟斤拷锟斤拷, Pause锟斤拷(VK_PAUSE)锟斤拷Break锟斤拷(VK_CANCEL)锟斤拷同一锟斤拷锟斤拷锟斤拷扫锟斤拷锟斤拷
VK_CANCEL锟斤拷锟斤拷锟紺trl一锟斤拷, 锟斤拷锟斤拷没锟斤拷应. VK_PAUSE锟斤拷锟诫不锟斤拷Ctrl一锟斤拷, 锟斤拷锟斤拷没锟斤拷应
Ctrl + Break
Ctrl + Alt + Break
Ctrl + Shift + Break
Ctrl + Shift + Alt + Break

acc

unread,
Oct 8, 2009, 12:08:36 PM10/8/09
to
�������ǡ�

��ǰ�������룬��ô�� Ctrl-Break����� Ctrl-Pause�������ǰ��� Ctrl Ȼ��
Pause��

����ͻȻ���� Ctrl-Pause ��ɵ�ɨ������ Break ��ɨ���룬���ڴ�ʱ Ctrl ���£����Խ� Ctrl-Break��

> �ҵ�ԭ����, Pause��(VK_PAUSE)��Break��(VK_CANCEL)��ͬһ������ɨ����

���Dz���ͬһ��ɨ����ɣ���ȫ�� 16 ���ƣ�
Pause ͨ�� E1 1D 45 E1 9D C5, 45 (lParam), 13(vk)
Break ͨ�� E0 46 E0 C6, E0 46(lParam), 3(vk)
lParam ���� Num Lock ɨ���� E0 45
�����ҿ���һ��ɨ���룬Num Lock �� 45

ɨ������ lParam �� 16~23 λ�Ķ�Ӧ��ϵ�һ����Ǻ�����������һ����ɨ����������΢���
Windows Platform Design Notes
Keyboard Scan Code Specification
���濴���ġ�

�ҿ����Ұ��� Ctrl ʱ�ٰ� Pause����ɨ���붼����ˡ�ͬһ���������� Ctrl�������˲�ͬ��ɨ���룬��Ӧ�����������֮ǰ���İɣ�����֪�������ĸ��ؽ��������ָĶ��������Ǹ� 8042 оƬ�ϣ������ϵļ��̿���
������

�㰴ס Ctrl���ٰ� Num Lock��������� VK_PAUSE����������Ҿ��ã�������������������İɡ�

���̵��������������Һܾ��ˣ���һֱ��û���ʳ��������ǵ�һ���֡�

"Cen" <C...@rixi.an> д����Ϣ����:hakumf$tgs$1...@aioe.org...
> �ҵ�ԭ����, Pause��(VK_PAUSE)��Break��(VK_CANCEL)��ͬһ������ɨ����
> VK_CANCEL�����Ctrlһ��, ����û��Ӧ. VK_PAUSE���벻��Ctrlһ��, ����û��Ӧ

acc

unread,
Oct 8, 2009, 11:25:27 PM10/8/09
to
С�ᡣ
Pause �������޸ļ��������Ϲ��� 14 ����ϣ�������Ч����˵��Ч�ģ�
VK_PAUSE, MOD_ALT
VK_PAUSE, MOD_SHIFT
VK_PAUSE, MOD_ALT | MOD_SHIFT
VK_CANCEL, MOD_CONTROL
VK_CANCEL, MOD_ALT | MOD_CONTROL
VK_CANCEL, MOD_CONTROL | MOD_SHIFT
VK_CANCEL, MOD_ALT | MOD_CONTROL | MOD_SHIFT

�߸���Ч�ġ������ע������������㰴�������������� SendInput ����ģ�⡣
VK_PAUSE, MOD_CONTROL
VK_PAUSE, MOD_ALT | MOD_CONTROL
VK_PAUSE, MOD_CONTROL | MOD_SHIFT
VK_PAUSE, MOD_ALT | MOD_CONTROL | MOD_SHIFT
VK_CANCEL, MOD_ALT
VK_CANCEL, MOD_SHIFT
VK_CANCEL, MOD_ALT | MOD_SHIFT

Alt-PrintScr Ҳ�޸�ɨ���룬�õ������޸����ֵ��

The Undocumented PC ������Ȼ�ã������� Windows��PS2 �����ο�Ҳ��������
�����ǹ����ţ��� BIOS �������� int9h ����̣��൱�� windows ���������
�� int16h���൱�� Windows ԭʼ������С�

������һ�Ѷѵ����ϣ������ĵ������Ҿͺܲ��뷭����һ��Ҳ���뿴������Щ������
���д��۸С�XD����������һ������ij���Ա����

XDDDDDDDDD

"Cen" <C...@rixi.an> д����Ϣ����:hakumf$tgs$1...@aioe.org...
> �ҵ�ԭ����, Pause��(VK_PAUSE)��Break��(VK_CANCEL)��ͬһ������ɨ����
> VK_CANCEL�����Ctrlһ��, ����û��Ӧ. VK_PAUSE���벻��Ctrlһ��, ����û��Ӧ

acc

unread,
Oct 8, 2009, 11:41:34 PM10/8/09
to
XD �㻹Ū�˸� Win-Pause�������ϵͳע����ȼ��������֪��ϵͳ�и�����ȼ�


"Cen" <C...@rixi.an> д����Ϣ����:4...@rixi.an...
> Pause
> Alt + Pause
> Shift + Pause ������
> Ψ�� Ctrl + Pause ���ҵ�XPsp3��û��Ӧ


Cen

unread,
Oct 8, 2009, 11:51:58 PM10/8/09
to
"Pause��(VK_PAUSE)��Break��(VK_CANCEL)��ͬһ������ɨ����"��ָ, Pause/Break��ͬһ�������, �ü����ļ���ɨ��������ͬ��, Windows���Ctrl�������, ����һ���������Ϊ��ͬ��VK_PAUSE/VK_CANCEL.

WM_*KEY*��lParam�е�scan code��PS/2 keyboard set 1 scan code�в���, MSDNû˵lParam��set 1 scan code, ֻ˵��depends on the OEM��, ��win2k\private\ntos\w32\ntuser\kbd\�����ϰٸ�OEM_KEYBOARD_LAYOUT, ����USA������̺���ʵ��Ľ��[1]��ȫ���.

[1] WM_*KEY*��lParam�е�scan code(hexadecimal, o = extended key)
.---..--.--.--.--..--.--.--.--..--.---.---.---..---.---.---.
|Esc||F1|F2|F3|F4||F5|F6|F7|F8||F9|F10|F11|F12||Prt|Scr|Pse| SysRq(Alt)54
| 01||3B|3C|3D|3E||3F|40|41|42||43| 44| 57| 58||o37| 46| 45| Break(Ctrl)o46
.---..--.--.--.--..--.--.--.--..--.---.---.---..---.---.---.
.--.--.--.--.--.--.--.--.--.--.--.--.--.----..---.---.---..---.---.---.---.
|` | 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| <--||Ins|Hom|PgU||Num| / | * | - |
|29|02|03|04|05|06|07|08|09|0A|0B|0C|0D| 0E||o52|o47|o49||o45|o35| 37| 4A|
.--..-..-..-..-..-..-..-..-..-..-..-..-..---..---.---.---..---.---.---.---.
|Tab| Q| W| E| R| T| Y| U| I| O| P| [| ]| \ ||Del|End|PgD|| 7 | 8 | 9 | |
| 0F|10|11|12|13|14|15|16|17|18|19|1A|1B| 2B||o53|o4F|o51|| 47| 48| 49| + |
.---..-..-..-..-..-..-..-..-..-..-..-..-.---..---.---.---..---.---.---. 4E|
|Caps| A| S| D| F| G| H| J| K| L| ;| '| <-.| | 4 | 5 | 6 | |
| 3A |1E|1F|20|21|22|23|24|25|26|27|28| 1C| | 4B| 4C|4D | |
.----.-..-..-..-..-..-..-..-..-..-..-..-----. .---. .---.---.---.---.
|Shift | Z| X| C| V| B| N| M| ,| .| /| Shift| | | | 1 | 2 | 3 | |
| 2A |2C|2D|2E|2F|30|31|32|33|34|35| 36 | |o48| | 4F| 50| 51|<-.|
.----.-.--..-.--.--.--.--.--.--.-..--.-.----..---.---.---..---.---.---.o1C|
|Ctrl| |Alt| | Space Bar | |Alt| |Ctrl|| | | || Ins |Del| |
| 1D | | 38| | 39 | |o38| |o10 ||o4B|o50|o4D|| 52 | 53| |
.----. .---. .-----------------. .---. .----..---.---.---..-------.---.---.

MSDN˵i8042��set 2 scan codeת��Ϊset 1 scan code. ��ôset 1 scan code��WM_*KEY*��lParam��"virtual scan code"Ӧ����i8042prt�����ת����. ��Ϊkernel mode��xxxKeyEvent[2]����������wScanCode, �����ݸ�WH_KEYBOARD_LL, ��WH_KEYBOARD_LL��ʾ��wScanCode����"virtual scan
code", ���set 1 scan code. WH_KEYBOARD_LL��ʾ��vkCodeҲ��ת��, Ctrl+NumLock vkCode=VK_PAUSE, Ctrl+ScrollLock vkCode=VK_CANCEL.

[2] win2k\private\ntos\w32\ntuser\kernel\ntinput.c
/****************************** Module Header ******************************\
* Module Name: ntinput.c
*
* Copyright (c) 1985 - 1999, Microsoft Corporation
*
* This module contains low-level input code specific to the NT
* implementation of Win32 USER, which is mostly the interfaces to the
* keyboard and mouse device drivers.
*
* History:
* 11-26-90 DavidPe Created
\***************************************************************************/
/***************************************************************************\
* xxxKeyEvent (RIT)
*
* All events from the keyboard driver go here. We receive a scan code
* from the driver and convert it to a virtual scan code and virtual
* key.
*
* The async keystate table and keylights are also updated here. Based
* on the 'focus' window we direct the input to a specific window. If
* the ALT key is down we send the events as WM_SYSKEY* messages.
*
* History:
* 10-18-90 DavidPe Created.
* 11-13-90 DavidPe WM_SYSKEY* support.
* 11-30-90 DavidPe Added keylight updating support.
* 12-05-90 DavidPe Added hotkey support.
* 03-14-91 DavidPe Moved most lParam flag support to xxxCookMessage().
* 06-07-91 DavidPe Changed to use gpqForeground rather than pwndFocus.
\***************************************************************************/

VOID xxxKeyEvent(
USHORT usFlaggedVk,
WORD wScanCode,
DWORD time,
ULONG_PTR ExtraInfo,
BOOL bInjected)
{ ...
VkHanded = (BYTE)usFlaggedVk; // get rid of state bits - no longer needed
...
/*
* Call low level keyboard hook to see if it allows this
* message to pass
*/
if ((pHook = PhkFirstValid(ptiCurrent, WH_KEYBOARD_LL)) != NULL) {
KBDLLHOOKSTRUCT kbds;
BOOL bAnsiHook;
USHORT msg = message;

/*
* Check if this is a WM_SYS* message
*/
if (TestRawKeyDown(VK_MENU) &&
!TestRawKeyDown(VK_CONTROL)) {

msg += (WM_SYSKEYDOWN - WM_KEYDOWN);
usExtraStuff |= 0x2000; // ALT key down
}
kbds.vkCode = (DWORD)VkHanded;
kbds.scanCode = (DWORD)wScanCode;
kbds.flags = HIBYTE(usExtraStuff | (bInjected ? (LLKHF_INJECTED << 8) : 0));
kbds.flags |= (fBreak ? (KBDBREAK >> 8) : 0);
kbds.time = time;
kbds.dwExtraInfo = ExtraInfo;

if (xxxCallHook2(pHook, HC_ACTION, (DWORD)msg, (LPARAM)&kbds, &bAnsiHook)) {

Cen

unread,
Oct 9, 2009, 12:00:28 AM10/9/09
to
锟斤拷锟角匡拷锟斤拷winuser.h锟斤拷4锟斤拷MOD_*锟斤拷全锟斤拷锟斤拷一锟斤拷
#define MOD_ALT 0x0001
#define MOD_CONTROL 0x0002
#define MOD_SHIFT 0x0004
#define MOD_WIN 0x0008

"acc" <jo...@sina.com> wrote:
> XD 锟姐还弄锟剿革拷 Win-Pause锟斤拷锟斤拷锟斤拷锟较低匙拷锟斤拷锟饺硷拷锟斤拷锟斤拷锟斤拷锟街拷锟较低筹拷懈锟斤拷锟斤拷锟饺硷拷

Cen

unread,
Oct 9, 2009, 12:06:32 AM10/9/09
to
��14����Ͼ�����, VK_PAUSE��MOD_CONTROL, VK_CANCEL��MOD_CONTROL
������һ�������, Ӳ�����������, ������MOD_CONTROL����VK_CANCEL, ��MOD_CONTROL����VK_PAUSE.
����MOD_CONTROL+VK_PAUSEû��Ӧ, ��ΪMOD_CONTROL��ʱ�������VK_CANCEL, ������VK_PAUSE.

acc

unread,
Oct 9, 2009, 12:34:15 AM10/9/09
to
�ּ�п�� hardcore ���롣�����¶����ˣ��������Ҹ��ط�תת��

"Cen" <C...@rixi.an> д����Ϣ����:hamc17$n2s$1...@news.eternal-september.org...

Moses

unread,
Oct 9, 2009, 4:08:05 AM10/9/09
to
下面的看不懂...不过扫描码是根据硬件的, 如果在物理上是同一个键, 那么扫描码不是肯定一样吗?


--
楼上 Cen 说的 "Re: 我用 RegisterHotKey 注册一个热键,Ctrl + Pause ..." 在某一分钟的第 15 秒被 Moses 所回复;
文件夹 ID 为 225733;
原帖 128 行共 7614 字节.

C> "Pause键(VK_PAUSE)和Break键(VK_CANCEL)是同一个键盘扫描码"是指, Pause/Break是同一个物理键,
C> 该键产生的键盘扫描码是相同的, Windows根据Ctrl键按下与否, 把这一个物理键翻译为不同的VK_PAUSE/VK_CANCEL.

C> WM_*KEY*的lParam中的scan code和PS/2 keyboard set 1 scan code有差异,
C> MSDN没说lParam是set 1 scan code, 只说“depends on the OEM”,
C> 而win2k\private\ntos\w32\ntuser\kbd\下有上百个OEM_KEYBOARD_LAYOUT,
C> 其中USA美国键盘和我实测的结果[1]完全相符.

C> [1] WM_*KEY*的lParam中的scan code(hexadecimal, o = extended key)
C> .---..--.--.--.--..--.--.--.--..--.---.---.---..---.---.---.


Esc||>> F1|F2|F3|F4||F5|F6|F7|F8||F9|F10|F11|F12||Prt|Scr|Pse| SysRq(Alt)54
01||>> 3B|3C|3D|3E||3F|40|41|42||43| 44| 57| 58||o37| 46| 45|

01||>> Break(Ctrl)o46
C> .---..--.--.--.--..--.--.--.--..--.---.---.---..---.---.---.
C> .--.--.--.--.--.--.--.--.--.--.--.--.--.----..---.---.---..---.---.---.-
C> --.


|> ` | 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| <--||Ins|Hom|PgU||Num| / | * | -
|> |
29|>> 02|03|04|05|06|07|08|09|0A|0B|0C|0D| 0E||o52|o47|o49||o45|o35| 37|

29|>> 4A|
C> .--..-..-..-..-..-..-..-..-..-..-..-..-..---..---.---.---..---.---.---.-
C> --.


Tab|>> Q| W| E| R| T| Y| U| I| O| P| [| ]| \ ||Del|End|PgD|| 7 | 8 | 9 |

Tab|>> |


0F|>> 10|11|12|13|14|15|16|17|18|19|1A|1B| 2B||o53|o4F|o51|| 47| 48| 49| +

0F|>> |
C> .---..-..-..-..-..-..-..-..-..-..-..-..-.---..---.---.---..---.---.---.
C> 4E|


Caps|>> A| S| D| F| G| H| J| K| L| ;| '| <-.| | 4 | 5 | 6 |

Caps|>> |


3A |>> 1E|1F|20|21|22|23|24|25|26|27|28| 1C| | 4B| 4C|4D |

3A |>> |
C> .----.-..-..-..-..-..-..-..-..-..-..-..-----. .---.
C> .---.---.---.---.


Shift |>> Z| X| C| V| B| N| M| ,| .| /| Shift| | | | 1 | 2 | 3 |

Shift |>> |


2A |>> 2C|2D|2E|2F|30|31|32|33|34|35| 36 | |o48| | 4F| 50| 51|<-.|

C> .----.-.--..-.--.--.--.--.--.--.-..--.-.----..---.---.---..---.---.---.o
C> 1C|


Ctrl| |>> Alt| | Space Bar | |Alt| |Ctrl|| | | || Ins |Del|

Ctrl| |>> |


1D | |>> 38| | 39 | |o38| |o10 ||o4B|o50|o4D|| 52 | 53| |

C> .----. .---. .-----------------. .---.
C> .----..---.---.---..-------.---.---.

C> MSDN说i8042把set 2 scan code转换为set 1 scan code. 那么set 1 scan
C> code到WM_*KEY*的lParam的"virtual scan code"应该是i8042prt驱动程序转换的. 因为kernel
C> mode的xxxKeyEvent[2]从驱动程序接收wScanCode, 并传递给WH_KEYBOARD_LL,
C> 而WH_KEYBOARD_LL显示的wScanCode已是"virtual scan code", 而非set 1 scan code.
C> WH_KEYBOARD_LL显示的vkCode也已转换, Ctrl+NumLock vkCode=VK_PAUSE,
C> Ctrl+ScrollLock vkCode=VK_CANCEL.

C> [2] win2k\private\ntos\w32\ntuser\kernel\ntinput.c
C> /************************* Module Header ******************************\
C> * Module Name: ntinput.c
C> *
C> * Copyright (c) 1985 - 1999, Microsoft Corporation
C> *
C> * This module contains low-level input code specific to the NT
C> * implementation of Win32 USER, which is mostly the interfaces to the
C> * keyboard and mouse device drivers.
C> *
C> * History:
C> * 11-26-90 DavidPe Created
C> \**********************************************************************/
C> /**********************************************************************\
C> * xxxKeyEvent (RIT)
C> *
C> * All events from the keyboard driver go here. We receive a scan code
C> * from the driver and convert it to a virtual scan code and virtual
C> * key.
C> *
C> * The async keystate table and keylights are also updated here. Based
C> * on the 'focus' window we direct the input to a specific window. If
C> * the ALT key is down we send the events as WM_SYSKEY* messages.
C> *
C> * History:
C> * 10-18-90 DavidPe Created.
C> * 11-13-90 DavidPe WM_SYSKEY* support.
C> * 11-30-90 DavidPe Added keylight updating support.
C> * 12-05-90 DavidPe Added hotkey support.
C> * 03-14-91 DavidPe Moved most lParam flag support to
C> xxxCookMessage(). * 06-07-91 DavidPe Changed to use gpqForeground
C> rather than pwndFocus. \***********************************************/

C> VOID xxxKeyEvent(
C> USHORT usFlaggedVk,
C> WORD wScanCode,
C> DWORD time,
C> ULONG_PTR ExtraInfo,
C> BOOL bInjected)
C> { ...
C> VkHanded = (BYTE)usFlaggedVk; // get rid of state bits - no
C> longer needed
C> ...
C> /*
C> * Call low level keyboard hook to see if it allows this
C> * message to pass
C> */
C> if ((pHook = PhkFirstValid(ptiCurrent, WH_KEYBOARD_LL)) != NULL) {
C> KBDLLHOOKSTRUCT kbds;
C> BOOL bAnsiHook;
C> USHORT msg = message;

C> /*
C> * Check if this is a WM_SYS* message
C> */
C> if (TestRawKeyDown(VK_MENU) &&
C> !TestRawKeyDown(VK_CONTROL)) {

C> msg += (WM_SYSKEYDOWN - WM_KEYDOWN);


usExtraStuff |> = 0x2000; // ALT key down

C> }
C> kbds.vkCode = (DWORD)VkHanded;
C> kbds.scanCode = (DWORD)wScanCode;
C> kbds.flags = HIBYTE(usExtraStuff | (bInjected ?
C> (LLKHF_INJECTED << 8) : 0));
C> kbds.flags |= (fBreak ? (KBDBREAK >> 8) : 0);
C> kbds.time = time;
C> kbds.dwExtraInfo = ExtraInfo;

C> if (xxxCallHook2(pHook, HC_ACTION, (DWORD)msg, (LPARAM)&kbds,
C> &bAnsiHook)) {

C> "acc" <jo...@sina.com> wrote:
>> 哈哈。是。
>>
>> 以前我老是想,怎么叫 Ctrl-Break,而不叫 Ctrl-Pause,明明是按下 Ctrl 然后按 Pause。
>>
>> 后来突然发现 Ctrl-Pause 生成的扫描码是 Break 的扫描码,由于此时 Ctrl 按下,所以叫 Ctrl-Break。
>>
>>> 找到原因了, Pause键(VK_PAUSE)和Break键(VK_CANCEL)是同一个键盘扫描码
>>
>> 它们不是同一个扫描码吧?(全是 16 进制)
>> Pause 通码 E1 1D 45 E1 9D C5, 45 (lParam), 13(vk)
>> Break 通码 E0 46 E0 C6, E0 46(lParam), 3(vk)
>> lParam 里面 Num Lock 扫描码 E0 45
>> 可是我看第一套扫描码,Num Lock 是 45
>>
>> 扫描码表和 lParam 第 16~23 位的对应关系我还不是很清楚。上面的一长串扫描码是我在微软的


>> Windows Platform Design Notes
>> Keyboard Scan Code Specification

>> 里面看到的。
>>
>> 我看当我按下 Ctrl 时再按 Pause,连扫描码都给改了。同一个键,由于有
>> Ctrl,产生了不同的扫描码,这应该是在驱动程序之前做的吧?我想知道是在哪个关节做的这种改动,是在那个 8042 芯片上(主板上的键盘控制
>> 器)?
>>
>> 你按住 Ctrl,再按 Num Lock,产生虚键 VK_PAUSE。这个动作我觉得,是在驱动程序那里作出的吧。
>>
>> 键盘的种种现象困扰我很久了,我一直都没有问出来,这是第一部分。
>>
>> "Cen" <C...@rixi.an> 写入消息新闻:hakumf$tgs$1...@aioe.org...
>>> 找到原因了, Pause键(VK_PAUSE)和Break键(VK_CANCEL)是同一个键盘扫描码
>>> VK_CANCEL必须和Ctrl一起, 否则没反应. VK_PAUSE必须不和Ctrl一起, 否则没反应

acc

unread,
Oct 9, 2009, 4:17:02 AM10/9/09
to
���̵����̿�������ɨ������һһ��Ӧ�ģ��Ǹ�����ϵͳɨ���루��Ҳ����ʹ��ɨ���뼯1����2�����Ǹ��Ǽ���ɨ���룬Ȼ���� i8042 ������Ϊɨ���뼯֮һ���ͽ��������ʵ��һ��
��������ɨ����Ҳ���Բ�һһ��Ӧ��

Den ˵��Pause �� Break ɨ����һ��ָ���Ǽ���ɨ���룻��˵ɨ���벻һ��ָ���Ƿ�����ϵͳɨ���롣

��� i8042 ��Ҫ���룬���� Ctrl-Break����ô��һ��ҲҪ����һ��״̬�ֽڣ����״̬�ֽڿ��ܼ�¼��������SHIFT��Ctrl��Alt���ĸ����ء��ҵ������ǣ��Ƿ��������ô��״̬�ֽڣ�

"Moses" <moses...@gmail.com> д����Ϣ����:hamr0v$jmj$1...@www.shinco.com...
����Ŀ�����...����ɨ�����Ǹ��Ӳ����, �������������ͬһ����, ��ôɨ���벻�ǿ϶�һ����?

Moses

unread,
Oct 9, 2009, 4:53:35 AM10/9/09
to
哦, 我对扫描码的区别还不是很了解..先去找资料看一下......................


--
楼上 acc 说的 "Re: 我用 RegisterHotKey 注册一个热键,Ctrl + Pause ..." 在某一分钟的第 27 秒被 Moses 所回复;
文件夹 ID 为 225733;
原帖 10 行共 1559 字节.

a> 键盘到键盘控制器,扫描码是一一对应的,那个不是系统扫描码(但也可能使用扫描码集1或者2),那个是键盘扫描码,然后由 i8042
a> 负责翻译为扫描码集之一,送交驱动程序。其实退一步 讲,键盘扫描码也可以不一一对应。

a> Den 说,Pause 和 Break 扫描码一样,指的是键盘扫描码;我说扫描码不一样,指的是翻译后的系统扫描码。

a> 如果 i8042 需要翻译,比如
a> Ctrl-Break,那么它一定也要保留一个状态字节,这个状态字节可能记录的是左右SHIFT,Ctrl,Alt和四个开关。我的疑问是,是否真的有
a> 这么个状态字节?

a> "Moses" <moses...@gmail.com> 写入消息新闻:hamr0v$jmj$1...@www.shinco.com...
a> 下面的看不懂...不过扫描码是根据硬件的, 如果在物理上是同一个键, 那么扫描码不是肯定一样吗?

Cen

unread,
Oct 9, 2009, 11:10:15 AM10/9/09
to
PS/2����
|
|ԭʼɨ����
|
����оƬ
|
|set 2 ɨ����
|
����8042оƬ
|
|set 1 ɨ����
|
�����
|
|virtual ɨ���� + vkCode1
|
Windows��Ϣ
|
|virtual ɨ���� + vkCode2
|
Ӧ�ó���

1) ԭʼɨ��������Ǽ��̳����Զ����һ��ɨ����, ����IBM[1]���ü򻯵�ɨ����.
2) 8042оƬ�������ƺ�һ��Ҫ��set 2 ɨ����. ���һ��Ĭ��set 1 ɨ����[2], ������ָʾ8042ѡ������ɨ����[3]
3) vkCode1��vkCode2��һ��, ����
LShift RShift LCtrl RCtrl LAlt RAlt
vkCode1 A0 A1 A2 A3 A4 A5
vkCode2 10 10 11 11 12 12
4) 8042Ӧ�������¼����״̬, ��ֻҪ���ĸ�����, �ĸ�����, ��ˮ�ʱ�������������, ��������¼����״̬[4].

[1] ftp://ftp.software.ibm.com/software/retail/pubs/hw/4614/sobrkyb2.pdf
[2] nt4\private\ntos\dd\i8042prt\i8042prt.h
// Default keyboard scan code mode.
#define KEYBOARD_SCAN_CODE_SET 0x01
[3] http://webster.cs.ucr.edu/AoA/DOS/pdf/ch20.pdf
Table 76: Keyboard Microcontroller Commands (Port 60h)
Select alternate scan code set (PS/2 only):
01: Select scan code set #1 (standard PC/AT scan code set).
02: Select scan code set #2.
03: Select scan code set #3.
[4] nt4\private\ntos\dd\i8042prt\kbddep.c
BOOLEAN
I8042KeyboardInterruptService(
IN PKINTERRUPT Interrupt,
IN PVOID Context
)
/*++
Routine Description:
This is the interrupt service routine for the keyboard device when
scan code set 1 is in use.
--*/
{ ...
if (scanCode == (UCHAR) 0xFF) {
input->MakeCode = KEYBOARD_OVERRUN_MAKE_CODE;
input->Flags = 0;
*scanState = Normal;
} else {
switch (*scanState) {
case Normal:
if (scanCode == (UCHAR) 0xE0) {
input->Flags |= KEY_E0;
*scanState = GotE0;
break;
} else if (scanCode == (UCHAR) 0xE1) {
input->Flags |= KEY_E1;
*scanState = GotE1;
break;
}
...
if(scanCode <= (UCHAR) 0x7F) {
//
// make code
//
switch(scanCode) {
case 0x1D: // 'CTRL'
if(*scanState == Normal) // Left
deviceExtension->DumpFlags |= 0x20;
else if(*scanState == GotE0) // Right
deviceExtension->DumpFlags |= 0x02;
break;
case 0x38: // 'ALT'
if(*scanState == Normal) // Left
deviceExtension->DumpFlags |= 0x40;
else if(*scanState == GotE0) // Right
deviceExtension->DumpFlags |= 0x04;
break;
case 0x36: // Right 'Shift'
if(*scanState == Normal)
deviceExtension->DumpFlags |= 0x01;
break;
case 0x2A: // Left 'Shift'
if(*scanState == Normal)
deviceExtension->DumpFlags |= 0x10;
break;
default:
if((DumpKey & 0x80) == 0) {
if(*scanState == Normal
&& DumpKey == scanCode)
break;
}
else {
if(*scanState == GotE0
&& (DumpKey & 0x7F) == scanCode)
break;
}
if((DumpKey2 & 0x80) == 0) {
if(*scanState == Normal
&& DumpKey2 == scanCode)
break;
}
else {
if(*scanState == GotE0
&& (DumpKey2 & 0x7F) == scanCode)
break;
}
deviceExtension->DumpFlags = 0;
break;
}
}
else {
//
// break code
//
switch(scanCode & 0x7F) {
case 0x1D: // 'CTRL'
if(*scanState == Normal) // Left
deviceExtension->DumpFlags &= ~0x320;
else if(*scanState == GotE0) // Right
deviceExtension->DumpFlags &= ~0x302;
break;
case 0x38: // 'ALT'
if(*scanState == Normal) // Left
deviceExtension->DumpFlags &= ~0x340;
else if(*scanState == GotE0) // Right
deviceExtension->DumpFlags &= ~0x304;
break;
case 0x36: // Right 'Shift'
if(*scanState == Normal)
deviceExtension->DumpFlags &= ~0x301;
break;
case 0x2A: // Left 'Shift'
if(*scanState == Normal)
deviceExtension->DumpFlags &= ~0x310;
break;
default:
onflag = 0;
if((DumpKey & 0x80) == 0) {
if(*scanState == Normal
&& DumpKey == (scanCode & 0x7F))
onflag = 1;
}
else {
if(*scanState == GotE0
&& DumpKey == scanCode)
onflag = 1;
}
if((DumpKey2 & 0x80) == 0) {
if(*scanState == Normal
&& DumpKey2 == (scanCode & 0x7F))
onflag = 1;
}
else {
if(*scanState == GotE0
&& DumpKey2 == scanCode)
onflag = 1;
}
if(onflag) {
if((deviceExtension->DumpFlags & Dump1Keys) != Dump1Keys)
break;
if(deviceExtension->DumpFlags & 0x100)
deviceExtension->DumpFlags |= 0x200;
else
deviceExtension->DumpFlags |= 0x100;
break;
}
deviceExtension->DumpFlags = 0;
break;
}
}

"acc" <jo...@sina.com> wrote:
> ���̵����̿�������ɨ������һһ��Ӧ�ģ��Ǹ�����ϵͳɨ���루��Ҳ����ʹ��ɨ���뼯1����2�����Ǹ��Ǽ���ɨ���룬Ȼ���� i8042 ������Ϊɨ���뼯֮һ���ͽ��������ʵ��һ��
> ��������ɨ����Ҳ���Բ�һһ��Ӧ��
>
> Den ˵��Pause �� Break ɨ����һ��ָ���Ǽ���ɨ���룻��˵ɨ���벻һ��ָ���Ƿ�����ϵͳɨ���롣
>
> ��� i8042 ��Ҫ���룬���� Ctrl-Break����ô��һ��ҲҪ����һ��״̬�ֽڣ����״̬�ֽڿ��ܼ�¼��������SHIFT��Ctrl��Alt���ĸ����ء��ҵ������ǣ��Ƿ��������ô��״̬�ֽڣ�
>

acc

unread,
Oct 11, 2009, 12:05:37 AM10/11/09
to
Pause һ������ Ctrl�����Բ����������Ч����ô����������Ϊ�˺���ǰ����
�������⵱Ȼ�Ǹ��ܳ�ֵ����ɣ���

��ǰ�ղ��˸���ҳ������û��ϸ����
http://en.wikipedia.org/wiki/Break_key
�ղ��ڿ� sobrkyb2.pdf �Լ��������ϵ�ʱ�򣬷��������˿���

On many modern PCs��Pause interrupts screen output by BIOS until another
key is pressed. This is effective during boot in text mode and in a DOS
box in Windows safe mode with 50 lines. On early keyboards without a
Pause key (before the introduction of 101-key keyboards) the Pause
function was assigned to Ctrl+NumLock, and the Break function to
Ctrl+ScrLock; these key-combination still work with most programs, even
on modern PCs with modern keyboards. Pressing the dedicated Pause key on
101-key keyboards sends the same scancodes as pressing Ctrl, then NumLock,
then releasing them in the reverse order would do; additionally, a E1h
prefix is sent which enables 101-key aware software to discern the two
situations, while older software usually just ignores the prefix. The
Pause key is different from all other keys in that it sends no scancodes
at all on release; therefore it is not possible for any software to
determine whether this key is being held down.

��λ�˵��
Ctrl-Num Lock ���� Pause �Ĺ��ܺ�ɨ����
Ctrl-Scroll Lock ���� Break ����
Pause ���� Pause �Ĺ��ܺ�ɨ���롢��ɨ����ǰ�渽�� E1h
�����ԣ���ͬ��ɨ����ָ����һ�ֽڵ�ɨ���룬û�а���ǰ׺ E1h��

������½�����Ӹ�������£���������ǰ Pause �� Break �Ƕ�����������������
�ļ��ݼ��̽� Pause �� Break �ϳ�һ������ Ctrl�������� Pause ���ֵ�������
���������?����ɨ���벻ͬ�����ͬ��ȱ���ǣ�

Pause��
. Ctrl-Num Lock ���� Ctrl-Pause ���������� Ctrl-Num Lock��
. Ctrl-Shift-Num Lock �������Ϊ Shift-Pause��������ֱ�Ӱ� Shift + Pause����
Ctrl-Num Lock ���޸�ɨ���룬�����������ʱ������ת�� Ctrl-Num Lock �����ת

����̡�

Break��
. ���۴�����Ǵ�ɨ����ĽǶȣ�Break ���벻�� Ctrl��
. �� Alt-Ctrl-Shift-Break ����������Ϊ Ctrl-Break �ǣ�ת����ģ���ʵɨ��
�롣

Ctrl + Pause �ȸı� Pause �����Ҳ�ı� Pause ��ɨ���롣
- ��������漰 kbddep.c �� ntinput.c��
Ctrl-Num Lock ֻ�����Ӧ���ı� Num Lock ��ɨ���롣
- �������ֻ�漰 ntinput.c��

Ctrl-Num Lock �� Pause��
==============================
set1��Num Lock
ͨ�� 45
�ϣ� C5
set1, Pause
ͨ��E1 1D 45 E1 9D C5
�ϣ�û�� Pause �Ķ��룬������ͨ�����һ�����롣

set2��Num Lock
ͨ�� 77
�ϣ� F0 77
set2, Pause
ͨ��E1 14 77 E1 F0 14 F0 77
�ϣ�û�� Pause �Ķ��룬������ͨ�����һ�����롣
==============================

Ctrl-Scroll Lock �� Break��
==============================
set1��Scroll Lock
ͨ�� 46
�ϣ� C6
set1��Break
ͨ��E0 46 E0 C6
�ϣ���ʵ������ Pause �� Ctrl ���ʱ��ɨ���롣 Pause ��Ӧ�ļ�֪���Dz�����
���뻹�Ƕ��뱻���ԣ���֮��������򿴲��������Ķ��룬������������
����ظ������Ժ������ Pause һ����ͨ����϶��롣

set2��Scroll Lock
ͨ�� 7E
�ϣ� F0 7E
set2��Break
ͨ��E0 7E E0 F0 7E
�ϣ�û�ж��룬ԭ��ͽ���취ͬ set1 �� Break �Ķ���һ��
==============================

ɨ����ժ��΢��� Keyboard Scan Code Specification ��
Pause ɨ������ E1 1D 45 E1 9D C5�����Dz���������޸ĺ��ɨ���룿kbddep.c
�յ��� Pause ɨ������ɶ��E1 45 ô��


����Ĵ�����п��Կ�����״̬�֡�������û�е�ʵ��������δ��� Pause/Break ��
����ġ�Print Screen/System Request Ӧ��Ҳ�����Ƶ����������ļ���û����ȫ
�汾��

// nt4\private\ntos\dd\i8042prt\kbddep.c
//
// Fragment

BOOLEAN I8042KeyboardInterruptService(PKINTERRUPT Interrupt, PVOID Context)
//
// Routine Description:
// ���Ǽ���ʹ��ɨ���뼯1 ʱ�ļ����жϷ������
//
{
// ...

// ���̵���������
// �������С��������ڲ���16�ֽ��Ƚ��ȳ�����������
// ��1 ʹ�� FFh����2 �� ��3 ʹ�� 0 ��ʾ���ޡ�
if (scanCode == (UCHAR)0xFF)


{
input->MakeCode = KEYBOARD_OVERRUN_MAKE_CODE;
input->Flags = 0;
*scanState = Normal;
}
else
{
switch (*scanState)
{
case Normal:

// E0h��E1h ��־��һ����չ���ʱ�����ٶ�һ�Ρ�
if (scanCode == (UCHAR)0xE0)


{
input->Flags |= KEY_E0;
*scanState = GotE0;
break;
}
else if (scanCode == (UCHAR)0xE1)
{
input->Flags |= KEY_E1;
*scanState = GotE1;
break;
}

} // ���ϵĺ�����

// ...

if (scanCode <= (UCHAR)0x7F) // ͨ��
{
// ��1 ScanCode ��ͨ�벿�ַ�Ϊ���ࡣ
// ��һ�࣬�޸ļ����
// ���� Ctrl������ Alt������ Shift��
// Ctrl �� Alt ͨ����չɨ����������ң�
// Shift ��������ɨ���붼����ͨ�ģ�����ʹ����չɨ���롣
// �޸ļ�Ӱ�조״̬�֡���deviceExtension->DumpFlags
// �ڶ��࣬������� default ��֧���?
// default ������Щɶ��
switch (scanCode)
{
case 0x1D: // 'CTRL'
if (*scanState == Normal) // Left
deviceExtension->DumpFlags |= 0x20;
else if (*scanState == GotE0) // Right


deviceExtension->DumpFlags |= 0x02;
break;

case 0x38: // 'ALT'
if (*scanState == Normal) // Left
deviceExtension->DumpFlags |= 0x40;
else if (*scanState == GotE0) // Right


deviceExtension->DumpFlags |= 0x04;
break;

case 0x36: // Right 'Shift'

if (*scanState == Normal)


deviceExtension->DumpFlags |= 0x01;
break;

case 0x2A: // Left 'Shift'

if (*scanState == Normal)


deviceExtension->DumpFlags |= 0x10;
break;

default:
if ((DumpKey & 0x80) == 0)
{

if (*scanState == Normal && DumpKey == scanCode)
break;
}
else if (*scanState == GotE0 && (DumpKey & 0x7F) == scanCode)
break;

if ((DumpKey2 & 0x80) == 0)
{

if (*scanState == Normal && DumpKey2 == scanCode)
break;
}
else if (*scanState == GotE0 && (DumpKey2 & 0x7F) == scanCode)


break;
deviceExtension->DumpFlags = 0;
break;
}

} // if (scanCode <= (UCHAR)0x7F)
else // ���롣(UCHAR)scanCode > 0x7F && (UCHAR)scanCode != 0xFF
{
// ֻ�� scanCode �ĺ���λ
// ���ж�����Ȼ��Ϊ���ࣺ�޸ļ�������
// �����Ƕ��룬������������Ҫ�޸ġ�״̬�֡�����
deviceExtension->DumpFlags
// �޸ĵķ����ǹر���Ӧ��λ�� &= ~mask
switch (scanCode & 0x7F)
{
case 0x1D: // 'CTRL'
if (*scanState == Normal) // Left
deviceExtension->DumpFlags &= ~0x320;
else if (*scanState == GotE0) // Right


deviceExtension->DumpFlags &= ~0x302;
break;

case 0x38: // 'ALT'
if (*scanState == Normal) // Left
deviceExtension->DumpFlags &= ~0x340;
else if (*scanState == GotE0) // Right


deviceExtension->DumpFlags &= ~0x304;
break;

case 0x36: // Right 'Shift'

if (*scanState == Normal)


deviceExtension->DumpFlags &= ~0x301;
break;

case 0x2A: // Left 'Shift'

if (*scanState == Normal)


deviceExtension->DumpFlags &= ~0x310;
break;

default:
onflag = 0;
if ((DumpKey & 0x80) == 0)
{

if (*scanState == Normal && DumpKey == (scanCode & 0x7F))
onflag = 1;
}
else if (*scanState == GotE0 && DumpKey == scanCode)
onflag = 1;

if ((DumpKey2 & 0x80) == 0)
{

if (*scanState == Normal && DumpKey2 == (scanCode & 0x7F))
onflag = 1;
}
else if (*scanState == GotE0 && DumpKey2 == scanCode)
onflag = 1;

if (onflag)
{
if ((deviceExtension->DumpFlags & Dump1Keys) != Dump1Keys)
break;
if (deviceExtension->DumpFlags & 0x100)


deviceExtension->DumpFlags |= 0x200;
else
deviceExtension->DumpFlags |= 0x100;
break;
}
deviceExtension->DumpFlags = 0;
break;

} // switch (scanCode & 0x7F)
} // else // if (scanCode <= (UCHAR)0x7F)
} // else // if (scanCode == (UCHAR)0xFF)
}

// win2k\private\ntos\w32\ntuser\kernel\ntinput.c
//
// Fragment

VOID xxxKeyEvent(USHORT usFlaggedVk, WORD wScanCode, DWORD time, ULONG_PTR
ExtraInfo, BOOL bInjected)
{
VkHanded = (BYTE)usFlaggedVk; // get rid of state bits - no longer
needed

//
// Call low level keyboard hook to see if it allows this
// message to pass
//

if ((pHook = PhkFirstValid(ptiCurrent, WH_KEYBOARD_LL)) != NULL)
{

KBDLLHOOKSTRUCT kbds;
BOOL bAnsiHook;
USHORT msg = message;

//
// Check if this is a WM_SYS* message
//
if (TestRawKeyDown(VK_MENU) && !TestRawKeyDown(VK_CONTROL))
{


msg += (WM_SYSKEYDOWN - WM_KEYDOWN);
usExtraStuff |= 0x2000; // ALT key down
}

kbds.vkCode = (DWORD)VkHanded;
kbds.scanCode = (DWORD)wScanCode;

kbds.flags = HIBYTE(usExtraStuff | (bInjected ? (LLKHF_INJECTED <<
8) : 0));


kbds.flags |= (fBreak ? (KBDBREAK >> 8) : 0);

kbds.time = time;
kbds.dwExtraInfo = ExtraInfo;

if (xxxCallHook2(pHook, HC_ACTION, (DWORD)msg, (LPARAM)&kbds, &bAnsiHook))
{
// ...
}
}
}

"Cen" <C...@rixi.an> д����Ϣ����:hankbf$adr$1...@news.eternal-september.org...

acc

unread,
Oct 11, 2009, 12:09:42 AM10/11/09
to
�׶��Խ�չ��

����밴�����ע����ȼ�ʹ�� Ctrl-Num Lock��

"acc" <jo...@sina.com> д����Ϣ����:hakoba$5p4$1...@www.shinco.com...

acc

unread,
Oct 11, 2009, 2:30:06 AM10/11/09
to
���1��Ctrl + Pause

�ȸı� Pause �����Ҳ�ı� Pause ��ɨ���롣
- ����������ϲ��� Ctrl-Break ������Ĺ��Ҫ�漰 kbddep.c �� ntinput.c��

���2��Ctrl-Num Lock


ֻ�����Ӧ���ı� Num Lock ��ɨ���롣

- ����������ϲ��� Ctrl-Pause ������Ĺ��ֻ�漰 ntinput.c��

�������Ƿ����1 Ҫ���� kbddep.c ���?Ȼ������ ntinput.c ���?�������
Ctrl-Break�������2 ֻ��Ҫ�� ntinput.c �д������Ӧ����

�������ͦ�ֿڵģ�Ҳ���Ǻ���Ҫ�����ȿ��� kbddep.c �ɡ�

"acc" <jo...@sina.com> д����Ϣ����:harlif$nn5$1...@www.shinco.com...

Cen

unread,
Oct 12, 2009, 10:32:11 AM10/12/09
to
1) Pause �� Break �������83/84������ȫ��û��(Break���ڵ籨������)
Pause ������CTRL+NumLock, �� 1D + 45 + C5 + 9D �� 1D + 45 + 9D + C5, CTRLһ��Ҫ��NumLock����, �������������ν.
break ������CTRL+ScrollLock, �� 1D + 46 + C6 + 9D �� 1D + 46 + 9D + C6.

�� ����ɨ����(set1) ����ɨ����(set1)
Num Lock 45 C5
Scroll Lock 46 C6
L CTRL 1D 9D
R CTRL EO 1D EO 9D
Pause E1 1D 45 E1 9D C5 ��
(L/R-Ctrl+Pause)Break E0 46 E0 C6 ��

2) ������101/102��������һ������Pause/Break����, �Ҳ�֪��Ϊʲô���󷽵�����2����1��1�� :-)
���ҵ��뷨, ���Ǽ�����ֻҪ��Pause��ɨ�������Ϊ E045/E0C5, L/R-Ctrl���µ�ʱ��ΪE046/E0C6 ������.
��֪��Ϊʲô��Ƴ���������, �м���ɨ����, �޼���ɨ����, ����ɨ���������������������
��ΪBreakʱһ������Ctrl�����Break(������Pause), ����Break�ı���ɨ���벻��LCtrl(1D/9D).
Pause = { E1(��չ, ���EO1D��R CTRL����������E1) + 1D(L CTRL) + 45(Num Lock) + E1(��չ) + 9D(L CTRL��) + C5(Num Lock��) }
L-Ctrl + Break = 1D(L CTRL) + { E0(��չ) + 46(ScrollLock) + E0(��չ) + C6(ScrollLock��) } + 9D(L CTRL��)
R-Ctrl + Break = EO1D(R CTRL) + { E0(��չ) + 46(ScrollLock) + E0(��չ) + C6(ScrollLock��) } + EO9D(R CTRL��)

3) �Ҿ���Windows�����˼����������vKeyCode(��������wParam), vScanCode��������Ϣ�Dz����(�ϲ�����lParam).
vKeyCode��������Ctrl���״̬, ��MOD_CONTROL��"ʵ������"�ط�ӳCtrl���״̬(�����Ƿ�������vKeyCode���).
KEY vKeyName vKey vScan Extend
NumLock VK_NUMLOCK 90 45 1
NumLock(Ctrl) VK_PAUSE 13 45 1
Pause VK_PAUSE 13 45 0
ScrollLock VK_SCROLL 91 46 0
ScrollLock(Ctrl) VK_CANCEL 3 46 0
Pause(Ctrl) VK_CANCEL 3 46 1
PrintScreen VK_SNAPSHOT 2c 37 1
PrintScreen(Alt) VK_SNAPSHOT 2c 54 0

4) ����ΪWindows��Pause��NumLock(Ctrl)��ExtendŪ����, NumLockҲŪ����(������򲻻�ȥʹ��Extend, ����Ҳ����ν),
��ΪNumLock(Ctrl)��vScan 45��83/84���̾��е�, Pause��101/102���̲��еIJ���Extend.

Ctrl+NumLock��������MOD_CONTROL+VK_NUMLOCK, ��Ctrl+Pause��������MOD_CONTROL+VK_PAUSE����һ��, Ctrl(ûShift Alt)���µ�ʱ��, NumLock��VK_PAUSE������VK_NUMLOCK.

5) NumLock/ScrollLock �� Pause ��һ��
a) NumLock/ScrollLock ֻ��Ctrl����(ûShift Alt)���µ�ʱ��, vKey��ת��. ������Ϊ��ǰֻ����Ctrl+NumLock=Pause Ctrl+ScrollLock=Break,
��Shift Alt������Խ�NumLock/ScrollLock.
b) Pause ֻҪCtrl����(����Shift Alt), vKey����VK_CANCEL. ������ΪPause/Break����ר�������, ��Ctrl����϶���Break
c) NumLock/ScrollLock Ctrl���µ�ʱ��, vScanCode����. ������Ϊ83/84����Pause/Breakֻ�Ǹ�����Ŀ�ݼ�, ����ʵ�ʵ������, �����ֻ��עNumLock/ScrollLock
d) Pause Ctrl���µ�ʱ��, vScanCode��=ScrollLock, Ctrlû���µ�ʱ��, vScanCode��=NumLock. ������Ϊ�Ǻ�83/84���̼���, Pause��ģ��NumLock�ľͼ�װNumLock��vScanCode, Ctrl+Pause��ģ��ScrollLock�ľͼ�װScrollLock��vScanCode.

6) ��eMule���ص���win2kû��dd(device driver)����, nt4��ddҲ�Dz�ȱ��, keyboard��Ŀ¼û�ļ�, ����������ת���Dz��ִ���.
�Ұ�nt4��dd"��Ƭ�м�"�����[1], ������Ȥ����"����"һ�� :-)
�ղ������http://sites.google.com https://sites.google.comȫ��reset, �Һ���fg689pb1.exe�ṩ150kB/s�ȶ����ϴ�����.
�Ҿ���GFW��FLG���޼��, ��ΪGFW�����Ҷ�GCD��ʹ��, ���Ͷ�FLG�ķ���, ÿresetһ�ξ�GCD--; FLG++;һ��.

[1] http://sites.google.com/site/gugoge/windowsnt/nt4_private_ntos_dd.7z

acc

unread,
Oct 12, 2009, 9:35:36 PM10/12/09
to
��ʵ�ϼ���ǰ�ҵ�һ�ۿ��� google �ġ��ݵ��ط��ɷ�������ߣ������������δ����
ʾ����ʱ�����룬google ���湻���ģ��������仰����Ҫ���㿴����������仰��ʾ

�㡣�����ҲҪ���������ҲҪ�����ڷ������Ĺ���м�����⣨����֤��������⣬
�Ǻǣ�google ������ϣ����������ʵ��һ�ֱ�������Ȼ�������Ǻ�ϲ�������ġ���

������Ȩ�⣬�����Ǿ仰Ӧ���������ŵĽ��������

"Cen" <C...@rixi.an> д����Ϣ����:havetb$fh8$1...@news.eternal-september.org...

acc

unread,
Oct 12, 2009, 9:37:57 PM10/12/09
to
���⣬�����ˡ��ܻ�����������

acc

unread,
Oct 12, 2009, 9:44:08 PM10/12/09
to
��ô�� folder folder folder ������the longest yard

acc

unread,
Oct 12, 2009, 9:52:34 PM10/12/09
to
���ȿ��������ǧ�߰��е� kbddep.c

"Cen" <C...@rixi.an> д����Ϣ����:havetb$fh8$1...@news.eternal-september.org...

Cen

unread,
Oct 13, 2009, 4:43:14 AM10/13/09
to
�Ҿ�������ʾ��"ʵ������"��"��ѧ"̬��,
������������ij��ʱ, ���ԭ�IJο�����, �����ⲻ���ҵ�ԭ��, �����ñ��˵�.
Google����ʾҲ�������˼, ��������������ԭʼ���������, �ǰ����˵ķ��ɷ�������߹��˹��.
�����ҵı��ذ�Ҳ������ʾ(�����һҳ�й���������ʾ, ��һҳû����������ʾ).

��Ȼ����ʾ���й�������˵, �͹�����"��"Ч��,
��Ϊ"��"�й�������С�ͱ���������������Ƚ�����ȷ��ȫ���,
ÿ�ο�������ʾ, ����Ϳ���һ��, ������DZ��˼��ù��.

Cen

unread,
Oct 13, 2009, 4:45:46 AM10/13/09
to
�����, 2274�� :-)
WindowsԴ����������, ���ж�, ���ж�, ������ȷʵ������Ŀ, �����ж���, һ�δ���Ҫ���Ϸ��²�̫����.

"acc" <jo...@sina.com> wrote:
> ���ȿ��������ǧ�߰��е� kbddep.c

acc

unread,
Oct 13, 2009, 11:26:58 PM10/13/09
to
�����ˡ�����ǧ�����С�

"Cen" <C...@rixi.an> д����Ϣ����:hb1eno$ibn$1...@aioe.org...

acc

unread,
Oct 14, 2009, 1:39:45 AM10/14/09
to
��ǧ���е��ļ�����ʵ���������Ȥֻ������һ������

BOOLEAN I8042KeyboardInterruptService(PKINTERRUPT Interrupt, PVOID Context)
600 ���У����кܶ��ձ����̵ģ����Բ�����

����������µذѺ���������һ�飬������������ͼ��Ȼ������Ҫ����
I8xWriteDataToKeyboardQueue ��������������ң�һ���Һ��ˡ�������ƪ���£�

JIURL������

��ƪ����ò�ƺ���ϸ�����֮�����������ù��ˡ��������ȿ�����ƪ���¡�

////////////////////////////////////////////////////////////////////////////////

BOOLEAN I8042KeyboardInterruptService(PKINTERRUPT Interrupt, PVOID Context)

{
UCHAR scanCode;
PDEVICE_EXTENSION deviceExtension;
PDEVICE_OBJECT deviceObject;
KEYBOARD_SCAN_STATE* scanState;
PKEYBOARD_INPUT_DATA input;
ULONG i;

UNREFERENCED_PARAMETER(Interrupt);

// ȡ�豸��չ
deviceObject = (PDEVICE_OBJECT)Context;
deviceExtension = (PDEVICE_EXTENSION)deviceObject->DeviceExtension;

// ��֤���豸�Ƿ������жϡ����״̬�Ĵ�����
// λ Output Buffer Full Ӧ��������״̬
// λ Auxiliary Device Output Buffer Full Ӧ�������״̬
//
// ����� if ���棬���鷵�� FALSE
if ((I8X_GET_STATUS_BYTE(deviceExtension->DeviceRegisters[CommandPort]) &
(OUTPUT_BUFFER_FULL | MOUSE_OUTPUT_BUFFER_FULL)) != OUTPUT_BUFFER_FULL);

// ��Ч���жϡ��� i8042 ��ݶ˿ڶ�һ���ֽڡ�scanCode ��ɸ�ֵ
I8xGetByteAsynchronous((CCHAR)KeyboardDeviceType, deviceExtension,
&scanCode);

// ����ֽ���Ҫô�Ǹ�������Ӧ��Ҫô�Ǹ�ɨ���롣���洦������ֽڡ�
switch(scanCode)
{
case RESEND: break; // 0xFE
case ACKNOWLEDGE: break; // 0xFA
ScanCodeCase:
default:
// �ֱ���չ�����к�һ������������
// ��չ�����У���һ�ֽ��� E0�����һ��һ���һ�ֽ�ͨ����
// һ��ͨ�룺һ�ֽڣ����λ����
// һ����룺һ�ֽڣ����λ��һ������λ��ͨ��һ��
// #126 �ֽ����У�E1 1D 45 9D C5����Ҫ���⴦�?
//
// ����⵽����ļ���߳��ޣ�ʹ�ü�1 ʱ���̷��� 0xFF��
// �����������ӳ������ָʾ��Windows �û� RIT Ҫʹ����
input = &deviceExtension->KeyboardExtension.CurrentInput;
scanState = &deviceExtension->KeyboardExtension.CurrentScanState;
if (scanCode == (UCHAR)0xFF); // ���?��


{
input->MakeCode = KEYBOARD_OVERRUN_MAKE_CODE;
input->Flags = 0;
*scanState = Normal;
}
else
{
switch (*scanState)
{
case Normal:

if (scanCode == (UCHAR)0xE0)
{
input->Flags |= KEY_E0;
*scanState = GotE0;
break;
}
else if (scanCode == (UCHAR)0xE1)
{
input->Flags |= KEY_E1;
*scanState = GotE1;
break;
}

// Fall through
case GotE0:
case GotE1:
if (scanCode > 0x7F)
{
// ���롣�ر����λ�Ի�ö�Ӧ��ͨ�룬��������Ӧ��־��ָʾ�������
// input->MakeCode �Ѷ���Ҳ����ͨ�뱣��
// input->Flags ָ���ü��״̬
input->MakeCode = scanCode & 0x7F;
input->Flags |= KEY_BREAK;
}
else
// ͨ�롣���浽 input->MakeCode
// ���û�е��� input->Flags������һ�� KEY_BREAK ʹ���� |=������
// �²�û��ͨ��ı�־���� Flags �� KEY_BREAK û����λ���Ǿ���ͨ�롣
input->MakeCode = scanCode;
*scanState = Normal;
break;
default: // �������
break;
}
}
if (*scanState == Normal);
{
if (deviceExtension->KeyboardEnableCount)
{
deviceExtension->KeyboardExtension.CurrentInput.UnitId =
deviceExtension->KeyboardExtension.UnitId;
// ���� I8xWriteDataToKeyboardQueue
if (!I8xWriteDataToKeyboardQueue(&deviceExtension->KeyboardExtension,
input))
{
// ���ܵĻ�����¼����
if (deviceExtension->KeyboardExtension.OkayToLogOverflow);
}
// I8xWriteDataToKeyboardQueue �ɹ��ң�����A��
else if (deviceExtension->DpcInterlockKeyboard >= 0)
deviceExtension->DpcInterlockKeyboard += 1;
// I8xWriteDataToKeyboardQueue �ɹ��ң�������A��
else
KeInsertQueueDpc(&deviceExtension->KeyboardIsrDpc,
deviceObject->CurrentIrp,NULL);
}
// ��������״̬
input->Flags = 0;
}
break;
}
return(TRUE);
}

"Cen" <C...@rixi.an> д����Ϣ����:hb1eno$ibn$1...@aioe.org...

Cen

unread,
Oct 14, 2009, 1:50:32 AM10/14/09
to
I8xWriteDataToKeyboardQueue ����ͬĿ¼�� kbdcmn.c ���氡.
JIURL������, ����ָ[1]? �������Ҫע��İ�?

[1] http://d.download.csdn.net/down/165806/xq20051221

acc

unread,
Oct 14, 2009, 2:31:27 AM10/14/09
to
csdn ������Ҫע�ᣬ�����˺þã��������ڻ���ע���ˡ�

�ºſ�ʼ��һЩ��֣�ÿ����һ�Σ�һ�㶼Ҫ��һЩ��֣����ǣ����������һ�£��־��ֻ����ˡ�����һ�㲻����ֲַ����������һ����Խ��Խ�ࡣ

�����¾��������� google ����һ�¾ͺܶ࣬�Ǹ���Ҫ���صIJ����ã�ֻ�����š����Ϊ...��������������ҳ����ˡ�

> I8xWriteDataToKeyboardQueue ����ͬĿ¼�� kbdcmn.c ���氡.
��������������һ�£������������������ܱ����ۣ������?^o^

"Cen" <C...@rixi.an> д����Ϣ����:hb3ork$ju2$1...@news.eternal-september.org...

acc

unread,
Oct 14, 2009, 2:36:38 AM10/14/09
to
��ʼ�� deviceExtension :D

"acc" <jo...@sina.com> д����Ϣ����:hb3r7v$4n7$1...@www.shinco.com...
> ��������������һ�£������������������ܱ����ۣ������?^o^


acc

unread,
Oct 14, 2009, 3:02:28 AM10/14/09
to
�����ڿ���ƪ
http://blog.csdn.net/iiprogram/archive/2007/05/30/1631477.aspx

"Cen" <C...@rixi.an> д����Ϣ����:hb3ork$ju2$1...@news.eternal-september.org...

Cen

unread,
Oct 14, 2009, 9:58:59 AM10/14/09
to
锟斤拷
win2k\private\ntos\w32\ntuser\kernel\xlate.c[1]
ddk\3790.1830\src\input\layout\kbdus\kbdus.c[2]([3]锟斤拷装锟斤拷)
锟斤拷证锟斤拷锟斤拷锟秸伙拷

[1] http://sites.google.com/site/gugoge/windowsnt/win2k_private_ntos_w32_ntuser.7z
1707KB
[2] http://sites.google.com/site/gugoge/windowsnt/DDK_3790.1830_src_input.7z
208KB
[3] http://download.microsoft.com/download/9/0/f/90f019ac-8243-48d3-91cf-81fc4093ecfd/1830_usa_ddk.iso
230MB

"acc" <jo...@sina.com> wrote:
> 锟斤拷锟斤拷锟节匡拷锟斤拷篇
> http://blog.csdn.net/iiprogram/archive/2007/05/30/1631477.aspx

acc

unread,
Oct 14, 2009, 8:20:06 PM10/14/09
to
��Ȼ��һ��ڶ�����ȥ���DZ?

��һ����ͷ��ע�ʹ�д����
"The great artist is the simplifier."

��ʵ�����һ���ʱд��Щ������������˵��

����������⣬�������൱�򵥣��������һϵ�е����ʣ������ڷ�����ϸ�ڡ���Ȼ�����ף����������ʻ�֮ǰ��һ����Խ��Խ���ӣ���ֵ����������һ�������������ʶ����������򡱣����ǿ�����һ�Ѷѵ���ݣ����е�������ùġ�

���쿴���������ļ��������Ϳ������������Ȼ��֪������ȥ�һῴ��ʲô���������������൱�ļ�������Ϊ������ո��뵽���ƵĶ�������

"Cen" <C...@rixi.an> д����Ϣ����:hb4lgp$65h$1...@aioe.org...
> ��


> win2k\private\ntos\w32\ntuser\kernel\xlate.c[1]

> ddk\3790.1830\src\input\layout\kbdus\kbdus.c[2]([3]��װ��)
> ��֤�����ջ�

Cen

unread,
Oct 15, 2009, 12:32:08 AM10/15/09
to
����һ��������˵, �Ǿ���[2]�����
#include <windows.h>
#include "kbd.h"
#include "kbdUS.h"
�ҿ�"kbd.h"��""����<>��Ϊ��ͬĿ¼, �����, ����incĿ¼, �����ҵ���������[4]
��[1]Ҫ�ȿ�[2], ��[2]Ҫ�ȿ�[4]

[4] http://sites.google.com/site/gugoge/windowsnt/DDK_3790.1830_inc_wxp_kbd.h.7z

�ո��뵽���ƵĶ��������ɺ�ʱ���е�, �ϴ�������"printf��C���ַ����, VC��ͼ�ν������û�е�ͬ�Ĺ���(OutputDebugStringֻ����ʾ��VS��output���ڻ�windbg��command����)."֮��ͻȻ�뵽ͼ�ν������Ҳ���ַ����printf������ַ�, ��WinMain����main, WinMain(x,x,x,x)�IJ���������ȡ��, ��������.

�һ���Ϊ�����´�½, ϲ����д������"˫��"����(�ַ����,ͼ�ν���). ��ûд����, �����ܸ��Windows via C/C++_Jeffrey Richter_Christophe
Nasarre_2007.chm, Chapter 4 - Processes, Writing Your First Windows Application.

"You can also create a GUI-based application that outputs text strings to a console window. I frequently create GUI-based
applications that create a console window in which I can view debugging information as the application executes."

��ô��, ԭ��������ͷ���, ��ǰûϸ���Ȿ��, ��������/SUBSYSTEM:CONSOLEʱ�����п�����, �粻�����ٲ�����, ƫƫ�����뵽��ʱ�򿴵�, ���е�а�� :-)

"acc" <jo...@sina.com> wrote:
> ��Ȼ��һ��ڶ�����ȥ���DZ?
>
> ��һ����ͷ��ע�ʹ�д����
> "The great artist is the simplifier."
>
> ��ʵ�����һ���ʱд��Щ������������˵��
>
> ����������⣬�������൱�򵥣��������һϵ�е����ʣ������ڷ�����ϸ�ڡ���Ȼ�����ף����������ʻ�֮ǰ��һ����Խ��Խ���ӣ���ֵ����������һ�������������ʶ����������򡱣����ǿ�����һ�Ѷѵ���ݣ����е�������ùġ�
>
> ���쿴���������ļ��������Ϳ������������Ȼ��֪������ȥ�һῴ��ʲô���������������൱�ļ�������Ϊ������ո��뵽���ƵĶ�������
>

acc

unread,
Oct 15, 2009, 3:00:11 AM10/15/09
to
��Ҳ�ǿ��� Windows ���ı�̺󣬾ͺ�ϲ���ڳ������� _tprintf ������ĺܡ�

"Cen" <C...@rixi.an> д����Ϣ����:hb68mg$h9$1...@news.eternal-september.org...

acc

unread,
Oct 15, 2009, 4:21:54 AM10/15/09
to
��������ʱ�ҿ�����д�����ӣ�˵������ļ�����ƪ���Dz����ˣ�������������ļ�����


�ڶ������벹��һ�£�Windows ���ı�������м򵥵ķ���������һ�������Ҳ����ˣ������Ҿ��ã����ƴ�Ҷ�֪�����Ͼ��Ȿ��Ҳͦ���������Ծ�û�ء�

"Cen" <C...@rixi.an> д����Ϣ����:hb68mg$h9$1...@news.eternal-september.org...

acc

unread,
Oct 15, 2009, 4:36:22 AM10/15/09
to
������Ӳ����ȼ�ʱ�����õij������ msdn �����ӳ�������λ�� RegisterHotKey
������

http://msdn.microsoft.com/en-us/library/ms646309(VS.85).aspx

#include "stdafx.h"

int _cdecl _tmain (int argc, TCHAR *argv[])
{
if (RegisterHotKey(NULL, 1, MOD_ALT | MOD_NOREPEAT, 0x42)) //0x42 is
'b'
{
_tprintf(_T("Hotkey 'ALT+b' registered, using MOD_NOREPEAT
flag\n"));
}

MSG msg = {0};
while (GetMessage(&msg, NULL, 0, 0) != 0)
{
if (msg.message == WM_HOTKEY)
{
_tprintf(_T("WM_HOTKEY received\n"));
}
}
return 0;
}

�о�������Ӻܼ����������̡߳�ע���߳��ȼ����Ϣ���С�

Cen

unread,
Oct 15, 2009, 4:38:59 AM10/15/09
to
"˫��"��������ϴ�˵����������±����ڸ�����;
1) "˫��"����һ���Լ�������, ��ʽ����˻��Լ�ƽ���õ�ʱ��, Ҫ#define printf(...) nothing, ����main�Ļ�WinMain,
�����Ǹ�console�����е����.

2) ��������±����ڲ���printf����, ��һ�α���, ������ʽ�ö�����, ���Ե�ʱ��(����ʽ�õ�ʱ�������), ��Լ���ļ����txt, �����⵽Լ���ļ���ļ��±�����, �Ͱ�buffer��¼���������������, ���Ͽ��Կ���. �رռ��±�����, �����ⲻ�����ھͲ����, ��buffer��¼�������ֵĿ����С,
��Ӱ����ʽ�õ�����.

Cen

unread,
Oct 15, 2009, 5:05:30 AM10/15/09
to
������ӻ�����"˫��"���� :-)
��Ϊ��û����ͼ�ν���(ֻ����Ϣ����û��������).

Cen

unread,
Oct 15, 2009, 5:10:16 AM10/15/09
to
MSDN90RegisterHotKey锟斤拷锟斤拷锟斤拷没锟斤拷锟斤拷锟斤拷,
VC9锟斤拷锟斤拷MOD_NOREPEAT, 锟斤拷去锟斤拷MOD_NOREPEAT锟斤拷锟杰憋拷锟斤拷

MSG msg = {0};
= {0}锟斤拷锟斤拷(锟剿凤拷一锟斤拷mov指锟斤拷目占锟斤拷时锟斤拷), GetMessage(&msg)锟斤拷锟斤拷锟斤拷锟絤sg, 没锟斤拷msg锟斤拷锟斤拷.

"acc" <jo...@sina.com> wrote:
> 锟斤拷锟斤拷锟斤拷硬锟斤拷锟斤拷燃锟绞憋拷锟斤拷锟斤拷玫某锟斤拷锟斤拷锟斤拷 msdn 锟斤拷锟斤拷锟接筹拷锟斤拷锟斤拷锟斤拷位锟斤拷 RegisterHotKey 锟斤拷锟斤拷锟斤拷


>
> http://msdn.microsoft.com/en-us/library/ms646309(VS.85).aspx
>
> #include "stdafx.h"
>
> int _cdecl _tmain (int argc, TCHAR *argv[])
> {
> if (RegisterHotKey(NULL, 1, MOD_ALT | MOD_NOREPEAT, 0x42)) //0x42 is 'b'
> {
> _tprintf(_T("Hotkey 'ALT+b' registered, using MOD_NOREPEAT flag\n"));
> }
>
> MSG msg = {0};
> while (GetMessage(&msg, NULL, 0, 0) != 0)
> {
> if (msg.message == WM_HOTKEY)
> {
> _tprintf(_T("WM_HOTKEY received\n"));
> }
> }
> return 0;
> }
>

> 锟叫撅拷锟斤拷锟斤拷锟斤拷雍芗锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷叱獭锟阶拷锟斤拷叱锟斤拷燃锟斤拷锟斤拷息锟斤拷锟叫★拷

acc

unread,
Oct 15, 2009, 5:10:14 AM10/15/09
to
��ȷʵ��ʹ�ñ�׼�����Ҫ��ͼʡ�¡�

"Cen" <C...@rixi.an> д����Ϣ����:hb6n3l$jpu$1...@news.eternal-september.org...

acc

unread,
Oct 15, 2009, 5:18:56 AM10/15/09
to
���Ӻܺá������кܶ�ϸ�ڿ��Լ������

MOD_NOREPEAT �� Windows 7 �����ϰ汾�����塣

"Cen" <C...@rixi.an> д����Ϣ����:hb6ot8$mlh$1...@aioe.org...
> MSDN90RegisterHotKey������û������,
> VC9����MOD_NOREPEAT, ��ȥ��MOD_NOREPEAT���ܱ���
>
> MSG msg = {0};
> = {0}����(�˷�һ��movָ��Ŀռ��ʱ��), GetMessage(&msg)�������msg, û��msg����.

acc

unread,
Oct 15, 2009, 5:20:53 AM10/15/09
to
�Ҹ����ҳ��ַ�ˡ���������������Ϊ mshelp ����û�����ӳ�����ҳ������С�

"Cen" <C...@rixi.an> д����Ϣ����:hb6ot8$mlh$1...@aioe.org...
> MSDN90RegisterHotKey������û������,
> VC9����MOD_NOREPEAT, ��ȥ��MOD_NOREPEAT���ܱ���
>

> MSG msg = {0};

acc

unread,
Oct 15, 2009, 5:37:21 AM10/15/09
to
����������ôϲ����˫�桱�����������������˫�桱��Ȼ�ͺ�ϲ����

����֮����ϲ��������ӳ����dz��ڲ�ͬ��ԭ����Ϊ��򵥡�רע����Ҫ��չʾ�˺���Ĺ��ܡ��۸������һ�� GetModuleHandle����Ϳ���˫�档

Cen ��д��ƪ��˫�桱��������£����������ô�ҿ����¡���Ȼ Jeffrey Richter
�й����������ǣ���ĺ���Ŀ϶�����ȫһ��ûд��Ҳ�ܷ�����������Ҳ����һ���㵱ʱ���������� :D

"Cen" <C...@rixi.an> д����Ϣ����:hb6ol8$uh4$1...@news.eternal-september.org...

Cen

unread,
Oct 15, 2009, 9:49:45 AM10/15/09
to
�ұ� http://msdn.microsoft.com/en-us/library/ms646309(VS.85).aspx ��VS.85����, ���(VS.85)Ӧ����΢��Ĺ�������, �ĵ�����(��VS.90����)��, �汾��û��. �����(VS.95)��һ��˳�����, MOD_NOREPEAT��SDK7(2009-7-24)������, ���������SDK7������.

MSG msg = {0}; ������һʱ"����". ��Ҳһʱ"����"˵����, ����"һ"��movָ��, msg���Ǽ򵥱���, ��"��"��movָ��.


MSG msg = {0};
while (GetMessage(&msg, NULL, 0, 0) != 0)

00401027 8b35a8204000 mov esi,dword ptr [hotkey2!_imp__GetMessageA (004020a8)]
0040102d 33c0 xor eax,eax
0040102f 50 push eax
00401030 50 push eax
00401031 50 push eax
00401032 89442418 mov dword ptr [esp+18h],eax
00401036 8944241c mov dword ptr [esp+1Ch],eax
0040103a 89442420 mov dword ptr [esp+20h],eax
0040103e 89442424 mov dword ptr [esp+24h],eax
00401042 89442428 mov dword ptr [esp+28h],eax
00401046 8944242c mov dword ptr [esp+2Ch],eax
0040104a 8d442414 lea eax,[esp+14h]
0040104e 50 push eax
0040104f c744241800000000 mov dword ptr [esp+18h],0
00401057 ffd6 call esi
typedef struct tagMSG {
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
} MSG;
typedef struct tagPOINT
{
LONG x;
LONG y;
} POINT;

acc

unread,
Oct 15, 2009, 11:01:45 AM10/15/09
to
�������度�˲�dz��

����������ӣ�������� Windows 7 �����ԣ�����ʵ�Ҿ��úܸ�Ц�������¿�����20��û���ˡ�ͻȻ����һ�¾������ Windows 7��������������һ�£�����Ҳ�ᵽ�� XP��

�����и����ϵͳҪ��
Windows 95, Windows NT 3.1, Windows 7

�����󡣡�����


����������������õģ�Ҳû���Ż�������������ʵ���Ż����Ǻ����У�

#include <tchar.h>
#include <windows.h>

int main()
{
MSG msg;

if (RegisterHotKey(NULL, 1, MOD_ALT, 0x42)) //0x42 is 'b'
_tprintf(_T("Hotkey 'ALT+b' registered.\n"));

while (GetMessage(&msg, NULL, 0, 0))


if (msg.message == WM_HOTKEY)
_tprintf(_T("WM_HOTKEY received\n"));
}

"Cen" <C...@rixi.an> д����Ϣ����:hb79a4$m30$1...@news.eternal-september.org...

Cen

unread,
Oct 15, 2009, 11:31:47 AM10/15/09
to
Windows 95��Windows NT 3.1д�����ǶԵ�, 95/98/me��NT/win2k/XP/Vista�Dz�ͬ�ں˵�����ϵ��.
Windows 7 �ǻ��������, win7����˼����NT3/4/5 win2k/5.1 XP/6 Vistaϵ�еĺ���, û�������һ��ϵ�а�.

���Ǵ�һ���ֳɵ���Ŀ����stdafx.h��targetver.h�����������#include "stdafx.h".

buzzard

unread,
Oct 16, 2009, 9:42:59 PM10/16/09
to
���������۵ĺ����֣�ֻ��СС���飬��C�йصĶ����೭��һ�ݸ�cn.comp.lang.c��
��ʵһֱ���Ƽ���������Ͷ���Ͼ����ڸ����鶼�ܸɺ���

On Thu, 15 Oct 2009 17:20:53 +0800, "acc" <jo...@sina.com> wrote:
--

acc

unread,
Oct 16, 2009, 11:03:48 PM10/16/09
to
��ϲ�����ͣ��о��������ҵ�����ĸо�����

�����Ժ������ﳭ��һ�ݰɡ�

"buzzard" <buz...@126.com> д����Ϣ����:4ada1fec...@news.cn99.com...

acc

unread,
Oct 16, 2009, 11:05:39 PM10/16/09
to
����ʱ��Ҳ������Ͷ���������ٷ�һ�顣

"acc" <jo...@sina.com> д����Ϣ����:hbbc6i$okq$1...@www.shinco.com...

buzzard

unread,
Oct 18, 2009, 9:37:06 PM10/18/09
to
^_^�ɺ�����£��ཽˮ

On Sat, 17 Oct 2009 11:03:48 +0800, "acc" <jo...@sina.com> wrote:
--

>��ϲ�����ͣ��о��������ҵ�����ĸо�����

Cen

unread,
Dec 5, 2009, 1:09:25 AM12/5/09
to
����2���¶϶������̽��, �����е�üĿ��(����16�������ֶ�ʡ��0x)
/***************************************************************************\
Pause
\***************************************************************************/
lkd> x win32k!gpKbdTbl
bf99ab98 win32k!gpKbdTbl
lkd> dd bf99ab98 l1
bf99ab98 e1fca608
typedef struct tagKbdLayer {
PMODIFIERS pCharModifiers;
VK_TO_WCHAR_TABLE *pVkToWcharTable; // ptr to tbl of ptrs to tbl
PDEADKEY pDeadKey;
VSC_LPWSTR *pKeyNames;
VSC_LPWSTR *pKeyNamesExt;
LPWSTR *pKeyNamesDead;
USHORT *pusVSCtoVK;
BYTE bMaxVSCtoVK;
PVSC_VK pVSCtoVK_E0; // Scancode has E0 prefix
PVSC_VK pVSCtoVK_E1; // Scancode has E1 prefix
...
} KBDTABLES, *PKBDTABLES;
lkd> dd e1fca608+24 l1
e1fca62c e1fca1a4
lkd> dd e1fca1a4 l2
e1fca1a4 0013001d 00000000

Pause E1 1D 45 E1 9D C5 ��6���
1)
E1 ��i8042prt!I8042KeyboardInterruptService��¼
2)
1D ��i8042prt!I8042KeyboardInterruptServiceת����kei
kei.MakeCode = 1D & 7f = 1D
kei.Flags = 4(KEY_E1)
win32k!VKFromVSCת����ke
ke.bScanCode = pei->MakeCode & 7f = 1D & 7f = 1D
usVKey = gpKbdTbl->pVSCtoVK_E1[pke->bScanCode]
= HIWORD(*pVSC) if LOWORD(*pVSC)==1D
= 0013(VK_PAUSE)
fVkPause = TRUE
ke.bScanCode = 45 (if usVKey==VK_PAUSE)
ke.usFlaggedVk = usVKey = 0013(VK_PAUSE)
win32k!xxxDoHotKeyStuff
fBreak = pke->usFlaggedVk & KBDBREAK = 0
vk = LOBYTE(pke->usFlaggedVk) = 13(VK_PAUSE)
fsModifiers = 0 (SHIFT/CRTL/ALT/WINû����)
(phk->fsModifiers == fsModifiers && phk->vk == vk)����WM_HOTKEY
3)
45 ��i8042prt!I8042KeyboardInterruptServiceת����kei
kei.MakeCode = 45 & 7f = 45
kei.Flags = 0(KEY_MAKE)
win32k!VKFromVSC
fVkPause = FALSE
return 0(����E1 1D 45��45)
4)
E1 ��i8042prt!I8042KeyboardInterruptService��¼
5)
9D ��i8042prt!I8042KeyboardInterruptServiceת����kei
kei.MakeCode = 9D & 7f = 1D
kei.Flags = 5(KEY_E1|KEY_BREAK)
win32k!VKFromVSCת����ke
ke.bScanCode = pei->MakeCode & 7f = 1D & 7f = 1D
usVKey = gpKbdTbl->pVSCtoVK_E1[pke->bScanCode]
= HIWORD(*pVSC) if LOWORD(*pVSC)==1D
= 0013(VK_PAUSE)
fVkPause = TRUE
ke.bScanCode = 45 (if usVKey==VK_PAUSE)
ke.usFlaggedVk = usVKey = 0013(VK_PAUSE)
ke.usFlaggedVk |= KBDBREAK(if pkei->Flags&KEY_BREAK)
win32k!xxxDoHotKeyStuff
fBreak = pke->usFlaggedVk & KBDBREAK = 8000
fBreak!=0����ͨ�ȼ���WM_HOTKEY
6)
C5 ��i8042prt!I8042KeyboardInterruptServiceת����kei
kei.MakeCode = C5 & 7f = 45
kei.Flags = 1(KEY_BREAK)
win32k!VKFromVSC
fVkPause = FALSE
return 0(����E1 9D C5��C5)


/***************************************************************************\
Break
\***************************************************************************/
lkd> dd e1fca608+20 l1
e1fca628 e1fca108
lkd> dd e1fca108 l27
e1fca108 01b10010 01b00019 01a3001d 01ad0020
e1fca118 01b70021 01b30022 01b20024 01ae002e
e1fca128 01af0030 01ac0032 016f0035 012c0037
e1fca138 01a50038 01240047 01260048 01210049
e1fca148 0125004b 0127004d 0123004f 01280050
e1fca158 01220051 012d0052 012e0053 015b005b
e1fca168 015c005c 015d005d 015f005f 01aa0065
e1fca178 01ab0066 01a80067 01a90068 01a70069
e1fca188 01a6006a 01b6006b 01b4006c 01b5006d
e1fca198 010d001c 01030046 00000000
CRTL���µ�Pause, ɨ�����ѱ�Ӳ��ת�� E0 46 E0 C6 ��4�δ���
1)
E0 ��i8042prt!I8042KeyboardInterruptService��¼
2)
46 ��i8042prt!I8042KeyboardInterruptServiceת����kei
kei.MakeCode = 46 & 7f = 46
kei.Flags = 2(KEY_E0)
win32k!VKFromVSCת����ke
ke.bScanCode = pei->MakeCode & 7f = 46
usVKey = gpKbdTbl->pVSCtoVK_E0[pke->bScanCode]
= HIWORD(*pVSC) if LOWORD(*pVSC)==46
= 0103(KBDEXT|VK_CANCEL)
ke.usFlaggedVk = usVKey = 0103(KBDEXT|VK_CANCEL)
win32k!xxxDoHotKeyStuff
fBreak = pke->usFlaggedVk & KBDBREAK = 0
vk = LOBYTE(pke->usFlaggedVk) = 03(VK_CANCEL)
fsModifiers = 2(MOD_CONTROL ;CRTL����)
(phk->fsModifiers == fsModifiers && phk->vk == vk)����WM_HOTKEY
MOD_CONTROL+VK_PAUSE�ȼ�, fsModifiers���, ��phk->vk=VK_PAUSE�����vk=VK_CANCEL, ������WM_HOTKEY.
����VK_CANCEL�ȼ�, vk���, ��phk->fsModifiers=0�����fsModifiers=MOD_CONTROL, Ҳ������WM_HOTKEY
3)
E0 ��i8042prt!I8042KeyboardInterruptService��¼
4)
C6 ��i8042prt!I8042KeyboardInterruptServiceת����kei
kei.MakeCode = C6 & 7f = 46
kei.Flags = 3(KEY_E0|KEY_BREAK)
win32k!VKFromVSCת����ke
ke.bScanCode = pei->MakeCode & 7f = 46
usVKey = gpKbdTbl->pVSCtoVK_E0[pke->bScanCode]
= HIWORD(*pVSC) if LOWORD(*pVSC)==46
= 0103(KBDEXT|VK_CANCEL)
ke.usFlaggedVk = usVKey = 0103(KBDEXT|VK_CANCEL)
ke.usFlaggedVk |= KBDBREAK(if pkei->Flags&KEY_BREAK)
win32k!xxxDoHotKeyStuff
fBreak = pke->usFlaggedVk & KBDBREAK = 8000
fBreak!=0����ͨ�ȼ���WM_HOTKEY


/***************************************************************************\
Numlock
\***************************************************************************/
lkd> dd e1fca608+18 l1
e1fca620 e1fca008
lkd> dw e1fca008 l46
e1fca008 00ff 001b 0031 0032 0033 0034 0035 0036
e1fca018 0037 0038 0039 0030 00bd 00bb 0008 0009
e1fca028 0051 0057 0045 0052 0054 0059 0055 0049
e1fca038 004f 0050 00db 00dd 000d 00a2 0041 0053
e1fca048 0044 0046 0047 0048 004a 004b 004c 00ba
e1fca058 00de 00c0 00a0 00dc 005a 0058 0043 0056
e1fca068 0042 004e 004d 00bc 00be 00bf 01a1 026a
e1fca078 00a4 0020 0014 0070 0071 0072 0073 0074
e1fca088 0075 0076 0077 0078 0079 0390

lkd> x win32k!gpModifiers_VK
bf99afbc win32k!gpModifiers_VK
lkd> dd bf99afbc l1
bf99afbc bf99af88
lkd> dd bf99af88 l1
bf99af88 bf99af80
lkd> dw bf99af88+4 l1
bf99af8c 0004
lkd> db bf99af88+6 l5
bf99af8e 0f 00 01 0f 02
typedef struct {
bf99af80 PVK_TO_BIT pVkToBit; // Virtual Keys -> Mod bits
0004 WORD wMaxModBits; // max Modification bit combination value
0f 00 01 0f 02 BYTE ModNumber[]; // Mod bits -> Modification Number
} MODIFIERS, *KBD_LONG_POINTER PMODIFIERS;

lkd> x win32k!gapulCvt_VK
bf99afb8 win32k!gapulCvt_VK
lkd> dd bf99afb8 l1
bf99afb8 bf99af98
lkd> dd bf99af98 l3
bf99af98 00000000 bf99af68 00000000
lkd> dd bf99af68 l3
bf99af68 01130090 00030091 00000000

CRTL���µ�Numlock����, ɨ���벻�� 45 1�δ���
1)
45 ��i8042prt!I8042KeyboardInterruptServiceת����kei
kei.MakeCode = 45 & 7f = 45
kei.Flags = 0(KEY_MAKE)
win32k!VKFromVSCת����ke
ke.bScanCode = pei->MakeCode & 7f = 45
usVKey = gpKbdTbl->pusVSCtoVK[pke->bScanCode]
= *(WORD*)((BYTE*)(gpKbdTbl->pusVSCtoVK)+45*sizeof(WORD))
= 0390(KBDEXT|KBDMULTIVK|VK_NUMLOCK)
usVKey = gapulCvt_VK[gafRawKeyState[gpModifiers_VK[SHIFT CONTROL ALT]]][LOBYTE(usVKey)](if usVKey&KBDMULTIVK)
= HIWORD(*pul) if LOBYTE(*pul)==LOBYTE(usVKey)
= 0113(KBDEXT|VK_PAUSE)
pke->usFlaggedVk = usVKey(KBDEXT|VK_PAUSE)

lkd> dw bf99af88+4 l1
bf99af8c 0004
lkd> dw bf99af80 l4
bf99af80 0110 0211 0412 0000
lkd> db bf99af88+6 l5
bf99af8e 0f 00 01 0f 02
SHIFT 10(VK_SHIFT) wModBits=01(KBDSHIFT) ModNumber[01(KBDSHIFT)]=00
CTRL 11(VK_CONTROL) wModBits=02(KBDCTRL) ModNumber[02(KBDCTRL)]=01
ALT 12(VK_MENU) wModBits=04(KBDALT) ModNumber[04(KBDALT)]=02
SHIFT+CTRL ModNumber[01+02]=0f(SHFT_INVALID) ��Ч
SHIFT+ALT 01(KBDSHIFT)+04(KBDALT)>0004(wMaxModBits) ��Ч
CTRL+ALT 02(KBDCTRL) +04(KBDALT)>0004(wMaxModBits) ��Ч
SHIFT+CTRL+ALT >0004(wMaxModBits) ��Ч
lkd> dd bf99af98 l3
bf99af98 00000000 bf99af68 00000000
gapulCvt_VK[ModNumber[01(KBDSHIFT)]=00]=00000000 ��Ч
gapulCvt_VK[ModNumber[04(KBDALT)]=02]=00000000 ��Ч
gapulCvt_VK[ModNumber[02(KBDCTRL)]=01]=bf99af683
lkd> dd bf99af68 l3
bf99af68 01130090 00030091 00000000

101���̵�gapulCvt_VKֻ�е���CONTROL��ת��ָ��, ����SHIFT,ALT��CONTROL��϶�����Ч��ת��ָ��Ӷ��ת��. CONTROL��ת��ָ��ֻ������01130090
00030091
0090(VK_NUMLOCK)��0113(KBDEXT|VK_PAUSE), 0091(VK_SCROLL)��0003(VK_CANCEL)

win32k!xxxDoHotKeyStuff
fBreak = pke->usFlaggedVk & KBDBREAK = 0
vk = LOBYTE(pke->usFlaggedVk) = 13(VK_PAUSE)
fsModifiers = 2(MOD_CONTROL ;CRTL����)
(phk->fsModifiers == fsModifiers && phk->vk == vk)����WM_HOTKEY
�ǵ���CONTROL���µ�SHIFT,ALT,CONTROL�����ΪVK_NUMLOCK��ת����VK_PAUSE���ᷢ��VK_PAUSE��WM_HOTKEY. VK_NUMLOCK+MOD_CONTROL��WM_HOTKEYҲ���ᷢ��, ��Ϊ����MOD_CONTROLʱ��VK_NUMLOCK�ѱ�ת����VK_PAUSE.


/***************************************************************************\
PrintScreen
\***************************************************************************/
lkd> dd e1fca108 lc
e1fca108 01b10010 01b00019 01a3001d 01ad0020
e1fca118 01b70021 01b30022 01b20024 01ae002e
e1fca128 01af0030 01ac0032 016f0035 012c0037

PrintScreen E0 37 2���
1)
E0 ��i8042prt!I8042KeyboardInterruptService��¼
2)
37 ��i8042prt!I8042KeyboardInterruptServiceת����kei
kei.MakeCode = 37 & 7f = 37
kei.Flags = 2(KEY_E0)
win32k!VKFromVSCת����ke
ke.bScanCode = pei->MakeCode & 7f = 37
usVKey = gpKbdTbl->pVSCtoVK_E0[pke->bScanCode]
= HIWORD(*pVSC) if LOWORD(*pVSC)==37
= 012c(KBDEXT|VK_SNAPSHOT)
ke.usFlaggedVk = usVKey = 012c(KBDEXT|VK_SNAPSHOT)

/***************************************************************************\
SysReq
\***************************************************************************/
lkd> dw e1fca008 l55
e1fca008 00ff 001b 0031 0032 0033 0034 0035 0036
e1fca018 0037 0038 0039 0030 00bd 00bb 0008 0009
e1fca028 0051 0057 0045 0052 0054 0059 0055 0049
e1fca038 004f 0050 00db 00dd 000d 00a2 0041 0053
e1fca048 0044 0046 0047 0048 004a 004b 004c 00ba
e1fca058 00de 00c0 00a0 00dc 005a 0058 0043 0056
e1fca068 0042 004e 004d 00bc 00be 00bf 01a1 026a
e1fca078 00a4 0020 0014 0070 0071 0072 0073 0074
e1fca088 0075 0076 0077 0078 0079 0390 0291 0c24
e1fca098 0c26 0c21 006d 0c25 0c0c 0c27 006b 0c23
e1fca0a8 0c28 0c22 0c2d 0c2e 002c

Alt���µ�PrintScreen ɨ����Ҳ�ѱ�Ӳ��ת�� 54 1�δ���
1)
54 ��i8042prt!I8042KeyboardInterruptServiceת����kei
kei.MakeCode = 54 & 7f = 54
kei.Flags = 0(KEY_MAKE)
win32k!VKFromVSCת����ke
ke.bScanCode = pei->MakeCode & 7f = 54
usVKey = gpKbdTbl->pusVSCtoVK[pke->bScanCode]
= *(WORD*)((BYTE*)(gpKbdTbl->pusVSCtoVK)+54*sizeof(WORD))
= 002c(VK_SNAPSHOT)
ke.usFlaggedVk = usVKey = 002c(VK_SNAPSHOT)

Alt-PrintScr���ֵ��������Ϊ�������зŵ����ֵ��һ���, ���԰���ת��������ͬһ�����ֵLOBYTE(usFlaggedVk).

"acc" <jo...@sina.com> wrote:
> ���Dz���ͬһ��ɨ����ɣ���ȫ�� 16 ���ƣ�
> Pause ͨ�� E1 1D 45 E1 9D C5, 45 (lParam), 13(vk)
> Break ͨ�� E0 46 E0 C6, E0 46(lParam), 3(vk)
> lParam ���� Num Lock ɨ���� E0 45
> �����ҿ���һ��ɨ���룬Num Lock �� 45
>
> �ҿ����Ұ��� Ctrl ʱ�ٰ� Pause����ɨ���붼����ˡ�ͬһ���������� Ctrl�������˲�ͬ��ɨ���룬��Ӧ�����������֮ǰ���İɣ�����֪�������ĸ��ؽ��������ָĶ��������Ǹ� 8042 оƬ�ϣ������ϵļ��̿��� ������
>
> �㰴ס Ctrl���ٰ� Num Lock��������� VK_PAUSE����������Ҿ��ã�������������������İɡ�
"acc" <jo...@sina.com> wrote:
> Alt-PrintScr Ҳ�޸�ɨ���룬�õ������޸����ֵ��


acc

unread,
Dec 5, 2009, 2:36:09 AM12/5/09
to
����Ϣ���dz��󣬰������16������

How Keyboard Data Gets Translated ( 1 ~ g )

"Cen" <C...@rixi.an> д����Ϣ����:1...@rixi.an...


> ����2���¶϶������̽��, �����е�üĿ��(����16�������ֶ�ʡ��0x)
>

> ...


acc

unread,
Dec 5, 2009, 2:41:33 AM12/5/09
to
11 �·��DZ� Windows Internals ����棬�Ҳ�ʱ�ؿ�����̳�Ǹ���Raw���������� 11
�� 10 �����Ҿ��ϴ�������档12 �³��������ϲ��˲飬�б����Ƶ������飬�������ݺ������Ƿ�һģһ��û����������Ϊ�鱾ҳ���Ŀ¼�������ֱ����ͼƬ���ȵȣ���֮���Ǻܺã�����Ҳû��ר�ŷ���

"Cen" <C...@rixi.an> д����Ϣ����:1...@rixi.an...

Cen

unread,
Dec 5, 2009, 8:03:14 AM12/5/09
to
�°��ҹ�����Ҫ������Vista Win7��һЩ�����Ե�����, ��XP���Ʋ����и���ϸ��������.
�����߳��л���DPC/APC�Ĺ�ϵ, ����û���ᵽ, �����ⲿ�ֵ�win2kԴ����ȫ, ���Һ�XPsp3����һģһ��һ�ֲ���, ���˼��������ͷ��.
������Щ�ط����ò�̫�Ͻ�, ����571ҳ
When a device interrupt occurs, the processor transfers control to the kernel trap handler,
which indexes into its interrupt dispatch table to locate the ISR for the device. ISRs in Windows
typically handle device interrupts in two steps. When an ISR is first invoked, it usually
remains at device IRQL only long enough to capture the device status and then stop the
device��s interrupt. It then queues a DPC and exits, dismissing the interrupt. Later, when the
DPC routine is called, the device finishes processing the interrupt. When that��s done, the
device calls the I/O manager to complete the I/O and dispose of the IRP. It might also start the
next I/O request that is waiting in the device queue.

1) trap handler
2) dispatch to ISR
3) queues a DPC
4) dismissing the interrupt
�����жϵ�dismissing the interruptʵ������2)֮ǰ,
trap handler����Ĵ������out 20h,al dismissing the interrupt, sti enable (����stop) interrupt, Ȼ��ŵ���ISR.

0 new messages