I czelion’s Tutorial Win32 ASM Tutorial 6 : Keyboard I nput
Nhp liu t bàn phím
Trong các bài trước, thông qua các đối tượng GDI, chúng ta đã làm quen cách
chương trình Windows to nhng kết xut đồ ha không s dng đến nhng d liu do
người s dng đưa vào. Nhng tin ích có sn đối vi nhng kết xut đồ ha như thế
được xem như cp cao (high-level): nhiu hình nh đồ ha tinh vi cu k có th được
to ra mt cách dng. Nếu không có GDI, th hi bn s b bao nhiêu công sc để đi
đến kết qu như trên.
Trong bài này, tôi và bn s cùng tìm hiu v vn đề nhp liu t nhng thiết b
Windows c th là bàn phím (keyboard), xem các chương trình Windows gii quyết thế
nào vn đề nhp liu. Ngược li đối vi kết xut cp cao ca GDI, dng nhp liu thông
qua keyboard, mouse được xem như cp thp (low-level), nghĩa là nhp liu tn
phím (người s dng n mt phím trên bàn phím) s đến dưới dng nhng lot thông đip
riêng r ca tng phím gõ (keystroke) vi 2 hoc 3 thông đip được phát sinh t mt
phím được n xung.
Nn tng cơ s v bàn phím
HĐH tiếp nhn và x lý thông tin nhn được t bàn phím, qua hình thc các thông
đip và gi cho ng dng. Trong ng dng Windows các thông đip s được h điu hành
chuyn cho hàm x lý ca s WndProc ca ng dng.
Windows cung cp 8 loi thông đip khác nhau để phân bit các tình hung ca các phím
được gõ. Tuy nhiên không phi lúc nào chúng ta cũng phi x lý toàn b các thông đip đó,
thông thường thì ch cn x lý mt na các thông đip được phát sinh t bàn phím, và các
thông đip còn li s được Windows x lý mc định.
Ví d, trong Windows có th b qua khi nhn phím Ctrl, Alt, Shift cùng vi các phím khác,
nếu không mun chn để x lý riêng cho ng dng. Trong trường hp nếu chúng ta mun
chn để x lý riêng cho mình, chng hn to phím nóng (hotkey) phi chú ý tránh dùng trùng
hp vi các phím nóng mà Windows cung cp. Vì khi đó theo quyn ưu tiên, ng dng ca
chúng ta s x lý thông đip đó và s làm cho h thng không hot động như bình thường.
Thành phn giao tiếp chung như hp thoi (dialog) cũng có nhiu giao tiếp vi bàn phím,
nhưng chúng ta không cn quan tâm đến vic giao tiếp vi bàn phím khi hp thoi được kích
hot. X lý bàn phím trong hp thoi thường được giao cho Windows x lý. Các điu khin
được dùng trong hp thoi như hp nhp liu (edit box), hp la chn (check box), hay các
nút nhn (button)...điu có kh năng t x lý phím gõ vào và ch tr li thông báo ca các
phím gõ cho ca s cha (parent window). Tuy vy, vi mt s các điu khin nht định theo
ng dng ta có th phi x lý các thông đip để tăng cường thêm sc mnh ca thành phn
điu khin này.
m li trong các ng dng được cu thành t các thành phn điu khin cơ bn này thì
chúng ta không quan tâm đến vic x lý các thông đip t bàn phím.
Người dch: Benina (REA TEAM) Trang 1
Tng hp và hiu chnh: NhatPhuongLe (VNCERT TEAM)
I czelion’s Tutorial Win32 ASM Tutorial 6 : Keyboard I nput
Input Focus
Windows đưa ra khái nim focus (s quan tâm) cho các ng dng được chy đồng
thi ti mt thi đim. Vì ch có mt bàn phím, nên Windows phi qun lý và phân phi các
thông đip được gõ vào cho các ng dng. Thông thường, có các trường hp trên Windows
là : mt trong s các ng dng đang chy được active (kích hot) hay không có ng dng nào
chy. Khi có mt chương trình ng dng được kích hot thì Windows xem như ng dng đó
nhn được s quan tâm.Trong mt ng dng có nhiu các ca s, mi thi đim ch mt ca
s nhn được s quan tâm. Theo cơ chế này, Windows cung cp mt dng gi là hàng đợi
thông đip. Mi thông đip s được đưa vào hàng đợi x lý thông đip và được Windows
phân phi đến các ng dng tương ng.
Hàm DispatchMessage trong vòng lp x lý thông đip s chu trách nhim chuyn thông
đip đến th tc x lý ca s WndProc ca các ca s tương ng.
Mt ca s có th xác định được trng thái quan tâm ca mình bng cách chn các thông đip
WM_SETFOCUS, WM_KILLFOCUS trong hàm xWndProc. Thông đip
WM_SETFOCUS s cho ca s biết được thi đim nhn được quan tâm ca Windows và
ngược li WM_KILLFOCUS s thông báo cho ca s biết được đã mt s quan tâm t
Windows. Phn sau s gii thiu k hơn v x lý thông đip.
Cơ chế hàng đợi và qun lý hàng đợi
Trong Windows khi người dùng nhn và nh phím trên bàn phím, thì thông qua trình
điu khin thiết b bàn phím (keyboard driver) s din dch mã quét (scan code) ca phn
cng sang hình thc thông đip. Trước hết Windows s tm thi lưu tr thông đip này vào
hàng đợi thông đip ca h thng (system message queue). Hàng đợi thông đip h thng ca
Windows là mt hàng đợi duy nht và qun lý các thao tác tin x lý thông tin nhp t bàn
phím và chut. Windows s ln lượt ly các thông đip trong hàng đợi x lý và s gi đến
hàng đợi ca ng dng khi ng dng đã x lý xong thông đip bàn phím và thiết b chut
trước đó.
Quá trình x lý bàn phím
Người dch: Benina (REA TEAM) Trang 2
Tng hp và hiu chnh: NhatPhuongLe (VNCERT TEAM)
I czelion’s Tutorial Win32 ASM Tutorial 6 : Keyboard I nput
Lý do mà Windows phi chia thành hai giai đon trong quá trình nhn và gi thông đip t
bàn phím đến hàng đợi ca ng dng là do vic đồng b hóa vi mi tiến trình. Nếu
Windows không qun lý hàng đợi h thng thì rt khó đồng b các tiến trình ca các ng
dng. Ví d, khi mt ca s nhn được s quan tâm chun b x lý các thông đip. Người
dùng có th gõ phím nhanh trong khi thông đip trước vn chưa x lý xong. Gi s người
dùng mun chuyn qua ng dng khác và nhn Alt-Tab, khi đó thông đip bàn phím mi
này s được đưa vào hàng đợi ca h thng và phân phát cho ng dng kia ch không phi
đưa vào hàng đợi ca ng dng. Vi tính năng đồng b hóa ca Windows thì các thông đip
t bàn phím đảm bo được chuyn giao đúng cho các ca s tương ng.
X lý thông đip t bàn phím
Thao tác căn bn ca nhp liu t bàn phím là thao tác nhn và nh mt phím. Khi
thao tác nhn mt phím trên bàn phím được thc hin thì Windows s phát sinh thông đip
WM_KEYDOWN hay WM_SYSKEYDOWNđưa vào hàng đợi thông đip ca ng
dng hay ca s nhn được s quan tâm (focus). Cũng tương t, khi ta nh phím thì thông
đip WM_KEYUP hay WM_SYSKEYUP s được h điu hành phân phát ti hàng đợi đó.
Khi thc hin thao tác nhp t bàn phím thì vic nhn (down) và nh (up) phi đi đôi vi
nhau. Tuy nhiên, nếu chúng ta nhn mt phím và gi luôn thì Windows s phát sinh hàng lot
các thông đip WM_KEYDOWN hay WM_SYSKEYDOWN, nhưng vi thao tác nh thì
ch phát sinh mt thông đip WM_KEYUP hay WM_SYSKEYUP. Các thông đip này s
được gi tun t đến các hàm WndProc ca các c s nhn được s quan tâm ca Windows.
Ngoài ra chúng ta có th biết được thi đim mà thông đip phím đưc gõ vào lúc nào bng
cách dùng hàm GetMessageTime.
Như chúng ta đã thy trong dòng trên mt thao tác nhn hay th thì có hai dng thông đip
khác nhau như WM_KEYDOWNWM_SYSKEYDOWN ca thao tác nhn, và tương t
đối vi thao tác nh. Thông đip có tiếp đầu ng là "SYS" thường được phát sinh khi người
dùng nhn các phím gõ h thng. Khi người dùng nhn phím Alt kết hp vi phím khác thì
thường phát sinh thông đip WM_SYSKEYDOWNWM_SYSKEYUP. Đối vi t hp
các phím Alt, chc năng thường là gi mt mc chn trên trình đơn menu ca ng dng hay
trình đơn h thng system menu và ngoài ra dùng để chuyn đổi các tác v gia nhiu ng
dng khác nhau (phím Alt+Tab hay Alt+Esc), và đóng ca s ng dng khi kết hp vi
phím chc năng F4.
Khi xây dng mt chương trình ng dng, thường ít quan tâm đến các thông đip
WM_SYSKEYDOWN và thông đip WM_SYSKEYUP. Chúng ta ch cn dùng hàm
DefWindowProc cui mi hàm WndProc ca ca s nhn thông đip. Windows s chu
trách nhim x lý các thông đip dng h thng này, nếu có nhng tác v đặc bit thì chúng
ta có th chn các thông đip này để x lý. Tuy nhiên ta không nên làm như vy vì khi đó
chương trình ca chúng ta s chy không bình thường như các ng dng khác. Không phi
chúng ta giao phó hoàn toàn cho Windows x lý các thông đip h thng ca ng dng, mà
Windows s x lý các thông đip h thng này và đưa ra các thông đip bình thường khác
đến ng dng. Ví d khi nhn phím Alt+Tab thì Windows s to mt thông đip h thng
gi vào hàng đợi ca ng dng và khi không x lý thông đip này thì theo mc định hàm
DefWindowProc s x lý và tr v thông đip WM_KILLFOCUS cho ng dng, khi đó
ng dng ca chúng ta s d dàng x lý hơn.
Người dch: Benina (REA TEAM) Trang 3
Tng hp và hiu chnh: NhatPhuongLe (VNCERT TEAM)
I czelion’s Tutorial Win32 ASM Tutorial 6 : Keyboard I nput
Tóm li thông đip WM_KEYDOWN WM_KEYUP thường được sinh ra bi các phím
nhn thông thường không kết hp vi phím Alt. Nếu chương trình ca chúng ta b qua
không x lý các thông đip này thì Windows cũng không to ra các thông đip hay x lý gì
đặc bit.
Bng mô t các thông đip phát sinh t bàn phím:
Thông đip Nguyên nhân phát sinh
WM_ACTIVATE Thông đip này cùng được gi đến các ca s b kích hot và ca s
không b kích hot. Nếu các ca s này cùng mt hàng đợi nhp liu,
các thông đip này s được truyn mt cách đồng b, đầu tiên th
tc Windows ca ca s trên cùng b mt kích hot, sau đó đến th
tc ca ca s trên cùng được kích hot. Nếu các ca s này không
nm trong cùng mt hàng đợi thì thông đip s được gi mt cách
không đồng b, do đó ca s s được kích hot ngay lp tc.
WM_APPCOMMAND Thông báo đến ca s rng người dùng đã to mt s kin lnh ng
dng, ví d khi người dùng kích vào button s dng chut hay đánh
vào mt kí t kích hot mt lnh ca ng dng.
WM_CHAR Thông đip này được gi ti ca s có s quan tâm khi thông đip
WM_KEYDOWN đã được dch t hàm TranslateMessage. Thông
đip WM_CHAR có cha mã kí t ca phím được nhn.
WM_DEADCHAR Thông đip này được gi ti ca s có s quan tâm khi thông đip
WM_KEYUP đã được x lý t hàm TranslateMessage. Thông đip
này xác nhn mã kí t khi mt phím dead key được nhn. Phím dead
key là phím kết hp để to ra kí t ngôn ng không có trong tiếng
anh (xut hin trong bàn phím h tr ngôn ng khác tiếng Anh).
WM_GETHOTKEY ng dng gi thông đip này để xác định mt phím nóng liên quan
đến mt ca s. Để gi thông đip này thì dùng hàm SendMessage.
WM_HOTKEY Thông đip này được gi khi người dùng nhn mt phím nóng được
đăng kí trong RegisterHotKey.
WM_KEYDOWN Thông đip này được gi cho ca s nhn được s quan tâm khi
người dùng nhn mt phím trên bàn phím. Phím này không phi
phím h thng (Phím không có nhn phím Alt).
WM_KEYUP
Thông đip này được gi cho ca s nhn được s quan tâm khi
người dùng nh mt phím đã được nhn trước đó.Phím này không
phi phím h thng (Phím không có nhn phím Alt).
WM_KILLFOCUS Thông đip này được gi ti ca s đang nhn được s quan tâm
trước khi nó mt quyn này.
WM_SETFOCUS Thông đip này được gi ti ca s sau khi ca s nhn được s
quan tâm ca Windows
Người dch: Benina (REA TEAM) Trang 4
Tng hp và hiu chnh: NhatPhuongLe (VNCERT TEAM)
I czelion’s Tutorial Win32 ASM Tutorial 6 : Keyboard I nput
WM_SETHOTKEY ng dng s gi thông đip này đến ca s liên quan đến phím
nóng, khi người dùng nhn mt phím nóng thì ca s tương ng liên
quan ti phím nóng này s được kích hot.
WM_SYSCHAR Thông đip này s được gi ti ca s nhn được s quan tâm khi
hàm TranslateMesage x lý xong thông đip
WM_SYSKEYDOWN. Thông đip WM_SYSCHAR cha mã ca
phím h thng. Phím h thng là phím có cha phím Alt và t hp
phím khác.
WM_SYSDEADCHAR Thông đip này được gi ti ca s nhn được s quan tâm khi mt
thông đip WM_SYSKEYDOWN được biên dch trong hàm
TranslateMessage. Thông đip này xác nhn mã kí t ca phím h
thng deadkey được nhn.
WM_SYSKEYDOWN Thông đip này được gi ti ca s nhn được s quan tâm khi
người dùng nhn phím F10 hay nhn Alt trước khi nhn phím khác.
Thông đip này cũng được gi khi không có ca s nào nhn được
s quan tâm và lúc này thì ca s nhn được là ca s đang được
kích hot (Active).
WM_SYSKEYUP Thông đip này được gi ti ca s nhn được s quan tâm khi
người dùng nhn mt phím mà trước đó đã gi phím Alt. Cũng
tương t nếu không có ca s nào nhn được s quan tâm thì thông
đip này s được gi cho ca s đang được kích hot.
Mã phím áo (Virtual Key Code)
Windows cung cp khái nim phím o nhm tách ri vi thiết b bàn phím hay nói
cách khác là tiến ti độc lp thiết b vi bàn phím. Khi mt phím được nhn thì phn cng
vt lý phát sinh ra mt mã quét (scan code), trên bàn phím tương thích IBM các phím
được gán vi các mã ví d phím W 17, phím E 18, và phím R 19... Cách sp xếp
này thun túy da trên v trí vt lý ca phím trên bàn phím. Nhng người xây dng nên
Windows nhn thy rng nếu dùng trc tiếp mã quét thì s không thích hp khi b l
thuc vào bàn phím hin ti và tương lai. Do đó h c x lý bàn phím bng cách độc lp
thiết b hơn, bng cách to ra mt bng định nghĩa tp giá tr phím tng quát mà sau này
được gi là mã phím o. Mt s giá tr bàn phím o mà ta không thy xut hin trên bàn
phím IBM tương thích nhưng có th tìm thy chúng trong bàn phím ca các nhà sn xut
khác hay chúng đưc để dành cho bàn phím trong tương lai. Các giá tr ca phím o này
đưc định nghĩa trong tp tin tiêu đề WINUSER.Hđược bt đầu vi các tiếp đầu ng
VK_xxxxx. sau đây là bng mô t các phím o thông dng trong Windows giao tiếp vi
bàn phím IBM tương thích.
Người dch: Benina (REA TEAM) Trang 5
Tng hp và hiu chnh: NhatPhuongLe (VNCERT TEAM)