1. 程式人生 > >windows視覺化程式設計(三)

windows視覺化程式設計(三)

這章總結下文字操作,先上一個簡單的文字輸出程式:

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,UINT wParam,LONG lParam)
{
		static long nXChar,nCaps,nYChar;
	HDC hDC;   //定義指向裝置上下文的控制代碼	
	short x;
    TEXTMETRIC tm;
		short LnCount=6;
		PAINTSTRUCT PtStr; //定義指向包含繪圖資訊的結構體變數
		static char *textbuf[]=
			{
			"This is the first line",
			"This is the second line",
			"This is the third line",
			"This is the fourth line",
			"This is the fifth line",
			"This is the sixth line"
		};
	switch(iMessage)  //處理訊息
		{
			case WM_CREATE:	//處理視窗建立訊息
				hDC=GetDC(hWnd) ;   //獲取當前裝置表控制代碼
				GetTextMetrics(hDC,&tm); //獲取字型資訊
				nXChar=tm.tmAveCharWidth;  //獲取字元寬度
				nYChar=tm.tmHeight+tm.tmExternalLeading;
				ReleaseDC(hWnd,hDC);  //釋放當前裝置控制代碼
				return 0;
			case WM_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);
				return 0;
			case WM_DESTROY: //結束應用程式
				PostQuitMessage(0);
				return 0;
			default://其他訊息處理程式
				return(DefWindowProc(hWnd,iMessage,wParam,lParam)) ;
		}
}
文字輸出有一個重要的結構體是 TEXTMETRIC,它的定義如下:
typedef struct tagTEXTMETRIC { // tm
LONG tmHeight; //字元高度
TEXTMETRIC結構欄位的圖示
TEXTMETRIC結構欄位的圖示
LONG tmAscent; //字元上部高度(基線以上)
LONG tmDescent; //字元下部高度(基線以下)
LONG tmInternalLeading, //由tmHeight定義的字元高度的頂部空間數目
LONG tmExternalLeading, //夾在兩行之間的空間數目
LONG tmAveCharWidth, //平均字元寬度
LONG tmMaxCharWidth, //最寬字元的寬度
LONG tmWeight; //字型的粗細輕重程度
LONG tmOverhang, //加入某些拼接字型上的附加高度
LONG tmDigitizedAspectX, //字型設計所針對的裝置水平方向
LONG tmDigitizedAspectY, //字型設計所針對的裝置垂直方向
BCHAR tmFirstChar; //為字型定義的第一個字元
BCHAR tmLastChar; //為字型定義的最後一個字元
BCHAR tmDefaultChar; //字型中所沒有字元的替代字元
BCHAR tmBreakChar; //用於拆字的字元
BYTE tmItalic, //字型為斜體時非零
BYTE tmUnderlined, //字型為下劃線時非零
BYTE tmStruckOut, //字型被刪去時非零
BYTE tmPitchAndFamily, //字型間距(低4位)和族(高4位)
BYTE tmCharSet; //字型的字符集
} TEXTMETRIC;
利用這個結構體我們可以在輸出前呼叫GetTextMetrics(hDC,&tm)先獲取到當前的文字資訊,根據此計算出下一行的位置,當然在此之前要先呼叫hDC=GetDC(hWnd)獲取當前裝置環境。

接下來是textout函式,一行一行輸出。

BOOL TextOut(
HDC hdc, // 裝置描述表控制代碼
int nXStart, // 字串的開始位置 x座標
int nYStart, // 字串的開始位置 y座標
LPCTSTR lpString, // 字串
int cbString // 字串中字元的個數
);

再看一個文字輸出程式,它的winproc函式如下:
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{	
	HDC hdc;
	HFONT hF_black,hF_big;	//定義兩種字型控制代碼
	PAINTSTRUCT ps;
	TEXTMETRIC tm;			//定義一個TEXTMETRIC結構,用以記錄字型資訊
	char lpsz_1[]="這是一行紅色的、字型為SYSTEM_FONT的文字,紅色代表未來";
	char lpsz_2[]="現在顯示的是自定義綠色字型,綠色代表生機勃勃";
	char lpsz_3[]="這一行是藍色的粗體字,藍色代表廣闊的海洋和天空";
	char lpsz_4[]="這是大號、斜體並帶有下劃線的文字";
	char lpsz_5[]="您掌握了字型的操作了嗎?";
	char lpsz_6[]="祝您成功!";
	int X=0,Y=0;
	SIZE size;					//定義一個SIZE型別的結構
	switch(message)
	{
		case WM_PAINT:
			hdc=BeginPaint(hwnd,&ps);
			SetTextColor(hdc,RGB(255,0,0));	//設定文字顏色為紅色
			GetTextMetrics(hdc,&tm);		//獲取預設字型,寫入tm結構中
			TextOut(hdc,X,Y,lpsz_1,strlen(lpsz_1));	//使用當前字型輸出文字
			Y=Y+tm.tmHeight+tm.tmExternalLeading;//計算換行時下一行文字的輸出座標
			hF_black=CreateFont		//建立自定義字型
					(
						20,				//字型的高度
						0,				//由系統根據高寬比選取字型最佳寬度值
						0,				//文字的傾斜度為0,表示水平
						0,				//字型的傾斜度為0
						FW_HEAVY,		//字型的粗度,FW_HEAVY為最粗
						0,				//非斜體字
						0,				//無下劃線
						0,				//無刪除線
						GB2312_CHARSET,	//表示所用的字符集為ANSI_CHARSET
						OUT_DEFAULT_PRECIS,	//輸出精度為預設精度
						CLIP_DEFAULT_PRECIS,	//剪裁精度為預設精度
						DEFAULT_QUALITY,		//輸出質量為預設值
						DEFAULT_PITCH|FF_DONTCARE,//字間距和字體系列使用預設值
						"粗體字"				//字型名稱
						);

				SetTextColor(hdc,RGB(0,255,0));	//設定文字顏色為綠色
				SelectObject(hdc,hF_black);		//將自定義字型選入裝置環境
				GetTextMetrics(hdc,&tm);		//獲取字型的資訊,並寫入tm結構中
				TextOut(hdc,X,Y,lpsz_2,strlen(lpsz_2));//使用當前字型輸出文字
				//換行繼續輸出文字,計算新行的起始Y座標位置
				Y=Y+tm.tmHeight+5*tm.tmExternalLeading;	
				GetTextExtentPoint32(hdc,lpsz_2,strlen(lpsz_2),&size);
													//獲取字串的寬度
				SetTextColor(hdc,RGB(0,0,255));	//設定文字顏色為藍色
				TextOut(hdc,X,Y,lpsz_3,strlen(lpsz_3));//用當前字型輸出文字
				Y=Y+tm.tmHeight+5*tm.tmExternalLeading; 
				hF_big=CreateFont		//引入新字型
					(
					30,					//字型高度
					0,
					0,
					0,
					FW_NORMAL,
					1,			//定義斜體
					1,			//定義輸出時帶下劃線
					0,
					GB2312_CHARSET,	//所使用的字符集
					OUT_DEFAULT_PRECIS,
					CLIP_DEFAULT_PRECIS,
					DEFAULT_QUALITY,
					DEFAULT_PITCH|FF_DONTCARE,
					"大號字"
					);

				SelectObject(hdc,hF_big);	//將第二種自定義字型選入裝置環境
				SetTextColor(hdc,RGB(155,155,155));	//設定文字顏色為灰色
				Y=Y+tm.tmHeight+5*tm.tmExternalLeading;	
 				TextOut(hdc,X,Y,lpsz_4,strlen(lpsz_4));//以當前字型輸出文字
				SetTextColor(hdc,RGB(255,0,0));	//設定文字顏色為紅色
				Y=Y+tm.tmHeight+10*tm.tmExternalLeading;	
				TextOut(hdc,X,Y,lpsz_5,strlen(lpsz_5)); 	//輸出文字
				//在該行繼續輸出文字
				GetTextExtentPoint32(hdc,lpsz_5,strlen(lpsz_5),&size);
													//獲取字串的寬度
				X=X+size.cx;							//獲取起始座標
				TextOut(hdc,X+5,Y,lpsz_6,strlen(lpsz_6)); 	//輸出文字
				EndPaint(hwnd,&ps);
				DeleteObject(hF_black);		//刪除自定義字型控制代碼
				DeleteObject(hF_big);
				break;
	case WM_DESTROY:
			PostQuitMessage(0);
			break;
	default:
		return  DefWindowProc(hwnd,message,wParam,lParam);
		}
		return 0;
}

這個函式我們用settextcolor自定義文字顏色,另外我們還用了GetTextExtentPoint32獲取指定文字的資訊以及建立自己的字型。