




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第6章輸出在多任務環境下,屏幕,打印機等硬件設備都是許多應用程序共享的,因此,任何一個應用程序都不能任意地進行輸出操作,所有的輸出,如屏幕,打印機,繪圖機等,都必須通過GDI(圖形設備接口(GRAPHISCDEVICEINTERFACE)函數來完成輸出.本章表面上是討論的字符串輸出,實際上是討論與設備無關的程序設計基礎。本章例舉了三個例程來說明應用程序的輸出。6.1客戶區的繪制和更新Windows是通過發送WM_PAINT消息給窗口函數,使得窗口顯示輸出。在初始化階段都要調用函數UpdateWindow,執行這個函數的結果是Windows向窗口函數發送第一個WM_PAINT消息。其他還有很多情況下Windows向窗口函數發送WM_PAINT消息,使得被覆蓋的部分客戶區得以重新繪制。
發送WM_PAINT的情況P1026.1客戶區的繪制和更新有效矩形和無效矩形1:Windows內部為每個窗口保存一個「繪圖信息結構」,這個結構包含了包圍無效區域的最小矩形的坐標以及其它信息,這個矩形就叫做「無效矩形」,有時也稱為「無效區域」。如果在窗口消息處理程序處理WM_PAINT消息之前顯示區域中的另一個區域變為無效,則Windows計算出一個包圍兩個區域的新的無效區域(以及一個新的無效矩形),并將這種變化后的信息放在繪制信息結構中。Windows不會將多個WM_PAINT消息都放在消息隊列中。6.1客戶區的繪制和更新有效矩形和無效矩形2:窗口消息處理程序可以通過呼叫InvalidataRect使顯示區域無效.3:在處理WM_PAINT消息處理期間,窗口消息處理程序在呼叫了BeginPaint之后,整個顯示區域即變為有效。程序也可以通過呼叫ValidateRect函數使顯示區域內的任意矩形區域變為有效。如果這呼叫具有令整個無效區域變為有效的效果,則目前隊列中的任何WM_PAINT消息都將被刪除。6.1客戶區的繪制和更新InvalidateRect只是增加重繪區域,在下次WM_PAINT的時候才生效,InvalidateRect函數中的參數TRUE表示系統會在你畫之前用背景色將所選區域覆蓋一次,默認背景色為白色,可以通過設置BRUSH來改變背景色。InvalidateRect(hWnd,&rect,TRUE);向hWnd窗體發出WM_PAINT的消息,強制客戶區域重繪制,rect是你指定要刷新的區域,此區域外的客戶區域不被重繪,這樣防止客戶區域的一個局部的改動,而導致整個客戶區域重繪而導致閃爍,如果最后的參數為TRUE,則還向窗體發送WM_ERASEBKGND消息,使背景重繪,當然在客戶區域重繪之前。UpdateWindow只向窗體發送WM_PAINT消息,在發送之前判斷GetUpdateRect(hWnd,NULL,TRUE)看有無可繪制的客戶區域,如果沒有,則不發送WM_PAINT。如果希望立即刷新無效區域,可以在調用InvalidateRect之后調用UpdateWindow,如果客戶區的任一部分無效,則UpdateWindow將導致Windows用WM_PAINT消息調用窗口過程(如果整個客戶區有效,則不調用窗口過程)。這一WM_PAINT消息不進入消息隊列,直接由WINDOWS調用窗口過程。窗口過程完成刷新以后立刻退出,WINDOWS將控制返回給程序中UpdateWindow調用之后的語句。6.2GDI簡介所有輸出都要通過GDI函數,當執行GDI函數輸出時,可得到與設備無關的輸出,其實現是源于Windows系統中為每一個設備建立一個數據結構,這個結構記錄了設備輸出時的詳細要求,例如,輸出時文字的顏色,線條的寬度,畫圖的坐標,…以及輸出時調用的驅動程序等,這個數據結構稱為設備描述表,簡稱DC。Windows系統中使用設備就抽象成使用DC。這種把設備抽象成為DC是實現設備無關性的關鍵。每個輸出用的GDI函數其第1個參數就是hdc,hdc是指向DC的指針,GDI函數通過設備進行輸出就變成通過DC進行輸出。同樣,要輸出都得要考慮在那個窗口上輸出,為此要為每個輸出窗口建立一個數據結構--繪圖信息結構(PAINTSTRUCT)注意:取得DC,必須釋放DC且必須寫到同一消息處理分支中例:P1056.2.2獲得hDC代號的方法。1.利用GetDC(hWnd)取得窗口hDC.
hdc=GetDC(hwnd);
注意:GetDC不會使任何無效區域變為有效,可以使用validateRect(hwnd,NULL)使整個客戶區有效。
ReleaseDC(hWnd,hdc);
2.處理WM_PAINT消息期間用
BeginPaint獲得hDC的方法。
PAINTSTRUCTps
;
hdc=BeginPaint(hwnd,&ps);
TextOut(hdc,0,0,“Hello,Windows!”,15);
EndPaint(hwnd,&ps);
.
6.2.3繪圖信息結構(PAINTSTRUCT)繪圖信息結構(PAINTSTRUCT)typedef
struct
tagPAINTSTRUCT{ HDC hdc;//輸出設備的設備描述表代號
BOOL fErase;//畫圖區域的背景要否擦去
RECT rcPaint;//畫圖區域坐標,無效矩形的邊界,
BOOL fRestore;//操作系統用
BOOL fIncUpdate;//操作系統用
BYTE rgbReserved[32];//操作系統用}PAINTSTRUCT;通過PAINTSTRUCTps;定義變量,程序調用BeginPaint時,返回值是hDC,Windows會把它填入PAINTSTRUCT中。用戶程序只使用畫圖信息結構的前三個條款,其他條款由Windows操作系統內部使用。hdc條款是BeginPaint的返回值。fErase被標志為FALSE(0),這意味著Windows已經擦除了無效矩形的背景。rcPaint
是一個結構指針,指向RECT結構,RECT結構記錄著畫圖區域坐標,無效矩形的邊界。6.2.3繪圖信息結構(PAINTSTRUCT)在調用BeginPaint後PAINTSTRUCT結構的fErase條款將成為TRUE(非零)
PAINTSTRUCT結構的rcPaint條款是RECT類型的結構,RECT結構定義了一個無效矩形的邊界坐標6.2.3繪圖信息結構(PAINTSTRUCT)BOOLInvalidateRect(HWNDhWnd,//handleofwindowwithchangedupdateregionCONSTRECT*lpRect,//addressofrectanglecoordinatesBOOLbErase//erase-backgroundflag);
其中InvalidateRect(hwnd,NULL,true);重畫時將擦除背景。InvalidateRect(hwnd,NULL,false);重畫時不擦除背景6.3TextOut函數。TextOut是在屏幕上顯示文字的最常用的GDI函數。語法是:TextOut(hdc,x,y,psText,iLength)hdc--屏幕也是設備。
1.hDC就是屏幕的設備描述表代號
2.x,y是客戶區內輸出字符串的開始地址,x是水平地址,y是垂直地址,
3.psText參數是指向需要在窗口顯示的字符串的指針,
4.iLength是輸出字符串中字符的個數6.4重畫區域的設定WM_PAINT窗口消息并非只來源于Windows系統,它們可以使用InvalidateRect或InvalidateRgn函數直接產生并送消息隊列。一般是先設定一個重畫區,然后再用它們中的一個送WM_PAINT消息到消息隊列,再排隊進入窗口函數并在這個分支中進行重畫。InvalidateRect設定的重畫區是矩形,InvalidateRgn函數設定的重畫區為不規則區域。6.4重畫區域的設定InvalidateRect函數(MSDN)6.5系統字體字體的基本概念等寬字體和變寬字體6.5.1系統字體字體參數存貯在TEXTMETRIC類型的結構typedef
struct
tagTEXTMETRIC{ LONGtmHeight; LONGtmAscent; LONGtmDescent; LONGtmInternalLeading; LONGtmExternalLeading; LONGtmAveCharWidth;LONGtmMaxCharWidth;
其他結構條款}TEXTMETRIC系統定義的TEXTMETRICS的結構如下:typedefstructtagTEXTMETRIC
{ //tmLONGtmHeight; //字符高度LONGtmAscent; //字符基線以上高度LONGtmDescent; //字符基線以下高度LONGtmInternalLeading; //tmHeight制訂的字符高度頂部的控件LONGtmExternalLeading; //行與行之間的間隔LONGtmAveCharWidth; //平均字符寬度LONGtmMaxCharWidth; //最大字符寬度LONGtmWeight; //字符的粗細度LONGtmOverhang; //合成字體間附加的寬度LONGtmDigitizedAspectX; //為輸出設備設計的X軸尺寸LONGtmDigitizedAspectY; //為輸出設備設計的Y軸尺寸BCHARtmFirstChar; //字體中第一個字符值BCHARtmLastChar; //字體中最后一個字符值BCHARtmDefaultChar; //代替不在字體中字符的字符BCHARtmBreakChar; //作為分割符的字符BYTEtmItalic; //非0則表示字體為斜體BYTEtmUnderlined; //非0則表示字體有下劃線BYTEtmStruckOut; //非0則表示字符為刪除字體BYTEtmPitchAndFamily; //字體間距和字體族BYTEtmCharSet; //字符集}TEXTMETRIC6.5.2系統字體用五個參數表示字體尺寸格式化文本(1)確定后續文本坐標換行時確定下一行文本的坐標需要格式化處理的情況在文本行中確定后續文本的坐標確定后續文本的坐標,應先獲取當前的字符串的寬度,
該工作由GetTextExtentPoint32函數完成,并把它存儲于一個SIZE結構中。BOOLGetTextExtentPoint32(
HDChdc,
LPCTSTRlpszString,//指定的字符串
int
nLength, //字符串中的字符數
LPSIZElpSize
//返回字符串寬度及高度的SIZE數據結構的地址)SIZE數據結構的定義typedefstructtagSIZE{LONGcx;
LONGcy;
}SIZE;例如,X軸起始坐標為cx0,后續文本起始坐標cx1為:
cx1=cx0+size.cx;
GetTextExtentPoint32(hDC,
Text,
lstrlen(Text),
size)
(2)確定換行時文本坐標字符的高度與行間隔均存儲在tm指向的TEXTMETRIC結構中,換行時Y軸上文本的起始坐標cy為:
cy=tm.tmHeight+tm.tmExternalLeading;通過計算當前行文本字符的高度與行間隔之和,即可得到換行時文本的起始坐標6.5.3格式化文字下面是取得系統字體的字符寬度和高度的WM_CREATE程序碼:caseWM_CREATE:hdc=GetDC(hwnd);//取得窗口的DCGetTextMetrics(hdc,&tm);//通過DC取得字體的尺寸信息存入tm結構cxChar=tm.tmAveCharWidth;//從tm結構中得到平均寬度cyChar=tm.tmHeight+tm.tmExternalLeading;//從tm結構中有關參數祘出總高度ReleaseDC(hwnd,hdc);//釋放DC return0;6.5.3格式化文字int
iLength;//定義變量存放長度TCHARszBuffer[40];//寬字符數組,存放sprintf-wsprintf的格式化輸出程序如下:iLength=wsprintf(szBuffer,TEXT("Thesumof%iand%iis%i"),
iA,iB,iA+iB);//TEXT把字符串輸出,wsprintf將它存進szbufferTextOut(hdc,x,y,szBuffer,iLength);文本操作實例【例】在用戶窗口上輸出幾行字符串,當窗口接收到WM_PAINT消息后,顯示的文本每次都被重新刷新。#include<windows.h>#include<stdlib.h>#include<string.h>longWINAPIWndProc(
HWNDhWnd,
UINTiMessage,
UINTwParam,
LONGlParam
);BOOLInitWindowsClass(HINSTANCE
hInstance);BOOLInitWindows(HINSTANCE
hInstance,int
nCmdShow);//主函數intWINAPIWinMain(
HINSTANCEhInstance,
HINSTANCEhPrevInstance,
LPSTRlpCmdLine,
intnCmdShow){
MSGMessage;
if(!InitWindowsClass(hInstance)) returnFALSE;
if(!InitWindows(hInstance,nCmdShow))returnFALSE;
while(GetMessage(&Message,0,0,0))//消息循環
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
returnMessage.wParam;}//消息處理函數longWINAPIWndProc(HWND
hWnd,UINT
iMessage,UINT
wParam,LONG
lParam){
staticlongnXChar,nYChar;
HDChDC;//定義指向設備上下文的句柄
shortx;
TEXTMETRICtm;
shortLnCount=6;
PAINTSTRUCTPtStr;//定義指向包含繪圖信息的結構體變量
staticchar*textbuf[]= {
"ThisistheFirstline",
"Thisisthesecondline",
"Thisisthethirdline",
"Thisisthefourthline",
"Thisisthefifthline",
"Thisisthesixthline"
};輸出的文本內容switch(iMessage)//處理消息
{caseWM_CREATE: //處理窗口創建消息
hDC=GetDC(hWnd); //獲取當前設備表句柄
GetTextMetrics(hDC,&tm); //獲取字體信息
nXChar=tm.tmAveCharWidth; //獲取字符寬度
nYChar=tm.tmHeight+tm.tmExternalLeading;
ReleaseDC(hWnd,hDC); //釋放當前設備句柄
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: //結束應用程序
PostQuitMessage(0); return0;default: //其他消息處理程序
return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}}BOOLInitWindowsClass(HINSTANCE
hInstance) //初始化窗口類{
WNDCLASSWndClass; …………;
WndClass.style=CS_HREDRAW|CS_VREDRAW;
returnRegisterClass(&WndClass);}BOOLInitWindows(HINSTANCE
hInstance,int
nCmdShow)//初始化窗口{
HWNDhWnd;
hWnd=CreateWindow("WinText",//生成窗口
"文本顯示示例程序", WS_OVERLAPPEDWINDOW, …….; NULL);
if(!hWnd) returnFALSE;
ShowWindow(hWnd,nCmdShow); //顯示窗口
UpdateWindow(hWnd);
returnTRUE;}【例】將一首四句的古詩從右到左豎排輸出。要求窗口每次接收到WM_PAINT消息時都刷新顯示的文本。
#include<windows.h>#include<stdlib.h>#include<string.h>longWINAPIWndProc(HWND
hWnd,UINT
iMessage,UINT
wParam,LONG
lParam);BOOLInitWindowsClass(HINSTANCE
hInstance);BOOLInitWindows(HINSTANCE
hInstance,int
nCmdShow);
//主函數intWINAPIWinMain(HINSTANCE
hInstance,HINSTANCEhPrevInstance, LPSTRlpCmdLine,int
nCmdShow){ MSGMessage;
if(!InitWindowsClass(hInstance)) returnFALSE;
if(!InitWindows(hInstance,nCmdShow)) returnFALSE; while(GetMessage(&Message,0,0,0)) //消息循環
{TranslateMessage(&Message);
DispatchMessage(&Message); } returnMessage.wParam;}longWINAPIWndProc(HWND
hWnd,UINT
iMessage,UINTwParam,LONGlParam)1.{staticlongnXChar,nCaps,nYChar;2.int
pointx,pointy,i,j;3.HDChDC; //定義指向設備環境的句柄 4.TEXTMETRICtm; //存放字體各種屬性的結構體變量5.PAINTSTRUCTPtStr; //指向包含繪圖信息的結構體變量6.staticchar*textbuf[4]={{"故人西辭黃鶴樓"},{"煙花三月下揚州"}, {"孤帆遠影碧空盡"},{"唯見長江天際流"}};7.switch(iMessage) //處理消息8.{ caseWM_CREATE: //處理窗口創建消息9. hDC=GetDC(hWnd); //獲取當前設備表句柄10. GetTextMetrics(hDC,&tm); //獲取字體信息11. nXChar=tm.tmAveCharWidth; //獲取字符寬度12.nYChar=tm.tmHeight+tm.tmExternalLeading; //字符高度13. nCaps=(tm.tmPitchAndFamily&1?3:2)*nXChar/2; //字間距14. ReleaseDC(hWnd,hDC);return0; //釋放當前設備句柄15. caseWM_PAINT: //處理重畫消息16. hDC=BeginPaint(hWnd,&PtStr); //開始繪圖17. for(i=4;i>0;i--)18. {for(j=0;j<7;j++) //輸出文本19.
{pointx=100+i*nXChar*5; pointy=50+j*(nYChar+nCaps);20.
TextOut(hDC,pointx,pointy,textbuf[4-i]+j*2,2);}}21.EndPaint(hWnd,&PtStr);return0; //結束繪圖22. caseWM_DESTROY://結束應用程序
PostQuitMessage(0); return0;23. default: return(DefWindowProc(hWnd,iMessage,wParam,lParam));}}6.6字體顯示的綜合使用SYSMETS1.c
視覺元件信息表struct
{
int Index;//索引
TCHAR* szLabel;//指向寬字符的指針
TCHAR* szDesc;//指向寬字符的指針}sysmetrics;//這是定義的結構名,sysmetrics[]//此結構數組用作視覺元件信息表P1156.7SYSMETS1.c
SYSMETS1.c程序例子:6\SYSMETS1.c6.7SYSMETS1.cSYSMETS1.c窗口函數的分析。
SYSMETS1.c程序存在問題。6.8滾動條的使用滾動條的范圍和地址6.8滾動條的使用滾動條的范圍BOOLSetScrollRange(HWND
hWnd,//handletowindowwithscrollbarint
nBar,//scrollbarflagint
nMinPos,//minimumscrolling positionint
nMaxPos,//maximumscrollingpositionBOOL
bRedraw//redrawflag);
nBar:SB_HORZSetstherangeofawindow'sstandardhorizontalscrollbar.SB_VERTSetstherangeofawindow'sstandardverticalscrollbar.SetScrollRange()6.8滾動條的使用滾動條的地址int
SetScrollPos(HWND
hWnd,//handletowindowwithscrollbarint
nBar,//scrollbarflagint
nPos,//newpositionofscrollboxBOOL
bRedraw//redrawflag);
GetScrollPos()6.8滾動條的使用如果設置滾動范圍為0到46.8滾動條的使用滾動條消息WM_VSCROLL(供上下移動)和WM_HSCROLL(供左右移動)消息。通知碼的解釋(MSDN中WM_VSCROLL)P123-124(注意)6.8滾動條的使用在SYSMETS1.C中加入滾動功能
(例子\6\SYSMETS2.C.doc)
6.8滾動條的使用
WM_VSCROLL消息分支中更新客戶區的方法。6.9建立更好的滾動在使用滾動條功能時,如果要設置它的范圍和位置可以用以前的函數,例如:SetScrollRange()、
SetScrollPos()、GetScrollRange(
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 育嬰師在多元文化中的角色與適應考題試題及答案
- 華潤面試題目及答案
- 文化產業管理與社會發展的互動試題及答案
- 藥物副作用識別試題及答案
- 應對變化的衛生管理考試試題及答案
- 紅巖西游記試題及答案
- 全民眼力測試題及答案
- 系統架構設計中面臨的技術挑戰試題及答案
- 編排醫學基礎知識復習計劃試題及答案
- 自如客服考試題及答案
- 2024年浙江長征職業技術學院單招綜合素質考試題庫附答案
- 2025屆安徽省池州市普通高中高三下學期教學質量統一監測物理試卷(含答案)
- 庫房管理工作職責與規范化
- 專題06文學文化常識中考語文一輪復習
- WMS倉庫管理系統采購協議
- 2024國家數字化范式與路徑-公共政策立場-67正式版
- 2025年河南工業和信息化職業學院單招職業技能測試題庫必考題
- 瑞吉歐幼兒教育
- 2025年中國人壽招聘筆試筆試參考題庫附帶答案詳解
- 中國輸電線路在線監測系統行業發展狀況及前景規模調查報告2025-2030年
- 第16課《有為有不為》公開課一等獎創新教學設計
評論
0/150
提交評論