windows視覺化程式設計(三)
阿新 • • 發佈:2019-01-03
這章總結下文字操作,先上一個簡單的文字輸出程式:
文字輸出有一個重要的結構體是 TEXTMETRIC,它的定義如下: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)) ; } }
利用這個結構體我們可以在輸出前呼叫GetTextMetrics(hDC,&tm)先獲取到當前的文字資訊,根據此計算出下一行的位置,當然在此之前要先呼叫hDC=GetDC(hWnd)獲取當前裝置環境。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;
接下來是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獲取指定文字的資訊以及建立自己的字型。