C語言控制臺界面編程(修正版)_第1頁
C語言控制臺界面編程(修正版)_第2頁
C語言控制臺界面編程(修正版)_第3頁
C語言控制臺界面編程(修正版)_第4頁
C語言控制臺界面編程(修正版)_第5頁
已閱讀5頁,還剩23頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、這就是控制臺窗口,與傳統(tǒng)的DOS屏幕窗口相比最主要的區(qū)別有:C+、掌握交互C+啲Windows圖形界面應(yīng)用程序,涉及知Visual C+ 6.0開發(fā)環(huán)境中,如何編寫具有美觀清晰控制臺窗口界面編程控制0、摘要一、概述二、控制臺文本窗口的一般控制步驟三、控制臺窗口操作四、文本屬性操作五、文本輸出六、文本操作示例七、滾動和移動八、光標操作九、讀取鍵盤信息 十、讀取鼠標信息 十一、結(jié)語補充篇-經(jīng)典程序(In ternet 資源)摘要:文本界面的控制臺應(yīng)用程序開發(fā)是深入學習C+掌握交互系統(tǒng)的實現(xiàn)方法的最簡單的一種手段。然而,Visual C+的C+專用庫卻沒有TC所支持的文本(字符)屏幕控制函數(shù),為此本

2、系列文章從一般控制步驟、控制臺窗口操作、文本(字符)控制、滾動和移動光標、鍵盤和鼠標等幾個方面討論控制臺窗口界面的編程控制方法。在眾多C+開發(fā)工具中,由于 Microsoft本身的獨特優(yōu)勢,選用 Visual C+已越來越 被眾多學習者所接受。顯然,現(xiàn)今如果還再把TC作為開發(fā)環(huán)境的話,不僅沒有必要,而且也不利于向 Windows應(yīng)用程序開發(fā)的過渡。然而,Visual C+的C+傳用庫卻沒有 TC所支持的文本屏幕(控制臺窗口)控制函數(shù)(相應(yīng)的頭文件是 conio.h)。這必然給C+學習者在文 本界面設(shè)計和編程上帶來諸多不便。要知道,文本界面設(shè)計是一種深入學習 系統(tǒng)的實現(xiàn)方法的最簡單的一種手段,它

3、不像 識過多。為此,本系列文章來討論在 的控制臺窗口界面的C+應(yīng)用程序。(一)概述操作所謂控制臺應(yīng)用程序, 就是指那些需要與傳統(tǒng) DOS操作系統(tǒng)保持某種程序的兼容,同時又不需要為用戶提供完善界面的程序。 簡單地講,就是指在Windows環(huán)境下運行的DOS程序。 一旦控制臺應(yīng)用程序在 Win dows操作系統(tǒng)中運行后,就會彈出一個窗口。例如下列代碼:#in clude int main (i nt argc,char *argv)prin tf(Hello, Co nsole!n); return 0;單擊小型編譯工具欄中的“Build ”按鈕或按F7鍵,系統(tǒng)出現(xiàn)一個對話框,詢問是否將此項目的工

4、作文件夾設(shè)定源文件所在的文件夾,單擊是按鈕,系統(tǒng)開始編譯。單擊小型編譯工具欄中的“Execute Program”按鈕或按Ctrl+F5鍵,運行剛才的程序。程序運行后,彈出下圖的窗口 :2鈕E址血脈 1“1“CniCni frfr ULfULf lala cockttituacockttitua精選文庫2GetStdHa ndle(1)默認的控制臺窗口有系統(tǒng)菜單和標題,它是一個內(nèi)存緩沖區(qū)窗口,緩沖區(qū)大小取決于Windows操作系統(tǒng)的分配; 而DOS屏幕是一種物理窗口,不具有 Windows窗口特性,其大小取決于ROM BlOS分配的內(nèi)存空間。(2)控制臺窗口的文本操作是調(diào)用低層的Win32 A

5、PIs,而DOS屏幕的文本操作是通過調(diào)用BlOS的16(10h)中斷而實現(xiàn)的。(3)默認的控制臺窗口可以接收鍵盤和鼠標的輸入信息,設(shè)備驅(qū)動由 Windows管理,而DOS屏幕窗口接收鼠標時需要調(diào)用33h中斷,且鼠標設(shè)備驅(qū)動程序由自己安裝。(二)控制臺文本窗口的一般控制步驟在Visual C+ 6.0 中,控制臺窗口界面的一般編程控制步驟如下:調(diào)用 獲取當前的標準輸入(STDlN)和標準輸出(STDOUT設(shè)備句柄。函數(shù)原型為:HANDLE GetStdHa ndle( DWORD n StdHa ndle );其中,nStdHandle可以是STD_lNPUT_HANDL標準輸入設(shè)備句柄)、 S

6、TD_OUTPUT_HAND標準輸出設(shè)備句柄 )和STD_ERROR_HANDLB(準錯誤句柄)。需要說明的是,句柄”是Win dows最常用的概念。它通常用來標識Win dows資源(如菜單、圖標、窗口等)和設(shè)備等對象。雖然可以把句柄理解為是一個指針變量類型,但它不 是對象所在的地址指針,而是作為Win dows系統(tǒng)內(nèi)部表的索引值來使用的。調(diào)用相關(guān)文本界面控制的API函數(shù)。這些函數(shù)可分為三類。一是用于控制臺窗口操作的函數(shù)(包括窗口的緩沖區(qū)大小、窗口前景字符和背景顏色、窗口標題、大小和位置等);二是用于控制臺輸入輸出的函數(shù)(包括字符屬性操作函數(shù));其他的函數(shù)并為最后一類。調(diào)用CloseHand

7、le()來關(guān)閉輸入輸出句柄。注意,在程序中還必須包含頭文件windows.h。下面看一個程序:#in clude #in clude #in clude int mai n(void)HANDLE hOut;CONSOLE_SCREEN_BUFFER_INFO bl nfo; / 存儲窗口信息COORD pos = 0, 0;/獲取標準輸出設(shè)備句柄hOut = GetStdHa ndle(STD_OUT PU T_HANDLE);/獲取窗口信息GetCo nsoleScree nBufferl nfo(hOut, &bl nfo );prin tf(nn The soul selects he

8、r own societyn);prin tf(The n shuts the door n);pnntf(On her devi ne majorityn);prin tf(Obtrude no morenn);_getch();/向窗口中填充字符以獲得清屏的效果FillConsoleOutputCharacter(hOut, blnfo.dwSize.X * blnfo.dwSize.Y,pos,NULL);/關(guān)閉標準輸出設(shè)備句柄CloseHa ndle(hOut); return 0;程序中,COOR和CONSOLE_SCREEN_BUFFER_ INF(Wincon.h定義的控制臺結(jié)構(gòu)

9、體類 型,其原型如下:/坐標結(jié)構(gòu)體typ edef struct _COORD SHORT X;SHORT Y; COORD;/控制臺窗口信息結(jié)構(gòu)體精選文庫3當前光標位置重新設(shè)置緩沖區(qū)大小重置窗口位置和大小1,typ edef struct _CONSOLE_SCREEN_BUFFER_INFO COORD dwSize; / 緩沖區(qū)大小COORD dwCursorPositio n; /WORD wAttributes; /字符屬性SMALL_RECT srWin dow; /當前窗口顯示的大小和位置 COORD dwMaximumWindowSize; / 最大的窗口緩沖區(qū)大小 CONSO

10、LE_SCREEN_BUFFER_INFO ;還需要說明的是,雖然在C+中,iostream.h 定義了 cin和cout的標準輸入和輸出流對象。但它們只能實現(xiàn)基本的輸入輸出操作,對于控制臺窗口界面的控制卻無能為力,而且不能與stdio.h 和conio.h友好相處,因為iostream.h 和它們是C+兩套不同的輸入 出操作方式,使用時要特別注意。(三)控制臺窗口操作操作用于控制臺窗口操作的 API函數(shù)如下:GetCo nsoleScree nBufferl nfo獲取控制臺窗口信息GetCo nsoleTitle獲取控制臺窗口標題ScrollCo nsoleScree nBuffer在緩沖

11、區(qū)中移動數(shù)據(jù)塊SetCo nsoleScree nBufferSize更改指定緩沖區(qū)大小SetCo nsoleTitle 設(shè)置控制臺窗口標題SetCo nsoleWi ndowl nfo設(shè)置控制臺窗口信息此外,還有窗口字體、顯示模式等控制函數(shù),這里不再細說。下列舉一個示例,程序如 下:#in clude #in clude #in clude int mai n(void)char strTitle255;CONSOLE_SCREEN_BUFFER_INFO bI nfo; / 窗口緩沖區(qū)信息COORD size = 80, 25;HANDLE hOut = GetStdHa ndle(STD

12、_OUT PU T_HANDLE); / 獲取標準輸出設(shè)備句柄 GetCo nsoleScree nBufferl nfo(hOut, &bI nfo ); /獲取窗口緩沖區(qū)信息GetCo nsoleTitle(strTitle, 255); /獲取窗口標題prin tf(當前窗口標題是:n %sn, strTitle);_getch();SetConsoleTitle(”控制臺窗口操作);/ 設(shè)置窗口標題GetCo nsoleTitle(strTitle, 255); prin tf(當前窗口標題是:n %sn, strTitle);_getch();SetC on soleScree nB

13、ufferSize(hOut,size); /_getch();SMALL_RECT rc = 0,0, 80-1,25-1; /SetCo nsoleWi ndowl nfo(hOut,true,&rc);CloseHa ndle(hOut); /關(guān)閉標準輸出設(shè)備句柄return 0;需要說明的是,控制臺窗口的原點坐標是(0, 0),而最大的坐標是緩沖區(qū)大小減如當緩沖區(qū)大小為80*25時,其最大的坐標是(79, 24)。(四)文本屬性操作操作精選文庫4與DOS字符相似,控制臺窗口中的字符也有相應(yīng)的屬性。 背景色和雙字節(jié)字符集(DBCS)屬性三種。 美觀的界面。顏色屬性都是一些預(yù)定義標識:FO

14、REGROUND_BL藍色 FOREGROUND_GR綠色 FOREGROUND_R紅色 FOREGROUND_INTENSITY雖 BACKGROUND_BL藍色 背景 BACKGROUND_GRE綠色背景 BACKGROUND_RE色背景 BACKGROUND_INTENSITY景 色加強 COMMON_LVB_REVERSE_VIDB色 與文本屬性相關(guān)的主要函數(shù)有: BOOL FillCo nsoleOut putAttribute( / HANDLE hCo nsoleOut put, / 句柄 WORD wAttribute, /文本屬性DWORD nLe ngth, / 個數(shù) CO

15、ORD dwWriteCoord, / 開始位置 LP DWORD lpNu mberOfAttrsWritte n II );BOOL SetCo nsoleTextAttribute( HANDLE hCo nsoleOut put, / 句柄 WORD wAttributes /文本屬性);BOOL WriteCo nsoleOut putAttribute( HANDLE hCo nsoleOut put, / 句柄 CONST WORD *lp Attribute, / 屬性DWORD nLe ngth, / 個數(shù) COORD dwWriteCoord, / 起始位置 LP DWOR

16、D lpNu mberOfAttrsWritte n );這些屬性分為:文本的前景色、 事實上,我們最關(guān)心是文本顏色, 這樣可以構(gòu)造出填充字符屬性返回填充的個數(shù)設(shè)置WriteConsole等函數(shù)的字符屬性在指定位置處寫屬性已寫個數(shù)填充指定數(shù)據(jù)的字符另外,獲取當前控制臺窗口的文本屬性是通過調(diào)用函數(shù)GetCo nsoleScree nBufferl nfo后,在 CONSOLE_SCREEN_ BUFFER結(jié)構(gòu)成員 wAttributes 中得到。(五)文本輸出操作文本輸出函數(shù)有:BOOL FillCo nsoleOut putCharacter( /HANDLE hCo nsoleOut put

17、, / 句柄TCHAR cCharacter, / 字符DWORD nLe ngth, / 字符個數(shù)COORD dwWriteCoord, / 起始位置LP DWORD lpNu mberOfCharsWritte n /已寫個數(shù));BOOL WriteCo nsole( /在當前光標位置處插入指定數(shù)量的字符HANDLE hCo nsoleOut put, / 句柄CONST VOID *lp Buffer, /字符串DWORD nNu mberOfCharsToWrite, / 字符個數(shù)LP DWORD lpNu mberOfCharsWritte n, /已寫個數(shù)精選文庫5LP VOID

18、lp Reserved /保留);BOOL WriteCo nsoleOut pu t( /向指定區(qū)域?qū)憥傩缘淖址鸋ANDLE hCo nsoleOut put, / 句柄精選文庫6在指定位置處插入指定數(shù)量的字符繪制邊框獲取窗口緩沖區(qū)信息CONST CHAR_INFO *lp Buffer, /字符數(shù)據(jù)區(qū)COORD dwBufferSize, / 數(shù)據(jù)區(qū)大小COORD dwBufferCoord, / 起始坐標P SMALL_RECT I pWriteRegio n /要寫的區(qū)域);BOOL WriteCo nsoleOut putCharacter( / HANDLE hCo nsoleO

19、ut put, /句柄LP CTSTR lp Character, /字符串DWORD nLe ngth, / 字符個數(shù) COORD dwWriteCoord, / 起始位置 LP DWORD lp NumberOfCharsWritte n /已寫個數(shù));可以看出:WriteCo nsoleOut put 函數(shù)功能相當于 SetCo nsoleTextAttribute和WriteConsole 的功能。而 WriteConsoleOutputCharacter函數(shù)相當于SetConsoleCursorPosition(設(shè)置光標位置)和WriteConsole的功能。不過在具體使用要注意它們

20、的區(qū)別。(六)文本操作示例操作下面看一個示例程序:/在具有陰影效果的窗口中顯示一行字符#i nclude HANDLE hOut;void ShadowWi ndowL in e(char *str);void DrawBox(bool bSi ngle, SMALL_RECT rc); /int mai n(void) hOut = GetStdHa ndle(STD_OUT PU T_HANDLE); / 獲取標準輸出設(shè)備句柄 SetConsoleOutputCP(437); /設(shè)置代碼頁,這里如果設(shè)置成936 (簡體中文),那么程序會怎樣?那樣的話,將畫不出邊框。ShadowWi ndo

21、wL in e(Dis play a line of words, and cen ter the window with shadow.);CloseHa ndle(hOut); /關(guān)閉標準輸出設(shè)備句柄return 0;void ShadowWi ndowL in e(char *str)SMALL_RECT rc;CONSOLE_SCREEN_BUFFER_INFO bI nfo; / 窗口緩沖區(qū)信息WORD attO,att1,attText; int i, chNum = strle n(str); GetCo nsoleScree nBufferl nfo( hOut, &bI nf

22、o ); / /計算顯示窗口大小和位置 rc丄 eft = (bI nfo.dwSize.X - chNum)/2 - 2;rc.Top = 8; /原代碼段中此處為 bI nfo.dwSize.Y/2 - 2,但是如果您的 DOS屏幕有垂直滾動條的話,還需要把滾動條下拉才能看到,為了方便就把它改為10rc.Right = rc.Left + chNum + 4;rc.Bottom = rc.T op + 4;att0 = BACKGROUND_INTENSITY; / 陰影屬性att1 = FOREGROUND_RED |FOREGROUND_GREEN |FOREGROUND_BLUE |

23、 FOREGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_BL文本;屬性 attText = FOREGROUND_RED |FOREGROUND_INTENSITY; /文本屬性/設(shè)置陰影然后填充精選文庫7寫文本和邊框恢復原來的屬性函數(shù)功能:畫邊框左上角點 右上角點 左下角點 右下角點 水平 堅直左上角點 右上角點 左下角點 右下角點 水平 堅直畫邊框的上下邊界COORD posShadow = rc.Left+1, rc.To p+1, posText = rc.Left, rc.To p;for (i=0; i5; i+)FillCo nso

24、leOut pu tAttribute(hOut, att0, chNum + 4, posShadow, NULL); po sShadow.Y+;for (i=0;i5;i+)FillCo nsoleOut pu tAttnbute(hOut, att1,chNum + 4, posText, NULL); po sText.Y+;/posText.X = rc.Left + 2;po sText.Y = rc.T op + 2;WriteCo nsoleOut putCharacter(hOut, str, strle n(str), p osText, NULL); DrawBox(t

25、rue, rc);SetCo nsoleTextAttribute(hOut, bI nfo.wAttributes); /void DrawBox(bool bSi ngle, SMALL_RECT rc) /char chBox 6;COORD pos;if (bSi ngle)chBox0 = (char)0 xda; / chBox1 = (char)0 xbf; / chBox2 = (char)OxcO; / chBox3 = (char)0 xd9; / chBox4 = (char)0 xc4; / chBox 5 = (char)0 xb3; /elsechBox0 = (c

26、har)0 xc9; / chBox1 = (char)0 xbb; / chBox2 = (char)0 xc8; / chBox3 = (char)0 xbc; / chBox4 = (char)Oxcd; / chBox 5 = (char)0 xba; /for(pos.X = rc.Left+1; po s.Xrc.Right-1; po s.X+)pos.Y = rc.T op;/ 畫上邊界WriteCo nsoleOut putCharacter(hOut, & chBox4, 1, pos, NULL);/ 畫左上角if(po s.X = rc.Left+1)pos.X-;Wr

27、iteCo nsoleOut pu tCharacter(hOut, & chBox0,1, pos, NULL);精選文庫8畫右下角P OS.X+;/畫右上角if(p os.X = rc.Right-2)p os.X+;WriteCo nsoleOut putCharacter(hOut, &chBox1, 1, pos, NULL); p os.X-;pos.Y = rc.Bottom;/畫下邊界WriteCo nsoleOut putCharacter(hOut, & chBox4, 1, pos, NULL);/畫左下角if(po s.X = rc.Left+1)pos.X-;Writ

28、eCo nsoleOut pu tCharacter(hOut, &chBox2, 1, pos, NULL); p os.X+;/if(p os.X=rc.Right-2)p os.X+;WriteCo nsoleOut putCharacter(hOut, &chBox3, 1, pos, NULL); p os.X-;/畫邊框的左右邊界for (po s.Y = rc.Top+1; p os.Y=rc.Bottom-1; po s.Y+)pos.X = rc.Left;/畫左邊界WriteCo nsoleOut putCharacter(hOut, & chBox5, 1, pos, N

29、ULL);p os.X = rc.Right-1;/畫右邊界WriteCo nsoleOut putCharacter(hOut, & chBox5, 1, pos, NULL);程序運行結(jié)果如下圖所示:SaSa E:E:;W W VDVZJftlCpCN5CiLECVDVZJftlCpCN5CiLEC qconsoqconso f-2f-2 exeexeFLTSS anan 中 hchc I I u u 匚 outout iiiuciiiucILcplavILcplav a.a. lineline ofof uardcuardc andand c&rtBr-c&rtBr- thethe 討I

30、ndouIndou uithuith DJiadou.DJiadou.精選文庫9需要說明的是:在上述例子中,如果調(diào)用DrawBox函數(shù)時,傳遞的第一個參數(shù)不是true而是false ,那么畫出來的邊框?qū)⑹请p線的。運行結(jié)果如下::;:;MYWyiJGMYWyiJG R R cncn NOLRDFhNOLRDFh urarKurarK rrrr F2.舟h s s AHAH屮 keykey toto ?an?an t t inueinueH H f.f. splaysplay a a lineline atatandand centercenter thethe ulndnuulndnu ulEt

31、iulEti 如果在上述程序無法編譯通過,您可以這樣修改,即程序中調(diào)用WriteConsoleOutputCharacter和 FillConsoleOutputAttribute函數(shù)的時候,最后一個參數(shù)不用NULL而是先定義一個變量:DWORD writte n;然后把&written作為最后一個參數(shù)。 上述程序在不同的字符代碼頁面(code page)下顯示的結(jié)果是不同的。例如,中文Windows操作系統(tǒng)的默認代碼頁是簡體中文(936),在該代碼頁面下值超過128的單字符在Windows NT/XP是顯示不出來的。下表列出了可以使用的代碼頁。代碼頁(Code page)說明1258越南文1

32、257波羅的海文1256阿拉伯文1255希伯來文1254土耳其語1253希臘文1252拉丁文(ANSI)1251斯拉夫文1250中歐文950繁體中文949韓文936簡體中文932日文874泰文850使用多種語言(MS-DOS 丁文)437MS-DOS美語/英語(七)滾動和移動操作ScrollConsoleScreenBuffer是實現(xiàn)文本區(qū)滾動和移動的API函數(shù)。它可以將指定的一塊文本區(qū)域移動到另一個區(qū)域,被移空的那塊區(qū)域由指定字符填充。函數(shù)的原型如下:BOOL ScrollCo nsoleScree nBuffer(HANDLE hCo nsoleOut put, / 句柄CONST SMA

33、LL_RECT* lp ScrollRecta ngle, /要滾動或移動的區(qū)域CONST SMALL_RECT* lp Cli pRecta ngle, /裁剪區(qū)域COORD dwDest in atio nOrigi n, /新的位置精選文庫10移動文本塊區(qū)域設(shè)置光標位置關(guān)閉標準輸出設(shè)備句柄CONST CHAR_INFO* lpF ill /填充字符);利用這個API函數(shù)還可以實現(xiàn)刪除指定行的操作。下面來舉一個例子,程序如下#in clude #in clude #in clude HANDLE hOut;void DeleteLi ne(int row); /刪除一行void MoveT

34、ext(i nt x, i nt y, SMALL_RECT rc); /void ClearScree n(void); /清屏int mai n(void)hOut = GetStdHa ndle(STD_OUT PU T_HANDLE); /獲取標準輸出設(shè)備句柄WORD att = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY | BACKGROUND_BLUE;背景是藍色,文本顏色是黃色SetC on soleTextAttribute(hOut, att);ClearScree n();prin tf(nn The

35、soul selects her own societyn);prin tf(The n shuts the door;n); printf(On her devi ne majority;n);prin tf(Obtrude no more.nn ”);COORD endPos = 0, 15;SetCo nsoleCursorPositio n(hOut, endP os); /SMALL_RECT rc = 0, 2, 40, 5;_getch();MoveText(10, 5, rc);_getch();DeleteLi ne(5);CloseHa ndle(hOut); /retur

36、n 0;void DeleteL in e(i nt row)SMALL_RECT rcScroll, rcCli p;COORD crDest = 0, row - 1;CHAR_INFO chFill;CONSOLE_SCREEN_BUFFER_INFO bI nfo;GetCo nsoleScree nBufferl nfo( hOut, &bI nfo ); rcScroll.Left = 0;rcScroll.T op = row;rcScroll.Right = bl nfo.dwSize.X - 1;rcScroll.Bottom = bI nfo.dwSize.Y - 1;rc

37、Clip = rcScroll;chFill.Attributes = bln fo.wAttributes; chFill.Char.AsciiChar =;ScrollCo nsoleScree nBuffer(hOut, & rcScroll, & rcCli p, crDest, & chFill);void MoveText(i nt x, i nt y, SMALL_RECT rc) COORD crDest = x, y;CHAR_INFO chFill;CONSOLE_SCREEN_BUFFER_INFO bl nfo;GetCo nsoleScree nBufferl nfo

38、( hOut, &bl nfo ); chFill.Attributes = bl nfo.wAttributes;chFill.Char.AsciiChar =;精選文庫11ScrollCo nsoleScree nBuffer(hOut, &rc, NULL, crDest, & chFill); void ClearScree n( void)CONSOLE_SCREEN_BUFFER_INFO bl nfo; GetCo nsoleScree nBufferl nfo( hOut, &bl nfo );COORD home = 0, 0;WORD att = bln fo.wAttri

39、butes;un sig ned long size = bln fo.dwSize.X * bln fo.dwSize.Y; FillCo nsoleOut pu tAttribute(hOut, att, size, home, NULL); FillCo nsoleOut pu tCharacter(hOut, , size, home, NULL);程序中,實現(xiàn)刪除行的操作DeleteL ine的基本原理是:首先將裁剪區(qū)域和移動區(qū)域都設(shè)置成指定行row(包括該行)以下的控制臺窗口區(qū)域, 然后將移動的位置指定為(0, row-1)。 這樣,超出裁剪區(qū)域的內(nèi)容被裁剪掉,從而達到刪除行的目的

40、。需要說明的是,若裁剪區(qū)域參數(shù)為NULL則裁剪區(qū)域為整個控制臺窗口。(八)光標操作操作控制臺窗口中的光標反映了文本插入的當前位置,通過SetCo nsoleCursorPositi on函數(shù)可以改變這個“當前”位置,這樣就能控制字符(串)輸出。事實上,光標本身的大小和顯示或隱藏也可以通過相應(yīng)的API函數(shù)進行設(shè)定。例如:BOOL SetCo nsoleCursorl nfo( /設(shè)置光標信息HANDLE hCo nsoleOut put, /句柄CONST CONSOLE_CURSOR_lNFO *lpCon soleCursorl nfo / 光標信息);BOOL GetCo nsoleCur

41、sorl nfo( /獲取光標信息HANDLE hCo nsoleOut put, /句柄P CONSOLE_CURSOR_lNFO l pCon soleCursorl nfo / 返回光標信息);這兩個函數(shù)都與 CONSOLE_CURSOR_IN結(jié)構(gòu)體類型有關(guān),其定義如下:typ edef struct _CONSOLE_CURSOR_INFO DWORD dwSize; /光標百分比大小BOOL bVisible; /是否可見 CONSOLE_CURSOR_INFO, * PCONSOLE_CURSOR_INFO;需要說明的是,dwSize值反映了光標的大小,它的值范圍為1-100 ;當

42、為1時,光標最小,僅是一條最靠下的水平細線,當為100,光標最大,為一個字符大小的方塊。(九)讀取鍵盤信息操作鍵盤事件通常有字符事件和按鍵事件,這些事件所附帶的信息構(gòu)成了鍵盤信息。是通過API函數(shù)ReadConsoleInput來獲取的,其原型如下:BOOL ReadCo nsole Inp ut(HANDLE hCo nsolel nput, /輸入設(shè)備句柄PINPU T_RECORD lp Buffer, /返回數(shù)據(jù)記錄DWORD nLen gth, / 要讀取的記錄數(shù)LPDWORD lpNumberOfEventsRead / 返回已讀取的記錄數(shù));其中,INPU T_RECOR定義如下

43、:typ edef struct _INPU T_RECORD WORD EventType; / 事件類型精選文庫12F面的程序是將用戶按鍵的字NUM LOCK CAPS LOCK和 SCROLL LOCK這個自定義函數(shù)在第六章用過將ch輸入到指定的窗口中 在最后一行顯示控制鍵的狀態(tài) 刪除指定窗口中最上面的行并滾動union KEY_EVENT_RECORD KeyEve nt;MOUSE_EVENT_RECORD MouseEve nt;WINDOW_BUFFER_SIZE_RECORD Win dowBufferSizeEve nt; MENU_EVENT_RECORD Men uEve

44、 nt;FOCUS_EVENT_RECORD FocusEve nt; Event; INPU T_RECORD;與鍵盤事件相關(guān)的記錄結(jié)構(gòu)KEY_EVENT_RECO定義如下:typ edef struct _KEY_EVENT_RECORD BOOL bKeyDown; / TRUE表示鍵按下,F(xiàn)ALSE表示鍵釋放WORD wRe peatCou nt; / 按鍵次數(shù)WORD wVirtualKeyCode; /虛擬鍵代碼WORD wVirtualSca nCode; /虛擬鍵掃描碼union WCHAR Un icodeChar; / 寬字符 CHAR AsciiChar; / ASCII

45、 字符 uChar; / 字符 DWORD dwCo ntrolKeyState; /控制鍵狀態(tài) KEY_EVENT_RECORD;我們知道,鍵盤上每一個有意義的鍵都對應(yīng)著一個唯一的掃描碼,雖然掃描碼可以作為鍵的標識,但它依賴于具體設(shè)備的。 因此,在應(yīng)用程序中,使用的往往是與具體設(shè)備無關(guān)的 虛擬鍵代碼。這種虛擬鍵代碼是與設(shè)備無關(guān)的鍵盤編碼。在Visual C+中,最常用的虛擬鍵代碼已被定義在 Winuser.h中,例如:VK_SHIFT表示SHIFT鍵,VK_F1表示功能鍵F1等。 上述結(jié)構(gòu)定義中,dwCo ntrolKeyState 用來表示控制鍵狀態(tài),它可以是CAP SLOCK_ON(CA

46、 PSLOCK燈亮)、ENHANCED_KE按下擴展鍵)、LEFT_ALT_PRESSE按下左 ALT鍵)、 LEFT_CTRL_PRESSE按下左 CTRL鍵)、NUMLOCK_ON NUMLOCK燈亮)、RIGHT_ALT_PRESSE按 下右 ALT鍵)、RIGHT_CTRL_PRESSE按下右 CTRL鍵)、SCROLLLOCK_ON(SCROIL LOCK燈亮) 和SHIFT_PRESSED按下SHIFT鍵)中的一個或多個值的組合。符輸入到一個控制臺窗口的某個區(qū)域中,并當按下 鍵時,在控制臺窗口的最后一行顯示這些鍵的狀態(tài)。#i nclude HANDLE hOut;HANDLE hi

47、n;void DrawBox(bool bSi ngle, SMALL_RECT rc); /void ClearScree n( void);void CharWi ndow(char ch, SMALL_RECT rc); /void Con trolStatus(DWORD state); /void DeleteTo pLi ne(SMALL_RECT rc); /int mai n(void)hOut = GetStdHa ndle(STD_OUT PU T_HANDLE); / 獲取標準輸出設(shè)備句柄 hIn = GetStdHa ndle(STD_ INPU T_HANDLE);

48、/獲取標準輸入設(shè)備句柄WORD att = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY | BACKGROUND_BLUE ; /背景是藍色,文本顏色是黃色SetC on soleTextAttribute(hOut, att);ClearScree n(); / 清屏 INPU T_RECORD keyRec; DWORD state = 0, res; char ch;SMALL_RECT rc = 20, 2, 40, 12;精選文庫13設(shè)置光標位置設(shè)置光標位置 關(guān)閉標準輸出設(shè)備句柄關(guān)閉標準輸入設(shè)備句柄將ch輸入到指定

49、的窗口中static COORD chPos = rc.Left+1, rc.To p+1;SetCo nsoleCursorPositio n(hOut, chPo s); IIif (ch0 x7e)/return;WriteCo nsoleOut putCharacter(hOut, &ch, 1, chPos, NULL); if (chP os.X = (rc.Right-2)chP os.X = rc.Left;chP OS.Y+;if (chP os.Y(rc.Bottom-1)DeleteTop Li ne(rc);chP os.Y = rc.Bottom-1;chP OS.X

50、+;SetCo nsoleCursorPositio n(hOut, chPo s); II=設(shè)置光標位置如果是不可打印的字符,具體查看ASCII碼表設(shè)置光標位置DrawBox(false, rc);COORD pos = rc.Left+1, rc.To p+1;SetC on soleCursorPositi on( hOut, po s); II for(;) / 循環(huán)ReadCo nsolel np ut(hl n, & keyRec, 1, & res);if (state != keyRec.Eve nt.KeyEve nt.dwC on trolKeyState) state =

51、 keyRec.Eve nt.KeyEve nt.dwC on trolKeyState; Con trolStatus(state);if (keyRec.Eve ntType = KEY_EVENT)if (keyRec.Eve nt.KeyEve nt.wVirtualKeyCode = VK_ESCA PE) break;II按ESC鍵退出循環(huán)if (keyRec.Eve nt.KeyEve nt.bKeyDow n)ch = keyRec.Eve nt.KeyEve nt.uChar.AsciiChar; CharWi ndow(ch, rc);p os.X = 0; p os.Y

52、= 0;SetC on soleCursorPositi on( hOut, po s); IICloseHa ndle(hOut); IICloseHa ndle(hl n); IIreturn 0;void CharWi ndow(char ch, SMALL_RECT rc) / 精選文庫14在第一行顯示控制鍵的狀態(tài)bl nfo.dwSize.Y-1恢復原來的屬性恢復原來的光,但為了更便于觀察,原來此處為void Con trolStatus(DWORD state) /CONSOLE_SCREEN_BUFFER_INFO bI nfo;GetCo nsoleScree nBufferl

53、 nfo( hOut, &bI nfo );COORD home = 0, 24; / 原來此處為 bI nfo.dwSize.Y-1我把這里稍微修改了一下WORD att0 = BACKGROUND_INTENSITY ;WORD att1 = FOREGROUND_GREEN | FOREGROUND_INTENSITY | BACKGROUND_RED;FillCo nsoleOut putAttnbute(hOut, att0, bI nfo.dwSize.X, home, NULL);FillCo nsoleOut pu tCharacter(hOut, , bln fo.dwSiz

54、e.X, home, NULL);SetC on soleTextAttribute(hOut, att1);COORD sta Pos = bI nfo.dwSize.X-16,24; /SetCo nsoleCursorPositio n(hOut, sta Pos);if (state & NUMLOCK_ON)WriteC on sole(hOut, NUM, 3, NULL, NULL);sta Pos.X += 4;SetCo nsoleCursorPositio n(hOut, sta Pos);if (state & CAP SLOCK_ON)WriteC on sole(hO

55、ut, CA PS, 4, NULL, NULL);sta Pos.X += 5;SetCo nsoleCursorPositio n(hOut, sta Pos);if (state & SCROLLLOCK_ON)WriteC on sole(hOut, SCROLL, 6, NULL, NULL);SetCo nsoleTextAttnbute(hOut, bI nfo.wAttributes); /SetCo nsoleCursorPositio n(hOut, bI nfo.dwCursorPositio n); /標位置void DeleteTo pLin e(SMALL_RECT

56、 rc)COORD crDest;CHAR_INFO chFill;SMALL_RECT rcClip = rc;rcCli p.Left+;rcCli p.Right -= 2;rcCli p.Top+;rcCli p.Bottom-;crDest.X = rcCli p.Left;crDest.Y = rcCli p.Top - 1;CONSOLE_SCREEN_BUFFER_INFO bI nfo;GetCo nsoleScree nBufferl nfo( hOut, &bI nfo );chFill.Attributes = bI nfo.wAttributes;chFill.Cha

57、r.AsciiChar =;ScrollCo nsoleScree nBuffer(hOut, & rcCli p, & rcCli p, crDest, & chFill);void ClearScree n( void)CONSOLE_SCREEN_BUFFER_INFO bI nfo;GetCo nsoleScree nBufferl nfo( hOut, &bI nfo );COORD home = 0, 0;WORD att = bl nfo.wAttributes;精選文庫15un sig ned long size = bln fo.dwSize.X * bln fo.dwSiz

58、e.Y;精選文庫16FillCo nsoleOut pu tAttribute(hOut, att, size, home, NULL); FillCo nsoleOut pu tCharacter(hOut, , size, home, NULL); /函數(shù)功能:畫邊框void DrawBox(bool bSin gle, SMALL_RECT rc)char chBox 6;COORD pos;if (bSi ngle)chBox0 = (char)0 xda; / chBox1 = (char)0 xbf; / chBox2 = (char)OxcO; / chBox3 = (char)

59、0 xd9; / chBox4 = (char)0 xc4; / chBox 5 = (char)0 xb3; /else左上角點 右上角點 左下角點 右下角點 水平 堅直chBox0 = (char)0 xc9; / chBox1 = (char)Oxbb; / chBox2 = (char)0 xc8; / chBox3 = (char)0 xbc; / chBox4 = (char)Oxcd; / chBox 5 = (char)0 xba; /左上角點 右上角點 左下角點 右下角點 水平 堅直/for(pos.X = rc.Left+1; po s.Xrc.Right-1; po s.

60、X+) pos.Y = rc.T op;/ 畫上邊界WriteCo nsoleOut pu tCharacter(hOut, & chBox4, 1, pos, NULL);/ 畫左上角if(pos.X = rc.Left+1)畫邊框的上下邊界P OS.X-;WriteCo nsoleOut pu tCharacter(hOut, & chBox0,1, pos, NULL);p os.X+;/if(po s.X = rc.Right-2) 畫右上角p os.X+;WriteCo nsoleOut pu tCharacter(hOut, &chBox1, 1, pos, NULL); pos.

溫馨提示

  • 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論