版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第5章文字與字體高級編程技術(shù)第七講
使用定義好的與設(shè)備無關(guān)的字體集,
Windows就能維護它的設(shè)備無關(guān)性,提供“所見即所得”的好處,即屏幕所見與設(shè)備輸出的文本是一樣的。
Windows經(jīng)常使用GDI進行文本輸出。在一定意義上,任何內(nèi)容都可以看成圖形實體圖形和文本并沒有明顯的界限文本操作先要獲得文本句柄設(shè)置字體、字符大小、字符顏色等有關(guān)屬性將這些屬性選入設(shè)備環(huán)境字體邏輯字體定義的字符集是設(shè)備無關(guān)的,它可以精確標(biāo)度,因此得到廣泛應(yīng)用描述所要顯示的文本的大小、類型和外形物理字體是為特殊設(shè)備設(shè)計的,因而是設(shè)備相關(guān)的Win系統(tǒng)提供了七種基本字體字體 說明 ANSI_FIXED ANSI標(biāo)準(zhǔn)的固定寬度的字體ANSI_VAR ANSI標(biāo)準(zhǔn)的可變寬度的字體
DEFAULT_GUI 當(dāng)前GUI的默認字體
OEM_FIXED 由標(biāo)準(zhǔn)原設(shè)備制造商(OEM)提供 DEVICE_DEFAULT 當(dāng)前圖形設(shè)備的字體 SYSTEM_FIXED Windows的標(biāo)準(zhǔn)固定寬度的字體SYSTEM Windows提供的可變寬度的字體
常作為默認字體
Win用它作為系統(tǒng)界面字體5.1設(shè)置文本的設(shè)備環(huán)境
5.1.1字體句柄(1)定義字體句柄變量:
HFONThF;//hF為字體的句柄(2)調(diào)函數(shù)GetStockObject獲得系統(tǒng)字體句柄它返回的是系統(tǒng)的默認字體
hF=GetStockObject():(3)調(diào)用函數(shù)SelectObject將字體選入設(shè)備環(huán)境
SelectObject(hdc,hF);選擇系統(tǒng)字體的步驟
若需要定義系統(tǒng)以外的字體,可以調(diào)用函數(shù)GreateFont自行創(chuàng)建HFont=CreateFont(intnHeight, //字體高度,0采用系統(tǒng)默認值,使用邏輯單位
intnWidth, //字體寬度,取0則由系統(tǒng)根據(jù)高寬比取最佳值
intnEscapement, //每行文字相對于頁底的角度,單位為0.1度
intnOrienation, //每個文字相對于頁底的角度,單位為0.1度
DWORDnWeight, //字體粗細度,范圍為0~1000DWORDDwltalic, //如果要求字體傾斜,則取非零
DWORDdwUnderline, //如果要求下劃線,則取非零
DWORDdwStrikeout, //如果要求中劃線,則取非零
DWORDdwCharset, //字體所屬字符集
DWORDdwOutputPrecision,//輸出精度,一般取默認值OUT_DEFAULT_PRECISDWORDdwClipPrecision,//剪裁精度,常取默認值CLIP_DEFAULT_PRECISDWORDdwQuality, //輸出質(zhì)量,一般取默認值DEFAULT_QUALITYDWORDdwPitchAndFamily,//字體名)可選的系統(tǒng)字符集:ANSI_CHARSETOEM_CHARSETSYMBOL_CHARSETDEFAULT_CHARSETSHIFTJIS_CHARSET5.1.2創(chuàng)建自定義字體
設(shè)置字體顏色:SetTextColor(hdc,crColor);設(shè)置背景顏色:SetBkColor(hdc,crColor);crColor為設(shè)置的顏色字體及背景顏色的設(shè)置在開發(fā)過程中非常重要5.1.3設(shè)置字體和背景顏色
確定后續(xù)文本坐標(biāo)確定換行時文本坐標(biāo)文本輸出過程獲取字體信息格式化文本調(diào)用函數(shù)輸出文本5.2文本的輸出過程
獲取字體信息輸出文本之前要獲取字體的信息,如字符高度等,以確定輸出格式和下一行字符的位置
GetTextMetrics(hdc,&tm);//tm為TEXTMETRICS結(jié)構(gòu)獲取當(dāng)前使用字體信息調(diào)用該函數(shù)時,系統(tǒng)將當(dāng)前字體的信息拷貝到tm標(biāo)識的TEXTMETRICS結(jié)構(gòu)中系統(tǒng)定義的TEXTMETRICS的結(jié)構(gòu)如下:typedefstructtagTEXTMETRIC{ //tmLONGtmHeight; //字符高度LONGtmAscent; //字符基線以上高度LONGtmDescent; //字符基線以下高度LONGtmInternalLeading; //tmHeight制訂的字符高度頂部的控件LONGtmExternalLeading; //行與行之間的間隔LONGtmAveCharWidth; //平均字符寬度LONGtmMaxCharWidth; //最大字符寬度LONGtmWeight; //字符的粗細度LONGtmOverhang; //合成字體間附加的寬度LONGtmDigitizedAspectX; //為輸出設(shè)備設(shè)計的X軸尺寸LONGtmDigitizedAspectY; //為輸出設(shè)備設(shè)計的Y軸尺寸BCHARtmFirstChar; //字體中第一個字符值BCHARtmLastChar; //字體中最后一個字符值BCHARtmDefaultChar; //代替不在字體中字符的字符BCHARtmBreakChar; //作為分割符的字符BYTEtmItalic; //非0則表示字體為斜體BYTEtmUnderlined; //非0則表示字體有下劃線BYTEtmStruckOut; //非0則表示字符為刪除字體BYTEtmPitchAndFamily; //字體間距和字體族BYTEtmCharSet; //字符集}TEXTMETRIC格式化文本(1)確定后續(xù)文本坐標(biāo)換行時確定下一行文本的坐標(biāo)需要格式化處理的情況在文本行中確定后續(xù)文本的坐標(biāo)確定后續(xù)文本的坐標(biāo),應(yīng)先獲取當(dāng)前的字符串的寬度,
該工作由GetTextExtentPoint32函數(shù)完成,并把它存儲于一個SIZE結(jié)構(gòu)中。BooLGetTextExtentPoint32(
HDChdc,
LPCTSTRlpszString,//指定的字符串
intnLength, //字符串中的字符數(shù)
LPSIZElpSize
//返回字符串寬度及高度的SIZE數(shù)據(jù)結(jié)構(gòu)的地址)SIZE數(shù)據(jù)結(jié)構(gòu)的定義typedefstructtagSIZE{LONGcx;
LONGcy;
}SIZE;例如,X軸起始坐標(biāo)為cx0,后續(xù)文本起始坐標(biāo)cx1為:
cx1=cx0+size.cx;(2)確定換行時文本坐標(biāo)字符的高度與行間隔均存儲在tm指向的TEXTMETRICS結(jié)構(gòu)中,換行時Y軸上文本的起始坐標(biāo)cy為:
cy=tm.tmHeight+tm.tmExternalLeading;
通過計算當(dāng)前行文本字符的高度與行間隔之和,即可得到換行時文本的起始坐標(biāo)文本輸出
常用的文本輸出函數(shù)TextOut原型如下:BOOLTextOut(
HDChdc,
intX,intY, //X,Y為用戶區(qū)中字符串的起始坐標(biāo)
LPCTSTRlpstring,//lpstring為顯示的字符串
intnCount //nCount為字符串中的字節(jié)數(shù)
);TextOut
以坐標(biāo)X,Y為起點,輸出字節(jié)數(shù)為nCount、名為lpstring中的字符串【例5-1】在用戶窗口上輸出幾行字符串,當(dāng)窗口接收到WM_PAINT消息后,顯示的文本每次都被重新刷新。#include<windows.h>#include<stdlib.h>#include<string.h>longWINAPIWndProc(
HWNDhWnd,
UINTiMessage,
UINTwParam,
LONGlParam
);BOOLInitWindowsClass(HINSTANCEhInstance);BOOLInitWindows(HINSTANCEhInstance,intnCmdShow);HWNDhWndMain;5.3文本操作實例
//主函數(shù)intWINAPIWinMain(
HINSTANCEhInstance,
HINSTANCEhPrevInstance,
LPSTRlpCmdLine,
intnCmdShow){
MSGMessage;
if(!InitWindowsClass(hInstance)) returnFALSE;
if(!InitWindows(hInstance,nCmdShow))returnFALSE;
while(GetMessage(&Message,0,0,0))//消息循環(huán)
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
returnMessage.wParam;}//消息處理函數(shù)longWINAPIWndProc(HWNDhWnd,UINTiMessage,UINTwParam,LONGlParam){
staticlongnXChar,nCaps,nYChar;
HDChDC;//定義指向設(shè)備上下文的句柄
shortx;
TEXTMETRICtm;
shortLnCount=6;
PAINTSTRUCTPtStr;//定義指向包含繪圖信息的結(jié)構(gòu)體變量
staticchar*textbuf[]= {
"ThisistheFirstline",
"Thisisthesecondline",
"Thisisthethirdline",
"Thisisthefourthline",
"Thisisthefifthline",
"Thisisthesixthline"
};輸出的文本內(nèi)容switch(iMessage)//處理消息
{caseWM_CREATE: //處理窗口創(chuàng)建消息
hDC=GetDC(hWnd); //獲取當(dāng)前設(shè)備表句柄
GetTextMetrics(hDC,&tm); //獲取字體信息
nXChar=tm.tmAveCharWidth; //獲取字符寬度
nYChar=tm.tmHeight+tm.tmExternalLeading; nCaps=(tm.tmPitchAndFamily&1?3:2)*nXChar/2; ReleaseDC(hWnd,hDC); //釋放當(dāng)前設(shè)備句柄
return0;
caseWM_PAINT: //處理重畫消息
hDC=BeginPaint(hWnd,&PtStr); //開始繪畫
for(x=0;x<LnCount;x=x+1) //輸出文本
TextOut(hDC,nXChar,nYChar*(1+x),textbuf[x],lstrlen(textbuf[x])); EndPaint(hWnd,&PtStr); return0;
caseWM_DESTROY: //結(jié)束應(yīng)用程序
PostQuitMessage(0); return0;default: //其他消息處理程序
return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}}BOOLInitWindowsClass(HINSTANCEhInstance) //初始化窗口類{
WNDCLASSWndClass;
…………;
WndClass.style=CS_HREDRAW|CS_VREDRAW;
returnRegisterClass(&WndClass);}BOOLInitWindows(HINSTANCEhInstance,intnCmdShow)//初始化窗口{
HWNDhWnd;
hWnd=CreateWindow("WinText",//生成窗口
"文本顯示示例程序", WS_OVERLAPPEDWINDOW,
…….; NULL);
if(!hWnd) returnFALSE;
hWndMain=hWnd;
ShowWindow(hWnd,nCmdShow); //顯示窗口
UpdateWindow(hWnd);
returnTRUE;}【例5-2】本程序通過在窗口中分五行分別顯示五行文本,以說明在窗口的用戶區(qū)中輸出文本的方法。本例題的源代碼如下:#include<windows.h>#include<string.h>#include<stdlib.h>#include<stdio.h>LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);intWINAPIWinMain(HINSTANCEhInstance,
HINSTANCEhPrevInst,LPSTRlpszCmdLine,intnCmdShow){
HWNDhwnd;
MSGMsg;
WNDCLASSwndclass;
charlpszClassName[]="文本輸出";
charlpszTitle[]="EXAMPLEFORTHETEXTOUTPUT";
wndclass.style=0;
…………;
wndclass.lpszClassName=lpszClassName;if(!RegisterClass(&wndclass)) {MessageBeep(0);returnFALSE; }hwnd=CreateWindow( lpszClassName,
lpszTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);ShowWindow(hwnd,nCmdShow);UpdateWindow(hwnd);while(GetMessage(&Msg,NULL,0,0)) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}returnMsg.wParam;}LRESULTCALLBACKWndProc(HWNDhwnd,UINTmessage, WPARAMwParam,LPARAMlParam){
HDChdc;HFONThF_black,hF_big; //定義兩種字體句柄PAINTSTRUCTps;TEXTMETRICtm; //定義一個TEXTMETRIC結(jié)構(gòu),用以記錄字體信息charlpsz_1[]=這是一行紅色的、字體為SYSTEM_FONT的文字,紅色代表未來。";charlpsz_2[]=現(xiàn)在顯示的是自定義字體,顏色為綠色,綠色代表生機勃勃。";charlpsz_3[]=現(xiàn)在展現(xiàn)在您面前的是藍色的粗體字,藍色代表廣闊的海洋和天空。";charlpsz_4[]="當(dāng)前字體為大號、斜體并帶有下劃線的文字。";charlpsz_5[]="現(xiàn)在您掌握了字體的操作了嗎?";charlpsz_6[]="祝您成功!";intX=0,Y=0;SIZEsize; //定義一個SIZE類型的結(jié)構(gòu)switch(message){
caseWM_PAINT: hdc=BeginPaint(hwnd,&ps); SetTextColor(hdc,RGB(255,0,0)); //設(shè)置文本顏色為紅色
GetTextMetrics(hdc,&tm);//獲取默認字體,寫入tm結(jié)構(gòu)中
TextOut(hdc,X,Y,lpsz_1,strlen(lpsz_1));//用當(dāng)前字體輸出文本
Y=Y+tm.tmHeight+100*tm.tmExternalLeading; //計算換行時下一行文本的輸出坐標(biāo)
hF_black=CreateFont( //創(chuàng)建自定義字體
20, //字體的高度
0, //由系統(tǒng)根據(jù)高寬比選取字體最佳寬度值
0, //文本的傾斜度為0,表示水平
0, //字體的傾斜度為0 FW_HEAVY, //字體的粗度,F(xiàn)W_HEAVY為最粗
0, //非斜體字
0, //無下劃線
0, //無刪除線
ANSI_CHARSET, //表示所用的字符集為ANSI_CHARSET OUT_DEFAULT_PRECIS, //輸出精度為默認精度
CLIP_DEFAULT_PRECIS, //剪裁精度為默認精度
DEFAULT_QUALITY, //輸出質(zhì)量為默認值
DEFAULT_PITCH|FF_DONTCARE,//字間距和字體系列使用默認值
"粗體字"); //字體名稱
SetTextColor(hdc,RGB(0,255,0)); //設(shè)置文本顏色為綠色
SelectObject(hdc,hF_black); //將自定義字體選入設(shè)備環(huán)境
GetTextMetrics(hdc,&tm);//獲取字體的信息,寫入tm結(jié)構(gòu)中
TextOut(hdc,X,Y,lpsz_2,strlen(lpsz_2));//用當(dāng)前字體輸出文本
//換行繼續(xù)輸出文本,計算新行的起始Y坐標(biāo)位置
Y=Y+tm.tmHeight+10*tm.tmExternalLeading; GetTextExtentPoint32(hdc,lpsz_2,strlen(lpsz_2),&size); //獲取字符串/的寬度
SetTextColor(hdc,RGB(0,0,255)); //設(shè)置文本顏色為藍色
TextOut(hdc,X,Y,lpsz_3,strlen(lpsz_3));//當(dāng)前字體輸出文本
X=0; //計算下一行文本的輸出起始坐標(biāo)
Y=Y+tm.tmHeight+20*tm.tmExternalLeading;hF_big=CreateFont //引入新字體
(30, //字體高度
0, 0, 0, FW_NORMAL, 1, //定義斜體
1, //定義輸出時帶下劃線
0, ANSI_CHARSET, //所使用的字符集
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE, "大號字"
); SelectObject(hdc,hF_big);//將自定義字體選入設(shè)備環(huán)境
SetTextColor(hdc,RGB(155,155,155)); //設(shè)置文本顏色
Y=Y+tm.tmHeight+20*tm.tmExternalLeading; TextOut(hdc,X,Y,lpsz_4,strlen(lpsz_4));//輸出文本
SetTextColor(hdc,RGB(255,0,0));//設(shè)置文本顏色為紅色
X=0; //設(shè)定輸出文本的X坐標(biāo)位置
Y=Y+tm.tmHeight+30*tm.tmExternalLeading; TextOut(hdc,X,Y,lpsz_5,strlen(lpsz_5)); //輸出文本
//在該行繼續(xù)輸出文本
GetTextExtentPoint32(hdc,lpsz_5,strlen(lpsz_5),&size); //獲取字符串的寬度
X=X+size.cx; //獲取起始坐標(biāo)
TextOut(hdc,X,Y,lpsz_6,strlen(lpsz_6)); //輸出文本
EndPaint(hwnd,&ps); break;caseWM_DESTROY: DeleteObject(hF_black); //退出窗口時刪除自定義字體
DeleteObject(hF_big); PostQuitMessage(0); break;
default: returnDefWindowProc(hwnd,message,wParam,lParam);
}
return0;}第6章Windows應(yīng)用程序
對鍵盤與鼠標(biāo)的響應(yīng)高級編程技術(shù)第七講
掃描碼是依賴于具體設(shè)備的,為達到設(shè)備無關(guān)性的要求,往往使用與具體設(shè)備無關(guān)的虛擬碼,虛擬碼是由Windows系統(tǒng)定義的與設(shè)備無關(guān)的鍵的標(biāo)識由于鍵盤的輸入產(chǎn)生一條消息掃描碼、虛擬碼以及其他與擊鍵有關(guān)的消息設(shè)備驅(qū)動程序截取鍵的掃描碼翻譯虛擬碼它含鍵盤上的鍵對應(yīng)一個唯一的標(biāo)識值(掃描碼)按下或釋放某鍵時產(chǎn)生取出鍵盤消息進行處理消息設(shè)備驅(qū)動程序把消息放到系統(tǒng)的消息隊列中Windows從系統(tǒng)消息隊列中取出消息發(fā)送到相應(yīng)的線程消息隊列中窗口過程6.1鍵盤在應(yīng)用程序中的應(yīng)用
虛擬碼是一種與設(shè)備無關(guān)的鍵盤編碼,它的值存放在鍵盤消息的wParam參數(shù)中,用以標(biāo)識哪一個鍵被按下或釋放,最常用的虛擬碼已經(jīng)在Windows.h中定義。操作系統(tǒng)在接收到鍵盤輸入后把消息發(fā)送給具有“輸入焦點(inputfocus)的窗口應(yīng)用程序一般有幾個窗口,但當(dāng)按下某一個鍵時,只有一個窗口能接收到該鍵盤消息,接收這個鍵盤消息的窗口稱為有“輸入焦點”的窗口有“輸入焦點”的窗口應(yīng)是活動窗口或者活動窗口的子窗口窗口正在接收輸入焦點
窗口函數(shù)通過捕獲WM_SETFOCUS和WM_KILLFOCUS消息確定當(dāng)前窗口是否具有輸入焦點。窗口失去輸入焦點鍵盤消息按鍵消息字符消息按下或松開一個鍵時就產(chǎn)生了一按鍵消息一個按鍵的組合產(chǎn)生了一個可以顯示的字符時,就產(chǎn)生了一個字符消息系統(tǒng)按鍵消息非系統(tǒng)按鍵消息Alt鍵與相關(guān)輸入鍵的組合產(chǎn)生的消息,這些鍵一般由Windows系統(tǒng)內(nèi)部直接處理,應(yīng)用程序不處理若應(yīng)用程序處理了這些系統(tǒng)鍵消息,還要調(diào)用DefWindowsProc()函數(shù),以便不影響系統(tǒng)對它們的處理不使用Alt鍵組合的的按鍵消息按鍵消息的兩個變量wParamlParam32位的變量重復(fù)計數(shù)位(0~15位)OEM掃描碼(16~23位)擴展鍵標(biāo)志(24位)保留位(25~28位)關(guān)聯(lián)碼(29位)鍵的先前狀態(tài)(位30)轉(zhuǎn)換狀態(tài)(31位)包含了識別按下的鍵的虛鍵碼
在WinMain函數(shù)的消息循環(huán)中包含了TranslateMessage函數(shù),其功能是把按鍵消息轉(zhuǎn)化為字符消息,但只有當(dāng)鍵盤驅(qū)動程序把鍵盤字符映射成ASCII碼后才能產(chǎn)生WM_CHAR消息。字符消息系統(tǒng)非系統(tǒng)WM_KEYDOWN和WM_KEYUP的按鍵消息只能產(chǎn)生非系統(tǒng)消息WM_SYSKEYDOWN和WM_SYSKEYUP按鍵消息只能產(chǎn)生系統(tǒng)消息【例6-1】設(shè)計一個窗口,在該窗口中練習(xí)鍵盤的響應(yīng),要求如下:(1)
單擊鍵盤上的向上箭頭時,窗口中顯示“Youhadhittedtheupkey”(2)
單擊<Shift>鍵時,窗口中顯示“YouhadhittedtheSHIFTkey”(3)
單擊<Ctrl>鍵時,窗口中顯示“YouhadhittedtheCTRLkey”(4)
單擊<Ctrl+A>鍵時,窗口中顯示“YouhadhittedtheCTRLAkey”(5)
單擊<Shift+B>鍵時,窗口中顯示“YouhadhittedtheSHIFTBkey”longWINAPIWndProc(HWNDhWnd,UINTiMessage,UINTwParam,LONGlParam){HDChDC; //定義設(shè)備環(huán)境句柄
PAINTSTRUCTps; //定義包含繪圖信息的結(jié)構(gòu)體變量
HPENhPen; //定義畫筆句柄
HBRUSHhBrush; //定義畫刷句柄//以下定義輸出的字符串
staticcharcUp[]="YouhadhittedtheUPkey";staticcharcCtrl[]="YouhadhittedtheCtrlkey";staticcharcShift[]="YouhadhittedtheSHIFTkey";staticcharcCtrl_A[]="YouhadhittedtheCTRLAkey";staticcharcShift_B[]="YouhadhittedtheSHIFTBkey";//下面定義并初始化按鍵標(biāo)志變量
staticBOOLnUpKeyDown=FALSE, nShiftKeyDown=FALSE, nCtrlKeyDown=FALSE, nCtrlAKeyDown=FALSE, nShiftBKeyDown=FALSE;switch(iMessage){caseWM_KEYDOWN: {switch(wParam) {caseVK_UP: //當(dāng)按上箭頭鍵時,變量置為真
nUpKeyDown=TRUE; break;
caseVK_SHIFT: //當(dāng)按Shift鍵時,變量置為真
nShiftKeyDown=TRUE;break;
caseVK_CONTROL: //當(dāng)按Control鍵時,變量置為真
nCtrlKeyDown=TRUE; break; default: break; } }break;
caseWM_KEYUP: InvalidateRect(hWnd,NULL,FALSE); break;caseWM_CHAR:if(wParam==(65&VK_CONTROL)) {if(nCtrlKeyDown==TRUE) {nCtrlAKeyDown=TRUE; nCtrlKeyDown=FALSE;} } elseif(wParam==98||wParam==66) //當(dāng)按下b鍵時
{if(nShiftKeyDown==TRUE) //檢查Shift鍵是否處于按下狀態(tài)。
{nShiftBKeyDown=TRUE; //當(dāng)Shift鍵按下時,變量置為真
nShiftKeyDown=FALSE;} }break;caseWM_PAINT: //處理繪圖消息. hDC=BeginPaint(hWnd,&ps); hBrush=(HBRUSH)GetStockObject(WHITE_BRUSH); //創(chuàng)建白畫刷。
hPen=(HPEN)GetStockObject(WHITE_PEN); //創(chuàng)建白畫筆。
SelectObject(hDC,hPen); //選入白畫刷
SelectObject(hDC,hBrush); //選入白畫筆
SetTextColor(hDC,RGB(255,0,0)); //設(shè)置字體顏色為紅色。//輸出信息。if(nUpKeyDown==TRUE){ Rectangle(hDC,0,0,300,200); TextOut(hDC,0,0,cUp,strlen(cUp)); nUpKeyDown=FALSE;}elseif(nCtrlAKeyDown==TRUE){ Rectangle(hDC,0,0,300,200); TextOut(hDC,0,100,cCtrl_A,strlen(cCtrl_A)); nCtrlAKeyDown=FALSE; nCtrlKeyDown=FALSE;}elseif(nCtrlAKeyDown==TRUE)elseif(nCtrlKeyDown==TRUE&&nCtrlAKeyDown==FALSE){ Rectangle(hDC,0,0,300,200); TextOut(hDC,0,60,cCtrl,strlen(cCtrl)); nCtrlKeyDown=FALSE;}elseif(nShiftBKeyDown==TRUE){ Rectangle(hDC,0,0,300,200); TextOut(hDC,0,0,cShift_B,strlen(cShift_B)); nShiftBKeyDown=FALSE; nShiftKeyDown=FALSE; }elseif(nShiftBKeyDown==FALSE&&nShiftKeyDown==TRUE){ Rectangle(hDC,0,0,300,200); TextOut(hDC,0,0,cShift,strlen(cShift)); nShiftKeyDown=FALSE; }else;//刪除畫筆和畫刷
DeleteObject(hPen); DeleteObject(hBrush); EndPaint(hWnd,&ps); break;caseWM_DESTROY: PostQuitMessage(0); return0;default: return(DefWindowProc(hWnd,iMessage,wParam,lParam));}return0;}用戶窗口區(qū)輸入“這是一個有關(guān)鍵盤操作的示例程序”的字符串程序中緩沖區(qū)大小只設(shè)30個字符,當(dāng)緩沖區(qū)滿時若再輸入任何字符,就出現(xiàn)(1)號錯誤提示用戶按下左箭頭鍵直至光標(biāo)到達本行起始位置時,就無法再往左移動,則出現(xiàn)(2)號錯誤信息若此時您按下Esc鍵,就出現(xiàn)(3)號錯誤提示信息若當(dāng)前光標(biāo)位置處于本行的起始位置,此時按下回退鍵(BackSpace),則出現(xiàn)編號為(4)的錯誤提示信息若字符緩沖區(qū)中已沒有任何字符,此時按下了Delete鍵,則出現(xiàn)(5)號錯誤提示信息【例6-2本例演示鍵盤輸入時所產(chǎn)生的消息序列并在窗口的客戶區(qū)顯示對應(yīng)的字符6.2鍵盤操作應(yīng)用舉例#include<windows.h>#include<stdlib.h>#include<string.h>voidWINAPICaretPos(int*xCaret,int*yCaret);longWINAPIWndProc(HWNDhWnd,UINTiMessage,UINTwParam,LONGlParam);BOOLInitWindowsClass(HINSTANCEhInstance);BOOLInitWindows(HINSTANCEhInstance,intnCmdShow);HWNDhWndMain;longWINAPIWndProc(HWNDhWnd,UINTiMessage,UINTwParam,LONGlParam){
#defineBufSize30 //設(shè)置存放字符的緩沖區(qū)大小
staticcharcCharBuf[BufSize]; //設(shè)置靜態(tài)字符數(shù)組,
//存放輸入的字符,字符個數(shù)不能超出緩沖區(qū)大小
staticintnNumChar=0; //現(xiàn)有字符個數(shù)
staticintnArrayPos=0; //字符的位置
staticintnLnHeight;staticintnCharWidth;staticintxCaret,yCaret;intx;HDChDC;TEXTMETRICtm;PAINTSTRUCTPtStr;//定義指向包含繪圖信息的結(jié)構(gòu)體變量switch(iMessage) //處理消息{caseWM_CHAR: //遇到非系統(tǒng)字符所作的處理
{if(wParam==VK_BACK)//處理遇到回退鍵的消息
{if(nArrayPos==0) //若已在一行文字的開始處,則提示"不能回退"MessageBox(hWnd,“當(dāng)前位置是文本的起始位置,不能回退",NULL,MB_OK);else{nArrayPos=nArrayPos-1;//按一次回退鍵就回退一字符位置
CaretPos(&xCaret,&yCaret); nNumChar=nNumChar-1; //對現(xiàn)有字符總數(shù)進行計數(shù)
InvalidateRect(hWnd,NULL,TRUE);//刷新并發(fā)送WM_PAINT消息
}
break;
}
if(wParam==VK_ESCAPE)//處理按下Escape鍵消息
{MessageBox(hWnd,“您現(xiàn)在不能按ESC鍵,請繼續(xù)其它操作",NULL,MB_OK);break;}if(nNumChar>=BufSize) //如寫入的字符數(shù)超過緩沖區(qū)大小,則報警
{MessageBox(hWnd,“緩沖區(qū)已滿,不能再輸入字符了\n
若需要刪除字符,請用BackSpace鍵",NULL,MB_OK);break;}
for(x=nNumChar;x>nArrayPos;x=x-1) cCharBuf[x]=cCharBuf[x-1];
cCharBuf[nArrayPos]=(unsignedchar)wParam;nArrayPos=nArrayPos+1;nNumChar=nNumChar+1;CaretPos(&xCaret,&yCaret);InvalidateRect(hWnd,NULL,TRUE);}break;caseWM_CREATE://處理窗口創(chuàng)建消息
{ hDC=GetDC(hWnd); GetTextMetrics(hDC,&tm);//獲取字體信息
nLnHeight=tm.tmHeight+tm.tmExternalLeading; nCharWidth=tm.tmAveCharWidth; yCaret=nLnHeight; ReleaseDC(hWnd,hDC); }break;caseWM_SETFOCUS://處理活動焦點消息
{CreateCaret(hWnd,0,0,nLnHeight);CaretPos(&xCaret,&yCaret);ShowCaret(hWnd);//在活動焦點的窗口中顯示插字符
}break;caseWM_KILLFOCUS: //處理失去焦點消息
DestroyCaret();break;caseWM_KEYDOWN: //處理按下鍵消息{
switch(wParam){
caseVK_END: //處理按下鍵為End時的消息
nArrayPos=nNumChar; //輸入位置從本行的末尾開始
CaretPos(&xCaret,&yCaret); break;
caseVK_HOME: //處理按下鍵為Home時的消息
nArrayPos=0; //輸入位置為本行的起始位置CaretPos(&xCaret,&yCaret); break;caseVK_DELETE://處理按下鍵為Delete時的消息
if(nArrayPos==nNumChar)//輸入位置處于本行的末尾
MessageBox(hWnd,"緩沖區(qū)已空,沒有字符可供刪除",NULL,MB_OK);else{for(x=nArrayPos;x<nNumChar;x=x+1) cCharBuf[x]=cCharBuf[x+1];//每刪一字符,緩沖區(qū)中總字符數(shù)減1nNumChar=nNumChar-1;InvalidateRect(hWnd,NULL,TRUE);//用戶區(qū)刷新
}break;caseVK_LEFT://處理按下左方向鍵時的消息
if(nArrayPos>0){nArrayPos=nArrayPos-1;//當(dāng)前輸入位置往前移一個位 置,再輸入字符時,等于插入字符
CaretPos(&xCaret,&yCaret);}else //已經(jīng)移到起始輸入位置,不能再往前了
MessageBox(hWnd,“您已經(jīng)移動到起始位置,不能再往左移動了",NULL,MB_OK);break;caseVK_RIGHT: //處理按下右方向鍵時的消息
if(nArrayPos<nNumChar)//如果當(dāng)前位置沒有到緩沖區(qū)的最后位置,還能向右移動
{nArrayPos=nArrayPos+1;CaretPos(&xCaret,&yCaret);}elseMessageBox(hWnd,“已經(jīng)到緩沖區(qū)的末尾,不能再向右移動了",NULL,MB_OK);break;}}break;caseWM_PAINT://處理重畫消息{hDC=BeginPaint(hWnd,&PtStr);TextOut(hDC,nCharWidth,nLnHeight,cCharBuf,nNumChar);//輸出緩沖區(qū)中文本
EndPaint(hWnd,&PtStr);}break;caseWM_DESTROY: PostQuitMessage(0); break;default:return(DefWindowProc(hWnd,iMessage,wParam,lParam));}return0;}BOOLInitWindowsClass(HINSTANCEhInstance)//初始化窗口類{
WNDCLASSWndClass; WndClass.cbClsExtra=0; ...... WndClass.style=CS_HREDRAW|CS_VREDRAW; returnRegisterClass(&WndClass);}BOOLInitWindows(HINSTANCEhInstance,intnCmdShow)//初始化窗口{ HWNDhWnd;
hWnd=CreateWindow(......); if(!hWnd) returnFALSE; hWndMain=hWnd;
ShowWindow(hWnd,nCmdShow); //顯示窗口
UpdateWindow(hWnd); //繪制用戶區(qū)
returnTRUE;}voidWINAPICaretPos(int*xCaret,int*yCaret) //處理插字符位置的函數(shù){SetCaretPos(*xCaret,*yCaret);} //設(shè)置插字符位置坐標(biāo)鼠標(biāo)作為定位輸入設(shè)備,通過鼠標(biāo)單擊、雙擊和拖動功能,用戶可以很容易地操作基于Windows圖形界面的應(yīng)用程序。Windows中通過光標(biāo)來指示當(dāng)前鼠標(biāo)的位置,在Windows操作系統(tǒng)中預(yù)定義了幾種光標(biāo),并在Windows.h頭文件中加以定義。6.3鼠標(biāo)在應(yīng)用程序中的應(yīng)用
例如,下面的語句為窗口類wndclassWNDCLASSwndclass;…wndclass.hCursor=LoadCursor(hThislnst,IDC_WAIT);…此外,還可在應(yīng)用程序中調(diào)用LoadCursor函數(shù)改變光標(biāo)形式。用戶自定義光標(biāo)自定義光標(biāo)保存在擴展名為.cur的文件中。
光標(biāo)名CURSOR光標(biāo)文件(.cur)采用自定義光標(biāo)時,需在資源文件中定義光標(biāo)資源加載光標(biāo)資源(常在定義窗口類時進行)
LoadCursor(hThisInst,lpszCursorname)當(dāng)前實例句柄當(dāng)前光標(biāo)鼠標(biāo)消息lParam包含了鼠標(biāo)位置低位包含鼠標(biāo)位置的x坐標(biāo)值高位包含鼠標(biāo)位置的y坐標(biāo)wParam包含了指示各種虛鍵狀態(tài)的值相當(dāng)于窗口的左上角為原點的坐標(biāo)值對于鼠標(biāo)消息的處理要對Shift和Ctrl鍵進行監(jiān)測caseWM_LBUTTONDOWN://按下鼠標(biāo)左鍵
if((wParam&MK_CONTROL)&&(wParam&MK_SHIFT))
… //Shift和Ctrl鍵都被按下
break;caseWM_LBUTTONUP: //釋放鼠標(biāo)左鍵
…break;…caseWM_LBUTTONDOWN://按下鼠標(biāo)左鍵
…
break;caseWM_LBUTTONUP: //釋放鼠標(biāo)左鍵
…break;
…不監(jiān)測Windows系統(tǒng)默認的時間間隔為0.5秒,也可以調(diào)用SetDoubleClickTime()重新設(shè)定間隔值若窗口不包含上述屬性的定義,即使進行了雙擊操作,該窗口也只能接收到兩條WM_BUTTONDOWN消息或兩條WN_BUTTONUP消息。鼠標(biāo)雙擊wndclass.style=CS_HEADRAW|CS_VERDRAW|CS_DBLCLKS;要使窗口函數(shù)能接收鼠標(biāo)雙擊產(chǎn)生的消息在注冊窗口類時必須具有CS_DBLCLKS屬性
由于鼠標(biāo)移動的隨機性,如果要使某一個窗口能不間斷地捕獲鼠標(biāo)消息,就必須對鼠標(biāo)加以捕獲SetCapture(hWnd):可以向句柄為hWnd的窗口發(fā)送所有的鼠標(biāo)消息調(diào)用SetCapture()函數(shù)一旦從窗口捕獲了鼠標(biāo),系統(tǒng)的鍵盤功能就暫時失效,其它窗口也無法得到鼠標(biāo)消息當(dāng)該窗口不再需要捕獲鼠標(biāo)消息時,應(yīng)及時調(diào)用ReleaseCapture()以釋放鼠標(biāo),否則,其他窗口無法接收鼠標(biāo)信息。菜單、滾動條工具條和標(biāo)題條等處不由應(yīng)用程序處理而是送往函數(shù)DefWindowProc用戶區(qū)以外的地方產(chǎn)生的鼠標(biāo)事件產(chǎn)生一個非用戶區(qū)鼠標(biāo)消息【例6-2】鼠標(biāo)輸入示范程序,本例介紹如何響應(yīng)鼠標(biāo)信息、并改變光標(biāo)形狀等用法,用戶在窗口的不同區(qū)域移動鼠標(biāo)時,光標(biāo)將顯示如下圖所標(biāo)識的不同箭頭的形狀6.4鼠標(biāo)應(yīng)用程序?qū)嵗?/p>
#include<windows.h>#include<stdio.h>LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInst,LPSTRlpszCmdLine,intnCmdShow){HWNDhwnd; MSGMsg;WNDCLASSwndclass;charlpszClassName[]="窗口";charlpszTitle[]="My_Windows";wndclass.style=0;
…
…
wndclass.lpszClassName=lpszClassName;if(!RegisterClass(&wndclass)) {MessageBeep(0); returnFALSE;}
hwnd=CreateWindow(lpszClassName,lpszTitle,WS_VISIBLE|WS_SYSMENU|WS_MINIMIZEB OX,50,50,450,450,NULL,NULL,hInstance,NULL);ShowWindow(hwnd,nCmdShow);UpdateWindow(hwnd);while(GetMessage(&Msg,NULL,0,0)) {TranslateMessage(&Msg); DispatchMessage(&Msg);} returnMsg.wParam;}LRESULTCALLBACKWndProc(HWNDhwnd,UINTmessage,WPARAMwParam,LPARAMlParam){ PAINTSTRUCTps; HDChdc; TEXTMETRICtm; HBRUSHhbrush; HPENhpen; HCURSORhcursor; charstr[15]; staticintx,y; switch(message){ caseWM_MOUSEMOVE: x=LOWORD(lParam); y=HIWORD(lParam); if(x>50&&x<150&&y>50&&y<150) { hcursor=LoadCursor(NULL,IDC_CROSS); //十字光標(biāo)
SetCursor(hcursor); } if(x>150&&x<250&&y>50&&y<150) { hcursor=LoadCursor(NULL,IDC_SIZEALL);//十字箭頭光標(biāo)
SetCursor(hcursor); }if(x>250&&x<350&&y>50&&y<150){hcursor=LoadCursor(NULL,IDC_SIZENESW);SetCursor(hcursor);}//西南-東北光標(biāo)if(x>50&&x<150&&y>150&&y<250){hcursor=LoadCursor(NULL,IDC_IBEAM);SetCursor(hcursor);}//I字型光標(biāo)if(x>50&&x<150&&y>250&&y<350){hcursor=LoadCursor(NULL,IDC_SIZEWE);SetCursor(hcursor); }//東西向箭頭if(x>150&&x<250&&y>150&&y<250){hcursor=LoadCursor(NULL,IDC_WAIT);SetCursor(hcursor);}//沙漏光標(biāo)if(x>250&&x<350&&y>150&&y<250){hcursor=LoadCursor(NULL,IDC_UPARROW);SetCursor(hcursor);}//向上箭頭光標(biāo)if(x>150&&x<250&&y>250&&y<350){hcursor=LoadCursor(NULL,IDC_SIZENWSE);SetCursor(hcursor);}//西北-東南箭頭if(x>250&&x<350&&y>250&&y<350){hcursor=LoadCursor(NULL,IDC_SIZENS);SetCursor(hcursor); }//南北向箭頭 hdc=GetDC(hwnd); GetTextMetrics(hdc,&tm); hbrush=(HBRUSH)GetStockObject(WHITE_BRUSH); SelectObject(hdc,hbrush); hpen=(HPEN)GetStockObject(WHITE_PEN); SelectObject(hdc,hpen); Rectangle(hdc,5,5,tm.tmAveCharWidth*8,tm.tmHeight+3); sprintf(str,"%d,%d\0",x,y); TextOut(hdc,5,5,str,lstrlen(str)); EndPaint(hwnd,&ps); break;caseWM_PAINT: hdc=BeginPaint(hwnd,&ps); hpen=(HPEN)GetStockObject(BLACK_PEN); SelectObject(hdc,hpen); Rectangle(hdc,50,50,350,350); MoveToEx(hdc,50,150,NULL); LineTo(hdc,350,150);
MoveToEx(hdc,50,250,NULL); LineTo(hdc,350,250);
MoveToEx(hdc,150,50,NULL); LineTo(hdc,150,350);
MoveToEx(hdc,250,50,NULL); LineTo(hdc,250,350); EndPaint(hwnd,&ps); break;caseWM_DESTROY: PostQuitMessage(0);default:returnDefWindowProc(hwnd,message,wParam,lParam);}return(0);}【6-3】編寫一個鼠標(biāo)應(yīng)用程序,按下鼠標(biāo)左鍵在窗口中移動時,將按下左鍵時所在點和當(dāng)前點所形成的矩形涂成灰色,此時光標(biāo)為十字型。當(dāng)抬起鼠標(biāo)左鍵時,將前面所繪制度矩形拉伸到整個窗口,拉伸過程中將光標(biāo)設(shè)置為沙漏型。然后,若雙擊鼠標(biāo)的左鍵,則灰色消失,窗口恢復(fù)到初始狀態(tài)。voidInvertBlock(HWNDhwnd,POINTptBeg,POINTptEnd){HDChdc;hdc=CreateDC("DISPLAY",NULL,NULL,
溫馨提示
- 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)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年個人住宅抵押擔(dān)保合同范文(2篇)
- 2025年度苗木繁殖與種質(zhì)資源保護合同3篇
- 某籃球場草坪工程施工合同
- 禮品購銷合同
- 2024物業(yè)合作協(xié)議合同書
- 2024石膏板購銷及綠色建筑智能化施工合同3篇
- 2024物業(yè)租賃合同協(xié)議條款
- 2024石材加工制作合同書
- 福建省寧德市福鼎民族中學(xué)高一英語模擬試題含解析
- 2025-2030年中國氨綸纖維產(chǎn)業(yè)發(fā)展趨勢及投資建議研究報告
- 2025年度土地經(jīng)營權(quán)流轉(zhuǎn)合同補充條款范本
- 南通市2025屆高三第一次調(diào)研測試(一模)地理試卷(含答案 )
- Python試題庫(附參考答案)
- 聚酯合成副反應(yīng)介紹
- DB37-T 1342-2021平原水庫工程設(shè)計規(guī)范
- 電除顫教學(xué)課件
- 廣東省藥品電子交易平臺結(jié)算門戶系統(tǒng)會員操作手冊
- DB32T 3960-2020 抗水性自修復(fù)穩(wěn)定土基層施工技術(shù)規(guī)范
- 大斷面隧道設(shè)計技術(shù)基本原理
- 41某31層框架結(jié)構(gòu)住宅預(yù)算書工程概算表
- 成都市國土資源局關(guān)于加強國有建設(shè)用地土地用途變更和
評論
0/150
提交評論