版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第5章文字與字體高級(jí)編程技術(shù)第七講
使用定義好的與設(shè)備無(wú)關(guān)的字體集,
Windows就能維護(hù)它的設(shè)備無(wú)關(guān)性,提供“所見(jiàn)即所得”的好處,即屏幕所見(jiàn)與設(shè)備輸出的文本是一樣的。
Windows經(jīng)常使用GDI進(jìn)行文本輸出。在一定意義上,任何內(nèi)容都可以看成圖形實(shí)體圖形和文本并沒(méi)有明顯的界限文本操作先要獲得文本句柄設(shè)置字體、字符大小、字符顏色等有關(guān)屬性將這些屬性選入設(shè)備環(huán)境字體邏輯字體定義的字符集是設(shè)備無(wú)關(guān)的,它可以精確標(biāo)度,因此得到廣泛應(yīng)用描述所要顯示的文本的大小、類型和外形物理字體是為特殊設(shè)備設(shè)計(jì)的,因而是設(shè)備相關(guān)的Win系統(tǒng)提供了七種基本字體字體 說(shuō)明 ANSI_FIXED ANSI標(biāo)準(zhǔn)的固定寬度的字體ANSI_VAR ANSI標(biāo)準(zhǔn)的可變寬度的字體
DEFAULT_GUI 當(dāng)前GUI的默認(rèn)字體
OEM_FIXED 由標(biāo)準(zhǔn)原設(shè)備制造商(OEM)提供 DEVICE_DEFAULT 當(dāng)前圖形設(shè)備的字體 SYSTEM_FIXED Windows的標(biāo)準(zhǔn)固定寬度的字體SYSTEM Windows提供的可變寬度的字體
常作為默認(rèn)字體
Win用它作為系統(tǒng)界面字體5.1設(shè)置文本的設(shè)備環(huán)境
5.1.1字體句柄(1)定義字體句柄變量:
HFONThF;//hF為字體的句柄(2)調(diào)函數(shù)GetStockObject獲得系統(tǒng)字體句柄它返回的是系統(tǒng)的默認(rèn)字體
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)默認(rèn)值,使用邏輯單位
intnWidth, //字體寬度,取0則由系統(tǒng)根據(jù)高寬比取最佳值
intnEscapement, //每行文字相對(duì)于頁(yè)底的角度,單位為0.1度
intnOrienation, //每個(gè)文字相對(duì)于頁(yè)底的角度,單位為0.1度
DWORDnWeight, //字體粗細(xì)度,范圍為0~1000DWORDDwltalic, //如果要求字體傾斜,則取非零
DWORDdwUnderline, //如果要求下劃線,則取非零
DWORDdwStrikeout, //如果要求中劃線,則取非零
DWORDdwCharset, //字體所屬字符集
DWORDdwOutputPrecision,//輸出精度,一般取默認(rèn)值OUT_DEFAULT_PRECISDWORDdwClipPrecision,//剪裁精度,常取默認(rèn)值CLIP_DEFAULT_PRECISDWORDdwQuality, //輸出質(zhì)量,一般取默認(rèn)值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è)置在開(kāi)發(fā)過(guò)程中非常重要5.1.3設(shè)置字體和背景顏色
確定后續(xù)文本坐標(biāo)確定換行時(shí)文本坐標(biāo)文本輸出過(guò)程獲取字體信息格式化文本調(diào)用函數(shù)輸出文本5.2文本的輸出過(guò)程
獲取字體信息輸出文本之前要獲取字體的信息,如字符高度等,以確定輸出格式和下一行字符的位置
GetTextMetrics(hdc,&tm);//tm為T(mén)EXTMETRICS結(jié)構(gòu)獲取當(dāng)前使用字體信息調(diào)用該函數(shù)時(shí),系統(tǒng)將當(dāng)前字體的信息拷貝到tm標(biāo)識(shí)的TEXTMETRICS結(jié)構(gòu)中系統(tǒng)定義的TEXTMETRICS的結(jié)構(gòu)如下:typedefstructtagTEXTMETRIC{ //tmLONGtmHeight; //字符高度LONGtmAscent; //字符基線以上高度LONGtmDescent; //字符基線以下高度LONGtmInternalLeading; //tmHeight制訂的字符高度頂部的控件LONGtmExternalLeading; //行與行之間的間隔LONGtmAveCharWidth; //平均字符寬度LONGtmMaxCharWidth; //最大字符寬度LONGtmWeight; //字符的粗細(xì)度LONGtmOverhang; //合成字體間附加的寬度LONGtmDigitizedAspectX; //為輸出設(shè)備設(shè)計(jì)的X軸尺寸LONGtmDigitizedAspectY; //為輸出設(shè)備設(shè)計(jì)的Y軸尺寸BCHARtmFirstChar; //字體中第一個(gè)字符值BCHARtmLastChar; //字體中最后一個(gè)字符值BCHARtmDefaultChar; //代替不在字體中字符的字符BCHARtmBreakChar; //作為分割符的字符BYTEtmItalic; //非0則表示字體為斜體BYTEtmUnderlined; //非0則表示字體有下劃線BYTEtmStruckOut; //非0則表示字符為刪除字體BYTEtmPitchAndFamily; //字體間距和字體族BYTEtmCharSet; //字符集}TEXTMETRIC格式化文本(1)確定后續(xù)文本坐標(biāo)換行時(shí)確定下一行文本的坐標(biāo)需要格式化處理的情況在文本行中確定后續(xù)文本的坐標(biāo)確定后續(xù)文本的坐標(biāo),應(yīng)先獲取當(dāng)前的字符串的寬度,
該工作由GetTextExtentPoint32函數(shù)完成,并把它存儲(chǔ)于一個(gè)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)確定換行時(shí)文本坐標(biāo)字符的高度與行間隔均存儲(chǔ)在tm指向的TEXTMETRICS結(jié)構(gòu)中,換行時(shí)Y軸上文本的起始坐標(biāo)cy為:
cy=tm.tmHeight+tm.tmExternalLeading;
通過(guò)計(jì)算當(dāng)前行文本字符的高度與行間隔之和,即可得到換行時(shí)文本的起始坐標(biāo)文本輸出
常用的文本輸出函數(shù)TextOut原型如下:BOOLTextOut(
HDChdc,
intX,intY, //X,Y為用戶區(qū)中字符串的起始坐標(biāo)
LPCTSTRlpstring,//lpstring為顯示的字符串
intnCount //nCount為字符串中的字節(jié)數(shù)
);TextOut
以坐標(biāo)X,Y為起點(diǎn),輸出字節(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í)例
//主函數(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: //處理重畫(huà)消息
hDC=BeginPaint(hWnd,&PtStr); //開(kāi)始繪畫(huà)
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】本程序通過(guò)在窗口中分五行分別顯示五行文本,以說(shuō)明在窗口的用戶區(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; //定義一個(gè)TEXTMETRIC結(jié)構(gòu),用以記錄字體信息charlpsz_1[]=這是一行紅色的、字體為SYSTEM_FONT的文字,紅色代表未來(lái)。";charlpsz_2[]=現(xiàn)在顯示的是自定義字體,顏色為綠色,綠色代表生機(jī)勃勃。";charlpsz_3[]=現(xiàn)在展現(xiàn)在您面前的是藍(lán)色的粗體字,藍(lán)色代表廣闊的海洋和天空。";charlpsz_4[]="當(dāng)前字體為大號(hào)、斜體并帶有下劃線的文字。";charlpsz_5[]="現(xiàn)在您掌握了字體的操作了嗎?";charlpsz_6[]="祝您成功!";intX=0,Y=0;SIZEsize; //定義一個(gè)SIZE類型的結(jié)構(gòu)switch(message){
caseWM_PAINT: hdc=BeginPaint(hwnd,&ps); SetTextColor(hdc,RGB(255,0,0)); //設(shè)置文本顏色為紅色
GetTextMetrics(hdc,&tm);//獲取默認(rèn)字體,寫(xiě)入tm結(jié)構(gòu)中
TextOut(hdc,X,Y,lpsz_1,strlen(lpsz_1));//用當(dāng)前字體輸出文本
Y=Y+tm.tmHeight+100*tm.tmExternalLeading; //計(jì)算換行時(shí)下一行文本的輸出坐標(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, //無(wú)下劃線
0, //無(wú)刪除線
ANSI_CHARSET, //表示所用的字符集為ANSI_CHARSET OUT_DEFAULT_PRECIS, //輸出精度為默認(rèn)精度
CLIP_DEFAULT_PRECIS, //剪裁精度為默認(rèn)精度
DEFAULT_QUALITY, //輸出質(zhì)量為默認(rèn)值
DEFAULT_PITCH|FF_DONTCARE,//字間距和字體系列使用默認(rèn)值
"粗體字"); //字體名稱
SetTextColor(hdc,RGB(0,255,0)); //設(shè)置文本顏色為綠色
SelectObject(hdc,hF_black); //將自定義字體選入設(shè)備環(huán)境
GetTextMetrics(hdc,&tm);//獲取字體的信息,寫(xiě)入tm結(jié)構(gòu)中
TextOut(hdc,X,Y,lpsz_2,strlen(lpsz_2));//用當(dāng)前字體輸出文本
//換行繼續(xù)輸出文本,計(jì)算新行的起始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è)置文本顏色為藍(lán)色
TextOut(hdc,X,Y,lpsz_3,strlen(lpsz_3));//當(dāng)前字體輸出文本
X=0; //計(jì)算下一行文本的輸出起始坐標(biāo)
Y=Y+tm.tmHeight+20*tm.tmExternalLeading;hF_big=CreateFont //引入新字體
(30, //字體高度
0, 0, 0, FW_NORMAL, 1, //定義斜體
1, //定義輸出時(shí)帶下劃線
0, ANSI_CHARSET, //所使用的字符集
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_DONTCARE, "大號(hào)字"
); 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); //退出窗口時(shí)刪除自定義字體
DeleteObject(hF_big); PostQuitMessage(0); break;
default: returnDefWindowProc(hwnd,message,wParam,lParam);
}
return0;}第6章Windows應(yīng)用程序
對(duì)鍵盤(pán)與鼠標(biāo)的響應(yīng)高級(jí)編程技術(shù)第七講
掃描碼是依賴于具體設(shè)備的,為達(dá)到設(shè)備無(wú)關(guān)性的要求,往往使用與具體設(shè)備無(wú)關(guān)的虛擬碼,虛擬碼是由Windows系統(tǒng)定義的與設(shè)備無(wú)關(guān)的鍵的標(biāo)識(shí)由于鍵盤(pán)的輸入產(chǎn)生一條消息掃描碼、虛擬碼以及其他與擊鍵有關(guān)的消息設(shè)備驅(qū)動(dòng)程序截取鍵的掃描碼翻譯虛擬碼它含鍵盤(pán)上的鍵對(duì)應(yīng)一個(gè)唯一的標(biāo)識(shí)值(掃描碼)按下或釋放某鍵時(shí)產(chǎn)生取出鍵盤(pán)消息進(jìn)行處理消息設(shè)備驅(qū)動(dòng)程序把消息放到系統(tǒng)的消息隊(duì)列中Windows從系統(tǒng)消息隊(duì)列中取出消息發(fā)送到相應(yīng)的線程消息隊(duì)列中窗口過(guò)程6.1鍵盤(pán)在應(yīng)用程序中的應(yīng)用
虛擬碼是一種與設(shè)備無(wú)關(guān)的鍵盤(pán)編碼,它的值存放在鍵盤(pán)消息的wParam參數(shù)中,用以標(biāo)識(shí)哪一個(gè)鍵被按下或釋放,最常用的虛擬碼已經(jīng)在Windows.h中定義。操作系統(tǒng)在接收到鍵盤(pán)輸入后把消息發(fā)送給具有“輸入焦點(diǎn)(inputfocus)的窗口應(yīng)用程序一般有幾個(gè)窗口,但當(dāng)按下某一個(gè)鍵時(shí),只有一個(gè)窗口能接收到該鍵盤(pán)消息,接收這個(gè)鍵盤(pán)消息的窗口稱為有“輸入焦點(diǎn)”的窗口有“輸入焦點(diǎn)”的窗口應(yīng)是活動(dòng)窗口或者活動(dòng)窗口的子窗口窗口正在接收輸入焦點(diǎn)
窗口函數(shù)通過(guò)捕獲WM_SETFOCUS和WM_KILLFOCUS消息確定當(dāng)前窗口是否具有輸入焦點(diǎn)。窗口失去輸入焦點(diǎn)鍵盤(pán)消息按鍵消息字符消息按下或松開(kāi)一個(gè)鍵時(shí)就產(chǎn)生了一按鍵消息一個(gè)按鍵的組合產(chǎn)生了一個(gè)可以顯示的字符時(shí),就產(chǎn)生了一個(gè)字符消息系統(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)對(duì)它們的處理不使用Alt鍵組合的的按鍵消息按鍵消息的兩個(gè)變量wParamlParam32位的變量重復(fù)計(jì)數(shù)位(0~15位)OEM掃描碼(16~23位)擴(kuò)展鍵標(biāo)志(24位)保留位(25~28位)關(guān)聯(lián)碼(29位)鍵的先前狀態(tài)(位30)轉(zhuǎn)換狀態(tài)(31位)包含了識(shí)別按下的鍵的虛鍵碼
在WinMain函數(shù)的消息循環(huán)中包含了TranslateMessage函數(shù),其功能是把按鍵消息轉(zhuǎn)化為字符消息,但只有當(dāng)鍵盤(pán)驅(qū)動(dòng)程序把鍵盤(pán)字符映射成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è)計(jì)一個(gè)窗口,在該窗口中練習(xí)鍵盤(pán)的響應(yīng),要求如下:(1)
單擊鍵盤(pán)上的向上箭頭時(shí),窗口中顯示“Youhadhittedtheupkey”(2)
單擊<Shift>鍵時(shí),窗口中顯示“YouhadhittedtheSHIFTkey”(3)
單擊<Ctrl>鍵時(shí),窗口中顯示“YouhadhittedtheCTRLkey”(4)
單擊<Ctrl+A>鍵時(shí),窗口中顯示“YouhadhittedtheCTRLAkey”(5)
單擊<Shift+B>鍵時(shí),窗口中顯示“YouhadhittedtheSHIFTBkey”longWINAPIWndProc(HWNDhWnd,UINTiMessage,UINTwParam,LONGlParam){HDChDC; //定義設(shè)備環(huán)境句柄
PAINTSTRUCTps; //定義包含繪圖信息的結(jié)構(gòu)體變量
HPENhPen; //定義畫(huà)筆句柄
HBRUSHhBrush; //定義畫(huà)刷句柄//以下定義輸出的字符串
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)按上箭頭鍵時(shí),變量置為真
nUpKeyDown=TRUE; break;
caseVK_SHIFT: //當(dāng)按Shift鍵時(shí),變量置為真
nShiftKeyDown=TRUE;break;
caseVK_CONTROL: //當(dāng)按Control鍵時(shí),變量置為真
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鍵時(shí)
{if(nShiftKeyDown==TRUE) //檢查Shift鍵是否處于按下?tīng)顟B(tài)。
{nShiftBKeyDown=TRUE; //當(dāng)Shift鍵按下時(shí),變量置為真
nShiftKeyDown=FALSE;} }break;caseWM_PAINT: //處理繪圖消息. hDC=BeginPaint(hWnd,&ps); hBrush=(HBRUSH)GetStockObject(WHITE_BRUSH); //創(chuàng)建白畫(huà)刷。
hPen=(HPEN)GetStockObject(WHITE_PEN); //創(chuàng)建白畫(huà)筆。
SelectObject(hDC,hPen); //選入白畫(huà)刷
SelectObject(hDC,hBrush); //選入白畫(huà)筆
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;//刪除畫(huà)筆和畫(huà)刷
DeleteObject(hPen); DeleteObject(hBrush); EndPaint(hWnd,&ps); break;caseWM_DESTROY: PostQuitMessage(0); return0;default: return(DefWindowProc(hWnd,iMessage,wParam,lParam));}return0;}用戶窗口區(qū)輸入“這是一個(gè)有關(guān)鍵盤(pán)操作的示例程序”的字符串程序中緩沖區(qū)大小只設(shè)30個(gè)字符,當(dāng)緩沖區(qū)滿時(shí)若再輸入任何字符,就出現(xiàn)(1)號(hào)錯(cuò)誤提示用戶按下左箭頭鍵直至光標(biāo)到達(dá)本行起始位置時(shí),就無(wú)法再往左移動(dòng),則出現(xiàn)(2)號(hào)錯(cuò)誤信息若此時(shí)您按下Esc鍵,就出現(xiàn)(3)號(hào)錯(cuò)誤提示信息若當(dāng)前光標(biāo)位置處于本行的起始位置,此時(shí)按下回退鍵(BackSpace),則出現(xiàn)編號(hào)為(4)的錯(cuò)誤提示信息若字符緩沖區(qū)中已沒(méi)有任何字符,此時(shí)按下了Delete鍵,則出現(xiàn)(5)號(hào)錯(cuò)誤提示信息【例6-2本例演示鍵盤(pán)輸入時(shí)所產(chǎn)生的消息序列并在窗口的客戶區(qū)顯示對(duì)應(yīng)的字符6.2鍵盤(pán)操作應(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ù)組,
//存放輸入的字符,字符個(gè)數(shù)不能超出緩沖區(qū)大小
staticintnNumChar=0; //現(xiàn)有字符個(gè)數(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) //若已在一行文字的開(kāi)始處,則提示"不能回退"MessageBox(hWnd,“當(dāng)前位置是文本的起始位置,不能回退",NULL,MB_OK);else{nArrayPos=nArrayPos-1;//按一次回退鍵就回退一字符位置
CaretPos(&xCaret,&yCaret); nNumChar=nNumChar-1; //對(duì)現(xiàn)有字符總數(shù)進(jìn)行計(jì)數(shù)
InvalidateRect(hWnd,NULL,TRUE);//刷新并發(fā)送WM_PAINT消息
}
break;
}
if(wParam==VK_ESCAPE)//處理按下Escape鍵消息
{MessageBox(hWnd,“您現(xiàn)在不能按ESC鍵,請(qǐng)繼續(xù)其它操作",NULL,MB_OK);break;}if(nNumChar>=BufSize) //如寫(xiě)入的字符數(shù)超過(guò)緩沖區(qū)大小,則報(bào)警
{MessageBox(hWnd,“緩沖區(qū)已滿,不能再輸入字符了\n
若需要?jiǎng)h除字符,請(qǐng)用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://處理活動(dòng)焦點(diǎn)消息
{CreateCaret(hWnd,0,0,nLnHeight);CaretPos(&xCaret,&yCaret);ShowCaret(hWnd);//在活動(dòng)焦點(diǎn)的窗口中顯示插字符
}break;caseWM_KILLFOCUS: //處理失去焦點(diǎn)消息
DestroyCaret();break;caseWM_KEYDOWN: //處理按下鍵消息{
switch(wParam){
caseVK_END: //處理按下鍵為End時(shí)的消息
nArrayPos=nNumChar; //輸入位置從本行的末尾開(kāi)始
CaretPos(&xCaret,&yCaret); break;
caseVK_HOME: //處理按下鍵為Home時(shí)的消息
nArrayPos=0; //輸入位置為本行的起始位置CaretPos(&xCaret,&yCaret); break;caseVK_DELETE://處理按下鍵為Delete時(shí)的消息
if(nArrayPos==nNumChar)//輸入位置處于本行的末尾
MessageBox(hWnd,"緩沖區(qū)已空,沒(méi)有字符可供刪除",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://處理按下左方向鍵時(shí)的消息
if(nArrayPos>0){nArrayPos=nArrayPos-1;//當(dāng)前輸入位置往前移一個(gè)位 置,再輸入字符時(shí),等于插入字符
CaretPos(&xCaret,&yCaret);}else //已經(jīng)移到起始輸入位置,不能再往前了
MessageBox(hWnd,“您已經(jīng)移動(dòng)到起始位置,不能再往左移動(dòng)了",NULL,MB_OK);break;caseVK_RIGHT: //處理按下右方向鍵時(shí)的消息
if(nArrayPos<nNumChar)//如果當(dāng)前位置沒(méi)有到緩沖區(qū)的最后位置,還能向右移動(dòng)
{nArrayPos=nArrayPos+1;CaretPos(&xCaret,&yCaret);}elseMessageBox(hWnd,“已經(jīng)到緩沖區(qū)的末尾,不能再向右移動(dòng)了",NULL,MB_OK);break;}}break;caseWM_PAINT://處理重畫(huà)消息{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è)備,通過(guò)鼠標(biāo)單擊、雙擊和拖動(dòng)功能,用戶可以很容易地操作基于Windows圖形界面的應(yīng)用程序。Windows中通過(guò)光標(biāo)來(lái)指示當(dāng)前鼠標(biāo)的位置,在Windows操作系統(tǒng)中預(yù)定義了幾種光標(biāo),并在Windows.h頭文件中加以定義。6.3鼠標(biāo)在應(yīng)用程序中的應(yīng)用
例如,下面的語(yǔ)句為窗口類wndclassWNDCLASSwndclass;…wndclass.hCursor=LoadCursor(hThislnst,IDC_WAIT);…此外,還可在應(yīng)用程序中調(diào)用LoadCursor函數(shù)改變光標(biāo)形式。用戶自定義光標(biāo)自定義光標(biāo)保存在擴(kuò)展名為.cur的文件中。
光標(biāo)名CURSOR光標(biāo)文件(.cur)采用自定義光標(biāo)時(shí),需在資源文件中定義光標(biāo)資源加載光標(biāo)資源(常在定義窗口類時(shí)進(jìn)行)
LoadCursor(hThisInst,lpszCursorname)當(dāng)前實(shí)例句柄當(dāng)前光標(biāo)鼠標(biāo)消息lParam包含了鼠標(biāo)位置低位包含鼠標(biāo)位置的x坐標(biāo)值高位包含鼠標(biāo)位置的y坐標(biāo)wParam包含了指示各種虛鍵狀態(tài)的值相當(dāng)于窗口的左上角為原點(diǎn)的坐標(biāo)值對(duì)于鼠標(biāo)消息的處理要對(duì)Shift和Ctrl鍵進(jìn)行監(jiān)測(cè)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)測(cè)Windows系統(tǒng)默認(rèn)的時(shí)間間隔為0.5秒,也可以調(diào)用SetDoubleClickTime()重新設(shè)定間隔值若窗口不包含上述屬性的定義,即使進(jìn)行了雙擊操作,該窗口也只能接收到兩條WM_BUTTONDOWN消息或兩條WN_BUTTONUP消息。鼠標(biāo)雙擊wndclass.style=CS_HEADRAW|CS_VERDRAW|CS_DBLCLKS;要使窗口函數(shù)能接收鼠標(biāo)雙擊產(chǎn)生的消息在注冊(cè)窗口類時(shí)必須具有CS_DBLCLKS屬性
由于鼠標(biāo)移動(dòng)的隨機(jī)性,如果要使某一個(gè)窗口能不間斷地捕獲鼠標(biāo)消息,就必須對(duì)鼠標(biāo)加以捕獲SetCapture(hWnd):可以向句柄為hWnd的窗口發(fā)送所有的鼠標(biāo)消息調(diào)用SetCapture()函數(shù)一旦從窗口捕獲了鼠標(biāo),系統(tǒng)的鍵盤(pán)功能就暫時(shí)失效,其它窗口也無(wú)法得到鼠標(biāo)消息當(dāng)該窗口不再需要捕獲鼠標(biāo)消息時(shí),應(yīng)及時(shí)調(diào)用ReleaseCapture()以釋放鼠標(biāo),否則,其他窗口無(wú)法接收鼠標(biāo)信息。菜單、滾動(dòng)條工具條和標(biāo)題條等處不由應(yīng)用程序處理而是送往函數(shù)DefWindowProc用戶區(qū)以外的地方產(chǎn)生的鼠標(biāo)事件產(chǎn)生一個(gè)非用戶區(qū)鼠標(biāo)消息【例6-2】鼠標(biāo)輸入示范程序,本例介紹如何響應(yīng)鼠標(biāo)信息、并改變光標(biāo)形狀等用法,用戶在窗口的不同區(qū)域移動(dòng)鼠標(biāo)時(shí),光標(biāo)將顯示如下圖所標(biāo)識(shí)的不同箭頭的形狀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】編寫(xiě)一個(gè)鼠標(biāo)應(yīng)用程序,按下鼠標(biāo)左鍵在窗口中移動(dòng)時(shí),將按下左鍵時(shí)所在點(diǎn)和當(dāng)前點(diǎn)所形成的矩形涂成灰色,此時(shí)光標(biāo)為十字型。當(dāng)抬起鼠標(biāo)左鍵時(shí),將前面所繪制度矩形拉伸到整個(gè)窗口,拉伸過(guò)程中將光標(biāo)設(shè)置為沙漏型。然后,若雙擊鼠標(biāo)的左鍵,則灰色消失,窗口恢復(fù)到初始狀態(tài)。voidInvertBlock(HWNDhwnd,POINTptBeg,POINTptEnd){HDChdc;hdc=CreateDC("DISPLAY",NULL,NULL,
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年度互聯(lián)網(wǎng)廣告行業(yè)勞動(dòng)合同范本及廣告內(nèi)容審核責(zé)任協(xié)議3篇
- 脫丙烷課程設(shè)計(jì)
- 船舶原理課程設(shè)計(jì)散貨船
- 美術(shù)生創(chuàng)新思維課程設(shè)計(jì)
- 線上花束插花課程設(shè)計(jì)
- 茶園生產(chǎn) 課程設(shè)計(jì)
- 線上課程設(shè)計(jì)公司
- 《精神分析技巧》課件
- 2024年美術(shù)教案設(shè)計(jì)(7篇)
- 穿銷單元課程設(shè)計(jì)
- 2024-2025學(xué)年銅官山區(qū)數(shù)學(xué)三年級(jí)第一學(xué)期期末調(diào)研試題含解析
- ISO 56001-2024《創(chuàng)新管理體系-要求》專業(yè)解讀與應(yīng)用實(shí)踐指導(dǎo)材料之18:“7支持-7.1資源”(雷澤佳編制-2025B0)
- ISO 56001-2024《創(chuàng)新管理體系-要求》專業(yè)解讀與應(yīng)用實(shí)踐指導(dǎo)材料之17:“6策劃-6.6合作”(雷澤佳編制-2025B0)
- ISO 56001-2024《創(chuàng)新管理體系-要求》專業(yè)解讀與應(yīng)用實(shí)踐指導(dǎo)材料之16:“6策劃-6.5組織結(jié)構(gòu)”(雷澤佳編制-2025B0)
- GB/T 45016-2024發(fā)動(dòng)機(jī)附件帶傳動(dòng)系統(tǒng)機(jī)械式自動(dòng)張緊輪試驗(yàn)方法
- 南寧市三好學(xué)生主要事跡(8篇)
- 2024版玻璃幕墻工程材料采購(gòu)合同2篇
- 全國(guó)英語(yǔ)教師賽課一等獎(jiǎng)七年級(jí)上冊(cè)(人教2024年新編)《Unit 7 Happy Birthday》教學(xué)設(shè)計(jì)
- 2025年婦產(chǎn)科工作計(jì)劃
- 《寒假安全教育班會(huì)》課件模板四套
- (T8聯(lián)考)2025屆高三部分重點(diǎn)中學(xué)12月第一次聯(lián)考 生物試卷(含答案詳解)
評(píng)論
0/150
提交評(píng)論