?? 見招拆招windows程序設(shè)計(五).txt
字號:
內(nèi)容代碼
右按鍵時,假如同時壓下ALT鍵,那么內(nèi)容代碼為1。對WM_SYSKEYUP與WM_SYSKEYDOWN而言,此位總視為1;而對WM_SYSKEYUP與WM_KEYDOW消息而言,此位為0。除了兩個之外:
如果活動窗口最小化了,則它沒有輸入焦點。這時候所有的按鍵都會產(chǎn)生WM_SYSKEYUP和WM_SYSKEYDOWN消息。如果Alt鍵未被按下,則內(nèi)容代碼字段被設(shè)定為0。Windows使用WM_SYSKEYUP和WM_SYSKEYDOWN消息,從而使最小化了的活動窗口不處理這些按鍵。
對于一些外國語文(非英文)鍵盤,有些字符是通過Shift、Ctrl或者Alt鍵與其它鍵相組合而產(chǎn)生的。這時內(nèi)容代碼為1,但是此消息并非系統(tǒng)按鍵消息。
鍵的先前狀態(tài)
如果在此之前鍵是釋放的,則鍵的先前狀態(tài)為0,否則為1。對WM_KEYUP或者WM_SYSKEYUP消息,它總是設(shè)定為1;但是對WM_KEYDOWN或者WM_SYSKEYDOWN消息,此位可以為0,也可以為1。如果為1,則表示該鍵是自動重復(fù)功能所產(chǎn)生的第二個或者后續(xù)消息。
轉(zhuǎn)換狀態(tài)
如果鍵正被按下,則轉(zhuǎn)換狀態(tài)為0;如果鍵正被釋放,則轉(zhuǎn)換狀態(tài)為1。對WM_KEYDOWN或者WM_SYSKEYDOWN消息,此字段為0;對WM_KEYUP或者WM_SYSKEYUP消息,此字段為1。
位移狀態(tài)
在處理按鍵消息時,您可能需要知道是否按下了位移鍵(Shift、Ctrl和Alt)或開關(guān)鍵(Caps Lock、Num Lock和Scroll Lock)。通過調(diào)用GetKeyState函數(shù),您就能獲得此信息。例如:
iState = GetKeyState (VK_SHIFT) ;
如果按下了Shift,則iState值為負(即設(shè)定了最高位置位)。如果Caps Lock鍵打開,則從
iState = GetKeyState (VK_CAPITAL) ;
傳回的值低位被設(shè)為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,您也可以獲得鼠標鍵的狀態(tài)。不過,大多數(shù)需要監(jiān)視鼠標鍵與按鍵相組合的Windows應(yīng)用程序都使用其它方法來做到這一點-即在接收到鼠標消息時檢查按鍵。實際上,位移狀態(tài)信息包含在鼠標信息中。
請注意GetKeyState的使用,它并非實時檢查鍵盤狀態(tài),而只是檢查直到目前為止正在處理的消息的鍵盤狀態(tài)。多數(shù)情況下,這正符合您的要求。如果您需要確定使用者是否按下了Shift-Tab,請在處理Tab鍵的WM_KEYDOWN消息時呼叫GetKeyState,帶有參數(shù)VK_SHIFT。如果GetKeyState傳回的值為負,那么您就知道在按下Tab鍵之前按下了Shift鍵。并且,如果在您開始處理Tab鍵之前,已經(jīng)釋放了Shift鍵也沒有關(guān)系。您知道,在按下Tab鍵的時候Shift鍵是按下的。
GetKeyState不會讓您獲得獨立于普通鍵盤消息的鍵盤信息。例如,您或許想暫停窗口消息處理程序的處理,直到您按下F1功能鍵為止:
while (GetKeyState (VK_F1) >= 0) ; // WRONG !!!
不要這么做!這將讓程序當死(除非在執(zhí)行此敘述之前早就從消息隊列中接收到了F1的WM_KEYDOWN)。如果您確實需要知道目前某鍵的狀態(tài),那么您可以使用GetAsyncKeyState。
使用按鍵消息
如果程序能夠獲得每個按鍵的信息,這當然很理想,但是大多數(shù)Windows程序忽略了幾乎所有的按鍵,而只處理部分的按鍵消息。WM_SYSKEYDOWN和WM_SYSKEYUP消息是由Windows系統(tǒng)函數(shù)使用的,您不必為此費心,就算您要處理WM_KEYDOWN消息,通常也可以忽略WM_KEYUP消息。
Windows程序通常為不產(chǎn)生字符的按鍵使用WM_KEYDOWN消息。雖然您可能認為借助按鍵消息和位移鍵狀態(tài)信息能將按鍵消息轉(zhuǎn)換為字符消息,但是不要這么做,因為您將遇到國際鍵盤間的差異所帶來的問題。例如,如果您得到wParam等于0x33的WM_KEYDOWN消息,您就可以知道使用者按下了鍵3,到此為止一切正常。這時,如果用GetKeyState發(fā)現(xiàn)Shift鍵被按下,您就可能會認為使用者輸入了#號,這可不一定。比如英國使用者就是在輸入£。
對于光標移動鍵、功能鍵、Insert和Delete鍵,WM_KEYDOWN消息是最有用的。不過, Insert、Delete和功能鍵經(jīng)常作為菜單快捷鍵。因為Windows能把菜單快捷鍵翻譯為菜單命令消息,所以您就不必自己來處理按鍵。
在Windows之前的MS-DOS應(yīng)用程序中大量使用功能鍵與Shift、Ctrl和Alt鍵的組合,同樣地,您也可以在Windows程序中使用(實際上,Microsoft Word將大量的功能鍵用作命令快捷方式),但并不推薦這樣做。如果您確實希望使用功能鍵,那么這些鍵應(yīng)該是重復(fù)菜單命令。Windows的目標之一就是提供不需要記憶或者使用復(fù)雜命令流程的使用者接口。
因此,可以歸納如下:多數(shù)情況下,您將只為光標移動鍵(有時也為Insert和Delete鍵)處理WM_KEYDOWN消息。在使用這些鍵的時候,您可以通過GetKeyState來檢查Shift鍵和Ctrl鍵的狀態(tài)。例如,Windows程序經(jīng)常使用Shift與光標鍵的組合鍵來擴大文書處理里選中的范圍。Ctrl鍵常用于修改光標鍵的意義。例如,Ctrl與右箭頭鍵相組合可以表示光標右移一個字。
決定您的程序中使用鍵盤方式的最佳方法之一是了解現(xiàn)有的Windows程序使用鍵盤的方式。如果您不喜歡那些定義,當然可以對其加以修改,但是這樣做不利于其它人很快地學(xué)會使用您的程序。
為SYSMETS加上鍵盤處理功能
在編寫前面三個版本的SYSMETS程序時,我們還不了解鍵盤,只能使用滾動條和鼠標來卷動文字。現(xiàn)在我們知道了處理鍵盤消息的方法,那么不妨在程序中加入鍵盤接口。顯然,這是處理光標移動鍵的工作。我們將大多數(shù)光標鍵(Home、End、Page Up、Page Down、Up Arrow和Down Arrow)用于垂直卷動,左箭頭鍵和右箭頭鍵用于不太重要的水平卷動。
建立鍵盤接口的一種簡單方法是在窗口消息處理程序中加入與WM_VSCROLL和WM_HSCROLL處理方式相仿,而且本質(zhì)上相同的WM_KEYDOWN處理方法。不過這樣子做是不聰明的,因為如果要修改滾動條的做法,就必須相對應(yīng)地修改WM_KEYDOWN。
為什么不簡單地將每一種WM_KEYDOWN消息都翻譯成同等效用的WM_VSCROLL或者WM_HSCROLL消息呢?通過向窗口消息處理程序發(fā)送假冒消息,我們可能會讓W(xué)ndProc認為它獲得了卷動信息。
在Windows中,這種方法是可行的。發(fā)送消息的函數(shù)叫做SendMessage,它所用的參數(shù)與傳遞到窗口消息處理程序的參數(shù)是相同的:
SendMessage (hwnd, message, wParam, lParam) ;
在呼叫SendMessage時,Windows呼叫窗口句柄為hwnd的窗口消息處理程序,并把這四個參數(shù)傳給它。當窗口消息處理程序完成消息處理之后,Windows把控制傳回到SendMessage呼叫之后的下一道敘述。您發(fā)送消息過去的窗口消息處理程序,可以是同一個窗口消息處理程序、同一程序中的其它窗口消息處理程序或者其它應(yīng)用程序,中的窗口消息處理程序。
下面說明在SYSMETS程序中使用SendMessage處理WM_KEYDOWN代碼的方法:
caseWM_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 ;
至此,您已經(jīng)有了大概觀念了吧。我們的目標是為滾動條添加鍵盤接口,并且也正在這么做。通過把卷動消息發(fā)送到窗口消息處理程序,我們實作了用光標移動鍵進行卷動列的功能。現(xiàn)在您知道在SYSMETS3中為WM_VSCROLL消息加上SB_TOP和SB_BOTTOM處理碼的原因了吧。在那里并沒有用到它,但是現(xiàn)在處理Home和End鍵時就有用了。如程序6-1所示的SYSENTS4就加上了這些變化。
程序6-1 SYSMETS4
SYSMETS4.ASM
;MASMPlus 代碼模板 - 普通的 Windows 程序代碼
.386
.Model Flat, StdCall
Option Casemap :None
Include windows.inc
Include user32.inc
Include kernel32.inc
Include gdi32.inc
Include winmm.inc
includelib gdi32.lib
IncludeLib user32.lib
IncludeLib kernel32.lib
IncludeLib winmm.lib
include macro.asm
WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
NUMLINES equ (sysmetricsEnd - sysmetrics) / 4 /3
.DATA
szAppName db "SysMets4",0
szShow01 db "SM_CXSCREEN",0
szShow02 db "Screen width in pixels",0
szShow03 db "SM_CYSCREEN",0
szShow04 db "Screen height in pixels",0
szShow05 db "SM_CXVSCROLL",0
szShow06 db "Vertical scroll width",0
szShow07 db "SM_CYHSCROLL",0
szShow08 db "Horizontal scroll height",0
szShow09 db "SM_CYCAPTION",0
szShow10 db "Caption bar height",0
szShow11 db "SM_CXBORDER",0
szShow12 db "Window border width",0
szShow13 db "SM_CYBORDER",0
szShow14 db "Window border height",0
szShow15 db "SM_CXFIXEDFRAME",0
szShow16 db "Dialog window frame width",0
szShow17 db "SM_CYFIXEDFRAME",0
szShow18 db "Dialog window frame height",0
szShow19 db "SM_CYVTHUMB",0
szShow20 db "Vertical scroll thumb height",0
szShow21 db "SM_CXHTHUMB",0
szShow22 db "Horizontal scroll thumb width",0
szShow23 db "SM_CXICON",0
szShow24 db "Icon width",0
szShow25 db "SM_CYICON",0
szShow26 db "Icon height",0
szShow27 db "SM_CXCURSOR",0
szShow28 db "Cursor width",0
szShow29 db "SM_CYCURSOR",0
szShow30 db "Cursor height",0
szShow31 db "SM_CYMENU",0
szShow32 db "Menu bar height",0
szShow33 db "SM_CXFULLSCREEN",0
szShow34 db "Full screen client area width",0
szShow35 db "SM_CYFULLSCREEN",0
szShow36 db "Full screen client area height",0
szShow37 db "SM_CYKANJIWINDOW",0
szShow38 db "Kanji window height",0
szShow39 db "SM_MOUSEPRESENT",0
szShow40 db "Mouse present flag",0
szShow41 db "SM_CYVSCROLL",0
szShow42 db "Vertical scroll arrow height",0
szShow43 db "SM_CXHSCROLL",0
szShow44 db "Horizontal scroll arrow width",0
szShow45 db "SM_DEBUG",0
szShow46 db "Debug version flag",0
szShow47 db "SM_SWAPBUTTON",0
szShow48 db "Mouse buttons swapped flag",0
szShow49 db "SM_CXMIN",0
szShow50 db "Minimum window width",0
szShow51 db "SM_CYMIN",0
szShow52 db "Minimum window height",0
szShow53 db "SM_CXSIZE",0
szShow54 db "Min/Max/Close button width",0
szShow55 db "SM_CYSIZE",0
szShow56 db "Min/Max/Close button height",0
szShow57 db "SM_CXSIZEFRAME",0
szShow58 db "Window sizing frame width",0
szShow59 db "SM_CYSIZEFRAME",0
szShow60 db "Window sizing frame height",0
szShow61 db "SM_CXMINTRACK",0
szShow62 db "Minimum window tracking width",0
szShow63 db "SM_CYMINTRACK",0
szShow64 db "Minimum window tracking height",0
szShow65 db "SM_CXDOUBLECLK",0
szShow66 db "Double click x tolerance",0
szShow67 db "SM_CYDOUBLECLK",0
szShow68 db "Double click y tolerance",0
szShow69 db "SM_CXICONSPACING",0
szShow70 db "Horizontal icon spacing",0
szShow71 db "SM_CYICONSPACING",0
szShow72 db "Vertical icon spacing",0
szShow73 db "SM_MENUDROPALIGNMENT",0
szShow74 db "Left or right menu drop",0
szShow75 db "SM_PENWINDOWS",0
szShow76 db "Pen extensions installed",0
szShow77 db "SM_DBCSENABLED",0
szShow78 db "Double-Byte Char Set enabled",0
szShow79 db "SM_CMOUSEBUTTONS",0
szShow80 db "Number of mouse buttons",0
szShow81 db "SM_SECURE",0
szShow82 db "Security present flag",0
szShow83 db "SM_CXEDGE",0
szShow84 db "3-D border width",0
szShow85 db "SM_CYEDGE",0
szShow86 db "3-D border height",0
szShow87 db "SM_CXMINSPACING",0
szShow88 db "Minimized window spacing width",0
szShow89 db "SM_CYMINSPACING",0
szShow90 db "Minimized window spacing height",0
szShow91 db "SM_CXSMICON",0
szShow92 db "Small icon width",0
szShow93 db "SM_CYSMICON",0
szShow94 db "Small icon height",0
szShow95 db "SM_CYSMCAPTION",0
szShow96 db "Small caption height",0
szShow97 db "SM_CXSMSIZE",0
szShow98 db "Small caption button width",0
szShow99 db "SM_CYSMSIZE",0
szShow100 db "Small caption button height",0
szShow101 db "SM_CXMENUSIZE",0
szShow102 db "Menu bar button width",0
szShow103 db "SM_CYMENUSIZE",0
szShow104 db "Menu bar button height",0
szShow105 db "SM_ARRANGE",0
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -