�������� Linux Tags

6. ����

��Microsoft Windows 98�У����̺ͻ�����������׼��ʹ����������Դ����һЩ��������г������������á���Ȼ�������ڽ����Ӧ�ó�ʽ�б�ʮ��ǰʹ�õø�Ϊ�㷺��������һЩӦ�ó�ʽ�У����Ǹ�ϰ���ʹ�û�����������Ϸ����ͼ��ʽ�����ֳ�ʽ�Լ�Web������ȳ�ʽ�о���������Ȼ�������ǿ��Բ�ʹ�û��󣬵����Բ��ܴ�һ���PC�аѼ��̲����

���춸��˵��Ե�����Ԫ���������зdz���Զ����ʷ������Դ�1874��ĵ�һ̨Remington���ֻ������ڵĵ��Գ�ʽԱ�ü�����Hollerith��Ƭ�ϴ�ף��������ն˻����ü���ֱ�������������ͨ��PC�ϵļ�����ijЩ������������䣬�����˹��ܼ����α��ƶ����͵��������ּ��̣������ǵ�����ԭ��������ͬ��

���̻���
��

������Ѿ��µ�Windows��ʽ����λ�ü�������ģ�����������ѶϢ����ʽ���ݸ���ʽ���Ӵ�ѶϢ������ʽ��ʵ���ϣ���һ��ѧϰѶϢʱ�������¼�����һ��ѶϢ��ν���ͬ��̬��Ѷ���ݸ�Ӧ�ó�ʽ��������

Windows�ð��ֲ�ͬ��ѶϢ�����ݲ�ͬ�ļ����¼��������̫���ˣ����ǣ�����������������һ������ʽ���Ժ�����������һ���ѶϢ���������κ����⡣���ң��ڴ��������£���ЩѶϢ�а����ļ�����Ѷ���춳�ʽ����Ҫ�ġ��������̵IJ��ֹ�������ʶ�����ЩѶϢ����Ҫ�ģ���Щ�Dz���Ҫ�ġ�

���Լ���
��

��Ȼ������Windows��ʽ��ʹ�����������Ҫ��Դ�����dz�ʽ���ض������յ�����ѶϢ��������Ӧ��Windows����Ҳ�ܴ���������̹��ܡ�

���磬�����Ժ�����Щ���ϵͳ���ܵİ���������ͨ���õ�Alt������ʽ���ؼ�����Щ��������ΪWindows�Ὣ����������֪ͨ��ʽ����Ȼ�������ʽ����ô������Ҳ�ܼ�����Щ����������Ȼ���г�ʽ���ܱ��İ�����ͨ���Ӵ����Ӵ�ѶϢ������ʽ����ͨ���ڶ��Ĵ�����ʽ�ǽ��������ݸ�DefWindowProc�����գ��Ӵ�ѶϢ������ʽ�����һ��ѶϢ����ʾһ�����ܱ��ѡ���ˡ�ͨ�������������Ӵ�ѶϢ������ʽ��Ҫ֪���ģ��ڵ�ʮ�½����ܹ��ܱ�����

��ЩWindows��ʽʹ�á����̼��ټ���������ͨ�ù��ܱ�����ټ�ͨ���ǹ��ܼ�����ĸͬCtrl������ϣ����磬Ctrl-S��춱��浵��������Щ���̼��ټ����ʽ���ܱ�һ���ڳ�ʽ����Դ���������ж��壨���ǿ����ڵ�ʮ�¿�������Windows����Щ���̼��ټ�ת��Ϊ���ܱ�����ѶϢ���������Լ�ȥ����ת����

�Ի�����Ҳ�м��̽��棬���ǵ��Ի����鴦춻״̬ʱ��Ӧ�ó�ʽͨ�����ؼ��Ӽ��̡����̽�����Windows������Windows�ѹ�춰������õ�ѶϢ���͸���ʽ���Ի�������԰�������������ֵı༭���������һ����С����ʹ���߿����ڿ��м����ִ���Windows�������б༭�������߼���������������ᣬ���༭��������������ݴ��͸���ʽ����춶Ի��������ϸ��Ѷ����μ���ʮһ�¡�

�༭������ؾ���춵���һ�У�����Ҳ�����ֻ�ڶԻ������С�һ���ڳ�ʽ���Ӵ��ڵĶ��б༭��������ܹ���Ϊһ���򵥵����ֱ༭���ˣ��μ��ھš�ʮ��ʮһ��ʮ���µ�POPPAD��ʽ����Windows������һ��Rich Text���ֱ༭������������༭����ʾ��ʽ�������֣���μ�/Platform SDK/User Interface Services/Controls/Rich Edit Controls����

�����ᷢ�֣��ڿ���Windows��ʽʱ������ʹ�ô������̺ͻ�����������Ӵ������������ϸ߲����Ѷ���ݻظ��Ӵ���ֻҪ�����Ŀ������õù��࣬���Ͳ�����������ѶϢ�������ˡ�

˭����˽���
��

�����еĸ��˵���Ӳ��һ�������̱�������Windows��ִ�е�����Ӧ�ó�ʽ���á���ЩӦ�ó�ʽ�����ж���Ӵ������̱����ɸ�Ӧ�ó�ʽ�ڵ������Ӵ����á�

����һ�£���ʽ������ѶϢ�����м���ѶϢ��MSG�ṹ����hwnd��λ������λָ������ѶϢ���Ӵ��������롣ѶϢ��Ȧ�е�DispatchMessage��ʽ���Ӵ�ѶϢ������ʽ���͸�ѶϢ�����Ӵ�ѶϢ������ʽ����ҪѶϢ���Ӵ�����ϵ���ڰ��¼����ϵļ�ʱ��ֻ��һ���Ӵ�ѶϢ������ʽ���ռ���ѶϢ�����Ҵ�ѶϢ��������ѶϢ���Ӵ��������롣

�����ض������¼����Ӵ��������뽹�㡣���뽹��ĸ������Ӵ��ĸ��������������뽹����Ӵ��ǻ�Ӵ����Ӵ��������Ӵ�����Ӵ������Ӵ������߻�Ӵ����Ӵ������Ӵ��ȵȣ���

ͨ�������ױ���Ӵ�����ͨ���Ƕ����Ӵ���Ҳ����˵�����ĸ��Ӵ�������NULL�������Ӵ��б����У�Windows��ͻ����ʾ�����С������Ӵ����жԻ�����ܣ��Ի������кܳ����ĸ�ʽ�������DZ����У�Windows��ͻ����ʾ��ܡ������Ӵ�Ŀǰ����С���ģ�Windows���ڹ�������ͻ����ʾ�������ʾ����һ�����µİ�ť��

�����Ӵ������Ӵ�����ô�����뽹����Ӵ��ȿ����ǻ�Ӵ�Ҳ�����������Ӵ�����������Ӵ����������¿���������ڶԻ������е���ѹ��ť����ѡť����ȡ���顢�����С��༭������嵥���顣���Ӵ������Լ���Ϊ��Ӵ���ֻ�е����ǻ�Ӵ��������Ӵ�ʱ�����Ӵ����������뽹�㡣���Ӵ�������һ��ͨ����ʾһ����˸�IJ�����Ż���������ʾ���������뽹�㡣

��ʱ���뽹�㲻���κ��Ӵ��С�����������������г�ʽ������С����ʱ����ʱ��Windows���������Ӵ����ͼ���ѶϢ��������ЩѶϢ�뷢�͸�����С���Ļ�Ӵ��ļ���ѶϢ�в�ͬ����ʽ��

�Ӵ�ѶϢ������ʽͨ������WM_SETFOCUS��WM_KILLFOCUSѶϢ���ж������Ӵ���ʱӵ�����뽹�㡣WM_SETFOCUSָʾ�Ӵ����ڵõ����뽹�㣬WM_KILLFOCUS��ʾ�Ӵ�����ʧȥ���뽹�㡣�ҽ��ڱ��µ�������ϸ˵����ЩѶϢ��

���к�ͬ��
��

��ʹ���߰��²��ͷż����ϵļ�ʱ��Windows�ͼ���������ʽ��Ӳ��ɨ����ת��Ϊ��ʽѶϢ��Ȼ������ЩѶϢ����������ѶϢ�����С�ʵ���ϣ�Windows����ν�ġ�ϵͳѶϢ���С��б�����ЩѶϢ��ϵͳѶϢ�����Ƕ�����ѶϢ���У�����Windowsά������춳�������ʹ���ߴӼ��̺ͻ����������Ѷ��ֻ�е�WindowsӦ�ó�ʽ������ǰһ��ʹ��������ѶϢʱ��Windows�Ż��ϵͳѶϢ������ȡ����һ��ѶϢ�����������Ӧ�ó�ʽ��ѶϢ�����С�

�˹��̷�Ϊ������������ϵͳѶϢ�����б���ѶϢ��Ȼ�Ὣ���Ƿ���Ӧ�ó�ʽ��ѶϢ���У���ԭ������Ҫͬ�����������Ǹղ���ѧ�ģ��ٶ����ռ���������Ӵ����������뽹����Ӵ���ʹ���ߵ������ٶȿ��ܱ�Ӧ�ó�ʽ�����������ٶȿ죬�����ض��İ������ܻ�ʹ�����һ���Ӵ��л�����һ���Ӵ��������İ��������뵽����һ���Ӵ�������������İ����Ѿ�������Ŀ���Ӵ���λַ����������Ӧ�ó�ʽѶϢ���У���ô�����İ����Ͳ������뵽��һ���Ӵ���

��������Ԫ
��

Ӧ�ó�ʽ��Windows���յĹ�춼����¼���ѶϢ���Է�Ϊ��������Ԫ���࣬�������������̵����ַ�ʽһ�¡�

���ȣ������Խ����̿����Ǽ��ļ��ϡ�����ֻ��Ψһ��A�������¸ü���һ�ΰ������ͷŸü�Ҳ��һ�ΰ��������Ǽ���Ҳ���ܲ�������ʾ��Ԫ�������Ԫ�������豸������Ctrl�� Shift��Caps Lock����״̬��A���ܲ���������Ԫ��ͨ������£�����ԪΪСдa���������Shift�����ߴ���Caps Lock�������Ԫ�ͱ�ɴ�дA�����������Ctrl�������ԪΪCtrl-A������ASCII�������壬����Windows�п�����ij�¼��ļ��̼��ټ�������һЩ�����ϣ�A����֮ǰ�����С�����Ԫ��(dead-character key)������Shift��Ctrl����Alt�IJ�ͬ��ϣ���Щ��Ͽ��Բ�������������ǵ�Сд���ߴ�д�����磬à��á��â��Ä���� Å��

�Բ�������ʾ��Ԫ�İ�����ϣ�Windows��������ʽ���Ͱ���ѶϢ�����һ�������ԪѶϢ����Щ����������Ԫ����Щ������shift�������ܼ����α��ƶ�����������Ԫ����Insert��Delete�������Щ����Windowsֻ��������ѶϢ��

����ѶϢ
��

��������һ����ʱ��Windows��WM_KEYDOWN����WM_SYSKEYDOWNѶϢ���������뽹����Ӵ���ѶϢ���У������ͷ�һ����ʱ��Windows��WM_KEYUP����WM_SYSKEYUPѶϢ����ѶϢ�����С�

��6-1
  ������ ���ͷ�
��ϵͳ�� WM_KEYDOWN WM_KEYUP
ϵͳ�� WM_SYSKEYDOWN WM_SYSKEYUP

ͨ����down�����£����͡�up���ſ�����ѶϢ�dzɶԳ��ֵġ��������������סһ����ʹ���Զ��ظ�������Ч����ô���ü����ᱻ�ͷ�ʱ��Windows����Ӵ�ѶϢ������ʽ����һϵ��WM_KEYDOWN������WM_SYSKEYDOWN��ѶϢ��һ��WM_KEYUP������WM_SYSKEYUP��ѶϢ�������з������е�ѶϢһ��������ѶϢҲ��ʱ����Ѷ��ͨ������GetMessageTime�������Ի�ð��»����ͷż������ʱ�䡣

ϵͳ�������ϵͳ����
��

WM_SYSKEYDOWN��WM_SYSKEYUP�еġ�SYS��������ϵͳ��������ʾ�ð�����Windows�ȶ�WindowsӦ�ó�ʽ������Ҫ��WM_SYSKEYDOWN��WM_SYSKEYUPѶϢ��������Alt����ϵİ�����������Щ����������ʽ���ܱ�����ϵͳ���ܱ��ϵ�ѡ���������л���Ӵ���ϵͳ���ܣ�Alt-Tab����Alt-Esc����Ҳ��������ϵͳ���ܱ����ټ���Alt����һ�����ܼ����ϣ�����Alt-F4��춹ر�Ӧ�ó�ʽ������ʽͨ������WM_SYSKEYUP��WM_SYSKEYDOWNѶϢ���������Ǵ��͵�DefWindowProc�����WindowsҪ��������Alt���Ĺ��ܣ�����������������ЩѶϢ�������Ӵ�ѶϢ������ʽ�������յ������Щ����������繦�ܱ�ѡ�񣩵�����ѶϢ������������Լ����Ӵ�ѶϢ������ʽ�м�������ϵͳ�����ij�ʽ�루�籾�������KEYVIEW1��KEYVIEW2��ʽ����������������ô�ڴ�����ЩѶϢ֮���ٴ��͵�DefWindowProc��Windows����Ȼ���Խ��������ͨ����Ŀ�ġ�

���ǣ����ٿ���һ�£��������л�Ӱ��ʹ���߳�ʽ�Ӵ���ѶϢ������ͨ��ʹ�����Ӵ�ѶϢ������ʽ��ֻ��ʹ���߰�ѶϢ���͵�DefWindowProc��Windows�Ż��ѶϢ���д��������磬����������漸��������

case 	WM_SYSKEYDOWN:
case 	WM_SYSKEYUP:
case	WM_SYSCHAR:
	    return 0 ;

���뵽һ���Ӵ�ѶϢ������ʽ�У���ô�����ij�ʽ���Ӵ�ӵ�����뽹��ʱ���Ϳ�����Ч����ֹ����Alt���������ҽ��ڱ��µ���������WM_SYSCHAR�������а���Alt-Tab��Alt-Esc�Լ����ܱ���������Ȼ�һ���������ô�������ǣ�����������е��Ӵ�ѶϢ������ʽ��ǿ���ܡ�

WM_KEYDOWN��WM_KEYUPѶϢͨ�����ڰ��»����ͷŲ���Alt���ļ�ʱ�����ģ����ij�ʽ����ʹ�û��ߺ�����ЩѶϢ��Windows��������������ЩѶϢ��

���������ఴ��ѶϢ��wParam����������룬��ʾ���»��ͷŵļ�����lParam�������춰������������ϡ�

�������
��

������뱣����WM_KEYDOWN��WM_KEYUP��WM_SYSKEYDOWN��WM_SYSKEYUPѶϢ��wParam�����С��˴����ʶ���»��ͷŵļ���

�������ǡ����⡹����ϲ�������������ָ���Ǽٶ������˼���ж�������ʵ�����е�һЩ���Ҳֻ������ʹ��DOS������Ա�дӦ�ó�ʽ�ij�ʽд���߲��п���ָ����Ϊʲô��Windows���̴�����˻����ļ���������Ķ�������ʵ�ġ�

������ڵij�ʽд������˵����ʵ�ļ�����ʵ�ʼ���Ӳ���������Windows�ļ��н���Щ�����Ϊ��ɨ����(scan codes)������IBM���ݻ����ϣ�ɨ����16��Q����17��W����18��E��19��R��20��T��21��Y�ȵȡ���ʱ���ᷢ�֣�ɨ���������ݼ��̵�ʵ�ʲ��ֵġ�Windows��������Ϊ��Щ���������豸����ˣ����������ͼͨ��������ν��������룬�Ա㾭����װ���޹صķ�ʽ�������̡�����һЩ������벻����IBM���ݻ����ϲ����������ܻ������������������ļ������ҵ���������δ���ļ������ҵ���

��ʹ�õĴ������������������WINUSER.H��ͷ�����ж�����Ϊ��VK_��ͷ����6-2�г�����Щ���ƺ���ֵ��ʮ��λ��ʮ����λ�����Լ�����������Ӧ��IBM���ݻ��ּ����ϵļ����±�Ҳ�����Windowsִ��ʱ�Ƿ���Ҫ��Щ�����±�������λ˳���г���������롣

ǰ�ĸ����������������ָ���ǻ������

��6-2
ʮ��λ ʮ����λ WINUSER.Hʶ���� ���裿 IBM���ݼ���
1 01 VK_LBUTTON   �������
2 02 VK_RBUTTON   �����Ҽ�
3 03 VK_CANCEL �� Ctrl-Break
4 04 VK_MBUTTON   �����м�

����Զ������Ӽ���ѶϢ�л����Щ��������롣����һ�¿��Կ����������ܹ��ӻ���ѶϢ�л�����ǡ�VK_CANCEL������һ��������룬������ͬʱ����������(Ctrl-Break)��WindowsӦ�ó�ʽͨ����ʹ�ô˼���

��6-3�еļ�--Backspace��Tab��Enter��Escape��Spacebar��ͨ�����Windows��ʽ��������Windowsһ������ԪѶϢ�������Ǽ���ѶϢ����������Щ����

��6-3
ʮ��λ ʮ����λ WINUSER.Hʶ���� ���裿 IBM���ݼ���
8 08 VK_BACK �� Backspace
9 09 VK_TAB �� Tab
12 0C VK_CLEAR   Num Lock�ر�ʱ�����ּ���5
13 0D VK_RETURN �� Enter ��������һ����
16 10 VK_SHIFT �� Shift ��������һ����
17 11 VK_CONTROL �� Ctrl ��������һ����
18 12 VK_MENU �� Alt ��������һ����
19 13 VK_PAUSE   Pause
20 14 VK_CAPITAL �� Caps Lock
27 1B VK_ESCAPE �� Esc
32 20 VK_SPACE �� Spacebar

���⣬Windows��ʽͨ������Ҫ����Shift��Ctrl��Alt����״̬��

��6-4�г���ǰ�˸����������VK_INSERT��VK_DELETEһ����õ�������룺

��6-4
ʮ��λ ʮ����λ WINUSER.Hʶ���� ���裿 IBM���ݼ���
33 21 VK_PRIOR �� Page Up
34 22 VK_NEXT �� Page Down
35 23 VK_END �� End
36 24 VK_HOME �� Home
37 25 VK_LEFT �� ���ͷ
38 26 VK_UP �� �ϼ�ͷ
39 27 VK_RIGHT �� �Ҽ�ͷ
40 28 VK_DOWN �� �¼�ͷ
41 29 VK_SELECT    
42 2A VK_PRINT    
43 2B VK_EXECUTE    
44 2C VK_SNAPSHOT   Print Screen
45 2D VK_INSERT �� Insert
46 2E VK_DELETE �� Delete
47 2F VK_HELP    

ע�⣬�������ƣ�����VK_PRIOR��VK_NEXT��������ϵı�־��ͬ������Ҳ��������е�ʶ���ֲ�ͳһ��Print Screen����ƽʱ����WindowsӦ�ó�ʽ�����ԡ�Windows������Ӧ�˼�ʱ�Ὣ��Ѷ��ʾ�ĵ���ͼӰ����ŵ��������С���ʹ�м����ṩ��VK_SELECT��VK_PRINT��VK_EXECUTE��VK_HELP�����Ҳû�����˿��������ļ��̡�

WindowsҲ�������������ϵ���ĸ����λ����������루���ּ��̽�������������

��6-5
ʮ��λ ʮ����λ WINUSER.Hʶ���� ���裿 IBM���ݼ���
48-57 30-39 �� �� �������ϵ�0��9
65-90 41-5A �� �� A��Z

ע�⣬���ֺ���ĸ�����������ASCII�롣Windows��ʽ�����Ӳ�ʹ����Щ������룻ʵ���ϣ���ʽʹ�õ���ASCII����Ԫ����ԪѶϢ��

��6-6��ʾ�Ĵ�������Microsoft Natural Keyboard�������ݼ��̲����ģ�

��6-6
ʮ��λ ʮ����λ WINUSER.Hʶ���� ���裿 IBM���ݼ���
91 5B VK_LWIN   ��Windows��
92 5C VK_RWIN   ��Windows��
93 5D VK_APPS   Applications��

Windows��VK_LWIN��VK_RWIN���򿪡���ʼ�����ܱ����ߣ�����ǰ�İ汾�У���������������Ա��ʽ������������������춵�¼��dz�Windows��ֻ��Microsoft Windows NT����Ч�������ߵ�¼��dz���·����Windows for Applications�У���Ӧ�ó�ʽ�ܹ�ͨ����ʾ������Ѷ���ߵ��ɽݾ�������������application����

��6-7��ʾ�Ĵ���������ּ����ϵļ�������еĻ�����

��6-7
ʮ��λ ʮ����λ WINUSER.Hʶ���� ���裿 IBM���ݼ���
96-105 60-69 VK_NUMPAD0��VK_ NUMPAD9   NumLock��ʱ���ּ����ϵ�0��9
106 6A VK_MULTIPLY   ���ּ����ϵ�*
107 6B VK_ADD   ���ּ����ϵ�+
108 6C VK_SEPARATOR    
109 6D VK_SUBTRACT   ���ּ����ϵ�-
110 6E VK_DECIMAL   ���ּ����ϵ�.
111 6F VK_DIVIDE   ���ּ����ϵ�/

���ᣬ��Ȼ�����ļ��̶���12�����ܼ�����Windowsֻ��Ҫ10������λԪ���ȴ��24�������⣬��ʽͨ���ù��ܼ���Ϊ���̼��ټ�������������ͨ����������6-8��ʾ�İ�����

��6-8
ʮ��λ ʮ����λ WINUSER.Hʶ���� ���裿 IBM���ݼ���
112-121 70-79 VK_F1��VK_F10 �� ���ܼ�F1��F10
122-135 7A-87 VK_F11��VK_F24   ���ܼ�F11��F24
144 90 VK_NUMLOCK   Num Lock
145 91 VK_SCROLL   Scroll Lock

���⣬��������һЩ����������룬������ֻ��춷DZ�׼�����ϵļ�������ͨ���ڴ��������ն˻���ʹ�õļ����鿴/ Platform SDK / User Interface Services / User Input / Virtual-Key Codes���ɵõ��������б���

lParam��Ѷ
��

���ĸ�����ѶϢ��WM_KEYDOWN��WM_KEYUP��WM_SYSKEYDOWN��WM_SYSKEYUP���У�wParamѶϢ�����������������۵�������룬��lParamѶϢ�������ж��˽ⰴ���dz����õ�������Ѷ��lParam��32λ��Ϊ6����λ����ͼ6-1��ʾ��


��

ͼ6-1 lParam������6������ѶϢ��λ

�ظ�����
��

�ظ������Ǹ�ѶϢ����ʾ�İ������������������£��ظ������趨Ϊ1���������������һ����֮�ᣬ�����Ӵ�ѶϢ������ʽ�����죬���²��ܴ����Զ��ظ����ʣ��������ڡ�����̨���ġ����̡��н����趨���µİ���ѶϢ��Windows�ͰѼ���WM_KEYDOWN����WM_SYSKEYDOWNѶϢ��ϵ�����ѶϢ�У�����Ӧ�������ظ�������WM_KEYUP��WM_SYSKEYUPѶϢ���ظ���������Ϊ1��

��Ϊ�ظ��������1ָʾ�������ʴ������ʽ�Ĵ���������������Ҳ�������ڴ�������ѶϢʱ�����ظ�����������ÿ���˶������鴦����ִ�������ʱ�������ͷ�ľ��飬��Ϊ����İ��������˼��̻����������Ե���ʽ��һЩʱ��������ÿһ�ΰ���ʱ�������������ʽ�е��ظ����������ܹ���������⡣��������ʱ����Ҳ���õ��ظ���������Ӧ�ó���ʹ�����ַ���ִ�г�ʽ���������ҳ�һ�ֽϺõķ�����

OEMɨ����
��

OEMɨ��������Ӳ�壨���̣������Ĵ��롣����й�ʱ����������Գ�ʽд������˵Ӧ�ú���Ϥ�����Ǵ�PC���ݻ��ֵ�ROM BIOS����������õ�ֵ��OEMָ����PC��ԭʼ�豸�����̣�Original Equipment Manufacturer�������롸IBM��׼��ͬ�������ݣ����ڴ����Dz���Ҫ�������Ѷ��������Ҫ����ʵ�ʼ��̲��ֵ���ò����ȻWindows��ʽ���Ժ��Ե��������е�OEMɨ������Ѷ���μ��ڶ�ʮ���µij�ʽKBMIDI��

��������
��

��������������IBM��ǿ���̵ĸ��Ӽ�֮һ����ô��������Ϊ1��IBM��ǿ�ͼ�����101��102���������ܼ��ڼ��̶��ˣ��α��ƶ��������ּ����з���������������ּ����ϻ��������α��ƶ����Ĺ��ܣ����Լ����Ҷ˵�Alt��Ctrl�����Լ��������ּ����Dz��ֵ��α��ƶ���������Insert��Delete���������ּ����ϵ�б�ߣ�������Enter���Լ�Num Lock���ȣ����������趨Ϊ1��Windows��ʽͨ�������������ꡣ

���ݴ���
��

�Ұ���ʱ������ͬʱѹ��ALT������ô���ݴ���Ϊ1����WM_SYSKEYUP��WM_SYSKEYDOWN���ԣ���λԪ����Ϊ1������WM_SYSKEYUP��WM_KEYDOWѶϢ���ԣ���λԪΪ0����������֮�⣺

  • �����Ӵ���С���ˣ�����û�����뽹�㡣��ʱ�����еİ����������WM_SYSKEYUP��WM_SYSKEYDOWNѶϢ�����Alt��δ�����£������ݴ�����λ���趨Ϊ0��Windowsʹ��WM_SYSKEYUP��WM_SYSKEYDOWNѶϢ���Ӷ�ʹ��С���˵Ļ�Ӵ���������Щ������
    ��
  • ���һЩ������ģ���Ӣ�ģ����̣���Щ��Ԫ��ͨ��Shift��Ctrl����Alt��������������϶������ġ���ʱ���ݴ���Ϊ1�����Ǵ�ѶϢ����ϵͳ����ѶϢ��
    ��

������ǰ״̬
��

����ڴ�֮ǰ�����ͷŵģ��������ǰ״̬Ϊ0������Ϊ1����WM_KEYUP����WM_SYSKEYUPѶϢ���������趨Ϊ1�����Ƕ�WM_KEYDOWN����WM_SYSKEYDOWNѶϢ����λԪ����Ϊ0��Ҳ����Ϊ1�����Ϊ1�����ʾ�ü����Զ��ظ������������ĵڶ�����������ѶϢ��

ת��״̬
��

������������£���ת��״̬Ϊ0������������ͷţ���ת��״̬Ϊ1����WM_KEYDOWN����WM_SYSKEYDOWNѶϢ������λΪ0����WM_KEYUP����WM_SYSKEYUPѶϢ������λΪ1��

λ��״̬
��

�ڴ�������ѶϢʱ����������Ҫ֪���Ƿ�����λ�Ƽ���Shift��Ctrl��Alt���򿪹ؼ���Caps Lock��Num Lock��Scroll Lock����ͨ������GetKeyState��ʽ�������ܻ�ô���Ѷ�����磺

iState = GetKeyState (VK_SHIFT) ;

���������Shift����iStateֵΪ�������趨�����λ��λԪ�������Caps Lock���򿪣����

iState = GetKeyState (VK_CAPITAL) ;

���ص�ֵ��λԪ����Ϊ1����λԪ������ϵ�С�Ʊ���һ�¡�

ͨ��������ʹ��GetKeyStateʱ��������������VK_SHIFT��VK_CONTROL��VK_MENU����˵��Alt��ʱ���У���ʹ��GetKeyStateʱ����Ҳ�����������ʶ������ȷ�����µ�Shift��Ctrl��Alt������ߵĻ����ұߵģ�VK_LSHIFT��VK_RSHIFT��VK_LCONTROL��VK_RCONTROL��VK_LMENU��VK_RMENU����Щʶ����ֻ���GetKeyState��GetAsyncKeyState�����潫��ϸ˵������

ʹ���������VK_LBUTTON��VK_RBUTTON��VK_MBUTTON����Ҳ���Ի�û������״̬���������������Ҫ���ӻ�����밴������ϵ�WindowsӦ�ó�ʽ��ʹ������������������һ�㣭���ڽ��յ�����ѶϢʱ��鰴����ʵ���ϣ�λ��״̬��Ѷ�����ڻ�����Ѷ�У�����������һ���н�������һ����

��ע��GetKeyState��ʹ�ã������Ǽ�ʱ������״̬����ֻ�Ǽ��ֱ��ĿǰΪֹ���ڴ�����ѶϢ�ļ���״̬����������£�������������Ҫ���������Ҫȷ��ʹ�����Ƿ�����Shift-Tab�����ڴ���Tab����WM_KEYDOWNѶϢʱ����GetKeyState�����в���VK_SHIFT�����GetKeyState���ص�ֵΪ������ô����֪���ڰ���Tab��֮ǰ������Shift�������ң����������ʼ����Tab��֮ǰ���Ѿ��ͷ���Shift��Ҳû�й�ϵ����֪�����ڰ���Tab����ʱ��Shift���ǰ��µġ�

GetKeyState����������ö������ͨ����ѶϢ�ļ�����Ѷ�����磬����������ͣ�Ӵ�ѶϢ������ʽ�Ĵ�����ֱ��������F1���ܼ�Ϊֹ��

while (GetKeyState (VK_F1) >= 0) ;    // WRONG !!!

��Ҫ��ô�����⽫�ó�ʽ������������ִ�д�����֮ǰ��ʹ�ѶϢ�����н��յ���F1��WM_KEYDOWN���������ȷʵ��Ҫ֪��Ŀǰij����״̬����ô������ʹ��GetAsyncKeyState��

ʹ�ð���ѶϢ
��

�����ʽ�ܹ����ÿ����������Ѷ���⵱Ȼ�����룬���Ǵ����Windows��ʽ�����˼������еİ�������ֻ�������ֵİ���ѶϢ��WM_SYSKEYDOWN��WM_SYSKEYUPѶϢ����Windowsϵͳ��ʽʹ�õģ�������Ϊ�˷��ģ�������Ҫ����WM_KEYDOWNѶϢ��ͨ��Ҳ���Ժ���WM_KEYUPѶϢ��

Windows��ʽͨ��Ϊ��������Ԫ�İ���ʹ��WM_KEYDOWNѶϢ����Ȼ��������Ϊ��������ѶϢ��λ�Ƽ�״̬��Ѷ�ܽ�����ѶϢת��Ϊ��ԪѶϢ�����Dz�Ҫ��ô������Ϊ�����������ʼ��̼�IJ��������������⡣���磬������õ�wParam���0x33��WM_KEYDOWNѶϢ�����Ϳ���֪��ʹ���߰����˼�3������Ϊֹһ����������ʱ�������GetKeyState����Shift�������£����Ϳ��ܻ���Ϊʹ����������#�ţ���ɲ�һ��������Ӣ��ʹ���߾���������ꡣ

����α��ƶ��������ܼ���Insert��Delete����WM_KEYDOWNѶϢ�������õġ������� Insert��Delete�͹��ܼ�������Ϊ���ܱ����ټ�����ΪWindows�ܰѹ��ܱ����ټ�����Ϊ���ܱ�����ѶϢ���������Ͳ����Լ�������������

��Windows֮ǰ��MS-DOSӦ�ó�ʽ�д���ʹ�ù��ܼ���Shift��Ctrl��Alt������ϣ�ͬ���أ���Ҳ������Windows��ʽ��ʹ�ã�ʵ���ϣ�Microsoft Word�������Ĺ��ܼ����������ݷ�ʽ�����������Ƽ��������������ȷʵϣ��ʹ�ù��ܼ�����ô��Щ��Ӧ�����ظ����ܱ����Windows��Ŀ��֮һ�����ṩ����Ҫ�������ʹ�ø����������̵�ʹ���߽��档

��ˣ����Թ������£���������£�����ֻΪ�α��ƶ�������ʱҲΪInsert��Delete��������WM_KEYDOWNѶϢ����ʹ����Щ����ʱ��������ͨ��GetKeyState�����Shift����Ctrl����״̬�����磬Windows��ʽ����ʹ��Shift���α������ϼ����������鴦����ѡ�еķ�Χ��Ctrl��������޸��α�������塣���磬Ctrl���Ҽ�ͷ������Ͽ��Ա�ʾ�α�����һ���֡�

�������ij�ʽ��ʹ�ü��̷�ʽ����ѷ���֮һ���˽����е�Windows��ʽʹ�ü��̵ķ�ʽ���������ϲ����Щ���壬��Ȼ���Զ�������޸ģ���������������������˺ܿ��ѧ��ʹ�����ij�ʽ��

ΪSYSMETS���ϼ��̴�������
��

�ڱ�д�������������汾��SYSMETS��ʽʱ�����ǻ����˽���̣�ֻ��ʹ�þ����кͻ������������֡���������֪���˴�������ѶϢ�ķ�������ô�����ڳ�ʽ�м�����̽��档��Ȼ�����Ǵ����α��ƶ����Ĺ��������ǽ�������α����Home��End��Page Up��Page Down��Up Arrow��Down Arrow����춴�ֱ���������ͷ�����Ҽ�ͷ����춲�̫��Ҫ��ˮƽ������

�������̽����һ�ּ򵥷��������Ӵ�ѶϢ������ʽ�м�����WM_VSCROLL��WM_HSCROLL������ʽ��£����ұ�������ͬ��WM_KEYDOWN�����������������������Dz������ģ���Ϊ���Ҫ�޸ľ����е��������ͱ������Ӧ���޸�WM_KEYDOWN��

Ϊʲô���򵥵ؽ�ÿһ��WM_KEYDOWNѶϢ�������ͬ��Ч�õ�WM_VSCROLL����WM_HSCROLLѶϢ�أ�ͨ�����Ӵ�ѶϢ������ʽ���ͼ�ðѶϢ�����ǿ��ܻ���WndProc��Ϊ������˾�����Ѷ��

��Windows�У����ַ����ǿ��еġ�����ѶϢ�ĺ�ʽ����SendMessage�������õIJ����봫�ݵ��Ӵ�ѶϢ������ʽ�IJ�������ͬ�ģ�

SendMessage (hwnd, message, wParam, lParam) ;

�ں���SendMessageʱ��Windows�����Ӵ�����Ϊhwnd���Ӵ�ѶϢ������ʽ���������ĸ����������������Ӵ�ѶϢ������ʽ���ѶϢ����֮�ᣬWindows�ѿ��ƴ��ص�SendMessage����֮�����һ��������������ѶϢ��ȥ���Ӵ�ѶϢ������ʽ��������ͬһ���Ӵ�ѶϢ������ʽ��ͬһ��ʽ�е������Ӵ�ѶϢ������ʽ��������Ӧ�ó�ʽ���е��Ӵ�ѶϢ������ʽ��

����˵����SYSMETS��ʽ��ʹ��SendMessage����WM_KEYDOWN����ķ�����

case	WM_KEYDOWN:
	switch (wParam)
 	{
	case	VK_HOME:
		SendMessage (hwnd, WM_VSCROLL, SB_TOP, 0) ;
		break ;

	case	VK_END:
		SendMessage (hwnd, WM_VSCROLL, SB_BOTTOM, 0) ;
		break ;

	case	VK_PRIOR:
		SendMessage (hwnd, WM_VSCROLL, SB_PAGEUP, 0) ;
		break ;

���ˣ����Ѿ����˴�Ź����˰ɡ����ǵ�Ŀ����Ϊ���������Ӽ��̽��棬����Ҳ������ô����ͨ���Ѿ���ѶϢ���͵��Ӵ�ѶϢ������ʽ������ʵ�������α��ƶ������о����еĹ��ܡ�������֪����SYSMETS3��ΪWM_VSCROLLѶϢ����SB_TOP��SB_BOTTOM�������ԭ���˰ɡ������ﲢû���õ������������ڴ���Home��End��ʱ�������ˡ����ʽ6-1��ʾ��SYSENTS4�ͼ�������Щ�仯�����������ʽʱ����Ҫ�õ������µ�SYSMETS.H������

 ï¿½ï¿½Ê½6-1  SYSMETS4
SYSMETS4.C
/*----------------------------------------------------------------------
   SYSMETS4.C -- System Metrics Display Program No. 4
                 (c) Charles Petzold, 1998
------------------------------------------------------------------------*/

#include <windows.h>
#include "sysmets.h"
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
					PSTR szCmdLine, int iCmdShow)
{
	static TCHAR szAppName[]	= TEXT ("SysMets4") ;
	HWND 			hwnd ;
	MSG 			msg ;
	WNDCLASS		wndclass ;
     
	wndclass.style			= CS_HREDRAW | CS_VREDRAW ;
	wndclass.lpfnWndProc	= WndProc ;
	wndclass.cbClsExtra		= 0 ;
	wndclass.cbWndExtra		= 0 ;
	wndclass.hInstance		= hInstance ;
	wndclass.hIcon 			= LoadIcon (NULL, IDI_APPLICATION) ;
	wndclass.hCursor		= LoadCursor (NULL, IDC_ARROW) ;
	wndclass.hbrBackground	= (HBRUSH) GetStockObject (WHITE_BRUSH) ;
	wndclass.lpszMenuName	= NULL ;
	wndclass.lpszClassName	= szAppName ;
     
	if (!RegisterClass (&wndclass))
	{
		MessageBox (NULL, TEXT ("Program requires Windows NT!"), 
                     szAppName, MB_ICONERROR) ;
		return 0 ;
	}
     
	hwnd = CreateWindow (szAppName, TEXT ("Get System Metrics No. 4"),
                						WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL,
						CW_USEDEFAULT, CW_USEDEFAULT,
						CW_USEDEFAULT, CW_USEDEFAULT,
						NULL, NULL, hInstance, NULL) ;
     
	ShowWindow (hwnd, iCmdShow) ;
	UpdateWindow (hwnd) ;
     
	while (GetMessage (&msg, NULL, 0, 0))
	{
		TranslateMessage (&msg) ;
		DispatchMessage (&msg) ;
	}
		return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static int  cxChar, cxCaps, cyChar, cxClient, cyClient, iMaxWidth ;
	HDC 			hdc ;
	int			i, x, y, iVertPos, iHorzPos, iPaintBeg, iPaintEnd ;
	PAINTSTRUCT	ps ;
	SCROLLINFO	si ;
	TCHAR			szBuffer[10] ;
	TEXTMETRIC 	tm ;
     
	switch (message)
	{
	case	WM_CREATE:
		hdc = GetDC (hwnd) ;
          
		GetTextMetrics (hdc, &tm) ;
		cxChar	= tm.tmAveCharWidth ;
		cxCaps	= (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2 ;
		cyChar	= tm.tmHeight + tm.tmExternalLeading ;

		ReleaseDC (hwnd, hdc) ;

			// Save the width of the three columns
          
		iMaxWidth = 40 * cxChar + 22 * cxCaps ;
		return 0 ;
          
	case	WM_SIZE:
		cxClient 		= LOWORD (lParam) ;
		cyClient 		= HIWORD (lParam) ;

			// Set vertical scroll bar range and page size

		si.cbSize	= sizeof (si) ;
		si.fMask	= SIF_RANGE | SIF_PAGE ;
		si.nMin 	= 0 ;
		si.nMax		= NUMLINES - 1 ;
		si.nPage	= cyClient / cyChar ;
		SetScrollInfo (hwnd, SB_VERT, &si, TRUE) ;

				// Set horizontal scroll bar range and page size

		si.cbSize	= sizeof (si) ;
		si.fMask	= SIF_RANGE | SIF_PAGE ;
		si.nMin		= 0 ;
		si.nMax		= 2 + iMaxWidth / cxChar ;
		si.nPage	= cxClient / cxChar ;
		SetScrollInfo (hwnd, SB_HORZ, &si, TRUE) ;
		return 0 ;
          
	case WM_VSCROLL:
				// Get all the vertical scroll bar information
		si.cbSize 	= sizeof (si) ;
		si.fMask	= SIF_ALL ;
		GetScrollInfo (hwnd, SB_VERT, &si) ;

				// Save the position for comparison later on

			iVertPos = si.nPos ;

			switch (LOWORD (wParam))
		{
	case SB_TOP:
		si.nPos = si.nMin ;
		break ;
               
	case SB_BOTTOM:
		si.nPos = si.nMax ;
		break ;
               
	case SB_LINEUP:
		si.nPos -= 1 ;
		break ;
               
	case SB_LINEDOWN:
		si.nPos += 1 ;
		break ;
               
	case SB_PAGEUP:
		si.nPos -= si.nPage ;
		break ;
               
	case SB_PAGEDOWN:
		si.nPos += si.nPage ;
		break ;
               
	case SB_THUMBTRACK:
		si.nPos = si.nTrackPos ;
		break ;
               
		default:
		break ;         
		}
			// Set the position and then retrieve it.  Due to adjustments
			//   by Windows it might not be the same as the value set.

		si.fMask = SIF_POS ;
		SetScrollInfo (hwnd, SB_VERT, &si, TRUE) ;
		GetScrollInfo (hwnd, SB_VERT, &si) ;

			// If the position has changed, scroll the window and update it

		if (si.nPos != iVertPos)
		{                    
			ScrollWindow (hwnd, 0, cyChar * (iVertPos - si.nPos), 
											NULL, NULL) ;
			UpdateWindow (hwnd) ;
		}
		return 0 ;
          
	case WM_HSCROLL:
				// Get all the vertical scroll bar information
		si.cbSize 		= sizeof (si) ;
		si.fMask		= SIF_ALL ;

				// Save the position for comparison later on

			GetScrollInfo (hwnd, SB_HORZ, &si) ;
			iHorzPos 	= si.nPos ;

		switch (LOWORD (wParam))
		{
	case SB_LINELEFT:
		si.nPos -= 1 ;
		break ;
               
	case SB_LINERIGHT:
		si.nPos += 1 ;
		break ;
               
	case SB_PAGELEFT:
		si.nPos -= si.nPage ;
		break ;
               
	case SB_PAGERIGHT:
		si.nPos += si.nPage ;
		break ;
               
	case SB_THUMBPOSITION:
		si.nPos = si.nTrackPos ;
		break ;
               
		default:
		break ;
		}
				// Set the position and then retrieve it.  Due to adjustments
				//   by Windows it might not be the same as the value set.

		si.fMask = SIF_POS ;
		SetScrollInfo (hwnd, SB_HORZ, &si, TRUE) ;
		GetScrollInfo (hwnd, SB_HORZ, &si) ;
          
				// If the position has changed, scroll the window 

		if (si.nPos != iHorzPos)
		{
			ScrollWindow (hwnd, cxChar * (iHorzPos - si.nPos), 0, 
			NULL, NULL) ;
		}
		return 0 ;

	case WM_KEYDOWN:
		switch (wParam)
	{
	case VK_HOME:
		SendMessage (hwnd, WM_VSCROLL, SB_TOP, 0) ;
		break ;
               
	case VK_END:
		SendMessage (hwnd, WM_VSCROLL, SB_BOTTOM, 0) ;
		break ;
               
	case VK_PRIOR:
		SendMessage (hwnd, WM_VSCROLL, SB_PAGEUP, 0) ;
		break ;
               
	case VK_NEXT:
		SendMessage (hwnd, WM_VSCROLL, SB_PAGEDOWN, 0) ;
		break ;
               
	case VK_UP:
		SendMessage (hwnd, WM_VSCROLL, SB_LINEUP, 0) ;
		break ;

	case VK_DOWN:
		SendMessage (hwnd, WM_VSCROLL, SB_LINEDOWN, 0) ;
		break ;
               
	case VK_LEFT:
		SendMessage (hwnd, WM_HSCROLL, SB_PAGEUP, 0) ;
		break ;
               
	case VK_RIGHT:
		SendMessage (hwnd, WM_HSCROLL, SB_PAGEDOWN, 0) ;
		break ;
		}
		return 0 ;
	case WM_PAINT:
		hdc = BeginPaint (hwnd, &ps) ;
				// Get vertical scroll bar position
		si.cbSize 		= sizeof (si) ;
		si.fMask  		= SIF_POS ;
		GetScrollInfo (hwnd, SB_VERT, &si) ;
		iVertPos 		= si.nPos ;

				// Get horizontal scroll bar position

		GetScrollInfo (hwnd, SB_HORZ, &si) ;
		iHorzPos 		= si.nPos ;

				// Find painting limits

		iPaintBeg 		= max (0, iVertPos + ps.rcPaint.top / cyChar) ;
		iPaintEnd 		= min (NUMLINES - 1,
		iVertPos + ps.rcPaint.bottom / cyChar) ;

		for (i = iPaintBeg ; i <= iPaintEnd ; i++)
		{
			x = cxChar * (1 - iHorzPos) ;
			y = cyChar * (i - iVertPos) ;
               
		TextOut (hdc, x, y,
		sysmetrics[i].szLabel,
		lstrlen (sysmetrics[i].szLabel)) ;
               
		TextOut (hdc, x + 22 * cxCaps, y,
		sysmetrics[i].szDesc,
		lstrlen (sysmetrics[i].szDesc)) ;
               
		SetTextAlign (hdc, TA_RIGHT | TA_TOP) ;

		TextOut (hdc, x + 22 * cxCaps + 40 * cxChar, y, szBuffer,
		wsprintf (szBuffer, TEXT ("%5d"),
		GetSystemMetrics (sysmetrics[i].iIndex))) ;
               
		SetTextAlign (hdc, TA_LEFT | TA_TOP) ;
		}

		EndPaint (hwnd, &ps) ;
		return 0 ;
          
	case	WM_DESTROY:
		PostQuitMessage (0) ;
		return 0 ;
	}
		return DefWindowProc (hwnd, message, wParam, lParam) ;
}

��ԪѶϢ
��

ǰ������������λ��״̬��Ѷ�Ѱ���ѶϢ����Ϊ��ԪѶϢ�ķ����������ᵽ��������ת��״̬��Ѷ����������Ϊ����Ҫ֪�������/�����йصļ������á�������ԭ������Ӧ����ͼ�Ѱ���ѶϢ����Ϊ��Ԫ���롣Windows��Ϊ�������һ��������ǰ�����������������µij�ʽ�룺

while	(GetMessage (&msg, NULL, 0, 0))
{
	TranslateMessage (&msg) ;
	DispatchMessage (&msg) ;
}

����WinMain�е��͵�ѶϢ��Ȧ��GetMessage��ʽ�������е���һ��ѶϢ����msg�ṹ����λ��DispatchMessage�Դ�ѶϢΪ���������ʵ����Ӵ�ѶϢ������ʽ��

����������ʽ֮����TranslateMessage��ʽ����������ѶϢת��Ϊ��ԪѶϢ�����ѶϢΪWM_KEYDOWN����WM_SYSKEYDOWN�����Ұ�����λ��״̬����ϲ���һ����Ԫ����TranslateMessage����ԪѶϢ����ѶϢ�����С�����ԪѶϢ����GetMessage��ѶϢ�����еõ��İ���ѶϢ֮�����һ��ѶϢ��

������ԪѶϢ
��

��ԪѶϢ���Է�Ϊ���࣬���6-9��ʾ��

��6-9
  ��Ԫ ����Ԫ
��ϵͳ��Ԫ WM_CHAR WM_DEADCHAR
ϵͳ��Ԫ WM_SYSCHAR WM_SYSDEADCHAR

WM_CHAR��WM_DEADCHARѶϢ�Ǵ�WM_KEYDOWN�õ��ģ���WM_SYSCHAR��WM_SYSDEADCHARѶϢ�Ǵ�WM_SYSKEYDOWNѶϢ�õ��ģ��ҽ���Ҫ������һ��ʲô������Ԫ����

��һ����ѶϢ���ڴ��������£�Windows��ʽ����Գ�WM_CHAR֮����κ�ѶϢ�������ĸ���ԪѶϢ��lParam�����������Ԫ����ѶϢ�İ���ѶϢ֮lParam������ͬ������������wParam����������롣ʵ���ϣ�����ANSI��Unicode��Ԫ���롣

��Щ��ԪѶϢ�����ǽ����ִ��ݸ��Ӵ�ѶϢ������ʽʱ�����ĵ�һ��ѶϢ�����Dz���Ψһ��ѶϢ������ѶϢ������0��β�������ִ����Ӵ�ѶϢ������ʽ�����֪������Ԫ��8λԪ��ANSI��Ԫ����16λԪ��Unicode����Ԫ�أ��ܼ򵥣��κ�������RegisterClassA��RegisterClass��ANSI�棩ע����Ӵ��������ϵ���Ӵ�ѶϢ������ʽ�������ú���ANSI��Ԫ�����ѶϢ������Ӵ�ѶϢ������ʽ��RegisterClassW��RegisterClass�Ŀ���Ԫ�棩ע�ᣬ��ô���ݸ��Ӵ�ѶϢ������ʽ��ѶϢ�ʹ���Unicode��Ԫ���롣�����ʽ��RegisterClassע���Ӵ������ô��UNICODEʶ���ֱ�����ʱ�ͺ���RegisterClassW���������RegisterClassA��

�����ڳ�ʽд����ʱ������ANSI��Unicode�ĺ�ʽ���Ӵ�ѶϢ������ʽ����WM_CHARѶϢ��������������ԪѶϢ��˵������Ԫ���뽫�ǣ�

(TCHAR) wParam

ͬһ���Ӵ�ѶϢ������ʽ���ܻ��õ������Ӵ����һ����RegisterClassAע�ᣬ����һ����RegisterClassWע�ᡣҲ����˵���Ӵ�ѶϢ������ʽ���ܻ���һЩANSI��Ԫ����ѶϢ��һЩUnicode��Ԫ����ѶϢ����������Ӵ�ѶϢ������ʽ��Ҫ����Ŀǰ�Ӵ��Ƿ���UnicodeѶϢ���������Ժ��У�

fUnicode = IsWindowUnicode (hwnd) ;

���hwnd���Ӵ�ѶϢ������ʽ���UnicodeѶϢ����ô����fUnicode��ΪTRUE�����ʾ�Ӵ�����RegisterClassWע����Ӵ����

ѶϢ˳��
��

��ΪTranslateMessage��ʽ��WM_KEYDOWN��WM_SYSKEYDOWNѶϢ��������ԪѶϢ��������ԪѶϢ�Ǽ��ڰ���ѶϢ֮�䴫�ݸ��Ӵ�ѶϢ������ʽ�ġ����磬���Caps Lockδ�򿪣���ʹ���߰������ͷ�A�������Ӵ�ѶϢ������ʽ�����յ����6-10��ʾ������ѶϢ��

��6-10
ѶϢ �������ߴ���
WM_KEYDOWN ��A����������루0x41��
WM_CHAR ��a������Ԫ���루0x61��
WM_KEYUP ��A����������루0x41��

���������Shift�����ٰ���A����Ȼ���ͷ�A�������ͷ�Shift�����ͻ������д��A�����Ӵ�ѶϢ������ʽ����յ����ѶϢ�����6-11��ʾ��

��6-11
ѶϢ �������ߴ���
WM_KEYDOWN �������VK_SHIFT ��0x10��
WM_KEYDOWN ��A����������루0x41��
WM_CHAR ��A������Ԫ���루0x41��
WM_KEYUP ��A����������루0x41��
WM_KEYUP �������VK_SHIFT��0x10��

Shift��������������ԪѶϢ��

���ʹ���߰�סA������ʹ�Զ��ظ�����һϵ�еİ�������ô��ÿ��WM_KEYDOWNѶϢ������õ�һ����ԪѶϢ�����6-12��ʾ��

��6-12
ѶϢ �������ߴ���
WM_KEYDOWN ��A����������루0x41��
WM_CHAR ��a������Ԫ���루0x61��
WM_KEYDOWN ��A����������루0x41��
WM_CHAR ��a������Ԫ���루0x61��
WM_KEYDOWN ��A����������루0x41��
WM_CHAR ��a������Ԫ���루0x61��
WM_KEYDOWN ��A����������루0x41��
WM_CHAR ��a������Ԫ���루0x61��
WM_KEYUP ��A����������루0x41��

���ijЩWM_KEYDOWNѶϢ���ظ��������1����ô��Ӧ��WM_CHARѶϢ������ͬ�����ظ�������

���ʹ��Ctrl������ĸ���������0x01��Ctrl-A����0x1A��Ctrl-Z����ASCII���ƴ��룬���е�ijЩ���ƴ���Ҳ�����ɱ�6-13�г��ļ�������

��6-13
���� ��Ԫ���� �������� ANSI C������Ԫ
Backspace 0x08 Ctrl-H \b
Tab 0x09 Ctrl-I \t
Ctrl-Enter 0x0A Ctrl-J \n
Enter 0x0D Ctrl-M \r
Esc 0x1B Ctrl-[

�����и�������ANSI C�ж���Ŀ�����Ԫ���������������Щ������Ԫ���롣

��ʱWindows��ʽ��Ctrl����ĸ��������������ܱ����ټ����ҽ��ڵ�ʮ�����ۣ�����ʱ�����Ὣ��ĸ��ת������ԪѶϢ��

����������Ԫ
��

������������ԪѶϢ�Ļ��������ǣ������Ҫ��ȡ���뵽�Ӵ��ļ�����Ԫ����ô�����Դ���WM_CHARѶϢ�������Ҫ��ȡ�α�������ܼ���Delete��Insert��Shift��Ctrl�Լ�Alt������ô�����Դ���WM_KEYDOWNѶϢ��

����Tab����ô�죿Enter��Backspace��Escape������ô�죿��ͳ�ϣ���Щ����������6-13�г���ASCII������Ԫ��������Windows�У�����Ҳ����������롣��Щ��Ӧ���ڴ���WM_CHAR�����ڴ���WM_KEYDOWN�ڼ䴦����

����10��Ŀ��ǣ��ع���Щ������д����Windows��ʽ�룩���Ҹ�ϲ����Tab��Enter��Backspace��Escape�������ɿ�����Ԫ�����������������ͨ����������WM_CHAR��

case WM_CHAR:
		//�����г�ʽ
	switch (wParam)
     {
	case '\b':		// backspace
		//�����г�ʽ
		break ;
	case '\t':		// tab
		//�����г�ʽ
		break ;

	case '\n':		// linefeed
		//�����г�ʽ
		break ;

	case '\r':		// carriage return
		//�����г�ʽ
		break ;

	default:			// character codes
		//�����г�ʽ
		break ;
     }
     return 0 ;

����ԪѶϢ
��

Windows��ʽ��������WM_DEADCHAR��WM_SYSDEADCHARѶϢ������Ӧ����ȷ��֪������Ԫ��ʲô���Լ����ǹ����ķ�ʽ��

��ijЩ��U.S.Ӣ������ϣ���Щ����춸���ĸ������������Ϊ���DZ�����������Ԫ�����Գ�֮Ϊ�������������磬ʹ�õ������ʱ�����U.S.�����ϵ�+/=����������̵Ķ�Ӧλ�þ���һ��������δ����Shift��ʱ����춱�ʶ����������Shift��ʱ����춱�ʶ������

��ʹ���߰����������ʱ���Ӵ�ѶϢ������ʽ���յ�һ��wParam�������������ASCII����Unicode�����WM_DEADCHARѶϢ����ʹ�����ٰ��¿��Դ��д���������ĸ��������A����ʱ���Ӵ�ѶϢ������ʽ����յ�WM_CHARѶϢ������wParam��춴�����������ĸ��a����ANSI���롣

��ˣ�ʹ���߳�ʽ����Ҫ����WM_DEADCHARѶϢ��ԭ����WM_CHARѶϢ�Ѻ��г�ʽ����Ҫ��������Ѷ��Windows������������������ڲ������������������֮����в��ܴ����������ŵ���ĸ�����硸s��������ô�Ӵ�ѶϢ������ʽ����һ�н��յ�����WM_CHARѶϢ��ǰһ��ѶϢ��wParam����������ű�����ASCII���루�봫�ݵ�WM_DEADCHARѶϢ��wParamֵ��ͬ�����ڶ���ѶϢ��wParam�����ĸs��ASCII���롣

��Ȼ��Ҫ��������������������ʽ����õķ�������ʵ�ʲ���������������ʹ��������������̣�����ǰ�潲���ĵ�����̡������������趨���ڡ�����̨����ѡ�񡸼��̡���Ȼ��ѡ����ϵ��ҳ���ǩ��Ȼ������Ҫһ��Ӧ�ó�ʽ���ó�ʽ������ʾ�����յ�ÿһ������ѶϢ����ϸ��Ѷ�������KEYVIEW1���������ij�ʽ��

����ѶϢ����Ԫ��
��

����ʣ�µķ�����ʽ��ȱ�ݡ����Dz��������а汾��Windows�¶�����ִ�С���Щȱ�ݲ�������������ʽ���еģ���ʵ�ϣ���Ҳ����Զ����������Щȱ�ݡ�ֻ���ڲ�ͬ�ļ������Ժͼ��̲��ּ��л����Լ��ڶ�λԪ����Ԫ����Զ����Windows��ִ�г�ʽʱ����Щ����Ż���֣������Ҳ�Ը�����dz�Ϊ�����󡹡�

�����������ʽʹ��Unicode���벢��Windows NT��ִ�У���ô��ʽ��ִ�еø��á����ڵڶ����ᵽ��������⣬����չʾ��Unicode�Լ򻯼��ֵĹ��ʻ��������Ҫ�ԡ�

KEYVIEW1��ʽ
��

�˽���̹��ʻ�����ĵ�һ�������Ǽ��Windows���ݸ��Ӵ�ѶϢ������ʽ�ļ������ݺ���ԪѶϢ����ʽ6-2��ʾ��KEYVIEW1��Դ������������ó�ʽ����ʾ������ʾWindows���Ӵ�ѶϢ������ʽ���͵�8�ֲ�ͬ����ѶϢ��ȫ����Ѷ��

 ï¿½ï¿½Ê½6-2  KEYVIEW1
KEYVIEW1.C
/*---------------------------------------------------------------------
	KEYVIEW1.C --	Displays Keyboard and Character Messages
          				(c) Charles Petzold, 1998
---------------------------------------------------------------------*/

#include <windows.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
					PSTR szCmdLine, int iCmdShow)
{
	static TCHAR szAppName[]	= TEXT ("KeyView1") ;
	HWND 			hwnd ;
	MSG 			msg ;
	WNDCLASS 		wndclass ;
     
	wndclass.style 				= CS_HREDRAW | CS_VREDRAW ;
	wndclass.lpfnWndProc		= WndProc ;
	wndclass.cbClsExtra 		= 0 ;
	wndclass.cbWndExtra 		= 0 ;
	wndclass.hInstance 			= hInstance ;
	wndclass.hIcon 				= LoadIcon (NULL, IDI_APPLICATION) ;
	wndclass.hCursor			= LoadCursor (NULL, IDC_ARROW) ;
	wndclass.hbrBackground 		= (HBRUSH) GetStockObject (WHITE_BRUSH) ;
	wndclass.lpszMenuName		= NULL ;
	wndclass.lpszClassName		= szAppName ;

	if (!RegisterClass (&wndclass))
	{
		MessageBox (NULL, TEXT ("This program requires Windows NT!"), 
						szAppName, MB_ICONERROR) ;
		return 0 ;
	}
     
	hwnd = CreateWindow (szAppName, TEXT ("Keyboard Message Viewer #1"),
							WS_OVERLAPPEDWINDOW,
							CW_USEDEFAULT, CW_USEDEFAULT,
							CW_USEDEFAULT, CW_USEDEFAULT,
							NULL, NULL, hInstance, NULL) ;
     
	ShowWindow (hwnd, iCmdShow) ;
	UpdateWindow (hwnd) ;
     
	while (GetMessage (&msg, NULL, 0, 0))
	{
		TranslateMessage (&msg) ;
		DispatchMessage (&msg) ;
	}
		return msg.wParam ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static int   cxClientMax, cyClientMax, cxClient, cyClient, cxChar, cyChar ;
	static int   cLinesMax, cLines ;
	static PMSG  pmsg ;
	static RECT  rectScroll ;
	static TCHAR szTop[] = TEXT ("Message Key   Char ")
								TEXT ("Repeat Scan Ext ALT Prev Tran") ;
	static TCHAR szUnd[] = TEXT ("_______        ___       ____     ")
								TEXT ("______ ____ ___ ___ ____ ____") ;

	static TCHAR * szFormat[2] = { 
				TEXT ("%-13s %3d %-15s%c%6u %4d %3s %3s %4s %4s"),
				TEXT ("%-13s  0x%04X%1s%c %6u %4d %3s %3s %4s %4s") } ;
		static TCHAR * szYes  = TEXT ("Yes") ;
		static TCHAR * szNo   = TEXT ("No") ;
		static TCHAR * szDown = TEXT ("Down") ;
		static TCHAR * szUp   = TEXT ("Up") ;

		static TCHAR * szMessage [] = { 
		TEXT ("WM_KEYDOWN"),	TEXT ("WM_KEYUP"), 
		TEXT ("WM_CHAR"), 	TEXT ("WM_DEADCHAR"), 
		TEXT ("WM_SYSKEYDOWN"),TEXT ("WM_SYSKEYUP"), 
		TEXT ("WM_SYSCHAR"),	TEXT ("WM_SYSDEADCHAR") } ;
		HDC			hdc ;
		int 			i, iType ;
		PAINTSTRUCT		ps ;
		TCHAR 			szBuffer[128], szKeyName [32] ;
		TEXTMETRIC 		tm ;
     
	switch (message)
	{
	case WM_CREATE:
	case WM_DISPLAYCHANGE:
				// Get maximum size of client area
		cxClientMax = GetSystemMetrics (SM_CXMAXIMIZED) ;
		cyClientMax = GetSystemMetrics (SM_CYMAXIMIZED) ;

				// Get character size for fixed-pitch font
		hdc = GetDC (hwnd) ;
		SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
		GetTextMetrics (hdc, &tm) ;
		cxChar = tm.tmAveCharWidth ;
		cyChar = tm.tmHeight ;

		ReleaseDC (hwnd, hdc) ;
				// Allocate memory for display lines
		if (pmsg)
			free (pmsg) ;
			cLinesMax = cyClientMax / cyChar ;
			pmsg = malloc (cLinesMax * sizeof (MSG)) ;
			cLines = 0 ;
			// fall through
	case WM_SIZE:
		if (message == WM_SIZE)
		{
			cxClient = LOWORD (lParam) ;
			cyClient = HIWORD (lParam) ;
		}
					// Calculate scrolling rectangle
		rectScroll.left		= 0 ;
		rectScroll.right	= cxClient ;
		rectScroll.top 		= cyChar ;
		rectScroll.bottom	= cyChar * (cyClient / cyChar) ;

		InvalidateRect (hwnd, NULL, TRUE) ;
		return 0 ;
          
	case WM_KEYDOWN:
	case WM_KEYUP:
	case WM_CHAR:
	case WM_DEADCHAR:
	case WM_SYSKEYDOWN:
	case WM_SYSKEYUP:
	case WM_SYSCHAR:
	case WM_SYSDEADCHAR: 
					// Rearrange storage array
		for (i = cLinesMax - 1 ; i > 0 ; i--)
		{
				pmsg[i] = pmsg[i - 1] ;
		}
					// Store new message
		pmsg[0].hwnd = hwnd ;
		pmsg[0].message = message ;
		pmsg[0].wParam = wParam ;
		pmsg[0].lParam = lParam ;

		cLines = min (cLines + 1, cLinesMax) ;
					// Scroll up the display
		ScrollWindow (hwnd, 0, -cyChar, &rectScroll, &rectScroll) ;
		break ; 		// i.e., call DefWindowProc so Sys messages work
	case WM_PAINT:
		hdc = BeginPaint (hwnd, &ps) ;
		SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
		SetBkMode (hdc, TRANSPARENT) ;
		TextOut (hdc, 0, 0, szTop, lstrlen (szTop)) ;
		TextOut (hdc, 0, 0, szUnd, lstrlen (szUnd)) ;

		for (i = 0 ; i < min (cLines, cyClient / cyChar - 1) ; i++)
		{
			iType = 	pmsg[i].message == WM_CHAR ||
					pmsg[i].message == WM_SYSCHAR ||
					pmsg[i].message == WM_DEADCHAR ||
					pmsg[i].message == WM_SYSDEADCHAR ;

			GetKeyNameText (pmsg[i].lParam, szKeyName, 
						sizeof (szKeyName) / sizeof (TCHAR)) ;

		TextOut (hdc, 0, (cyClient / cyChar - 1 - i) * cyChar, szBuffer,
		wsprintf (szBuffer, szFormat [iType],
		szMessage [pmsg[i].message - WM_KEYFIRST],
		pmsg[i].wParam,
		(PTSTR) (iType ? TEXT (" ") : szKeyName),
		(TCHAR) (iType ? pmsg[i].wParam : ' '),
		LOWORD (pmsg[i].lParam),
		HIWORD (pmsg[i].lParam) & 0xFF,
				0x01000000 & pmsg[i].lParam ? szYes  : szNo,
				0x20000000 & pmsg[i].lParam ? szYes  : szNo,
				0x40000000 & pmsg[i].lParam ? szDown : szUp,
				0x80000000 & pmsg[i].lParam ? szUp   : szDown)) ;
		}
		EndPaint (hwnd, &ps) ;
		return 0 ;

	case	WM_DESTROY:
		PostQuitMessage (0) ;
		return 0 ;
	}
	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

KEYVIEW1��ʾ�Ӵ�ѶϢ������ʽ���յ���ÿ�ΰ�������ԪѶϢ�����ݣ�������ЩѶϢ������һ��MSG�ṹ�������С������еĴ�С��������Ӵ��Ĵ�С�͵ȿ���ϵͳ���塣���ʹ�����ڳ�ʽִ��ʱ��������Ѷ��ʾ�Ĵ�С�������������KEYVIEW1����WM_DISPLAYCHANGEѶϢ���������·�������С�KEYVIEW1ʹ�ñ�׼C��malloc��ʽΪ�������ü����塣

ͼ6-2�������ڼ��롸Windows��֮��KEYVIEW1��өĻ��ʾ����һ����ʾ�˼���ѶϢ���ڶ����ڼ����Ƶ�ǰ����ʾ�˰���ѶϢ����������룬�˴����Ǿ���GetKeyNameText��ʽȡ�õģ������У���עΪ��Char��������Ԫ������������ʾ��ԪѶϢ��ʮ����λ��Ԫ���롣����������ʾ��lParamѶϢ������������λ��״̬��


��

ͼ6-2 KEYVIEW1��өĻ��ʾ

Ϊ����Է��еķ�ʽ��ʾ����Ѷ��KEYVIEW1ʹ���˵ȿ����塣��ǰһ�������۵�һ��������Ҫ����GetStockObject��SelectObject��

SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;

KEYVIEW1����ʾ�����ϲ�����һ��������ȷ���ֳɾ��С��������ִ��е��ߡ���Ȼ���Խ���һ�ִ����ߵ����壬������ʹ������һ�ַ������Ҷ����������ִ�����szTop�������֣���szUnd���е��ߣ�������WM_PAINTѶϢ�����ڼ佫����ͬʱ��ʾ���Ӵ�������ͬһλ�á�ͨ����Windows��һ�֡���͸�����ķ�ʽ��ʾ���֣�Ҳ����˵��ʾ��ԪʱWindows��������Ԫ���������⽫���µڶ����ִ���szUnd��������ǰһ����szTop����Ҫ��ֹ��һ����ķ������ɽ�װ�������л�����͸����ģʽ��

SetBkMode (hdc, TRANSPARENT) ;

���ּӵ��ߵķ���ֻ����ʹ�õȿ�����ʱ�ſ��С����򣬵�����Ԫ���޷��������ڵ����������Ԫ�ȿ���

�����������
��

�����ִ������Ӣ��汾��Windows����ô���ɰ�װ��ͬ�ļ��̲��֣���������������� ï¿½ï¿½ï¿½ï¿½Ì¨ ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ ï¿½Ð°ï¿½×°ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ì²ï¿½ï¿½Ö¡ï¿½Ñ¡ï¿½ï¿½ ï¿½ï¿½Ïµ Ò³ï¿½ï¿½ï¿½Ç©ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½Òªï¿½é¿´ï¿½ï¿½ï¿½ï¿½ï¿½Ä¹ï¿½ï¿½ï¿½ï¿½ï¿½Ê½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ë°²×°ï¿½ï¿½ï¿½ï¿½ï¿½ï¡¹ï¿½ï¿½ï¿½Ì¡ï¿½ï¿½ï¿½ï¿½â£¬ï¿½Ò»ï¿½Òªï¿½ï¿½ï¿½Û¡ï¿½ï¿½ï¿½ï¿½ï¡¹ï¿½Í¡ï¿½Ï£ï¿½ï¿½ï¿½ï¡¹ï¿½Ä¼ï¿½ï¿½Ì²ï¿½ï¿½Ö£ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ò²ï¿½É°ï¿½×°ï¿½ï¿½Ð©ï¿½ï¿½ï¿½Ì²ï¿½ï¿½Ö¡ï¿½ï¿½ï¿½ï¿½ï¿½Ú¡ï¿½ï¿½ï¿½ï¿½Ì¡ï¿½ï¿½ï¿½Ê¾ï¿½ï¿½ï¿½Ð±ï¿½ï¿½ï¿½ï¿½Ò²ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¡¹ï¿½Í¡ï¿½Ï£ï¿½ï¿½ï¿½ï¡¹ï¿½Ä¼ï¿½ï¿½Ì²ï¿½ï¿½Ö£ï¿½ï¿½ï¿½ï¿½ï¿½Òªï¿½ï¿½×°ï¿½ï¿½ï¿½ï¿½ÏµÖ§Ô®ï¿½ï¿½ï¿½Ó¡ï¿½ï¿½ï¿½ï¿½ï¿½Ì¨ï¿½ï¿½ï¿½ï¿½Ñ¡ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½/ɾ�� ï¿½ï¿½Ê½ï¿½ï¿½È»ï¿½ï¿½Ñ¡ï¿½ï¿½ Windows��װ��ʽ Ò³ï¿½ï¿½ï¿½Ç©ï¿½ï¿½È·ï¿½ï¿½Ñ¡ï¿½ï¿½ ï¿½ï¿½ï¿½ï¿½ÏµÖ§Ô® ï¿½ï¿½È¡ï¿½ï¿½ï¿½é¡£ï¿½ï¿½ï¿½Îºï¿½ï¿½ï¿½ï¿½ï¿½Â£ï¿½ï¿½ï¿½Ð©ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ÒªÔ­Ê¼ï¿½ï¿½Windows�����

��װ���������̲����ᣬ�����ڹ������Ҳ��֪ͨ������һ������������ĸ�������ɫ������ڶ�����Ӣ���ô��������ĸ�ǡ�EN����������ͼʾ�����õ������Ѱ�װ���̲��ֵ��б������е�����Ҫ�ļ��̲��ּ��ɸ���Ŀǰ���ʽ�ļ��̡��˸ı�ֻӰ��Ŀǰ��ij�ʽ��

���ڿ�ʼ����ʵ�顣��ʹ��UNICODEʶ���ֶ���������KEYVIEW1��ʽ���ڱ��鸽���Ĺ���У���Unicode�汾��KEYVIEW1��ʽλ�RELEASE��Ŀ¼����������Ӣ��汾��Windows��ִ�иó�ʽ����������Ԫ��abcde���� WM_CHARѶϢ������������һ����ASCII��Ԫ����0x61��0x62��0x63��0x64��0x65�Լ���ĸa��b��c��d��e��

���ڣ�KEYVIEW1����ִ�У�ѡ�������̲��֡�����=��Ȼ������һ��ĸ����a��e��i��o����u����=��������һ��WM_DEADCHARѶϢ��ĸ������һ��WM_CHARѶϢ�ͣ������ģ���Ԫ����0xE1��0xE9��0xED��0xF3��0xFA����Ԫ á��é��í��ó ï¿½ï¿½ ú������������Ĺ�����ʽ��

����ѡ��ϣ�����̲��֡����롺abcde��������õ�ʲô�������õ�WM_CHARѶϢ����Ԫ����0xE1��0xE2��0xF8��0xE4��0xE5����Ԫ á��â��¢ï¿½ï¿½ä ï¿½ï¿½ å����������Щ��Ԫ������ȷ��ʾ���ѵ�����Ӧ�õõ�ϣ����ĸ���е���ĸ��

�����л���������̲��������롺abcde�����������õ�WM_CHARѶϢ����Ԫ����0xF4��0xE8��0xF1��0xE2��0xF3���Լ���Ԫ ô��è��ñ��â ï¿½ï¿½ ó�����ң�������Щ��ĸ����������ʾ����Ӧ��˹������ĸ���еõ���Щ��ĸ��

������춣����Ѿ��л������Բ�����ͬ����Ԫ���룬������û�н����л�֪ͨGDI������GDI��ѡ���ʵ��ķ�������ʾ������Щ��Ԫ���롣

������dz��¸ң����п��õı���PC��������רҵ��ȫ���Microsoft Developer Network��MSDN���Ķ��Ļ�����ô��Ҳ���밲װ�����磩ϣ�����Windows���������԰������ּ��̲��֣�Ӣ�ϣ�������Ͷ����װ��ȥ������ִ��KEYLOOK1���л���Ӣ����̲��֣�Ȼ�����롺abcde������Ӧ�õ�ASCII��Ԫ����0x61��0x62��0x63��0x64��0x65�Լ���Ԫa��b��c��d��e�����������Է��ģ���ʹ��ϣ���棬ASCII��������ͨ�еģ���

��ϣ�����Windows�У��л���ϣ�����̲��ֲ����롺abcde���������õ�WM_CHARѶϢ����Ԫ����0xE1��0xE2��0xF8��0xE4��0xE5���������ڰ�װϣ�����̲��ֵ�Ӣ���Windows�еõ�����Ԫ������ͬ����������ʾ����Ԫ�� t��b��y��d ï¿½ï¿½ e����Щȷʵ��Сд��ϣ����ĸalpha��beta��psi��delta��epsilon��gamma��ô�ˣ������������ʹ��ϣ�����Windows����ô����ʹ�ü�ñ�ϴ���ϣ����ĸ�ļ��̡���Ӣ��c���Ӧ�ļ�������psi��gamma����Ӣ��g���Ӧ�ļ�������������Nadine Kano��д�ġ�Developing International Software for Windows 95 and Windows NT���ĵ�587ҳ����������ϣ����ĸ������

������ϣ�����Windows������KEYVIEW1���л���������̲��֡����롺=������Ȼ����������a��e��i��o��u�������õ�WM_CHARѶϢ����Ԫ����0xE1��0xE9��0xED��0xF3��0xFA����Щ��Ԫ�����밲װ������̲��ֵ�Ӣ���Windows�е�һ������������ʾ����Ԫȴ�� a��i��n��s ï¿½ï¿½ ϊ����������ȷ�� á��é��í��ó ï¿½ï¿½ ú��

�����л���������̲����롺abcde��������õ���Ԫ����0xF4��0xE8��0xF1��0xE2��0xF3�����밲װ������̵�Ӣ���Windows�еõ���һ������������ʾ����Ԫ�� t��q��r��b ï¿½ï¿½ s��������˹������ĸ���е���ĸ��

�����ɰ�װ������Windows�����������Բµ���Ӣ��Ͷ�����̶����Թ������������ϣ�������С�

���ڣ��������ĺ��¸ң������ɰ�װ������Windows��ִ��KEYVIEW1��������������������룬��ô��������Ӣ�����֣�һ���ƺ�������������������л������ϣ������߶�����̲��֣������������������ܵ��κ���ϰ�����������Ե���ʾ����Ԫ����������д����ĸ�������Ǵ��������ŵĵ�����ĸ��ϣ������ĸ���Ƕ�����ĸ������������Щ��ĸ��ʾΪ���������ƴд�������Ƭ��������Ҳ��������Ƭ��������Ȥ�����Dz��ǵ��ϣ������߶��

Զ���汾��Windows����һ�����������뷨�༭������IME����ʵ�ó�ʽ���ó�ʽ��ʾΪ�����Ĺ����У����������ñ�׼���������������֣����������ͳ�������ʹ�õĸ�����Ԫ��һ����˵������һ����ĸ�ᣬ��ɵ���Ԫ����ʾ����һ�������Ӵ��ڡ�Ȼ�ᰴ Enter ï¿½ï¿½ï¿½ï¿½ï¿½Ï³Éµï¿½ï¿½ï¿½Ôªï¿½ï¿½ï¿½ï¿½Í·ï¿½ï¿½Íµï¿½ï¿½Ë»î¶¯ï¿½Ó´ï¿½ï¿½ï¿½ï¿½ï¿½KEYVIEW1����KEYVIEW1����ûʲô��Ӧ��WM_CHARѶϢ��������Ԫ������128������Щ����û�����壨Nadine Kano��������������ʹ��IME�����ݣ���

��ʱ�������Ѿ�����������KEYLOOK1��ʾ������Ԫ�����ӣ���ִ�а�װ�˶����ϣ������̲��ֵ�Ӣ���Windowsʱ����ִ�а�װ�˶���������̲��ֵ�ϣ����Windowsʱ���Լ�ִ�а�װ�˵���������ϣ������̲��ֵĶ����Windowsʱ����������������Ҳ�����˴������Windows�����뷨�༭��������Ԫʱ�Ĵ�����ʾ��

��Ԫ��������
��

KEYLOOK1���������������⡣�����өĻ����ʾ��Ԫ������ͼ��̽��յ���Ԫ���벻һ�¡���ˣ������ǿ�һ�����塣

�ҽ��ڵ�ʮ���½�����ϸ���ۣ�Windows֧Ԯ�������壭�������塢��������ͣ���Windows 3.1��ʼ�ģ�TrueType���塣

��ʵ�����������Ѿ���ʱ�ˡ���Щ�����е���Ԫ�ɼ򵥵��߶���ɣ�����Щ�߶�û�ж���������������������ԽϺõ����ŵ������С������Ԫͨ������ȥ��Щ������

TrueType�����Ƕ�������������������������塣TrueType��������ţ����Ҹ���Ԫ�Ķ����������ʾ�������������ܴ��������ֲ��ɼ����߲��ɶ���Բ�����⡣ʹ��TrueType���壬Windows������ʵ����WYSIWYG�������������á���������������Ѷ��ʾ����ʾ��ӡ���������ȫһ�¡�

�ڵ��������У�ÿ����Ԫ������Ϊ����Ѷ��ʾ���ϵ�ͼ�ض�Ӧ��λԪ���󡣵�����������쵽�ϴ�ijߴ磬������ȥ���о�ݡ���������ͨ������Ƴɷ�������Ѷ��ʾ�����Ķ������塣��ˣ�Windows�еı����С����ܱ�����ť�ͶԻ��������ʾ���ֶ�ʹ�õ������塣

���ڶ���װ�������»�õĵ��������Ϊϵͳ���塣����ͨ�����д���SYSTEM_FONTʶ���ֵ�GetStockObject��ʽ�����������š�KEYVIEW1��ʽѡ��ʹ��SYSTEM_FIXED_FONT��ʾ�ĵȿ�ϵͳ���塣GetStockObject��ʽ����һ��ѡ����OEM_FIXED_FONT��

�����������У����Եģ��������ƣ�System��FixedSys��Terminal����ʽ������CreateFont����CreateFontIndirect��ʽ������ʹ������������ָ�����塣���������崢�����������WindowsĿ¼�ڵ�FONTS��Ŀ¼�µ����������С�Windowsʹ����һ�鵵��ȡ��춡�����̨����ġ���ʾ������ѡ����ʾ��С���塹���ǡ������塹���༴����ϣ��Windows�ٶ���Ѷ��ʾ����96 dpi�Ľ����Ȼ���120 dpi�Ľ����ȣ�����6-14�ܽ������е������

��6-14
GetStockObjectʶ���� �������� С���嵵�� �����嵵��
SYSTEM_FONT System VGASYS.FON 8514SYS.FON
SYSTEM_FIXED_FONT FixedSys VGAFIX.FON 8514FIX.FON
OEM_FIXED_FONT Terminal VGAOEM.FON 8514OEM.FON

�ڵ��������У���VGA��ָ������Ƶͼ�����У�Video Graphics Array����IBM��1987���Ƴ�����ʾ��������IBM��һ�����ʾ640��480ͼ�ش�С��PC��ʾ��������ڡ�����̨���ġ���ʾ������ѡ���ˡ�С���塹����ʾ��ϣ��Windows�ٶ���Ѷ��ʾ�Ľ�����Ϊ96 dpi������Windowsʹ�õ����������嵵�������ԡ�VGA����ͷ�����ѡ���ˡ������塹����ʾ��ϣ��������Ϊ120 dpi����Windowsʹ�õĵ��������ԡ�8514����ͷ��8514��IBM��1987���Ƴ�����һ����ʾ�������������ʾ�ߴ�Ϊ1024��768��

Windows��ϣ����������Щ��������Щ�����������趨Ϊϵͳ�����أ������Windows Explorer���鿴FONTS��Ŀ¼�����ݣ����Dz��ῴ�����ǵģ���ʹѡ���˲鿴ϵͳ�����ص���Ҳ���С��ӿ�ʼ���ܱ�ѡ��Ѱ�ҡ�ѡ����Ѱ�ҵ������� *.FON�޶������ĵ�������ʱ��������˫�����������鿴������Ԫ��Щʲô��

��������׼�������ʹ���߽���Ԫ����Windows��ʹ��ϵͳ���塣�෴�أ�ʹ������ΪMS Sans Serif�����壨��MS������Microsoft������Ҳ��һ�ֵ������塣��������ΪSSERIFE.FON����������96 dpi��Ѷ��ʾ�������壬��ֵΪ8��10��12��14��18��24��������GetStockObject��ʽ��ʹ��DEFAULT_GUI_FONTʶ�������õ������塣Windowsʹ�õĵ�ֵȡ��춡�����̨���ġ���ʾ����ѡ�����ʾ�����ȡ�

��ĿǰΪֹ�������ᵽ����ʶ���֣�����������ʶ���֣���������GetStockObject��������װ�����ݵ����塣����������������ʶ���֣�ANSI_FIXED_FONT��ANSI_VAR_FONT��DEVICE_DEFAULT_FONT��Ϊ�˿�ʼ�������̺���Ԫ��ʾ���⣬�������ȿ�һ��Windows�е����б������塣��ʾ��Щ����ij�ʽ��STOKFONT�����ʽ6-3��ʾ��

 ï¿½ï¿½Ê½6-3  STOKFONT
STOKFONT.C
/*----------------------------------------------------------------------
	STOKFONT.C -- 	Stock Font Objects
				(c) Charles Petzold, 1998
-----------------------------------------------------------------------*/

#include <windows.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
					PSTR szCmdLine, int iCmdShow)
{
	static TCHAR szAppName[] = TEXT ("StokFont") ;
	HWND			hwnd ;
	MSG		    	msg ;
	WNDCLASS 		wndclass ;
     
	wndclass.style 			= CS_HREDRAW | CS_VREDRAW ;
	wndclass.lpfnWndProc	= WndProc ;
	wndclass.cbClsExtra		= 0 ;
	wndclass.cbWndExtra		= 0 ;
	wndclass.hInstance		= hInstance ;
	wndclass.hIcon 			= LoadIcon (NULL, IDI_APPLICATION) ;
	wndclass.hCursor 		= LoadCursor (NULL, IDC_ARROW) ;
	wndclass.hbrBackground	= (HBRUSH) GetStockObject (WHITE_BRUSH) ;
	wndclass.lpszMenuName	= NULL ;
	wndclass.lpszClassName	= szAppName ;
     
	if (!RegisterClass (&wndclass))
	{
		MessageBox (	NULL, TEXT ("Program requires Windows NT!"), 
             						szAppName, MB_ICONERROR) ;
		return 0 ;
	}
     
	hwnd = CreateWindow (	szAppName, TEXT ("Stock Fonts"),
								WS_OVERLAPPEDWINDOW | WS_VSCROLL,
								CW_USEDEFAULT, CW_USEDEFAULT,
								CW_USEDEFAULT, CW_USEDEFAULT,
								NULL, NULL, hInstance, NULL) ;
     
	ShowWindow (hwnd, iCmdShow) ;
	UpdateWindow (hwnd) ;
	while (GetMessage (&msg, NULL, 0, 0))
	{
		TranslateMessage (&msg) ;
		DispatchMessage (&msg) ;
	}
	return msg.wParam ;
}

LRESULT CALLBACK WndProc (	HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam)
{
	static struct
	{
		int     idStockFont ;
		TCHAR * szStockFont ;
	}
	stockfont [] = { OEM_FIXED_FONT,		"OEM_FIXED_FONT",
						ANSI_FIXED_FONT,	"ANSI_FIXED_FONT",    
						ANSI_VAR_FONT,		"ANSI_VAR_FONT",
						SYSTEM_FONT, 		"SYSTEM_FONT",
						DEVICE_DEFAULT_FONT,"DEVICE_DEFAULT_FONT",
						SYSTEM_FIXED_FONT, 	"SYSTEM_FIXED_FONT",
						DEFAULT_GUI_FONT, 	"DEFAULT_GUI_FONT" } ;

	static int  iFont, cFonts = sizeof stockfont / sizeof stockfont[0] ;
	HDC			hdc ;
	int			i, x, y, cxGrid, cyGrid ;
	PAINTSTRUCT	ps ;
	TCHAR 			szFaceName [LF_FACESIZE], szBuffer [LF_FACESIZE + 64] ;
	TEXTMETRIC  tm ;
	switch (message)
	{
	case	WM_CREATE:
		SetScrollRange (hwnd, SB_VERT, 0, cFonts - 1, TRUE) ;
		return 0 ;

	case	WM_DISPLAYCHANGE:
		InvalidateRect (hwnd, NULL, TRUE) ;
		return 0 ;

	case	WM_VSCROLL:
		switch (LOWORD (wParam))
		{	
		case SB_TOP: 	 	iFont = 0 ; 			break ;
	case SB_BOTTOM:		    iFont = cFonts - 1 ;	break ;
		case SB_LINEUP:
		case SB_PAGEUP:	    iFont -= 1 ;			break ;
	case SB_LINEDOWN:
	case SB_PAGEDOWN:		iFont += 1 ; 				break ;
	case SB_THUMBPOSITION:	iFont = HIWORD (wParam) ;	break ;
		}
		iFont = max (0, min (cFonts - 1, iFont)) ;
		SetScrollPos (hwnd, SB_VERT, iFont, TRUE) ;
		InvalidateRect (hwnd, NULL, TRUE) ;
		return 0 ;

	case	WM_KEYDOWN:
		switch (wParam)
		{
		case VK_HOME: SendMessage (hwnd, WM_VSCROLL, SB_TOP, 0) ;	   break ;
		case VK_END:  SendMessage (hwnd, WM_VSCROLL, SB_BOTTOM, 0) ;   break ;
		case VK_PRIOR:
		case VK_LEFT:
		case VK_UP:   SendMessage (hwnd, WM_VSCROLL, SB_LINEUP, 0) ;   break ;
		case VK_NEXT: 
		case VK_RIGHT:
		case VK_DOWN: SendMessage (hwnd, WM_VSCROLL, SB_PAGEDOWN, 0) ; break ;
		}
		return 0 ;

	case	WM_PAINT:
		hdc = BeginPaint (hwnd, &ps) ;

		SelectObject (hdc, GetStockObject (stockfont[iFont].idStockFont)) ;
		GetTextFace (hdc, LF_FACESIZE, szFaceName) ;
		GetTextMetrics (hdc, &tm) ;
		cxGrid = max (3 * tm.tmAveCharWidth, 2 * tm.tmMaxCharWidth) ;
		cyGrid = tm.tmHeight + 3 ;

		TextOut (hdc, 0, 0, szBuffer, 
		wsprintf (	szBuffer, TEXT (" %s: Face Name = %s, CharSet = %i"),
					stockfont[iFont].szStockFont, 
					szFaceName, tm.tmCharSet)) ;

	SetTextAlign (hdc, TA_TOP | TA_CENTER) ;
		// vertical and horizontal lines
		for (i = 0 ; i < 17 ; i++)
		{
			MoveToEx (hdc, (i + 2) * cxGrid,  2 * cyGrid, NULL) ;
			LineTo   (hdc, (i + 2) * cxGrid, 19 * cyGrid) ;

			MoveToEx (hdc,      cxGrid, (i + 3) * cyGrid, NULL) ;
			LineTo   (hdc, 18 * cxGrid, (i + 3) * cyGrid) ;
		}
				// vertical and horizontal headings

		for (i = 0 ; i < 16 ; i++)
		{
		TextOut (hdc, (2 * i + 5) * cxGrid / 2, 2 * cyGrid + 2, szBuffer,
		wsprintf (szBuffer, TEXT ("%X-"), i)) ;

		TextOut (hdc, 3 * cxGrid / 2, (i + 3) * cyGrid + 2, szBuffer,
		wsprintf (szBuffer, TEXT ("-%X"), i)) ;
		}
				// characters

		for (y = 0 ; y < 16 ; y++)
		for (x = 0 ; x < 16 ; x++)
		{
		TextOut (hdc, (2 * x + 5) * cxGrid / 2, 
									(y + 3) * cyGrid + 2, szBuffer,
		wsprintf (szBuffer, TEXT ("%c"), 16 * x + y)) ;
          }

		EndPaint (hwnd, &ps) ;
		return 0 ;
          
	case	WM_DESTROY:
		PostQuitMessage (0) ;
		return 0 ;
     }
	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

�����ʽ�൱�򵥡���ʹ�þ����к��α��ƶ�������ѡ����ʾ���ֱ�������֮һ���ó�ʽ��һ����������ʾһ�������256����Ԫ�������ı��������������ʾ��Ԫ�����ʮ����λֵ��

����ʾ����Ķ�����STOKFONT��GetStockObject��ʽ��ʾ���ѡ�������ʶ���֡�������ʾ��GetTextFace��ʽ�õ���������ʽ���ƺ�TEXTMETRIC�ṹ��tmCharSet��λ���������Ԫ��ʶ���֡�������Windows��δ�������汾��Windows�Ƿdz���Ҫ�ġ�

���������Ӣ��汾��Windows��ִ��STOKFONT����ô�������ĵ�һ�����潫��ʾʹ��OEM_FIXED_FONTʶ���ֺ���GetStockObject��ʽ�õ������塣��ͼ6-3��ʾ��


��

ͼ6-3 ������Windows�е�OEM_FIXED_FONT

�ڱ���Ԫ���У��뱾����������һ��������������һЩASCII�������סASCII��7λԪ���룬�������˴Ӵ���0x20��0x7E�Ŀ���ʾ��Ԫ����IBM������IBM PCԭ�ͻ�ʱ��8λԪλԪ������ѱ��ȹ̵ؽ�����������˿�ʹ��ȫ8λԪ������Ϊ��Ԫ���롣IBM����ʹ��һϵ�����ߺͷ�����ɵ���Ԫ����������ĸ��ϣ����ĸ����ѧ���ź�һЩ������Ԫ����չASCII��Ԫ������������ģʽ��MS-DOS��ʽ����өĻ��ʾ�ж�ʹ�û�ͼ��Ԫ����������MS-DOS��ʽ���ڵ�����ʹ����һЩ��չ��Ԫ��

����������Ԫ����Windows����Ŀ����ߴ�����һ�����⡣һ���棬��ΪWindows��������ͼ�γ�ʽ������ԣ������ߺͷ�����Ԫ��Windows�в���Ҫ����ˣ���Щ��Ԫʹ�õ�48������������������ŷ��������Ҫ�ĸ���������ĸ����һ���棬IBM��Ԫ��������һ���޷���ȫ���Եı�׼��

��ˣ�Windows����Ŀ����߾���֧ԮIBM��Ԫ������������Ҫ�Խ��͵��ڶ�λ�����Ǵ��������Ӵ���ִ�еľ�MS-DOSӦ�ó�ʽ������Ҫʹ����MS-DOSӦ�ó�ʽ����������Windows��ʽ��WindowsӦ�ó�ʽ��ʹ��IBM��Ԫ������������ʱ������ƣ�����Ҫ���ս�˥�ˡ�Ȼ���������Ҫ�������ǿ���ʹ�á��ڴ˻����£���OEM��ָ�ľ��ǡ�IBM����

����Ӧ֪������汾��Windows����֧Ԯ������Ӣ�����ͬ��OEM��Ԫ�����������������Լ���MS-DOS��Ԫ�������Ǹ����������⣬�Ͳ��ڱ����������ˡ���

��ΪIBM��Ԫ������Ϊ���ʺ�Windows�����ѡ������һ����չ��Ԫ��������Ԫ��������ANSI��Ԫ���������������ұ�׼Э�ᣨAmerican National Standards Institute���ƶ�������ʵ������ISO��International Standards Organization�����ʱ�׼����֯����׼��Ҳ����ISO��׼8859��������ΪLatin 1��Western European�����������1252��ͼ6-4��ʾ��ANSI��Ԫ����һ���汾������Ӣ���Windows��ϵͳ���塣


��

ͼ6-4 ������Windows�е�SYSTEM_FONT

�ֵĴ�ֱ����ʾ��Щ��Ԫ����û�ж��塣ע�⣬����0x20��0x7E����ASCII�����⣬ASCII������Ԫ��0x00��0x1F�Լ�0x7F�������ǿ���ʾ��Ԫ�����DZ�Ӧ��ˡ�

����0xC0��0xFFʹ��ANSI��Ԫ���������Windows��˵�dz���Ҫ����Щ�����ṩ64������ŷ�������ձ�ʹ�õ���Ԫ����Ԫ0xA0����������ո񣬵�ʵ���϶���Ϊ�ǶϿ��ո����硸WW II���еĿո�

֮����˵����ANSI��Ԫ���ġ�һ���汾��������Ϊ���ڴ���0x80��0x9F����Ԫ���ȿ���ϵͳ����ֻ�������е�������Ԫ����ͼ6-5��ʾ��


��

ͼ6-5 ������Windows�е�SYSTEM_FIXED_FONT

��Unicode�У�����0x0000��0x007F��ASCII��ͬ������0x0080��0x009F������0x0000��0x001F�Ŀ�����Ԫ������0x00A0��0x00FF��Windows��ʹ�õ�ANSI��Ԫ����ͬ��

���ִ�е�����Windows����ô������SYSTEM_FONT����SYSTEM_FIXED_FONTʶ����������GetStockObject��ʽʱ��õ�ͬ����ANSI��Ԫ����������ŷ��WindowsҲ����ˡ�ANSI��Ԫ���к�����Щ��������Ҫ��������Ԫ��

����������ִ��ϣ�����Windowsʱ���ڶ�����Ԫ���͸ı��ˡ��෴�أ�SYSTEM_FONT��ͼ6-6��ʾ��


��

ͼ6-6 ϣ����Windows�е�SYSTEM_FONT

SYSTEM_FIXED_FONT��ͬ������Ԫ��ע���0xC0��0xFF�Ĵ��롣��Щ�������ϣ����ĸ���еĴ�д��ĸ��Сд��ĸ������ִ�ж����Windowsʱ���ڶ�����Ԫ����ͼ6-7��ʾ��


��

ͼ6-7 �����Windows�е�SYSTEM_FONT

���⣬ ע��˹������ĸ���еĴ�д��Сд��ĸռ���˴���0xC0��0xFF��

ͼ6-8��ʾ�������Windows��SYSTEM_FONT����0xA5��0xDF����Ԫ����Ƭ������ĸ����һ���֡�


��

ͼ6-8 �����Windows�е�SYSTEM_FONT

ͼ6-8��ʾ������ϵͳ���岻ͬ�ǰ����ʾ����Щ����Ϊ��ʵ������˫λԪ����Ԫ����DBCS������Ϊ��Shift-JIS������JIS�������ձ���ҵ��׼��Japanese Industrial Standard������0x81��0x9F�Լ���0xE0��0xFF�Ĵ������Ԫ����ʵ����ֻ��˫λԪ�����ĵ�һ��λԪ�飬��ڶ���λԪ��ͨ����0x40��0xFC�ķ�Χ�ڣ������Щ���������������μ�Nadine Kano���еĸ�¼G����

���ڣ����ǾͿ��Կ���KEYVIEW1�е�����������������װ��ϣ�����̲��ֲ����롺abcde����������ִ�е�Windows�汾��Windows������WM_CHARѶϢ����Ԫ����0xE1��0xE2��0xF8��0xE4��0xE5����ֻ��ִ�д���ϣ��ϵͳ�����ϣ����Windowsʱ����Щ��Ԫ��������� t��b��y��d ï¿½ï¿½ e ï¿½ï¿½ï¿½Ó¦ï¿½ï¿½

�������װ�˶�����̲��ֲ����롺abcde������������ʹ�õ�Windows�汾��Windows������WM_CHARѶϢ����Ԫ����0xF4��0xE8��0xF1��0xE2��0xF3����ֻ����ʹ�ö����Windows����ʹ��˹������ĸ�����������԰棬����ʹ��˹����ϵͳ����ʱ����Щ��Ԫ����Ż�����Ԫ ï¿½ï¿½ï¿½ï¿½и��с��в ï¿½ï¿½ у ï¿½ï¿½ï¿½Ó¦ï¿½ï¿½

�������װ�˵�����̲��ֲ�����=��������λ�ͬһλ�õļ�����Ȼ�ᰴ��a��e��i��o����u����������ʹ�õ�Windows�汾��Windows������WM_CHARѶϢ����Ԫ����0xE1��0xE9��0xED��0xF3��0xFA��ֻ��ִ����ŷ������������Windowsʱ��Ҳ����˵����ŷϵͳ���壬��Щ��Ԫ����Ż����Ԫamp;nbsp;á��é��í��ó ï¿½ï¿½ ú ï¿½ï¿½ï¿½Ó¦ï¿½ï¿½

�����װ������Ӣ����̲��֣��������ڼ����ϼ����κ���Ԫ��Windows������WM_CHARѶϢ�Լ�����Ԫ��ȷƥ�����Ԫ���롣

Unicode����
��

���ڵڶ���̸����Windows NT֧Ԯ��Unicode�����Ϊ�����г���ʽд���������DZ���һ�¶�����UNICODEʶ���ֵ�KEYVIEW1�����ڲ�ͬ�汾��Windows NT��ִ�У��ڱ��鸽���Ĺ���У�Unicode���KEYVIEW1λ�DEBUGĿ¼�У���

�����ʽ����ʱ������UNICODEʶ���֣���KeyView1���Ӵ�������RegisterClassW��ʽע�ᣬ������RegisterClassA��ʽ������ζ���κδ�����Ԫ���������ϵ�ѶϢ���ݸ�WndProcʱ����ʹ��16λԪ��Ԫ������8λԪ��Ԫ���ر���WM_CHARѶϢ��������16λԪ��Ԫ���������8λԪ��Ԫ���롣

��������Ӣ����Windows NT��ִ��Unicode���KEYVIEW1������ٶ����Ѿ���װ��������������������ļ��̲��֣������ϣ����Ͷ��

ʹ������Ӣ����Windows NT������װ��Ӣ����ߵ���ļ��̲��֣�Unicode���KEYVIEW1�ڹ���ʱ�����Unicode����ͬ������������ͬ����Ԫ���루����0xFF���߸��͵�ֵ��������ʾͬ����ȷ����Ԫ��������Ϊ�����256��Unicode��Ԫ��Windows��ʹ�õ�ANSI��Ԫ����ͬ��

�����л���ϣ�����̲��֣������롺abcde����WM_CHARѶϢ������Unicode��Ԫ����0x03B1�� 0x03B2��0x03C8�� 0x03B4��0x03B5��ע�⣬�����ȿ�������Ԫ����ֵ��0xFF�ߡ���ЩUnicode��Ԫ������ϣ����ĸ t��b��y��d ï¿½ï¿½ e ï¿½ï¿½ï¿½Ó¦ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ôªï¿½ï¿½ï¿½ï¿½Ê¾Îªï¿½ï¿½ï¿½é£¡ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ÎªSYSTEM_FIXED_FONTֻ����256����Ԫ��

�����л���������̲��֣������롺abcde����KEYVIEW1��ʾWM_CHARѶϢ��Unicode��Ԫ����0x0444��0x0438��0x0441��0x0432��0x0443����Щ��Ԫ��Ӧ�˹������ĸ ï¿½ï¿½ï¿½ï¿½и��с��в ï¿½ï¿½ у�������������������ĸҲ��ʾΪʵ�ķ��顣

����֮����Unicode���KEYVIEW1��ʾ������Ԫ�ĵط���Unicode���KEYVIEW1����ʾʵ�ķ��飬�Ա�ʾĿǰ������û������������Ԫ����Ȼ�Ҳ�Ը˵Unicode���KEYVIEW1�Ƿ�Unicode��ĸĽ�������ʵȷʵ��ˡ���Unicode����ʾ������Ԫ����Unicode�治��������

Unicode�ͷ�Unicode��KEYVIEW1�IJ�֮ͬ����Ҫ���������档

���ȣ�WM_CHARѶϢ����һ��16λԪ��Ԫ���룬������8λԪ��Ԫ���롣�ڷ�Unicode�汾��KEYVIEW1�У�8λԪ��Ԫ����ĺ���ȡ���Ŀǰ��ļ��̲��֡�������Ե�����̣���0xE1�����ʾ á���������ϣ������������ a��������Զ����������� s����Unicode�汾��ʽ�У�16λԪ��Ԫ����ĺ������ȷ��a��Ԫ��0x00E1��a ï¿½ï¿½Ôªï¿½ï¿½0x03B1���� s ï¿½ï¿½Ôªï¿½ï¿½0x0431��

�ڶ���Unicode��TextOutW��ʽ��ʾ����Ԫ����16λԪ��Ԫ���룬�����Ƿ�Unicode��TextOutA��ʽ��8λԪ��Ԫ���롣��Ϊ��Щ16λԪ��Ԫ���뺬����ȷ��GDI����ȷ��Ŀǰ��װ��������ѡ��������Ƿ����ʾÿ����Ԫ��

������Ӣ���Windows NT��ִ��Unicode���KEYVIEW1�������˸е���Щ�Ի���Ϊ������ʾ�ľͺ���GDIֻ��ʾ��0x0000��0x00FF֮�����Ԫ���룬��û����ʾ���0x00FF�Ĵ��롣Ҳ����˵��ֻ������Ԫ�����ϵͳ������256����Ԫ֮��򵥵�һ��һӳ�䡣

Ȼ���������װ��ϣ�����߶�����Windows NT��������������ʹ�һ���ˡ����磬�����װ��ϣ�����Windows NT��������Ӣ����ϣ����Ͷ�����̽������������Ӣ���Windows NTͬ����Unicode��Ԫ���롣������ϣ�����Windows NT������ʾ����������Ԫ���߶�����Ԫ����Ϊ��Щ��Ԫ������ϣ��ϵͳ�����С�ͬ����������Windows NTҲ����ʾ����������Ԫ����ϣ����Ԫ����Ϊ��Щ��ԪҲ���ڶ���ϵͳ�����С�

���У�Unicode���KEYVIEW1�������������Windows NT�¸���Ϸ���ԡ�����IME����������Ԫ����Щ��Ԫ������ȷ��ʾ��Ψһ�������Ǹ�ʽ����Ϊ������Ԫͨ���������dz����ӣ����ǵ���ʾ������������Ԫ��������

TrueType�ʹ�����
��

����ʹ�õĵ������壨�����İ�Windows�д��и������壩������256����Ԫ������������ϣ���ģ���Ϊ���ٶ���Ԫ������8λԪʱ���������嵵���ĸ�ʽ�͸�����Windowsʱ��������һ���ˡ������Ϊʲô������ʹ��SYSTEM_FONT����SYSTEM_FIXED_FONTʱ��ijЩ������һЩ��Ԫ�ܲ�����ȷ��ʾ���ձ�ϵͳ�����е㲻ͬ����Ϊ����˫λԪ����Ԫ�����������Ԫʵ���ϱ�����TrueType���ϵ����У�������������.TTC����

TrueType�����������Ԫ���Զ��256��������������TrueType�����е���Ԫ�����256������Windows 98��Windows NT�����������256����Ԫ�����ߣ���װ�˶���ϵ֧Ԯ�ᣬTrueType������Ҳ�������256����Ԫ���ڡ� ï¿½ï¿½ï¿½ï¿½Ì¨ ï¿½ï¿½ï¿½Ä¡ï¿½ ï¿½ï¿½ï¿½ï¿½/ɾ����ʽ ï¿½ï¿½ï¿½Ð£ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ Windows��װ��ʽ ï¿½ï¿½Ò³ï¿½ï¿½ï¿½Ç©ï¿½ï¿½ï¿½ï¿½È·ï¿½ï¿½Ñ¡ï¿½ï¿½ï¿½Ë¡ï¿½ ï¿½ï¿½ï¿½ï¿½ÏµÖ§Ô® ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ÏµÖ§Ô®ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ôªï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ÞµÄºï¿½ï¿½ï¿½Ïµï¿½ï¿½ï¿½ï¿½Å·ï¿½ï¿½Ïµï¿½ï¿½Ë¹ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ïµï¿½ï¿½Ï£ï¿½ï¿½ï¿½ï¿½Ïµï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ïµï¿½ï¿½ï¿½ï¿½ï¿½ÞµÄºï¿½ï¿½ï¿½Ïµï¿½ï¿½Ôªï¿½ï¿½ï¿½ï¿½ì¶°ï¿½É³ï¿½ï¿½ï¿½ï¿½ï¿½ï¡¢ï¿½ï¿½ï¿½ï¿½Î¬ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¡£ï¿½ï¿½Å·ï¿½ï¿½Ôªï¿½ï¿½ï¿½ï¿½ì¶°ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¡¢ï¿½Ý¿ï¿½ï¿½ï¡¢ï¿½ï¿½ï¿½Þµï¿½ï¿½ï¿½ï¿½ï¡¢ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¡¢ï¿½ï¿½ï¿½ï¿½ï¿½ï¡¢ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¡¢Ë¹ï¿½å·¥ï¿½ï¿½ï¿½ï¿½ï¿½Ë¹ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¡£Ë¹ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ôªï¿½ï¿½ï¿½ï¿½ì¶±ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¡¢ï¿½×¶ï¿½ï¿½ï¿½Ë¹ï¿½ï¡¢ï¿½ï¿½ï¿½ï¡¢ï¿½ï¿½ï¿½ï¿½Î¬ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ú¿ï¿½ï¿½ï¿½ï¿½ï¡£

Windows 98�е�TrueType����֧Ԯ��������Ԫ�����ټ�����ŷ��ANSI����Ԫ������ŷ��Ԫ��ʵ������������������ԣ���Զ�����ԣ��������ͳ�������⡣֧Ԯ������Ԫ����TrueType������ʱҲ��Ϊ�������塹������������µġ��󡹲�����ָ��Ԫ�Ĵ�С������ָ������

��ʹ�ڷ�Unicode��ʽ��Ҳ�����ô����壬����ζ�������ô�������ʾ���ֲ�ͬ��ĸ���е���Ԫ��Ȼ����Ϊ��Ҫ���õ�������ѡ��װ�����ݣ�����ҪGetStockObject����ĺ�ʽ��

��ʽCreateFont��CreateFontIndirect������һ���߼����壬����CreatePen�����߼������Լ�CreateBrush�����߼���ˢ�ķ�ʽ���ơ�CreateFont��14����������Ҫ���������塣CreateFontIndirectֻ��һ�����������ò�����ָ��LOGFONT�ṹ��ָ�ꡣLOGFONT�ṹ��14����λ���ֱ��Ӧ�CreateFont��ʽ�IJ������ҽ��ڵ�ʮ������ϸ������Щ��ʽ�����ڣ������ǿ�һ��CreateFont��ʽ��������ֻע���������������������������趨Ϊ0��

�����Ҫ�ȿ����壨����KEYVIEW1��ʽ��ʹ�õģ�����CreateFont�ĵ�13�������趨ΪFIXED_PITCH�������Ҫ���ڶ���Ԫ�������壨��Ҳ����������Ҫ�ģ�����CreateFont�ĵ�9�������趨Ϊij������Ԫ��ID��������Ԫ��ID����WINGDI.H�ж��������ֵ֮һ�����Ѹ���ע�ͣ�ָ������Щ��Ԫ����ص��������

#define ANSI_CHARSET 0 // 1252 Latin 1 (ANSI)
#define DEFAULT_CHARSET 1  
#define SYMBOL_CHARSET 2  
#define MAC_CHARSET 77  
#define SHIFTJIS_CHARSET 128 // 932 (DBCS, �ձ�)
#define HANGEUL_CHARSET 129 // 949 (DBCS, ����)
#define HANGUL_CHARSET 129 // " "
#define JOHAB_CHARSET 130 // 1361 (DBCS, ����)
#define GB2312_CHARSET 134 // 936 (DBCS, ��������)
#define CHINESEBIG5_CHARSET 136 // 950 (DBCS, ��������)
#define GREEK_CHARSET 161 // 1253ϣ����
#define TURKISH_CHARSET 162 // 1254 Latin 5 (��������)
#define VIETNAMESE_CHARSET 163 // 1258Խ����
#define HEBREW_CHARSET 177 // 1255ϣ������
#define ARABIC_CHARSET 178 // 1256��������
#define BALTIC_CHARSET 186 // 1257���޵ĺ��ּ�
#define RUSSIAN_CHARSET 204 // 1251���� (˹������ϵ)
#define THAI_CHARSET 222 // 874̩��
#define EASTEUROPE_CHARSET 238 // 1250 Latin 2 (��ŷ��ϵ)
#define OEM_CHARSET 255 // �����Զ�

ΪʲôWindows��ͬһ����Ԫ����������ͬ��ID����Ԫ��ID�������ID����ֻ��Windows�е�һ�ֹ�񱡣ע�⣬��Ԫ��IDֻ��Ҫ1λԪ��Ĵ���ռ䣬����LOGFONT�ṹ����Ԫ����λ�Ĵ�С���Ի���Windows 1.0ʱ�ڣ�������ʹ���ռ����ޣ�ÿ��λԪ�鶼������ƽϣ���ע�⣬�����಻ͬ��MS-DOS���������������ң���ֻ��һ����Ԫ��ID��OEM_CHARSET�����MS-DOS��Ԫ����

������ע�⵽����Щ��Ԫ����ֵ��STOKFONT��ʽ����ͷ�ġ�CharSet��ֵһ�¡�������Ӣ���Windows�У����ǿ��������������Ԫ��ID��0����ANSI_CHARSET����255��OEM_CHARSET����ϣ����Windows�е���161��GREEK_CHARSET�����ڶ�����е���204��RUSSIAN_CHARSET���������������128��SHIFTJIS_CHARSET����

������Ĵ����У�DBCS����˫λԪ����Ԫ�������Զ�����Windows���������Windows��֧ԮDBCS���壬��˲���ʹ����Щ��Ԫ��ID��

CreateFont����HFONTֵ���߼�����Ĵ��š�������ʹ��SelectObject��������ѡ��װ�����ݡ�ʵ���ϣ����������DeleteObject��ɾ���������������߼����塣

������������������������WM_INPUTLANGCHANGEѶϢ��һ����ʹ�������¶˵�ͻ��ʽ���ܱ����ı���̲��֣�Windows�����������Ӵ�ѶϢ������ʽ����WM_INPUTLANGCHANGEѶϢ��wParamѶϢ�������¼��̲��ֵ���Ԫ��ID��

��ʽ6-4��ʾ��KEYVIEW2��ʽʵ���˼��̲��ָı�ʱ�ı�������߼���

 ï¿½ï¿½Ê½6-4  KEYVIEW2
KEYVIEW2.C
/*----------------------------------------------------------------------------
   KEYVIEW2.C -- Displays Keyboard and Character Messages
           				 (c) Charles Petzold, 1998
-----------------------------------------------------------------------------*/

#include <windows.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
				  PSTR szCmdLine, int iCmdShow)
{
	static TCHAR szAppName[] = TEXT ("KeyView2") ;
	HWND 			hwnd ;
	MSG 			msg ;
	WNDCLASS		wndclass ;
     
	wndclass.style 			= CS_HREDRAW | CS_VREDRAW ;
	wndclass.lpfnWndProc	= WndProc ;
	wndclass.cbClsExtra		= 0 ;
	wndclass.cbWndExtra		= 0 ;
	wndclass.hInstance		= hInstance ;
	wndclass.hIcon			= LoadIcon (NULL, IDI_APPLICATION) ;
	wndclass.hCursor		= LoadCursor (NULL, IDC_ARROW) ;
	wndclass.hbrBackground	= (HBRUSH) GetStockObject (WHITE_BRUSH) ;
	wndclass.lpszMenuName	= NULL ;
	wndclass.lpszClassName	= szAppName ;

	if (!RegisterClass (&wndclass))
	{
	MessageBox (NULL, TEXT ("This program requires Windows NT!"), 
                  						 szAppName, MB_ICONERROR) ;
		return 0 ;
	}
     
	hwnd = CreateWindow (szAppName, TEXT ("Keyboard Message Viewer #2"),
							WS_OVERLAPPEDWINDOW,
							CW_USEDEFAULT, CW_USEDEFAULT,
							CW_USEDEFAULT, CW_USEDEFAULT,
							NULL, NULL, hInstance, NULL) ;
     
	ShowWindow (hwnd, iCmdShow) ;
	UpdateWindow (hwnd) ;

	while (GetMessage (&msg, NULL, 0, 0))
     	{
			TranslateMessage (&msg) ;
			DispatchMessage (&msg) ;
     	}
	return msg.wParam ;
}

LRESULT CALLBACK WndProc (	HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam)
{
	static DWORD dwCharSet = DEFAULT_CHARSET ;            
	static int   cxClientMax, cyClientMax, cxClient, cyClient, cxChar, cyChar ;
	static int   cLinesMax, cLines ;
	static PMSG  pmsg ;
	static RECT  rectScroll ;
	static TCHAR szTop[] =		TEXT ("Message   Key   Char   ")
								TEXT ("Repeat Scan Ext ALT Prev Tran") ;
	static TCHAR szUnd[] =		TEXT ("_______  ___  ____   ")
								TEXT ("______ ____ ___ ___ ____ ____") ;

	static TCHAR * szFormat[2] = { 
			TEXT ("%-13s %3d %-15s%c%6u %4d %3s %3s %4s %4s"),
			TEXT ("%-13s   0x%04X%1s%c %6u %4d %3s %3s %4s %4s") } ;

	static TCHAR * szYes	= TEXT ("Yes") ;
	static TCHAR * szNo		= TEXT ("No") ;
	static TCHAR * szDown	= TEXT ("Down") ;
	static TCHAR * szUp		= TEXT ("Up") ;

	static TCHAR * szMessage [] = { 
				TEXT ("WM_KEYDOWN"),    TEXT ("WM_KEYUP"), 
				TEXT ("WM_CHAR"),       TEXT ("WM_DEADCHAR"), 
				TEXT ("WM_SYSKEYDOWN"), TEXT ("WM_SYSKEYUP"), 
				TEXT ("WM_SYSCHAR"),    TEXT ("WM_SYSDEADCHAR") } ;
	HDC          hdc ;
	int          i, iType ;
	PAINTSTRUCT  ps ;
	TCHAR        szBuffer[128], szKeyName [32] ;
	TEXTMETRIC   tm ;

	switch (message)
	{
	case	WM_INPUTLANGCHANGE:
		dwCharSet = wParam ;
         // fall through
	case WM_CREATE:
	case WM_DISPLAYCHANGE:
			// Get maximum size of client area
		cxClientMax = GetSystemMetrics (SM_CXMAXIMIZED) ;
		cyClientMax = GetSystemMetrics (SM_CYMAXIMIZED) ;

			// Get character size for fixed-pitch font
		hdc = GetDC (hwnd) ;
		SelectObject (hdc, CreateFont (0, 0, 0, 0, 0, 0, 0, 0,
							dwCharSet, 0, 0, 0, FIXED_PITCH, NULL)) ; 
		GetTextMetrics (hdc, &tm) ;
		cxChar = tm.tmAveCharWidth ;
		cyChar = tm.tmHeight ;

		DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;
		ReleaseDC (hwnd, hdc) ;

			// Allocate memory for display lines
		if (pmsg)
				free (pmsg) ;
		cLinesMax = cyClientMax / cyChar ;
		pmsg = malloc (cLinesMax * sizeof (MSG)) ;
		cLines = 0 ;
			// fall through
	case	WM_SIZE:
		if (message == WM_SIZE)
		{
				cxClient		= LOWORD (lParam) ;
				cyClient		= HIWORD (lParam) ;
		}
				// Calculate scrolling rectangle

		rectScroll.left		= 0 ;
		rectScroll.right	= cxClient ;
		rectScroll.top		= cyChar ;
		rectScroll.bottom	= cyChar * (cyClient / cyChar) ;

		InvalidateRect (hwnd, NULL, TRUE) ;

		if (message == WM_INPUTLANGCHANGE)
				return TRUE ;
		return 0 ;
          
	case WM_KEYDOWN:
	case WM_KEYUP:
	case WM_CHAR:
	case WM_DEADCHAR:
	case WM_SYSKEYDOWN:
	case WM_SYSKEYUP:
	case WM_SYSCHAR:
	case WM_SYSDEADCHAR: 
			// Rearrange storage array
		for (i = cLinesMax - 1 ; i > 0 ; i--)
		{
				pmsg[i] = pmsg[i - 1] ;
 		}
				// Store new message
		pmsg[0].hwnd = hwnd ;
		pmsg[0].message = message ;
		pmsg[0].wParam = wParam ;
		pmsg[0].lParam = lParam ;

		cLines = min (cLines + 1, cLinesMax) ;
				// Scroll up the display
		ScrollWindow (hwnd, 0, -cyChar, &rectScroll, &rectScroll) ;
		break ; 	// ie, call DefWindowProc so Sys messages work
          
	case	WM_PAINT:
		hdc = BeginPaint (hwnd, &ps) ;

		SelectObject (hdc, CreateFont (0, 0, 0, 0, 0, 0, 0, 0,
              							dwCharSet, 0, 0, 0, FIXED_PITCH, NULL)) ; 
		SetBkMode (hdc, TRANSPARENT) ;
	TextOut (hdc, 0, 0, szTop, lstrlen (szTop)) ;
	TextOut (hdc, 0, 0, szUnd, lstrlen (szUnd)) ;

	for (i = 0 ; i < min (cLines, cyClient / cyChar - 1) ; i++)
	{
		iType =	pmsg[i].message == WM_CHAR ||
				pmsg[i].message == WM_SYSCHAR ||
				pmsg[i].message == WM_DEADCHAR ||
				pmsg[i].message == WM_SYSDEADCHAR ;

		GetKeyNameText (pmsg[i].lParam, szKeyName, 
							sizeof (szKeyName) / sizeof (TCHAR)) ;

		TextOut (hdc, 0, (cyClient / cyChar - 1 - i) * cyChar, szBuffer,
				wsprintf (	szBuffer, szFormat [iType],
								szMessage [pmsg[i].message - 
	WM_KEYFIRST],                   
								pmsg[i].wParam,
								(PTSTR) (iType ? TEXT (" ") : szKeyName),
								(TCHAR) (iType ? pmsg[i].wParam : ' '),
								LOWORD (pmsg[i].lParam),
								HIWORD (pmsg[i].lParam) & 0xFF,
								0x01000000 & pmsg[i].lParam ? szYes  : szNo,
								0x20000000 & pmsg[i].lParam ? szYes  : szNo,
								0x40000000 & pmsg[i].lParam ? szDown : szUp,
								0x80000000 & pmsg[i].lParam ? szUp : szDown));
		}
		DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;
		EndPaint (hwnd, &ps) ;
		return 0 ;

	case	WM_DESTROY:
		PostQuitMessage (0) ;
		return 0 ;
	}
	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

ע�⣬�����������Ըı��ᣬKEYVIEW2��������沢���·��䴢��ռ䡣������������ԭ�򣺵�һ����ΪKEYVIEW2������ij������ר�õģ����������Ըı�ʱ�������ֵĴ�СҲ��ı䡣��ʽ��Ҫ��������Ԫ��С���¼���ijЩ�������ڶ����ڽ���ÿ����ԪѶϢʱ��KEYVIEW2������Ч�ر�����Ԫ��ID����ˣ���������������Ըı��ˣ�����KEYVIEW2��Ҫ�ػ���ʾ����ʱ�����е���Ԫ������������ʾ��

��ʮ���½���ϸ�����������Ԫ����������������о����ʻ����⣬������/Platform SDK/Windows Base Services/International Features�ҵ���Ҫ���ļ����������������Ѷ��λ�/Platform SDK/Windows Base Services/General Library/String Manipulation��

������ţ������α꣩
��

��������ʽ����������ʱ��ͨ����һ�����ߡ��������߷�����ָʾ�������һ����Ԫ��������өĻ�ϵ�λ�á������־ͨ����Ϊ���α꡹��������Windows��д��ʽ��������ı����ϰ�ߡ���Windows�У�����Ϊ��������š������α꡹��ָ��ʾ����λ�õ��Ǹ�����ͼͼ��

������ź�ʽ
��

��Ҫ�����������ź�ʽ��

  • CreateCaret���������Ӵ��йصIJ������
    ��
  • SetCaretPos�����Ӵ����趨������ŵ�λ��
    ��
  • ShowCaret����ʾ�������
    ��
  • HideCaret�����ز������
    ��
  • DestroyCaret�������������
    ��

���⻹��ȡ�ò������Ŀǰλ�ã�GetCaretPos����ȡ���Լ��趨���������˸ʱ�䣨GetCaretBlinkTime��SetCaretBlinkTime���ĺ�ʽ��

��Windows�У�������Ŷ���Ϊˮƽ�ߡ�����Ԫ��С��ͬ�ķ��򣬻�������Ԫͬ�ߵ����ߡ����ʹ�õ������壬����Windows�ڶ���ϵͳ���壬���Ƽ�ʹ�����߲�����š���Ϊ���������е���Ԫû�й̶���С��ˮƽ�߻򷽿����趨Ϊ��Ԫ�Ĵ�С��

�����ʽ����Ҫ������ţ���ô����Ӧ�ü򵥵����Ӵ�ѶϢ������ʽ��WM_CREATEѶϢ�����ڼ佨������Ȼ����WM_DESTROYѶϢ�����ڼ䳷������ԭ���Զ��׼���һ��ѶϢ����ֻ��֧Ԯһ��������š���ˣ�������ij�ʽ�ж���Ӵ�����ô�����Ӵ�������Ч�ع�����ͬ�IJ�����š�

��ʵ������������������ô�����ơ���������ͻᷢ�֣�ֻ�����Ӵ������뽹��ʱ���Ӵ�����ʾ������Ų������塣��ʵ�ϣ���˸�IJ������ֻ��һ���Ӿ���ʾ���������ڳ�ʽ���������֡���Ϊ�κ�ʱ��ֻ��һ���Ӵ�ӵ�����뽹�㣬���Զ���Ӵ�ͬʱ������˸�IJ��������û������ġ�

ͨ������WM_SETFOCUS��WM_KILLFOCUSѶϢ����ʽ�Ϳ���ȷ�����Ƿ������뽹�㡣������������ʾ�ģ��Ӵ�ѶϢ������ʽ�������뽹���ʱ����յ�WM_SETFOCUSѶϢ��ʧȥ���뽹���ʱ����յ�WM_KILLFOCUSѶϢ����ЩѶϢ�ɶԳ��֣��Ӵ�ѶϢ������ʽ�ڽ��յ�WM_KILLFOCUSѶϢ֮ǰ��һֱ���յ�WM_SETFOCUSѶϢ���������Ӵ����ڼ䣬���Ӵ����ǽ��յ���ͬ������WM_SETFOCUS��WM_KILLFOCUSѶϢ��

ʹ�ò�����ŵ���Ҫ����ܼ򵥣��Ӵ�ѶϢ������ʽ��WM_SETFOCUSѶϢ�����ڼ����CreateCaret����WM_KILLFOCUSѶϢ�����ڼ����DestroyCaret��

���ﻹ�м����������򣺲�����Ÿս���ʱ�����εġ������ʹ������ſɼ�����ô���ں���CreateCaret֮�ᣬ�Ӵ�ѶϢ������ʽ���������ShowCaret�����⣬���Ӵ�ѶϢ������ʽ����һ����WM_PAINTѶϢ����ϣ�����Ӵ��ڻ���ijЩ����ʱ�����������HideCaret���ز�����š��ڻ�������ᣬ�ٺ���ShowCaret��ʾ������š�HideCaret��Ӱ������ۻ�Ч���������κ���HideCaret��������ShowCaret����ôֻ�к���ShowCaret��ͬ����ʱ�����ܿ���������š�

TYPER��ʽ
��

��ʽ6-5��ʾ��TYPER��ʽʹ���˱������۵��������ݣ���������ΪTYPER��һ���൱�򵥵����ֱ༭�������Ӵ��У�������������Ԫ�����α��ƶ�����Ҳ���Գ�Ϊ��������ƶ��������ƶ��α꣨I�ͱ꣩������Escape������Ӵ������ݵȡ������Ӵ����ı������������ʱ��������Ӵ������ݡ�����ʽû�о�����û������Ѱ�ҺͶ�λ���ܣ����ܴ��浵����û��ƴд��飬����ȷʵ��д��һ�����ֱ༭���Ŀ�ʼ��

 ï¿½ï¿½Ê½6-5  TYPER
TYPER.C
/*------------------------------------------------------------------------
   TYPER.C -- 	Typing Program
         				(c) Charles Petzold, 1998
--------------------------------------------------------------------------*/

#include <windows.h>

#define BUFFER(x,y) *(pBuffer + y * cxBuffer + x)

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
             PSTR szCmdLine, int iCmdShow)
{
	static TCHAR	szAppName[] = TEXT ("Typer") ;
	HWND 			hwnd ;
	MSG  			msg ;
	WNDCLASS		wndclass ;
     
	wndclass.style 					= CS_HREDRAW | CS_VREDRAW ;
	wndclass.lpfnWndProc			= WndProc ;
	wndclass.cbClsExtra 			= 0 ;
	wndclass.cbWndExtra				= 0 ;
	wndclass.hInstance 				= hInstance ;
	wndclass.hIcon					= LoadIcon (NULL, IDI_APPLICATION) ;
	wndclass.hCursor				= LoadCursor (NULL, IDC_ARROW) ;
	wndclass.hbrBackground			= (HBRUSH) GetStockObject (WHITE_BRUSH) ;
	wndclass.lpszMenuName  			= NULL ;
	wndclass.lpszClassName 			= szAppName ;
	if (!RegisterClass (&wndclass))
     {
	MessageBox (	NULL, TEXT ("This program requires Windows NT!"), 
				szAppName, MB_ICONERROR) ;
	return 0 ;
	}
	hwnd = CreateWindow (	szAppName, TEXT ("Typing Program"),
								WS_OVERLAPPEDWINDOW,
								CW_USEDEFAULT, CW_USEDEFAULT,
								CW_USEDEFAULT, CW_USEDEFAULT,
								NULL, NULL, hInstance, NULL) ;
     
	ShowWindow (hwnd, iCmdShow) ;
	UpdateWindow (hwnd) ;
     
	while (GetMessage (&msg, NULL, 0, 0))
	{
			TranslateMessage (&msg) ;
			DispatchMessage (&msg) ;
	}
	return msg.wParam ;
}

LRESULT CALLBACK WndProc (	HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam)
{
	static DWORD		dwCharSet = DEFAULT_CHARSET ;
	static int    		cxChar, cyChar, cxClient, cyClient, cxBuffer, cyBuffer,
					xCaret, yCaret ;
	static TCHAR *	pBuffer = NULL ;
	HDC				hdc ;
	int				x, y, i ;
	PAINTSTRUCT		ps ;
	TEXTMETRIC		tm ;
     
	switch (message)
	{
	case	WM_INPUTLANGCHANGE:
		dwCharSet = wParam ;
		    // fall through
	case	WM_CREATE:
		hdc = GetDC (hwnd) ;
		SelectObject (	hdc, CreateFont (0, 0, 0, 0, 0, 0, 0, 0,
              							dwCharSet, 0, 0, 0, FIXED_PITCH, NULL)) ;
          
		GetTextMetrics (hdc, &tm) ;
		cxChar = tm.tmAveCharWidth ;
		cyChar = tm.tmHeight ;
          
		DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;
		ReleaseDC (hwnd, hdc) ;
             // fall through                
	case	WM_SIZE:
			// obtain window size in pixels

		if (message == WM_SIZE)
		{
				cxClient = LOWORD (lParam) ;
				cyClient = HIWORD (lParam) ;
		}
			// calculate window size in characters
          
		cxBuffer = max (1, cxClient / cxChar) ;
		cyBuffer = max (1, cyClient / cyChar) ;
          
			// allocate memory for buffer and clear it
          
		if (pBuffer != NULL)
				free (pBuffer) ;

		pBuffer = (TCHAR *) malloc (cxBuffer * cyBuffer * sizeof (TCHAR)) ;
          
		for (y = 0 ; y < cyBuffer ; y++)
				for (x = 0 ; x < cxBuffer ; x++)
						 BUFFER(x,y) = ' ' ;

			// set caret to upper left corner

		xCaret = 0 ;
		yCaret = 0 ;
                    
		if (hwnd == GetFocus ())
				SetCaretPos (xCaret * cxChar, yCaret * cyChar) ;

		InvalidateRect (hwnd, NULL, TRUE) ;
		return 0 ;
                    
	case	WM_SETFOCUS:
				// create and show the caret
		CreateCaret (hwnd, NULL, cxChar, cyChar) ;
		SetCaretPos (xCaret * cxChar, yCaret * cyChar) ;
 		ShowCaret (hwnd) ;
		return 0 ;
          
	case WM_KILLFOCUS:
				// hide and destroy the caret
		HideCaret (hwnd) ;
		DestroyCaret () ;
		return 0 ;
          
	case	WM_KEYDOWN:
		switch (wParam)
		{
		case VK_HOME:
				xCaret = 0 ;
				break ;
               
				case	VK_END:
						xCaret = cxBuffer - 1 ;
						break ;
               
				case	VK_PRIOR:
						yCaret = 0 ;
						break ;
               
				case	VK_NEXT:
						yCaret = cyBuffer - 1 ;
						break ;
               
				case	VK_LEFT:
						xCaret = max (xCaret - 1, 0) ;
						break ;
               
			case	VK_RIGHT:
				xCaret = min (xCaret + 1, cxBuffer - 1) ;
				break ;
               
			case	VK_UP:
				yCaret = max (yCaret - 1, 0) ;
				break ;
               
			case	VK_DOWN:
				yCaret = min (yCaret + 1, cyBuffer - 1) ;
				break ;
               
			case	VK_DELETE:
				for (x = xCaret ; x < cxBuffer - 1 ; x++)
						BUFFER (x, yCaret) = BUFFER (x + 1, yCaret) ;
               
				BUFFER (cxBuffer - 1, yCaret) = ' ' ;
               
				HideCaret (hwnd) ;
				hdc = GetDC (hwnd) ;
          
				SelectObject (hdc, CreateFont (0, 0, 0, 0, 0, 0, 0, 0,
									dwCharSet, 0, 0, 0,FIXED_PITCH, NULL)) ;
				TextOut (hdc, xCaret * cxChar, yCaret * cyChar,
								& BUFFER (xCaret, yCaret),
								cxBuffer - xCaret) ;

				DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;
				ReleaseDC (hwnd, hdc) ;
    				ShowCaret (hwnd) ;
   				break ;
		}
		SetCaretPos (xCaret * cxChar, yCaret * cyChar) ;
		return 0 ;
          
	case	WM_CHAR:
		for (i = 0 ; i < (int) LOWORD (lParam) ; i++)
		{
			switch (wParam)
				{
			case '\b':						// backspace
 					if (xCaret > 0)
						{
							xCaret-- ;
							SendMessage (hwnd, WM_KEYDOWN, VK_DELETE, 1) ;
						}
					break ;
                    
		case '\t': 							// tab
				do
					{
						SendMessage (hwnd, WM_CHAR, ' ', 1) ;
					}
				while (xCaret % 8 != 0) ;
				break ;
		case '\n':							// line feed
				if (++yCaret == cyBuffer)
						yCaret = 0 ;
				break ;
                    
		case '\r':							// carriage return
				xCaret = 0 ;
                    
				if (++yCaret == cyBuffer)
						yCaret = 0 ;
				break ;
                    
		case '\x1B':						// escape
				for (y = 0 ; y < cyBuffer ; y++)
				for (x = 0 ; x < cxBuffer ; x++)
						BUFFER (x, y) = ' ' ;
                         
				xCaret = 0 ;
				yCaret = 0 ;
                         
				InvalidateRect (hwnd, NULL, FALSE) ;
				break ;
                         
		default: 							// character codes
			BUFFER (xCaret, yCaret) = (TCHAR) wParam ;
                    
			HideCaret (hwnd) ;
			hdc = GetDC (hwnd) ;
          
			SelectObject (hdc, CreateFont (0, 0, 0, 0, 0, 0, 0, 0,
								dwCharSet, 0, 0, 0, FIXED_PITCH, NULL)) ;
			TextOut (hdc, xCaret * cxChar, yCaret * cyChar,
						& BUFFER (xCaret, yCaret), 1) ;
			DeleteObject (
				SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;
			ReleaseDC (hwnd, hdc) ;
			ShowCaret (hwnd) ;

			if (++xCaret == cxBuffer)
				{
					xCaret = 0 ;
					if (++yCaret == cyBuffer)
							yCaret = 0 ;
				}
			break ;
		}
	}
          
		SetCaretPos (xCaret * cxChar, yCaret * cyChar) ;
		return 0 ;
          
	case	WM_PAINT:
		hdc = BeginPaint (hwnd, &ps) ;
          
		SelectObject (hdc, CreateFont (0, 0, 0, 0, 0, 0, 0, 0,
							dwCharSet, 0, 0, 0, FIXED_PITCH, NULL)) ;
		for (y = 0 ; y < cyBuffer ; y++)
			TextOut (hdc, 0, y * cyChar, & BUFFER(0,y), cxBuffer) ;
		DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))) ;
		EndPaint (hwnd, &ps) ;
		return 0 ;
          
	case	WM_DESTROY:
		PostQuitMessage (0) ;
		return 0 ;
	}
	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

Ϊ�˼������TYPER��ʽʹ��һ�ֵȿ����壬��Ϊ��д����������������ֱ༭��Ҫ���ѵöࡣ��ʽ�ںü����ط�ȡ��װ�����ݣ���WM_CREATEѶϢ�����ڼ䣬��WM_KEYDOWNѶϢ�����ڼ䣬��WM_CHARѶϢ�����ڼ��Լ���WM_PAINTѶϢ�����ڼ䣬ÿ�ζ�ͨ��GetStockObject��SelectObject������ѡ��ȿ����塣

��WM_SIZEѶϢ�����ڼ䣬TYPER�����Ӵ�����Ԫ���Ⱥ͸߶Ȳ���ֵ������cxBuffer��cyBuffer�����У�Ȼ��ʹ��malloc���仺�����Ա������Ӵ��������������Ԫ��ע�⣬��������λԪ���Сȡ���cxBuffer��cyBuffer��sizeof��TCHAR������������1��2��������춳�ʽ����8λԪ����Ԫ����������Unicode��ʽ����ġ�

xCaret��yCaret��������������λ�á���WM_SETFOCUSѶϢ�����ڼ䣬TYPER����CreateCaret����������Ԫ����ͬ���Ⱥ͸߶ȵIJ�����ţ�����SetCaretPos���趨������ŵ�λ�ã�����ShowCaretʹ������ſɼ�����WM_KILLFOCUSѶϢ�����ڼ䣬TYPER����HideCaret��DestroyCaret��

��WM_KEYDOWN�Ĵ������Ҫ�漰�α��ƶ�����Home��End�Ѳ����������һ�еĿ�ʼ��ĩβ����Page Up��Page Down�Ѳ�����������Ӵ��Ķ��˺͵ײ�����ͷ���÷����䡣��Delete����TYPER���������дӲ������֮����Ǹ�λ�ÿ�ʼ����β������������ǰ�ƶ���������β��ʾ�ո�

WM_CHAR����Backspace��Tab��Linefeed��Ctrl-Enter����Enter��Escape����Ԫ����ע�⣬�ڴ���WM_CHARѶϢʱ������ʹ���������ÿ����Ԫ���dz���Ҫ������ʹ����lParam�е��ظ����������ڴ���WM_KEYDOWNѶϢʱȴ����ô���������к����ظ�����������Backspace��Tab�Ĵ������ʹ����SendMessage��ʽ���õ��򻯣�Backspace��Delete������£���Tab����ͬ���������ɸ��ո�

ǰ�����Ѿ��ᵽ�����ڷ�WM_PAINTѶϢ�����ڼ䣬���Ҫ���Ӵ��л������ݣ���Ӧ�������αꡣTYPERΪDelete������WM_KEYDOWNѶϢ��Ϊ��Ԫ������WM_CHARѶϢʱ������ˡ�������������£�TYPER�ı仺�����е����ݣ�Ȼ�����Ӵ��л���һ�����߶������Ԫ��

��ȻTYPERʹ������KEYVIEW2��ͬ������������Ԫ��֮���л�������ʹ�����л����̲���һ�����������Զ�����Windows�������Dz�������������TYPER������ʹ���������ȵ���Ԫ�������⽫�ڵ�ʮ�������ۣ���ʱ���ǽ���ϸ�������������������