版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、CodeBlockCodeBlock下的人機(jī)交互界面設(shè)計人機(jī)交互界面指的是計算機(jī)系統(tǒng)與用戶之間的接口。通過該接口,一方面,計算機(jī)系統(tǒng)向用戶輸出系統(tǒng)的運(yùn)行狀態(tài)、運(yùn)行控制和運(yùn)行結(jié)果等方面信息;另一方面,用戶根據(jù)輸出信息向系統(tǒng)輸入相應(yīng)的指令和數(shù)據(jù)等信息。3.4.1控制臺窗口和屏幕緩沖區(qū)控制臺窗口是個二維平面空間,其坐標(biāo)系統(tǒng)的原點(0,00,0)設(shè)在窗口左上角,即窗口第一行第一列字符單元的位置。橫軸(X X 軸)的正向沿原點向右,與窗口的第一行重合,每刻度為一個字符寬度;縱軸(Y Y 軸)的正向沿原點向下,與窗口的第一列重合,每刻度為一個字符高度。窗口中每個字符單元對應(yīng)一個二維坐標(biāo)。比如,第 5 行第
2、 32 列字符單元的坐標(biāo)為(31,4)。如圖 3.8 所示。圖3.8控制臺窗口和屏幕緩沖區(qū)關(guān)系示意圖屏幕緩沖區(qū)是個二維數(shù)組,邏輯上可看作一個二維平面空間。數(shù)組第一個元素的下標(biāo)0000對應(yīng)此平面空間坐標(biāo)系統(tǒng)的原點(0,00,0), ,數(shù)組第 1 1 維的下標(biāo)對應(yīng)坐標(biāo)系統(tǒng)的縱坐標(biāo)(Y Y 坐標(biāo)),第 2 2 維下標(biāo)對應(yīng)坐標(biāo)系統(tǒng)的橫坐標(biāo) (X X 坐標(biāo)) 。 屏幕緩沖區(qū)存放著 M 行 N 列字符單元的信息, M 和 N 的大小由系統(tǒng)設(shè)置,并可以進(jìn)行修改。每個字符單元信息用一個 CHAR_INFOCHAR_INFO 結(jié)構(gòu)類型的數(shù)據(jù)來表示,結(jié)構(gòu)成員 CharChar 存放字符的碼值(Unicode碼或
3、ASCII 碼,取決于系統(tǒng)所采用的字符集),結(jié)構(gòu)成員 AttributesAttributes 存放字符的屬性(字符顯示所用的前景色和背景色)。操作系統(tǒng)以一定的頻率從屏幕緩沖區(qū)讀取字符單元信息,并顯示在控制臺窗口中。應(yīng)用程序的輸出信息實際上輸出到了屏幕緩沖區(qū),由此改變了控制臺窗口所顯示的內(nèi)容。初始狀態(tài)下,屏幕緩沖區(qū)坐標(biāo)系統(tǒng)與控制臺窗口坐標(biāo)系統(tǒng)重合,窗口中第 m 行第 n 列字符的碼值和顏色值存放在屏幕緩沖區(qū)二維數(shù)組中下標(biāo)為m-1n-1的元素中。利用控制臺函數(shù)可以改變這兩個坐標(biāo)系統(tǒng)的對應(yīng)關(guān)系,實現(xiàn)特殊的顯示效果。圖 3.8 表示了控制臺窗口和屏幕緩沖區(qū)的相互關(guān)系。一個控制臺可擁有多個屏幕緩沖區(qū),
4、但只有處于激活狀態(tài)的屏幕緩沖區(qū)內(nèi)容顯示在控制臺窗口中。操作系統(tǒng)在為進(jìn)程創(chuàng)建控制臺的同時會創(chuàng)建一個屏幕緩沖區(qū)。進(jìn)程可調(diào)用函數(shù) CreateConsoleScreenBufferCreateConsoleScreenBuffer 為其控制臺創(chuàng)建另外的屏幕緩沖區(qū)。調(diào)用函數(shù) SetConsoleActiveScreenBufferSetConsoleActiveScreenBuffer 可以將某個已有的屏幕緩沖區(qū)置為激活狀態(tài),使其內(nèi)容顯示在屏幕窗口中。不管是否處于激活狀態(tài),屏幕緩沖區(qū)都可以通過句柄來進(jìn)行讀寫操作,只不過激活狀態(tài)下屏幕緩沖區(qū)的內(nèi)容可以看到,非激活狀態(tài)下看不到而已。屏幕緩沖區(qū)相關(guān)的多個屬性
5、可以獨(dú)立進(jìn)行設(shè)置。激活的屏幕緩沖區(qū)屬性值的變化能在控制臺窗口中產(chǎn)生奇妙的外觀效果。屏幕緩沖區(qū)相關(guān)的屬性包括:屏幕緩沖區(qū)大小,以字符行和列為單位;文本屬性(文本信息顯示的前景色和背景色);窗口大小和定位(控制臺屏幕緩沖區(qū)在控制臺窗口中顯示時所處的矩形區(qū)域);光標(biāo)位置、外觀和是否可見;輸出模式(控制字符的輸出處理和行末換行處理)。屏幕緩沖區(qū)在創(chuàng)建時,它所包含的字符內(nèi)容初始化為空格,光標(biāo)設(shè)為可見并定位在緩沖區(qū)原點(0,00,0), ,而窗口的原點(左上角)與緩沖區(qū)原點置為重合。控制臺屏幕緩沖區(qū)的大小、窗口的大小、文本屬性和光標(biāo)的外觀取決于用戶或系統(tǒng)的缺省設(shè)置。為獲取控制臺屏幕緩沖區(qū)各種相關(guān)屬性的當(dāng)前
6、值,可分別調(diào)用函數(shù):GetConsoleScreenBufferInfo;GetConsoleCursorInfo;GetConsoleMode。屏幕緩沖區(qū)光標(biāo)信息用 CONSOLE_CURSOR_INFO 結(jié)構(gòu)類型的數(shù)據(jù)表示,成員 bVisible 表不光標(biāo)是否可見,成員 dwSize 表不光標(biāo)外觀大小,取值范圍為 1100。光標(biāo)可見時,dwSize 的取值從 100 變?yōu)?1,光標(biāo)外觀大小從充滿整個字符單元變?yōu)槌霈F(xiàn)在單元底部的一條水平線。調(diào)用函數(shù) GetConsoleCursorInfo 和 SetConsoleCursorInfo 分別可以獲得和設(shè)置光標(biāo)屬性值。由高級控制臺 I/O 函數(shù)
7、(如 getchar,putchar,printf,scanf 等)輸出的字符將輸出在光標(biāo)當(dāng)前位置,同時光標(biāo)移動到下一個字符輸出位置。調(diào)用函數(shù):GetConsoleScreenBufferInfo 和 SetConsoleCursorPosition,分別可以獲得和設(shè)置光標(biāo)在屏幕緩沖區(qū)坐標(biāo)系統(tǒng)中的當(dāng)前位置,由此可以控制高級 I/O函數(shù)輸出或回顯字符的位置。字符屬性分為兩類:顏色屬性和 DBCS(Double-ByteCharacterSet,雙字節(jié)字符集)屬性。表 3.14 中的符號常量在 wincon.h 頭文件中進(jìn)行定義。表3.143.14字符屬性符號常量表含義FOREGROUND_BLU
8、EFOREGROUND_GREENFOREGROUND_REDFOREGROUND_INTENSITYBACKGROUND_BLUEBACKGROUND_GREENBACKGROUND_REDBACKGROUND_INTENSITY屬性文本顏色包含藍(lán)色文本顏色包含綠色文本顏色包含紅色文本顏色加亮背景含藍(lán)色背景含綠色背景含紅色背景加亮COMMON_LVB_LEADING_BYTE首字節(jié)COMMON_LVB_TRAILING_BYTE末字節(jié)COMMON_LVB_GRID_HORIZONTAL首行COMMON_LVB_GRID_LVERTICAL左列COMMON_LVB_GRID_RVERTICAL
9、右列COMMON_LVB_REVERSE_VIDEO翻轉(zhuǎn)前景及背景屬性COMMON_LVB_UNDERSCORE下劃線前綴為 FOREGROUND 的常量值指定文本顏色(文本的前景色)。 前綴為 BACKGROUND 的常量值指定用于填充字符單元背景的顏色。其他常量值用于 DBCS 屬性。應(yīng)用程序可以將前景色和背景色常量值組合起來,獲得不同顏色。例如,下面顏色組合的效果為藍(lán)色背景上的亮青色文本。FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_INTENSITY|BACKGROUND_BLUE配色問題可以由實驗的輸出試驗確定!如果不指定背景顏色值,那么背景
10、為黑色,而不指定前景顏色值,文本為黑色。例如,下面顏色組合將產(chǎn)生白色背景上的黑色文本效果。BACKGROUND_BLUE|BACKGROUND_GREEN|BACKGROUND_RED每個屏幕緩沖區(qū)字符單元儲存了在“畫”該單元的文本(前景)和背景時所使用的顏色屬性值。應(yīng)用程序可以分別設(shè)置每個字符單元的顏色值,并將顏色值存儲在每個單元 CHAR_INFO 結(jié)構(gòu)類型數(shù)據(jù)的 Attributes 成員中。3.4.2在屏幕上指定位置輸出信息有多種方法在屏幕指定位置輸出帶屬性的字符串信息,這里介紹其中四種基本方法。(1)(1)用標(biāo)準(zhǔn)輸出函數(shù)(putchar,printf,putsputchar,prin
11、tf,puts 等)輸出字符串信息;/設(shè)置光標(biāo)位置SetConsoleCursorPosition(output_handle,new_pos);SetConsoleCursorPosition(output_handle,new_pos);/輸出字符串 stringstringprintf(%sprintf(%s”,string);,string);在字符串輸出位置填充指定的文本屬性FillConsoleOutputAttribute(output_handle,new_attributes,strlen(string),new_pos,NULL);其中 output_handle 是屏幕緩
12、沖區(qū)句柄,new_pos 為 COORD 類型的變量,存放指定的光標(biāo)位置坐標(biāo),new_attributes 為 WORD 類型的變量,存放指定的文本屬性值,string 是字符數(shù)組,存放被輸出的字符串。(2)用函數(shù) WriteConsole 輸出字符串信息;設(shè)置光標(biāo)位置SetConsoleCursorPosition(output_handle,new_pos);設(shè)置文本屬性SetConsoleTextAttribute(output_handle,new_attributes);輸出字符串WriteConsole(output_handle,string,strlen(string),NUL
13、L,NULL);變量的含義同上。(3)用函數(shù) WriteConsoleOutputCharacter 輸出字符串信息;在指定位置填充與所輸出字符串等長的文本屬性值FillConsoleOutputAttribute(output_handle,new_attributes,strlen(string),new_pos,NULL);在該指定位置輸出字符串WriteConsoleOutputCharacter(output_handle,string,strlen(string),new_pos,NULL);(4)(4)用函數(shù) WriteConsoleOutputWriteConsoleOutpu
14、t 輸出字符串信息;CHAR_INFO*IpBuffer;CHAR_INFO*IpBuffer;COORDpos=0,0;COORDpos=0,0;COORDsize=strlen(string),1;COORDsize=strlen(string),1;SMALL_RECTarea=new_pos.X,new_pos.Y,new_pos.X+strlen(string)-1,new_pos.Y;SMALL_RECTarea=new_pos.X,new_pos.Y,new_pos.X+strlen(string)-1,new_pos.Y;lpBuffer=(CHAR_INFO*)malloc(
15、size.X*size.Y*sizeof(CHAR_INFO);lpBuffer=(CHAR_INFO*)malloc(size.X*size.Y*sizeof(CHAR_INFO);for(i=0;istrlen(string);i+)for(i=0;iChar.AsciiChar=stringlpBuffer-Char.AsciiChar=string。;lpBuffer-Attributes=new_attributes;lpBuffer-Attributes=new_attributes; WriteConsoleOutput(output_handle,lpBuffer,size,p
16、os,&area);free(&area);WriteConsoleOutput(output_handle,lpBuffer,size,pos,&area);free(&area);演示并解釋例3.1menu_ex3_13.1menu_ex3_1這種方法使用起來相對復(fù)雜一些?;舅枷胧菍⑤敵鲂畔?dāng)作一個矩形字符信息塊,設(shè)置矩形塊的大小 size,矩形塊在窗口中的輸出位置 area,將矩形塊內(nèi)字符信息存放在一個動態(tài)存儲緩沖區(qū) lpBuffer 內(nèi),字符信息包含了字符的碼值和顏色屬性,最后調(diào)用函數(shù)WriteConsoleOutput 將 lpBuffer 中字符塊
17、信息寫到控制臺屏幕緩沖區(qū)指定位置。3.4.3彈出窗口的設(shè)計屏幕窗口是個有限的信息顯示區(qū)域。在文本字符界面下,控制臺窗口的大小通常設(shè)為 80 個字符的寬度和25 行字符的高度,即每屏可以顯示 2000 個字符。彈出窗口設(shè)計的基本思路是:1 1、確定輸出信息的屏幕位置和大??;2 2、將新窗口彈出后所要覆蓋的屏幕區(qū)域字符信息讀入到一塊內(nèi)存緩沖區(qū);3 3、在新窗口內(nèi)輸出信息,模擬“彈出”效果。4 4、彈出窗口內(nèi)的操作完成后,把保存在內(nèi)存緩沖區(qū)的字符信息寫到其原來所在的屏幕位置,彈出窗口消失,屏幕恢復(fù)為窗口彈出之前的外觀。演示并解釋例3.1menu_ex3_23.1menu_ex3_2多層彈出窗口自學(xué)按
18、照這一思路,可以實現(xiàn)多層彈出窗口。窗口的多層彈出和逐層關(guān)閉,給屏幕信息的維護(hù)帶來了復(fù)雜性。為了便于處理,我們用鏈表來模擬堆棧,實現(xiàn)彈出窗口的棧式管理。彈出窗口棧式管理用到以下結(jié)構(gòu)類型。彈出窗口層數(shù)彈出窗口區(qū)域坐標(biāo)彈出窗口區(qū)域字符單元原信息存儲緩沖區(qū)彈出窗口區(qū)域字符單元原屬性值存儲緩沖區(qū)下一結(jié)點的地址LAYER_NODE;利用這種結(jié)構(gòu)類型的數(shù)據(jù)可以模擬出如圖 3.10 所示的堆棧,對彈出窗口信息進(jìn)行管理。LayerNo:彈出窗口的層數(shù)rcArea:彈出窗口位置和大小pContent:原字符信息存儲區(qū)地址pScrAtt:原單元屬性值存儲區(qū)地址next:下層結(jié)點圖3.10彈出窗口信息堆棧LAYER_
19、NODE 結(jié)構(gòu)的 5 個成員分別表示了彈出窗口相關(guān)信息。LayerNo 表示當(dāng)前彈出窗口的層數(shù);rcArea 表示當(dāng)前彈出窗口矩形區(qū)域的位置和大??;pContent 指向的動態(tài)存儲區(qū)存放被彈出窗口所覆蓋區(qū)域的原字符單元信息,用于當(dāng)前彈出窗口關(guān)閉后恢復(fù)原屏幕窗口信息;pScrAtt 指向的動態(tài)存儲區(qū)存放內(nèi)容的用途與輸入處理相關(guān),將在下面的輸入處理中進(jìn)行介紹;next 存放下層彈出窗口相關(guān)信息的地址。堆棧棧頂由 LAYER_NODE 結(jié)構(gòu)指針 TopLayer 來指示,初值為 NULL。系統(tǒng)界面初始化完成之后,屏幕窗口看作第一層彈出窗口,窗口相關(guān)信息用 LAYER_NODE 結(jié)構(gòu)類型的動態(tài)存儲區(qū)存
20、放后入棧,結(jié)構(gòu)指針 TopLayer 指向棧頂;以后每彈出一層窗口,就執(zhí)行一次入棧操作。關(guān)閉彈出窗口時,用 TopLayer 指向的 LAYER_NODE 結(jié)構(gòu)類型數(shù)據(jù)恢復(fù)被覆蓋的屏幕區(qū)域,將 TopLayer指向下一層結(jié)點,釋放用過的動態(tài)存儲區(qū),完成出棧操作。typedefstructlayer_nodecharLayerNo;SMALL_RECTrcArea;CHAR_INFO*pContent;char*pScrAtt;structlayer_node*next;TopLayer3.4.4鍵盤和鼠標(biāo)輸入信息的獲取ReadConsoleInputReadConsoleInput 函數(shù)原型為
21、:BOOLWINAPIReadConsoleInputBOOLWINAPIReadConsoleInput(HANDLEhConsoleInput,PINPUT_RECORDIpBuffer,DWORDnLength,LPDWORDlpNumberOfEventsReadHANDLEhConsoleInput,PINPUT_RECORDIpBuffer,DWORDnLength,LPDWORDlpNumberOfEventsRead); ;功能:用來從控制臺輸入緩沖區(qū)讀取輸入數(shù)據(jù),并將讀出數(shù)據(jù)從輸入緩沖區(qū)刪除掉。函數(shù) ReadConsoleInput 被調(diào)用時,如果緩沖區(qū)中沒有輸入數(shù)據(jù),函數(shù)將
22、等待下去,直到讀到至少一條記錄后返回。讀到的記錄存放在參數(shù) IpBuffer 所指向的內(nèi)存單元。記錄用 INPUT_RECORDINPUT_RECORD 結(jié)構(gòu)類型的數(shù)據(jù)來表示;成員 EventTypeEventType 表示事件的類型;成員 EventEvent 是聯(lián)合類型,存放事件的具體內(nèi)容。編程時,需要對 EventTypeEventType 的值為 KEY_EVENTKEY_EVENT(鍵盤輸入)或 MOUSE_EVENTMOUSE_EVENT(鼠標(biāo)輸入)的兩類事件進(jìn)行處理。當(dāng) EventTypeEventType 的值為 KEY_EVENTKEY_EVENT 時,EventEvent
23、的聯(lián)合成員 KeyEventKeyEvent 存放了按鍵相關(guān)信息、。KeyEvent 是KEY_EVENT_RECORD 結(jié)構(gòu)類型,其成員 bKeyDown 表明鍵是被按下(TRUE)還是被釋放(FALSE),成員 wRepeatCount 表明按鍵重復(fù)的次數(shù),成員 wVirtualKeyCode 存放按鍵的虛擬鍵碼, 成員 wVirtualScanCode 存放按鍵的虛擬掃描碼, 成員 uChar 存放按鍵的 ASCII 碼或 Unicode 碼 (取決于系統(tǒng)所采用的字符集),成員dwControlKeyState 表示有哪些控制鍵被同時按下。我們每按一次鍵會產(chǎn)生兩個事件記錄,一個記錄表示鍵
24、被按下,另一條記錄表示鍵被釋放。常用鍵的各種碼值參見附錄。當(dāng)EventTypEventType e的值為MOUSE_EVENMOUSE_EVENT T時, EvenEvent t的聯(lián)合成員MouseEvenMouseEvent t存放了鼠標(biāo)操作相關(guān)信息。 MouseEvent是 MOUSE_EVENT_RECORD 結(jié)構(gòu)類型,其成員 dwMousePosition 存放了鼠標(biāo)操作時的坐標(biāo)位置,表明鼠標(biāo)處于窗口中的某行和某列的字符單元位置上,成員 dwButtonState 表明鼠標(biāo)哪些按鈕被按下,取值可為下面符號常量之一或多個符號常量的組合值:FROM_LEFT_1ST_BUTTON_PRES
25、SED值為1,表示按下了鼠標(biāo)最左邊按鈕;RIGHTMOST_BUTTON_PRESSED值為2,表示按下了鼠標(biāo)最右邊按鈕;FROM_LEFT_2ND_BUTTON_PRESSED值為4,表示按下了鼠標(biāo)左起第二個按鈕;FROM_LEFT_3RD_BUTTON_PRESSED值為8,表示按下了鼠標(biāo)左起第三個按鈕;FROM_LEFT_4TH_BUTTON_PRESSED值為16,表示按下了鼠標(biāo)左起第四個按鈕。成員 dwControlKeyState 表示在鼠標(biāo)事件發(fā)生時有哪些控制鍵被同時按下,成員 dwEventFlags表示鼠標(biāo)事件的具體類型,取值為以下符號常量:MOUSE_MOVED 值為 1,
26、表示鼠標(biāo)移動事件;DOUBLE_CLICK 值為 2,表示鼠標(biāo)雙擊事件;MOUSE_WHEELED 值為 4,表示鼠標(biāo)滾輪滾動事件。3.4.5輸入處理(略)(1)鍵盤輸入處理按照表 3.15 進(jìn)行處理,對其他按鍵不予響應(yīng)。表3.15主界面下的鍵盤輸入處理設(shè)計按鍵系統(tǒng)響應(yīng)F1執(zhí)行幫助菜單下的幫助主題子菜單對應(yīng)功能模塊Alt+X執(zhí)行文件菜單下的退出系統(tǒng)子菜單對應(yīng)功能模塊Alt+F清除當(dāng)前選中菜單項標(biāo)記,標(biāo)記文件菜單項并彈出文件菜單的子菜單Alt+M清除當(dāng)前選中菜單項標(biāo)記,標(biāo)記數(shù)據(jù)維護(hù)菜單項并彈出數(shù)據(jù)維護(hù)菜單的子菜單Alt+Q清除當(dāng)前選中菜單項標(biāo)記,標(biāo)記數(shù)據(jù)查詢菜單項并彈出數(shù)據(jù)查詢菜單的子菜單Alt
27、+S清除當(dāng)前選中菜單項標(biāo)記,標(biāo)記數(shù)據(jù)統(tǒng)計菜單項并彈出數(shù)據(jù)統(tǒng)計菜單的子菜單Alt+H清除當(dāng)前選中菜單項標(biāo)記,標(biāo)記幫助菜單項并彈出幫助菜單的子菜單向左一清除當(dāng)前選中菜單項標(biāo)記,標(biāo)記左側(cè)菜單項向右 T清除當(dāng)前選中菜單項標(biāo)記,標(biāo)記右側(cè)菜單項向下J彈出當(dāng)前菜單項的子菜單f或F清除當(dāng)前選中菜單項標(biāo)記,標(biāo)記文件菜單項并彈出文件菜單的子菜單m或M清除當(dāng)前選中菜單項標(biāo)記,標(biāo)記數(shù)據(jù)維護(hù)菜單項并彈出數(shù)據(jù)維護(hù)菜單的子菜單q或Q清除當(dāng)前選中菜單項標(biāo)記,標(biāo)記數(shù)據(jù)查詢菜單項并彈出數(shù)據(jù)查詢菜單的子菜單s或S清除當(dāng)前選中菜單項標(biāo)記,標(biāo)記數(shù)據(jù)統(tǒng)計菜單項并彈出數(shù)據(jù)統(tǒng)計菜單的子菜單h或H清除當(dāng)前選中菜單項標(biāo)記,標(biāo)記幫助菜單項并彈出幫
28、助菜單的子菜單回車彈出當(dāng)前菜單項的子菜單鍵盤輸入處理時,要考慮輸入處理的優(yōu)先級,應(yīng)先響應(yīng)快捷鍵,再響應(yīng)組合鍵,最后響應(yīng)單鍵。以 Alt 組合鍵為例,判斷組合鍵的方法為:ReadConsoleInput(hIn,&inRec,1,&res);/從輸入緩沖區(qū)讀取一條輸入記錄if(inRec.EventType=KEY_EVENT&inRec.Event.KeyEvent.bKeyDown)輸入事件類別為 KEY_EVENT,且事件由鍵被按下所觸發(fā)vkc=inRec.Event.KeyEvent.wVirtualKeyCode;/提取虛擬鍵碼asc=inRec.Event.K
29、eyEvent.uChar.AsciiChar;提取 ASCII 碼if(inRec.Event.KeyEvent.dwControlKeyState如果左或右 Alt 鍵被按下&(LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED)/進(jìn)一步判斷與 Alt 組合的另一個鍵,并做響應(yīng)處理非 Alt 組合鍵的響應(yīng)處理常用控制鍵所對應(yīng)的符號常量在 wincon.h 頭文件中進(jìn)行了定義,如表 3.16 所示。表3.16控制鍵對應(yīng)符號常量表鍵名符號常量值鍵名符號常量值右AltRIGHT_ALT_PRESSED1左AltLEFT_ALT_PRESSED2右CtrlRIGHT_CT
30、RL_PRESSED4左CtrlLEFT_CTRL_PRESSED8左右ShiftSHIFT_PRESSED16數(shù)字鎖定NUMLOCK_ON32屏幕鎖定SCROLLLOCK_ON64大寫鎖定CAPSLOCK_ON128(2)鼠標(biāo)輸入處理熱區(qū)本是網(wǎng)頁設(shè)計中用到的一個概念,是指網(wǎng)頁上建有鏈接的區(qū)域。我們將熱區(qū)這個概念借用到程序設(shè)計中人機(jī)交互界面的設(shè)計上來,用來指界面上需要對鼠標(biāo)事件(包括鼠標(biāo)移動、滾輪轉(zhuǎn)動、雙擊和任意一到多個鍵的按下)產(chǎn)生反應(yīng)的區(qū)域?;谶@一思想,可用一個字符(8 個二進(jìn)制位)來表示窗口中某個字符單元的屬性。如圖 3.12 所示,這 8個二進(jìn)制位分為三段:01 比特為 A1,25
31、比特為 A2,67 比特為 A3。A1 的取值范圍為 03,用來表示字符單元的“高度”,即該字符單元上彈出窗口的層數(shù),0表示字符單元處于系統(tǒng)主界面層,沒有彈出窗口覆蓋該字符單元,這樣彈出窗口的層數(shù)最多可到 3 層;A2 取值范圍為 015,用來表示字符單元的熱區(qū)編號,0 表示字符單元不屬于熱區(qū),這樣同一層上的熱區(qū)最多可為 15 個;A3 取值范圍為 03,在 A2 取值不為 0 時用來表示字符單元的熱區(qū)類型,。代表按鈕類型,1 代表輸入框類型,2 代表下拉選框類型,3 保留備用。不同類型的熱區(qū)被鼠標(biāo)擊中時,系統(tǒng)可以分別進(jìn)行處理。本課程設(shè)計中,字符單元的屬性用 8 個二進(jìn)制位來存放,剛好夠用。在
32、其他應(yīng)用程序開發(fā)中,如果彈出菜單超過 3 層,或某層窗口中熱區(qū)超過 15 個,或熱區(qū)類型超過 4 類,可以考慮用 16 個二進(jìn)制位來存放字符單元屬性。A3A2A1圖3.12字符單元屬性的表示前面在介紹彈出窗口設(shè)計時,彈出窗口的棧式管理用到以下結(jié)構(gòu)類型:彈出窗口層數(shù)彈出窗口區(qū)域坐標(biāo)彈出窗口區(qū)域字符單元原信息存儲緩沖區(qū)彈出窗口區(qū)域字符單元原屬性值存儲緩沖區(qū)下一結(jié)點的地址LAYER_NODE;其中,結(jié)構(gòu)成員 pScrAtt 用來指向一個動態(tài)存儲區(qū),該存儲區(qū)存放被彈出窗口所覆蓋字符單元的原先屬性值,在彈出窗口關(guān)閉時用于恢復(fù)窗口彈出前屏幕字符單元的屬性。系統(tǒng)界面初始化完成之后,屏幕顯示系統(tǒng)的主界面(如圖
33、 3.9 所示)。用一個字符數(shù)組 ScrAtt 存放屏幕上所有字符單元的屬性值,字符單元的坐標(biāo) X 和 Y 與存放其屬性值的數(shù)組元素下標(biāo) n 的關(guān)系為:n=YX 屏幕緩沖區(qū)的寬度+X主界面中只有 5 個主菜單項顯示區(qū)域為熱區(qū),依次編號 15,熱區(qū)類型為按鈕型。此后,如果有窗口彈出(彈出菜單也是彈出窗口),則將窗口所覆蓋區(qū)域字符單元的信息和屬性分別保存起來,執(zhí)行彈出窗口信息入棧操作,然后在彈出窗口區(qū)域輸出提示信息,將彈出窗口字符單元的屬性值寫入數(shù)組 ScrAtt 對應(yīng)元素以設(shè)置熱區(qū)。鼠標(biāo)輸入處理時,取鼠標(biāo)所在字符單元的屬性值,根據(jù)字符單元的層數(shù)、熱區(qū)編號和熱區(qū)類型,結(jié)合鼠標(biāo)事件類型做出相應(yīng)處理。
34、當(dāng)彈出窗口關(guān)閉時,用所保存的彈出窗口區(qū)域字符單元原先的屬性值修改數(shù)組 ScrAtt對應(yīng)元素值,恢復(fù)窗口彈出前屏幕字符單元的屬性,最后執(zhí)行彈出窗口信息出棧操作。3.4.6菜單操作與系統(tǒng)功能函數(shù)的調(diào)用按照概要設(shè)計,系統(tǒng)功能分為五個模塊,各模塊所包含的子模塊共有 22 個,分別用 22個函數(shù)實現(xiàn)相應(yīng)功能。其中,數(shù)據(jù)加載函數(shù)和界面初始化函數(shù)只在系統(tǒng)啟動時執(zhí)行一次,以后不再執(zhí)行。其余 20 個函數(shù)可以通過菜單操作或快捷鍵執(zhí)行相應(yīng)功能。例 3.3 在圖 3.9 所示的主界面下,實現(xiàn)菜單操作與系統(tǒng)功能函數(shù)的調(diào)用。本例中給出了函數(shù) SysRun 和函數(shù) ExeFunction 的定義,分別用于菜單操作和系統(tǒng)功
35、能函數(shù)的調(diào)用。例子中調(diào)用了例 3.1 和例 3.2 中的函數(shù),而其余函數(shù)的定義沒有給出。#includedorm.hvoidSysRun()INPUT_RECORDinRec;DWORDres;typedefstructlayer_nodecharLayerNo;SMALL_RECTrcArea;CHAR_INFO*pContent;char*pScrAtt;structlayer_node*next;COORDpos=0,0;BOOLbRet=TRUE;inti,loc,num;intcNo,cAtt;/cNo:字符單元層號,cAtt:字符單元屬性charvkc,asc;/vkc:虛擬鍵代碼
36、,asc:字符的ASCII碼值while(bRet)/循環(huán)ReadConsoleInput(hIn,&inRec,1,&res);ReadConsoleInput(hIn,&inRec,1,&res);if(inRec.EventType=MOUSE_EVENT)(inRec.EventType=MOUSE_EVENT)pos=inRec.Event.MouseEvent.dwMousePosition;/*pospos=inRec.Event.MouseEvent.dwMousePosition;/*pos 是坐標(biāo)*/*/cNo=ScrAttpos.Y*Scr
37、Col+pos.X&3;cAtt=ScrAttpos.Y*ScrCol+pos.X2;if(cNo=0)if(cAtt0&cAtt!=SelMenu&TopLayer-LayerNo0)PopOff();SelSMenu=0;PopMenu(cAtt);elseif(cAtt0)TagSMenu(cAtt);if(inRec.Event.MouseEvent.dwButtonStateinRec.Event.MouseEvent.dwButtonState=FROM_LEFT_1ST_BUTTON_PRESSED=FROM_LEFT_1ST_BUTTON_PRESSED
38、)if(cNo=0)if(cAtt0)PopMenu(cAtt);elseif(TopLayer-LayerNo0)PopOff();SelSMenu=0;elseif(cAtt0)PopOff();SelSMenu=0;bRet=ExeFunction(SelMenu,cAtt);elseif(inRec.Event.MouseEvent.dwButtonStateinRec.Event.MouseEvent.dwButtonState=RIGHTMOST_BUTTON_PRESSED=RIGHTMOST_BUTTON_PRESSED)if(cNo=0)PopOff();SelSMenu=0
39、;)elseif(inRec.EventType=KEY_EVENTinRec.EventType=KEY_EVENT&inRec.Event.KeyEvent.bKeyDown&inRec.Event.KeyEvent.bKeyDown)vkc=inRec.Event.KeyEvent.wVirtualKeyCode;asc=inRec.Event.KeyEvent.uChar.AsciiChar;系統(tǒng)快捷鍵的處理if(vkc=112)/F1鍵if(TopLayer-LayerNo!=0)PopOff();SelSMenu=0;)bRet=ExeFunction(5,1);/
40、F1幫助主題)elseif(inRec.Event.KeyEvent.dwControlKeyState&(LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED)switch(vkc)/組合鍵Alt+字母case88:if(TopLayer-LayerNo!=0)PopOff();SelSMenu=0;)bRet=ExeFunction(1,4);break;/Alt+X退出case70:PopMenu(1);break;/Alt+Fcase77:PopMenu(2);break;/Alt+Mcase81:PopMenu(3);break;/Alt+Qcase83:Po
41、pMenu(4);break;/Alt+Scase72:PopMenu(5);break;/Alt+H)elseif(asc=0)方向鍵的處理if(TopLayer-LayerNo=0)未彈出子菜單時switch(vkc)方向鍵(左、右、下)的處理case37:SelMenu-;if(SelMenu=0)SelMenu=5;)TagMenu(SelMenu);break;SelMenu+;if(SelMenu=6)SelMenu=1;)TagMenu(SelMenu);break;PopMenu(SelMenu);TagSMenu(1);break;)else已彈出子菜單時for(loc=0,
42、i=1;iSelMenu;i+)loc+=cSMenui-1;)找到子菜單第一項在子菜單數(shù)組中的位置(下標(biāo))switch(vkc)方向鍵(左、右、上、下)的處理SelMenu-;if(SelMenu1)SelMenu=5;)TagMenu(SelMenu);PopOff();PopMenu(SelMenu);TagSMenu(1);break;num=SelSMenu-1;if(num5)SelMenu=1;)TagMenu(SelMenu);PopOff();PopMenu(SelMenu);TagSMenu(1);break;num=SelSMenu+1;if(numcSMenuSelMe
43、nu-1)num=1;)if(strlen(SMenuloc+num-1)=0)num+;)TagSMenu(num);break;)elseif(asc-vkc=0)|(asc-vkc=32)按下普通鍵if(TopLayer-LayerNo=0)未彈出子菜單時switch(vkc)case70:PopMenu(1);break;/f或Fcase77:PopMenu(2);break;/m或Mcase81:PopMenu(3);break;/q或Qcase83:PopMenu(4);break;/s或Scase72:PopMenu(5);break;/h或Hcase13:PopMenu(SelMenu);/回車TagSMenu(1);break;)else/已彈出子菜單時的鍵盤輸入處理if(vkc=27)/按下ESC鍵時,關(guān)閉子菜單PopOff();SelSMenu=0;)elseif(vkc=13)/|vkc=32num=SelSMenu;PopOff();SelSMenu=0;bRet=ExeFunction(
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 校園應(yīng)急預(yù)案解讀
- 食品安全伴我行
- 認(rèn)識銷售課件教學(xué)課件
- 假如課件教學(xué)課件
- 高三化學(xué)一輪復(fù)習(xí) 第一章 離子反應(yīng) 離子方程式 課件
- 稻田餐廳課件教學(xué)課件
- 3.1.1鐵及鐵的氧化物 課件 高一上學(xué)期化學(xué)人教版(2019)必修第一冊
- 2.2化學(xué)平衡 課件高二上學(xué)期化學(xué)人教版(2019)選擇性必修1
- 成人夏季食品安全教育
- 企業(yè)宿舍管理培訓(xùn)
- 軸承質(zhì)檢報告
- 燃燒與爆炸理論課件
- 2022中考語文熱點聚焦:航天科技( 有答案)
- 第1章 復(fù)合材料概論
- 中藥材種植課件
- 大貨車安全隱患排查方案及流程
- 業(yè)務(wù)經(jīng)營弄虛作假專項治理心得體會范文
- 無人機(jī)飛行操作手冊
- 癌癥治療指南手冊
- 醫(yī)美行業(yè)發(fā)展趨勢
- 自發(fā)性腹膜炎的護(hù)理查房課件
評論
0/150
提交評論