pos機交互過程,CodeBlock下的人機交互界面設計

 新聞資訊2  |   2023-06-13 10:01  |  投稿人:pos機之家

網上有很多關于pos機交互過程,CodeBlock下的人機交互界面設計的知識,也有很多人為大家解答關于pos機交互過程的問題,今天pos機之家(www.bangarufamily.com)為大家整理了關于這方面的知識,讓我們一起來看下吧!

本文目錄一覽:

1、pos機交互過程

pos機交互過程

人機交互界面指的是計算機系統與用戶之間的接口。通過該接口,一方面,計算機系統向用戶輸出系統的運行狀態、運行控制和運行結果等方面信息;另一方面,用戶根據輸出信息向系統輸入相應的指令和數據等信息。

3.4.1 控制臺窗口和屏幕緩沖區

控制臺窗口是個二維平面空間,其坐標系統的原點(0, 0)設在窗口左上角,即窗口第一行第一列字符單元的位置。橫軸(X軸)的正向沿原點向右,與窗口的第一行重合,每刻度為一個字符寬度;縱軸(Y軸)的正向沿原點向下,與窗口的第一列重合,每刻度為一個字符高度。窗口中每個字符單元對應一個二維坐標。比如,第5行第32列字符單元的坐標為(31, 4)。如圖3.8所示。

圖3.8 控制臺窗口和屏幕緩沖區關系示意圖

屏幕緩沖區是個二維數組,邏輯上可看作一個二維平面空間。數組第一個元素的下標[0][0]對應此平面空間坐標系統的原點(0, 0),數組第1維的下標對應坐標系統的縱坐標(Y坐標),第2維下標對應坐標系統的橫坐標(X坐標)。屏幕緩沖區存放著M行N列字符單元的信息,M和N的大小由系統設置,并可以進行修改。

每個字符單元信息用一個Char_INFO結構類型的數據來表示,結構成員CHAR存放字符的碼值(Unicode碼或ASCII碼,取決于系統所采用的字符集),結構成員Attributes存放字符的屬性(字符顯示所用的前景色和背景色)。

操作系統以一定的頻率從屏幕緩沖區讀取字符單元信息,并顯示在控制臺窗口中。應用程序的輸出信息實際上輸出到了屏幕緩沖區,由此改變了控制臺窗口所顯示的內容。初始狀態下,屏幕緩沖區坐標系統與控制臺窗口坐標系統重合,窗口中第m行第n列字符的碼值和顏色值存放在屏幕緩沖區二維數組中下標為[m-1][n-1]的元素中。利用控制臺函數可以改變這兩個坐標系統的對應關系,實現特殊的顯示效果。圖3.8表示了控制臺窗口和屏幕緩沖區的相互關系。

一個控制臺可擁有多個屏幕緩沖區,但只有處于激活狀態的屏幕緩沖區內容顯示在控制臺窗口中。操作系統在為進程創建控制臺的同時會創建一個屏幕緩沖區。

進程可調用函數CreateConsoleScreenBuffer為其控制臺創建另外的屏幕緩沖區。

調用函數SetConsoleActiveScreenBuffer可以將某個已有的屏幕緩沖區置為激活狀態,使其內容顯示在屏幕窗口中。

不管是否處于激活狀態,屏幕緩沖區都可以通過句柄來進行讀寫操作,只不過激活狀態下屏幕緩沖區的內容可以看到,非激活狀態下看不到而已。

屏幕緩沖區相關的多個屬性可以獨立進行設置。激活的屏幕緩沖區屬性值的變化能在控制臺窗口中產生奇妙的外觀效果。屏幕緩沖區相關的屬性包括:

l 屏幕緩沖區大小,以字符行和列為單位;

l 文本屬性(文本信息顯示的前景色和背景色);

l 窗口大小和定位(控制臺屏幕緩沖區在控制臺窗口中顯示時所處的矩形區域);

l 光標位置、外觀和是否可見;

l 輸出模式(控制字符的輸出處理和行末換行處理)。

屏幕緩沖區在創建時,它所包含的字符內容初始化為空格,光標設為可見并定位在緩沖區原點(0, 0),而窗口的原點(左上角)與緩沖區原點置為重合??刂婆_屏幕緩沖區的大小、窗口的大小、文本屬性和光標的外觀取決于用戶或系統的缺省設置。

為獲取控制臺屏幕緩沖區各種相關屬性的當前值,可分別調用函數:

GetConsoleScreenBufferInfo;

GetConsoleCursorInfo;

GetConsoleMode。

屏幕緩沖區光標信息用CONSOLE_CURSOR_INFO結構類型的數據表示,成員bVisible表示光標是否可見,成員dwSize表示光標外觀大小,取值范圍為1~100。光標可見時,dwSize的取值從100變為1,光標外觀大小從充滿整個字符單元變為出現在單元底部的一條水平線。調用函數GetConsoleCursorInfo和SetConsoleCursorInfo分別可以獲得和設置光標屬性值。

由高級控制臺I/O函數(如getchar,putchar,printf,scanf等)輸出的字符將輸出在光標當前位置,同時光標移動到下一個字符輸出位置。

調用函數:

GetConsoleScreenBufferInfo和SetConsoleCursorPosition,

分別可以獲得和設置光標在屏幕緩沖區坐標系統中的當前位置,由此可以控制高級I/O函數輸出或回顯字符的位置。

字符屬性分為兩類:顏色屬性和DBCS(Double-Byte Character Set,雙字節字符集)屬性。表3.14中的符號常量在wincon.h頭文件中進行定義。

表3.14 字符屬性符號常量表

屬性

含義

FOREGROUND_BLUE

文本顏色包含藍色

FOREGROUND_GREEN

文本顏色包含綠色

FOREGROUND_RED

文本顏色包含紅色

FOREGROUND_INTENSITY

文本顏色加亮

BACKGROUND_BLUE

背景含藍色

BACKGROUND_GREEN

背景含綠色

BACKGROUND_RED

背景含紅色

BACKGROUND_INTENSITY

背景加亮

COMMON_LVB_LEADING_BYTE

首字節

COMMON_LVB_TRAILING_BYTE

末字節

COMMON_LVB_GRID_HORIZONTAL

首行

COMMON_LVB_GRID_LVERTICAL

左列

COMMON_LVB_GRID_RVERTICAL

右列

COMMON_LVB_REVERSE_VIDEO

翻轉前景及背景屬性

COMMON_LVB_UNDERSCORE

下劃線

前綴為FOREGROUND的常量值指定文本顏色(文本的前景色)。前綴為BACKGROUND的常量值指定用于填充字符單元背景的顏色。其他常量值用于DBCS屬性。

應用程序可以將前景色和背景色常量值組合起來,獲得不同顏色。例如,下面顏色組合的效果為藍色背景上的亮青色文本。

FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY | BACKGROUND_BLUE

配色問題可以由實驗的輸出試驗確定!

如果不指定背景顏色值,那么背景為黑色,而不指定前景顏色值,文本為黑色。例如,下面顏色組合將產生白色背景上的黑色文本效果。

BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED

每個屏幕緩沖區字符單元儲存了在“畫”該單元的文本(前景)和背景時所使用的顏色屬性值。應用程序可以分別設置每個字符單元的顏色值,并將顏色值存儲在每個單元CHAR_INFO結構類型數據的Attributes成員中。

3.4.2 在屏幕上指定位置輸出信息

有多種方法在屏幕指定位置輸出帶屬性的字符串信息,這里介紹其中四種基本方法。

(1) 用標準輸出函數(putchar, printf, puts等)輸出字符串信息;

//設置光標位置

SetConsoleCursorPosition(output_handle, new_pos);

//輸出字符串string

printf(“%s”, string);

//在字符串輸出位置填充指定的文本屬性

FillConsoleOutputAttribute(output_handle, new_attributes, strlen(string), new_pos, NULL);

其中output_handle是屏幕緩沖區句柄,new_pos為COORD類型的變量,存放指定的光標位置坐標,new_attributes為WORD類型的變量,存放指定的文本屬性值,string是字符數組,存放被輸出的字符串。

(2) 用函數WriteConsole輸出字符串信息;

//設置光標位置

SetConsoleCursorPosition (output_handle, new_pos);

//設置文本屬性

SetConsoleTextAttribute(output_handle, new_attributes);

//輸出字符串

WriteConsole(output_handle, string, strlen(string), NULL, NULL);

變量的含義同上。

(3) 用函數WriteConsoleOutputCharacter輸出字符串信息;

//在指定位置填充與所輸出字符串等長的文本屬性值

FillConsoleOutputAttribute(output_handle, new_attributes, strlen(string), new_pos, NULL);

//在該指定位置輸出字符串

WriteConsoleOutputCharacter(output_handle, string, strlen(string), new_pos, NULL);

(4) 用函數WriteConsoleOutput輸出字符串信息;

CHAR_INFO * lpBuffer;

COORD pos = {0, 0};

COORD size = { strlen(string), 1};

SMALL_RECT area = {new_pos.X, new_pos.Y, new_pos.X+strlen(string)-1, new_pos.Y};

lpBuffer = (CHAR_INFO *)malloc(size.X * size.Y * sizeof(CHAR_INFO));

for(i=0; i<strlen(string); i++) {

lpBuffer->Char.AsciiChar = string[i];

lpBuffer->Attributes = new_attributes;

}

WriteConsoleOutput(output_handle, lpBuffer, size, pos, &area);

free(&area);

演示并解釋例3.1 menu_ex3_1

這種方法使用起來相對復雜一些?;舅枷胧菍⑤敵鲂畔斪饕粋€矩形字符信息塊,設置矩形塊的大小size,矩形塊在窗口中的輸出位置area,將矩形塊內字符信息存放在一個動態存儲緩沖區lpBuffer內,字符信息包含了字符的碼值和顏色屬性,最后調用函數WriteConsoleOutput將lpBuffer中字符塊信息寫到控制臺屏幕緩沖區指定位置。

3.4.3 彈出窗口的設計

屏幕窗口是個有限的信息顯示區域。在文本字符界面下,控制臺窗口的大小通常設為80個字符的寬度和25行字符的高度,即每屏可以顯示2000個字符。

彈出窗口設計的基本思路是:

1、確定輸出信息的屏幕位置和大??;

2、將新窗口彈出后所要覆蓋的屏幕區域字符信息讀入到一塊內存緩沖區;

3、在新窗口內輸出信息,模擬“彈出”效果。

4、彈出窗口內的操作完成后,把保存在內存緩沖區的字符信息寫到其原來所在的屏幕位置,彈出窗口消失,屏幕恢復為窗口彈出之前的外觀。

演示并解釋例3.1 menu_ex3_2

多層彈出窗口自學

按照這一思路,可以實現多層彈出窗口。窗口的多層彈出和逐層關閉,給屏幕信息的維護帶來了復雜性。為了便于處理,我們用鏈表來模擬堆棧,實現彈出窗口的棧式管理。

彈出窗口棧式管理用到以下結構類型。

typedef struct layer_node {

char LayerNo; //彈出窗口層數

SMALL_RECT rcArea; //彈出窗口區域坐標

CHAR_INFO *pContent; //彈出窗口區域字符單元原信息存儲緩沖區

char *pScrAtt; //彈出窗口區域字符單元原屬性值存儲緩沖區

struct layer_node *next; //下一結點的地址

} LAYER_NODE;

利用這種結構類型的數據可以模擬出如圖3.10所示的堆棧,對彈出窗口信息進行管理。

圖3.10 彈出窗口信息堆棧

LAYER_NODE結構的5個成員分別表示了彈出窗口相關信息。LayerNo表示當前彈出窗口的層數;rcArea表示當前彈出窗口矩形區域的位置和大??;pContent指向的動態存儲區存放被彈出窗口所覆蓋區域的原字符單元信息,用于當前彈出窗口關閉后恢復原屏幕窗口信息;pScrAtt指向的動態存儲區存放內容的用途與輸入處理相關,將在下面的輸入處理中進行介紹;next存放下層彈出窗口相關信息的地址。

堆棧棧頂由LAYER_NODE結構指針TopLayer來指示,初值為NULL。系統界面初始化完成之后,屏幕窗口看作第一層彈出窗口,窗口相關信息用LAYER_NODE結構類型的動態存儲區存放后入棧,結構指針TopLayer指向棧頂;以后每彈出一層窗口,就執行一次入棧操作。關閉彈出窗口時,用TopLayer指向的LAYER_NODE結構類型數據恢復被覆蓋的屏幕區域,將TopLayer指向下一層結點,釋放用過的動態存儲區,完成出棧操作。

3.4.4 鍵盤和鼠標輸入信息的獲取

ReadConsoleInput函數原型為:

BOOL WINAPI ReadConsoleINPUT(HANDLE hConsoleInput, PINPUT_RECORD

lpBuffer, DWORD nLength, LPDWORD lpNumberOfEventsRead);

功能:用來從控制臺輸入緩沖區讀取輸入數據,并將讀出數據從輸入緩沖區刪除掉。

函數ReadConsoleInput被調用時,如果緩沖區中沒有輸入數據,函數將等待下去,直到讀到至少一條記錄后返回。讀到的記錄存放在參數lpBuffer所指向的內存單元。

記錄用INPUT_RECORD結構類型的數據來表示;

成員EventType表示事件的類型;

成員Event是聯合類型,存放事件的具體內容。

編程時,需要對EventType的值為KEY_EVENT(鍵盤輸入)或MOUSE_EVENT(鼠標輸入)的兩類事件進行處理。

當EventType的值為KEY_EVENT時,Event的聯合成員KeyEvent存放了按鍵相關信息。KeyEvent是KEY_EVENT_RECORD結構類型,其成員bKeyDown表明鍵是被按下(TRUE)還是被釋放(FALSE),成員wRepeatCount表明按鍵重復的次數,成員wVirtualKeyCode存放按鍵的虛擬鍵碼,成員wVirtualScanCode存放按鍵的虛擬掃描碼,成員uChar存放按鍵的ASCII碼或Unicode碼(取決于系統所采用的字符集),成員dwControlKeyState表示有哪些控制鍵被同時按下。我們每按一次鍵會產生兩個事件記錄,一個記錄表示鍵被按下,另一條記錄表示鍵被釋放。常用鍵的各種碼值參見附錄。

當EventType的值為MOUSE_EVENT時,Event的聯合成員MouseEvent存放了鼠標操作相關信息。MOUSEEvent是MOUSE_EVENT_RECORD結構類型,其成員dwMousePosition存放了鼠標操作時的坐標位置,表明鼠標處于窗口中的某行和某列的字符單元位置上,成員dwButtonState表明鼠標哪些按鈕被按下,取值可為下面符號常量之一或多個符號常量的組合值:

FROM_LEFT_1ST_BUTTON_PRESSED值為1,表示按下了鼠標最左邊按鈕;

RIGHTMOST_BUTTON_PRESSED值為2,表示按下了鼠標最右邊按鈕;

FROM_LEFT_2ND_BUTTON_PRESSED值為4,表示按下了鼠標左起第二個按鈕;

FROM_LEFT_3RD_BUTTON_PRESSED值為8,表示按下了鼠標左起第三個按鈕;

FROM_LEFT_4TH_BUTTON_PRESSED值為16,表示按下了鼠標左起第四個按鈕。

成員dwControlKeyState表示在鼠標事件發生時有哪些控制鍵被同時按下,成員dwEventFlags表示鼠標事件的具體類型,取值為以下符號常量:

MOUSE_MOVED值為1,表示鼠標移動事件;

DOUBLE_CLICK值為2,表示鼠標雙擊事件;

MOUSE_WHEELED值為4,表示鼠標滾輪滾動事件。

3.4.5 輸入處理(略)

(1) 鍵盤輸入處理

按照表3.15進行處理,對其他按鍵不予響應。

表3.15 主界面下的鍵盤輸入處理設計

按鍵

系統響應

F1

執行幫助菜單下的幫助主題子菜單對應功能模塊

Alt+X

執行文件菜單下的退出系統子菜單對應功能模塊

Alt+F

清除當前選中菜單項標記,標記文件菜單項并彈出文件菜單的子菜單

Alt+M

清除當前選中菜單項標記,標記數據維護菜單項并彈出數據維護菜單的子菜單

Alt+Q

清除當前選中菜單項標記,標記數據查詢菜單項并彈出數據查詢菜單的子菜單

Alt+S

清除當前選中菜單項標記,標記數據統計菜單項并彈出數據統計菜單的子菜單

Alt+H

清除當前選中菜單項標記,標記幫助菜單項并彈出幫助菜單的子菜單

向左←

清除當前選中菜單項標記,標記左側菜單項

向右→

清除當前選中菜單項標記,標記右側菜單項

向下↓

彈出當前菜單項的子菜單

f或F

清除當前選中菜單項標記,標記文件菜單項并彈出文件菜單的子菜單

m或M

清除當前選中菜單項標記,標記數據維護菜單項并彈出數據維護菜單的子菜單

q或Q

清除當前選中菜單項標記,標記數據查詢菜單項并彈出數據查詢菜單的子菜單

s或S

清除當前選中菜單項標記,標記數據統計菜單項并彈出數據統計菜單的子菜單

h或H

清除當前選中菜單項標記,標記幫助菜單項并彈出幫助菜單的子菜單

回車

彈出當前菜單項的子菜單

鍵盤輸入處理時,要考慮輸入處理的優先級,應先響應快捷鍵,再響應組合鍵,最后響應單鍵。以Alt組合鍵為例,判斷組合鍵的方法為:

ReadConsoleInput(hIn, &inRec, 1, &res); //從輸入緩沖區讀取一條輸入記錄

if (inRec.EventType == KEY_EVENT && inRec.Event.KeyEvent.bKeyDown) {

//輸入事件類別為KEY_EVENT,且事件由鍵被按下所觸發

vkc = inRec.Event.KeyEvent.wVirtualKeyCode; //提取虛擬鍵碼

asc = inRec.Event.KeyEvent.uChar.AsciiChar; //提取ASCII碼

if (inRec.Event.KeyEvent.dwControlKeyState //如果左或右Alt鍵被按下

& (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) {

…… //進一步判斷與Alt組合的另一個鍵,并做響應處理

}

…… //非Alt組合鍵的響應處理

}

常用控制鍵所對應的符號常量在wincon.h頭文件中進行了定義,如表3.16所示。

表3.16 控制鍵對應符號常量表

鍵名

符號常量

鍵名

符號常量

右Alt

RIGHT_ALT_PRESSED

1

左Alt

LEFT_ALT_PRESSED

2

右Ctrl

RIGHT_CTRL_PRESSED

4

左Ctrl

LEFT_CTRL_PRESSED

8

左右Shift

SHIFT_PRESSED

16

數字鎖定

NUMLOCK_ON

32

屏幕鎖定

SCROLLLOCK_ON

64

大寫鎖定

CAPSLOCK_ON

128

(2) 鼠標輸入處理

熱區本是網頁設計中用到的一個概念,是指網頁上建有鏈接的區域。我們將熱區這個概念借用到程序設計中人機交互界面的設計上來,用來指界面上需要對鼠標事件(包括鼠標移動、滾輪轉動、雙擊和任意一到多個鍵的按下)產生反應的區域。

基于這一思想,可用一個字符(8個二進制位)來表示窗口中某個字符單元的屬性。如圖3.12所示,這8個二進制位分為三段:0~1比特為A1,2~5比特為A2,6~7比特為A3。A1的取值范圍為0~3,用來表示字符單元的“高度”,即該字符單元上彈出窗口的層數,0表示字符單元處于系統主界面層,沒有彈出窗口覆蓋該字符單元,這樣彈出窗口的層數最多可到3層;A2取值范圍為0~15,用來表示字符單元的熱區編號,0表示字符單元不屬于熱區,這樣同一層上的熱區最多可為15個;A3取值范圍為0~3,在A2取值不為0時用來表示字符單元的熱區類型,0代表按鈕類型,1代表輸入框類型,2代表下拉選框類型,3保留備用。不同類型的熱區被鼠標擊中時,系統可以分別進行處理。本課程設計中,字符單元的屬性用8個二進制位來存放,剛好夠用。在其他應用程序開發中,如果彈出菜單超過3層,或某層窗口中熱區超過15個,或熱區類型超過4類,可以考慮用16個二進制位來存放字符單元屬性。

7

6

5

4

3

2

1

0

A3

A2

A1

圖3.12 字符單元屬性的表示

前面在介紹彈出窗口設計時,彈出窗口的棧式管理用到以下結構類型:

typedef struct layer_node {

char LayerNo; //彈出窗口層數

SMALL_RECT rcArea; //彈出窗口區域坐標

CHAR_INFO *pContent; //彈出窗口區域字符單元原信息存儲緩沖區

char *pScrAtt; //彈出窗口區域字符單元原屬性值存儲緩沖區

struct layer_node *next; //下一結點的地址

} LAYER_NODE;

其中,結構成員pScrAtt用來指向一個動態存儲區,該存儲區存放被彈出窗口所覆蓋字符單元的原先屬性值,在彈出窗口關閉時用于恢復窗口彈出前屏幕字符單元的屬性。

系統界面初始化完成之后,屏幕顯示系統的主界面(如圖3.9所示)。用一個字符數組ScrAtt存放屏幕上所有字符單元的屬性值,字符單元的坐標X和Y與存放其屬性值的數組元素下標n的關系為:

n = Y × 屏幕緩沖區的寬度 + X

主界面中只有5個主菜單項顯示區域為熱區,依次編號1~5,熱區類型為按鈕型。此后,如果有窗口彈出(彈出菜單也是彈出窗口),則將窗口所覆蓋區域字符單元的信息和屬性分別保存起來,執行彈出窗口信息入棧操作,然后在彈出窗口區域輸出提示信息,將彈出窗口字符單元的屬性值寫入數組ScrAtt對應元素以設置熱區。鼠標輸入處理時,取鼠標所在字符單元的屬性值,根據字符單元的層數、熱區編號和熱區類型,結合鼠標事件類型做出相應處理。當彈出窗口關閉時,用所保存的彈出窗口區域字符單元原先的屬性值修改數組ScrAtt對應元素值,恢復窗口彈出前屏幕字符單元的屬性,最后執行彈出窗口信息出棧操作。

3.4.6 菜單操作與系統功能函數的調用

按照概要設計,系統功能分為五個模塊,各模塊所包含的子模塊共有22個,分別用22個函數實現相應功能。其中,數據加載函數和界面初始化函數只在系統啟動時執行一次,以后不再執行。其余20個函數可以通過菜單操作或快捷鍵執行相應功能。

例3.3 在圖3.9所示的主界面下,實現菜單操作與系統功能函數的調用。本例中給出了函數SysRun和函數ExeFunction的定義,分別用于菜單操作和系統功能函數的調用。例子中調用了例3.1和例3.2中的函數,而其余函數的定義沒有給出。

#include "dorm.h"

void SysRun( )

{

INPUT_RECORD inRec;

DWORD res;

COORD pos = {0, 0};

BOOL bRet = TRUE;

int i, loc, num;

int cNo, cAtt; //cNo:字符單元層號, cAtt:字符單元屬性

char vkc, asc; //vkc:虛擬鍵代碼, asc:字符的ASCII碼值

while (bRet) { // 循環

ReadConsoleInput(hIn, &inRec, 1, &res);

if (inRec.EventType == MOUSE_EVENT) {

pos = inRec.Event.MouseEvent.dwMousePosition; /* pos 是坐標 */

cNo = ScrAtt[pos.Y * ScrCol + pos.X] & 3;

cAtt = ScrAtt[pos.Y * ScrCol + pos.X] >> 2;

if (cNo == 0) {

if (cAtt > 0 && cAtt != SelMenu && TopLayer->LayerNo > 0) {

PopOff();

SelSMenu = 0;

PopMenu(cAtt);

}

}

else if (cAtt > 0) {

TagSMenu(cAtt);

}

if (inRec.Event.MouseEvent.dwButtonState

== FROM_LEFT_1ST_BUTTON_PRESSED) {

if (cNo == 0) {

if (cAtt > 0) {

PopMenu(cAtt);

}

else if (TopLayer->LayerNo > 0) {

PopOff();

SelSMenu = 0;

}

}

else {

if (cAtt > 0) {

PopOff();

SelSMenu = 0;

bRet = ExeFunction(SelMenu, cAtt);

}

}

}

else if (inRec.Event.MouseEvent.dwButtonState

== RIGHTMOST_BUTTON_PRESSED) {

if (cNo == 0) {

PopOff();

SelSMenu = 0;

}

}

}

else if (inRec.EventType == KEY_EVENT

&& inRec.Event.KeyEvent.bKeyDown) {

vkc = inRec.Event.KeyEvent.wVirtualKeyCode;

asc = inRec.Event.KeyEvent.uChar.AsciiChar;

//系統快捷鍵的處理

if (vkc == 112) { //F1鍵

if (TopLayer->LayerNo != 0) {

PopOff();

SelSMenu = 0;

}

bRet = ExeFunction(5, 1); //F1幫助主題

}

else if (inRec.Event.KeyEvent.dwControlKeyState

& (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) {

switch (vkc) { //組合鍵Alt+字母

case 88: if (TopLayer->LayerNo != 0) {

PopOff();

SelSMenu = 0;

}

bRet = ExeFunction(1,4); break; //Alt+X 退出

case 70: PopMenu(1); break; //Alt+F

case 77: PopMenu(2); break; //Alt+M

case 81: PopMenu(3); break; //Alt+Q

case 83: PopMenu(4); break; //Alt+S

case 72: PopMenu(5); break; //Alt+H

}

}

else if (asc == 0) { //方向鍵的處理

if (TopLayer->LayerNo == 0) { //未彈出子菜單時

switch (vkc) { //方向鍵(左、右、下)的處理

case 37: SelMenu--;

if (SelMenu == 0) {

SelMenu = 5;

}

TagMenu(SelMenu); break;

case 39: SelMenu++;

if (SelMenu == 6) {

SelMenu = 1;

}

TagMenu(SelMenu); break;

case 40: PopMenu(SelMenu);

TagSMenu(1); break;

}

}

else { //已彈出子菜單時

for (loc=0,i=1; i<SelMenu; i++) {

loc += cSMenu[i-1];

} //找到子菜單第一項在子菜單數組中的位置(下標)

switch (vkc) { //方向鍵(左、右、上、下)的處理

case 37: SelMenu--;

if (SelMenu < 1) {

SelMenu = 5;

}

TagMenu(SelMenu); PopOff();

PopMenu(SelMenu); TagSMenu(1);

break;

case 38: num = SelSMenu - 1;

if (num < 1) {

num = cSMenu[SelMenu-1];

}

if (strlen(SMenu[loc+num-1]) == 0) {

num--;

}

TagSMenu(num); break;

case 39: SelMenu++;

if (SelMenu > 5) {

SelMenu = 1;

}

TagMenu(SelMenu); PopOff();

PopMenu(SelMenu); TagSMenu(1);

break;

case 40: num = SelSMenu + 1;

if (num > cSMenu[SelMenu-1]) {

num = 1;

}

if (strlen(SMenu[loc+num-1]) == 0) {

num++;

}

TagSMenu(num); break;

}

}

}

else if ((asc-vkc == 0) || (asc-vkc == 32)){ //按下普通鍵

if (TopLayer->LayerNo == 0) { //未彈出子菜單時

switch (vkc) {

case 70: PopMenu(1); break; //f或F

case 77: PopMenu(2); break; //m或M

case 81: PopMenu(3); break; //q或Q

case 83: PopMenu(4); break; //s或S

case 72: PopMenu(5); break; //h或H

case 13: PopMenu(SelMenu); //回車

TagSMenu(1); break;

}

}

else { //已彈出子菜單時的鍵盤輸入處理

if (vkc == 27) { //按下ESC鍵時, 關閉子菜單

PopOff();

SelSMenu = 0;

}

else if(vkc == 13) { //|| vkc == 32

num = SelSMenu;

PopOff();

SelSMenu = 0;

bRet = ExeFunction(SelMenu, num);

}

else {

for (loc=0,i=1; i<SelMenu; i++) {

loc += cSMenu[i-1];

}

for (i=loc; i<loc+cSMenu[SelMenu-1]; i++) {

if (strlen(SMenu[i])>0 && vkc==SMenu[i][1]) {

PopOff();

SelSMenu = 0;

bRet = ExeFunction(SelMenu, i-loc+1);

}

}

}

}

}

}

}

}

BOOL ExeFunction(int m, int s)

{

BOOL bRet = TRUE;

BOOL (*pFunction[cSMenu[0]+cSMenu[1]+cSMenu[2]+cSMenu[3]+cSMenu[4]])(void);

int i, loc;

//pFunction

pFunction[0] = DataSave;

pFunction[1] = DataBackup;

pFunction[2] = DataRestore;

pFunction[3] = SySexit;

pFunction[4] = MaintainSex;

pFunction[5] = MaintainType;

pFunction[6] = NULL;

pFunction[7] = MaintainDorm;

pFunction[8] = MaintainStu;

pFunction[9] = MaintainCharge;

pFunction[10] = QuerySex;

pFunction[11] = QueryType;

pFunction[12] = NULL;

pFunction[13] = QueryDorm;

pFunction[14] = QueryStu;

pFunction[15] = QueryCharge;

pFunction[16] = StatIn;

pFunction[17] = StatType;

pFunction[18] = StatCharge;

pFunction[19] = StatUncharge;

pFunction[20] = HelpTopic;

pFunction[21] = NULL;

pFunction[22] = AboutDorm;

for (i=1,loc=0; i<m; i++) {

loc += cSMenu[i-1];

}

loc += s - 1;

if (pFunction[loc] != NULL) {

bRet = (*pFunction[loc])();

}

return bRet;

}

演示并解釋例3.1 menu_ex3_2

作者:liaojiaohong https://www.bilibili.com/read/cv12993546 出處:bilibili

以上就是關于pos機交互過程,CodeBlock下的人機交互界面設計的知識,后面我們會繼續為大家整理關于pos機交互過程的知識,希望能夠幫助到大家!

轉發請帶上網址:http://www.bangarufamily.com/newsone/67210.html

你可能會喜歡:

版權聲明:本文內容由互聯網用戶自發貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如發現本站有涉嫌抄襲侵權/違法違規的內容, 請發送郵件至 babsan@163.com 舉報,一經查實,本站將立刻刪除。