Windows程式設計零基礎自學_5_GDI基礎_之擷取裝置內容資訊

來源:互聯網
上載者:User

    不知道怎麼回事,最近火氣特別大, 而且也難以靜下心來學習。

     非常不適應國有企業中的明爭暗鬥的, 整天在刀光劍影中掙紮,而且還戰戰兢兢的,如履薄冰。不知道外資企業怎麼樣,是不是沒有這樣的東西。

一直聽說外資企業就是看技術看能力,基本沒有這種的東西,不知道是不是.....................

     已經好幾天沒有靜心學習了,昨天半夜被叫醒處理故障,今天雖然是周末但上午還到廠子裡面處理故障,實在是累啊.....下午睡了一覺,感覺精神稍好,就

起來看看書。

    下面是今天總結的內容......

5.2.2 取得裝置內容資訊
     一個裝置內容通常指一個實際顯示裝置,通常可以通過呼叫系統函數取得有關該裝置的資訊: 例如顯示器大小和色彩顯示能力。可以通過
GetDeviceCaps函數來取得這些訊息。
Exp:
     iValue=GetDeviceCaps(hdc,iIndex);
  Tip:
       iIndex為WINGDI.H標頭檔中定義的29個宏之一。
    例如:
       iIndex為HORZRES將使GetDeviceCaps傳回裝置的寬度(單位為圖素), iIndex為VERTRES時GetDeviceCaps將
    返回裝置的高度資訊。如果hdc是印表機裝置內容控制代碼,則GetDeviceCaps將返回印表機顯示地區的高度和寬度(單位
    是圖素)。

5.2.3 裝置的大小
    為了繪製一個邊長是1英寸的正方形,則需要知道顯示器上1英寸對應多少圖素。在Windows程式裡面可以使用GetDeviceCaps
函數擷取有關顯示器和印表機之類輸出裝置的實際顯示大小資訊。
    解析度:
            印表機用DPI表示解析度:300dpi
            顯示器則一般用水平和垂直的總圖素來表示解析度: 1024*768
    在windows程式設計中我們採用嚴格定義:
       解析度: 每度量單位內的圖素數目
       圖素大小/圖素尺寸: 表示裝置水平或垂直顯示的總圖素
       度量大小/度量尺寸: 以英寸或mm為單位的裝置顯示地區的大小,即顯示的x軸方向的大小或y軸大小
        這樣:
                解析度=圖素大小/度量大小
    擷取螢幕圖素大小:
       1)windows應用程式可以使用SM_CXSCREEN和SM_CYSCREEN參數從GetSystemMetrics得到圖素尺寸。
       2)可以利用HORZRES(水平解析度: 水平圖素大小)和VERTRES(垂直解析度:垂直圖素大小)參數
          從GetDeviceCaps中取得同樣的值
    關於HORZSIZE和VERTSIZE:
       HORZSIZE:表示以毫米計算的實際螢幕寬度
       VERTSIZE:表示以毫米計算的實際螢幕高度
5.2.3.1
    當我們在改變顯示內容: 案頭-》右擊——》屬性——》外觀——》字型大小。
    這裡有:字型大小的原因是用於當提高顯示器的解析度例如有640*480——》1024*768時可以顯示更大的字型。
    這些字型大小是指系統字型大小:指顯示器程式的設定頁面卷標中的小字型和大字型。

    在傳統的排版中,字型的字母大小由點表示。 1點~= 1/72 英寸。
    理論上;字型的點值是從字型中最高字元頂部到字元底部的距離,其中不包括重音符號。  高字元如: j、p、q、y等。
    例如在10點的字型中字元的點值就是10/72英寸。
       在TEXTMETRIC結構中:
                          字型點值= tmHeight- tmInternalLeading欄位。
       tmHeight欄位指出文字的連續行在螢幕或印表機上的間隔方式,這也可以用點來測量。
       行距: 兩行字型間基準線間的點距離, 12點行距指出文字連續行的基準線間距為12/72英寸。

5.2.3.2 色彩
   當顯示黑色圖素和白色圖素的時候,則每個圖素僅需要記憶體中的一位,彩色顯示器的每個圖素需要多個位;通常
顯示的顏色越多則需要的位元也越多。
   顯示器可以顯示的不同色彩的數目等於2的位元的乘方數。
 
   Full-color 顯示器的分別率是每個圖素24位: 8位紅色、8位綠色和8為藍色。 紅、綠、藍為色光三原色,混合
這三種顏色可以產生各種其他的顏色。

   High-color 顯示解析度每個圖素16位: 5位紅色、6為綠色、5位藍色, 因為人眼對綠色敏感,所以多一位。

   顯示256中顏色是顯示卡每個圖素需要8位。這些8位值一般由定義實際顏色的調色盤組織。

   顯示16種顏色的顯示卡每個圖素需要4位,這些顏色一般固定為: 暗紅/亮紅、黑、藍、青、紫、黃、兩種灰色。
  
   通常只有某些特殊的程式需要知道顯示卡上的記憶體是如何組織的。 可以通過GetDeviceCaps函數擷取顯示卡的儲存組織以及
   顯卡支援的顏色數目:
        iPlanes=GetDeviceCaps(hdc,PLANES);
   通過:
        iBitsPixel=GetDeviceCaps(hdc,BITSPIXEL); 可以擷取每個圖素的色彩位元
   大多數的顯示裝置使用多個色彩平面或每個圖素有多個色彩位設計,這兩種方式不能同時一起使用。
   這兩個函數的傳回值一定有一個 == 1 。
   顯卡支援的色彩數:
        大約為  iColors=1<<(iPlanes * iBitPixel);
   這個值與用NUMCOLORS參數得到的值可能一樣,也可能不一樣。
        Exp:
              iColors=GetDeviceCaps(hdc,NUMCOLORS);

   對於256色的顯示卡,使用色彩調色盤,這種情況下,以NUMCOLORS參數為參數時,GetDeviceCaps返回的值是windows
   保留的色彩數,值為20, 剩下的236種顏色由windows的調色盤管理其進行設定。對於Highcolor和True-color顯示的
   解析度,當用NUMCOLORS參數調用GetDeviceCaps函數傳回值為-1, 表示無法擷取所需資訊,這時就需要使用PLANES和
   BITSPIXEL值的iColors計算公式。

RGB顏色
   在大多數的GDI函數呼叫中,使用COLORREF值(unsigned int )來表示一種色彩。COLORREF值按照紅、綠、藍的亮度
指定了一種顏色, 通常叫做、RGB顏色。
     31...24   23...16   15....8   7....0
        0        藍色      綠色      紅色
  注意這就是Full-color顯示的顏色: D31-D24位為0; D23-D16表示的是藍色, D15-D8是綠色, D7-D0是紅色。理論上
這樣採用RGB可以表示2^24 或1600萬中色彩。

   這樣的一個無符號數常常成為一個RGB色彩。 在windows的標頭檔WINGDI.H 提供了幾種使用RGB色彩值的宏。RGB宏要求
三個參數分別代表:紅、綠、藍的值,然後將其組合為一個不帶正負號的整數。
Exp:
    #define RGB(r,g,b)  ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))
因此值:
    RGB(255,255,0);是0x0000FFFF或黃色(紅色和綠色的合成)。
    當r、g、b全設定為0時,則色彩位黑色,
      r、g、b全為255時,色彩為白色。
可以用GetRValue、GetGValue和GetBValue宏從COLORREF值中抽取原色值。

在16色或者256色的顯示卡上,windows可以使用混色來類比裝置能夠顯示的顏色之外的顏色。混色利用了有多種
色彩的圖素組成的圖素圖案,可以呼叫:
     GetNearestColor來決定於某一色彩最接近的純色:
Exp:
   crPureColor=GetNearestColor(hdc,crColor);

5.2.4  裝置內容屬性
    windows使用裝置內容來儲存控制GDI函數在顯示器上是如何操作的各種屬性。
Exp:
     windows函數TextOut不需要指定文字的色彩和字型,windows會從裝置內容上取得這些資訊。

    應用程式在取得一個裝置內容的控制代碼時,windows用預設值設定其所有的屬性。
    windows定義了很多裝置內容屬性,這些屬性可以查表擷取。

5.2.4.1 儲存裝置內容
    通常在呼叫GetDC或BeginPaint時,windows會用預設值建立一個新的裝置內容,在處理訊息時對屬性
所作的一切改變在裝置內容用ReleaseDC或EndPaint呼叫釋放時,都會丟失。如果程式使用非預設的裝置內容
屬性,則必須在應用程式內部在處理訊息取得裝置內容控制代碼時初始化裝置內容。
Exp:
    case WM_PAINT:
         hdc=BeginPaint(hwnd,&ps);
         裝置內容屬性
         繪製視窗顯示地區
         EndPaint(hwnd,&ps);
         return 0;

    利用上述的方法雖然可以滿足一定的需求,但是有時需要在裝置內容被釋放後,仍然可以儲存裝置內容屬性所作的更改,
以便於在下次調用GetDC和BeginPaint時屬性仍然可以起作用。 這樣的話需要:
    在註冊視窗類別別時將CS_OWNDC位旗標加入到視窗類別別的style屬性中。
Exp:
    wndclss.style=CS_VREDRAW | CS_HREDRAW | CS_OWNDC;
    這樣依據這個視窗類別別建立的每個視窗,都將擁有自己的裝置內容,並且這些屬性一直存在,直到
視窗被刪除,如果使用了CS_OWNDC風格,則只需初始化裝置內容一次,可以在處理WM_CREATE訊息時完成
裝置內容的初始化工作:
Exp:
   case WM_CREATE:
        hdc=GetDC(hwnd);
        初始化裝置內容
        ReleaseDC(hwnd,hdc);
        return 0;
 這樣改變的裝置內容屬性,一直有效,直到再一次改變,或者視窗刪除。
要點:
     1)WM_OWNDC風格隻影響GetDC和BeginPaint擷取的裝置內容,不影響其他函數(如GetWindowDC)擷取
的裝置內容。
     2)即使使用了WM_OWNDC風格,仍然需要在訊息處理return 0之前釋放裝置內容控制代碼。
     3)WM_OWNDC需要佔用記憶體,但在圖形處理常式中可以提供效能。
5.2.4.2
   有時可能想改變某些裝置內容屬性,用改變後的屬性進行繪圖,在繪製完圖形後再恢複至繪圖前的
裝置內容屬性。可以通過
Exp:
   case WM_LBUTTONDOWN:
        hdc=GetDC(hwnd);
        i=GetTextColor(hdc);
        SetSystemMetrics(hdc,某些屬性);
        繪製圖形;
        SetTextColor(hdc, i);
        ReleaseDC(hwnd,hdc);
也可以通過:
Exp:
    idSaved=SaveDC(hdc);
    改變屬性
    繪圖
    RestoreDC(hdc,idSaved);
可以在呼叫RestroreDC之前呼叫SaveDC多次。
這裡還提供了一個更直接的方法:
Exp:
     SaveDC(hdc);
     改變某些屬性
     這時還可以呼叫一次SaveDC。
     RestoreDC(hdc,-1); 這個操作會恢複到最近一次儲存裝置內容屬性值的情況。
如果多次呼叫SaveDC,如果想恢複到最初的狀態則需要進行多次RestoreDC操作。

下面進行測試的代碼,比較簡單,只有小部分地方加了注釋:

   

/*
*
* 裝置內容入門基礎執行個體程式
*
*/

#include <windows.h>
#include <winuser.h>

#define NUMLINES ( (int)(sizeof devcaps/sizeof devcaps[0]))

struct DEVCAPS
{
int iIndex;
TCHAR *szLabel;
TCHAR *szDesc;
};
DEVCAPS devcaps[]=
{
HORZSIZE, TEXT("HORZSIZE"), TEXT("Width in millimeters:"),
VERTSIZE, TEXT("VERTSIZE"), TEXT("Height in millimeters:"),
HORZRES, TEXT("HORZRES"), TEXT("Width in pixels:"),
VERTRES, TEXT("VERTRES"), TEXT("Height in pixels"),
BITSPIXEL,TEXT("BITSPIXEL"), TEXT("Color bits per pixel"),
PLANES, TEXT("PLANES"), TEXT("Number of color planes:"),
NUMBRUSHES,TEXT("NUMBRUSHES"),TEXT("Number of device brushes:"),
NUMPENS,TEXT("NUMPENS"),TEXT("Number of device pens:"),
NUMMARKERS,TEXT("NUMMARKERS"),TEXT("Number of device marks:"),
NUMFONTS,TEXT("NUMFONTS"),TEXT("Number of device fonts"),
NUMCOLORS,TEXT("NUMCOLORS"),TEXT("Number of device colors:"),
PDEVICESIZE,TEXT("PDEVICESIZE"),TEXT("Size of device of structure:"),
ASPECTX,TEXT("ASPECTX"),TEXT("Relative width of pixel:"),
ASPECTY,TEXT("ASPECTY"),TEXT("Relative height of pixel:"),
LOGPIXELSX,TEXT("LOGPIXELSX"),TEXT("Horizontal dots per inch:"),
LOGPIXELSY,TEXT("LOGPIXELSY"),TEXT("Vertical dots per inch:"),
SIZEPALETTE,TEXT("SIZEPALETTE"),TEXT("Reserved palette entries:"),
COLORRES,TEXT("COLORRES"),TEXT("Actual color resolution:")
};

LRESULT CALLBACK WndProc(HWND, UINT,WPARAM,LPARAM);

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int iShowCmd)
{
static TCHAR szAppName[]=TEXT("Devcaps1");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;

wndclass.cbClsExtra=0;
wndclass.cbWndExtra=0;
wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wndclass.hInstance=hInstance;
wndclass.lpfnWndProc=WndProc;
wndclass.lpszClassName=szAppName;
wndclass.lpszMenuName=NULL;
wndclass.style=CS_HREDRAW | CS_VREDRAW ;

if(!RegisterClass(&wndclass))
{
MessageBox(NULL,"You need WinNT to run this program!",TEXT("Warning"),MB_OK);
return 0;
}

hwnd=CreateWindow(szAppName,
TEXT("GetDevcaps"),
WS_OVERLAPPEDWINDOW | WS_HSCROLL|WS_VSCROLL,
100,
100,
640,
480,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hwnd,iShowCmd);
UpdateWindow(hwnd);

while(GetMessage(&msg,hwnd,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
TEXTMETRIC tm;
static int cxChar,
cyChar,
cxCaps,
cyCaps;
static int i,
j=0;
TCHAR szBuffer[10];

switch(message)
{
case WM_CREATE:
hdc=GetDC(hwnd);
GetTextMetrics(hdc,&tm); //擷取裝置系統字型資訊
cxChar=tm.tmAveCharWidth;
cxCaps=(tm.tmPitchAndFamily &1 ? 3:2 )*cxChar/2;
cyChar=tm.tmHeight+tm.tmExternalLeading;
ReleaseDC(hwnd,hdc);
return 0;
case WM_PAINT:
hdc=BeginPaint(hwnd,&ps);
EndPaint(hwnd,&ps);
return 0; //這個程式表示WM_PAINT 這樣處理的話,不會對無效地區進行重畫。
case WM_LBUTTONDOWN:
hdc=GetDC(hwnd);
for(i=0;i<NUMLINES;i++)
{
j=j+20;
SetTextColor(hdc,RGB(j+5,j-10,j));
TextOut(hdc,0,cyChar*i,devcaps[i].szLabel,lstrlen(devcaps[i].szLabel));
TextOut(hdc,14*cxCaps,cyChar*i,devcaps[i].szDesc,lstrlen(devcaps[i].szDesc));
SetTextAlign(hdc,TA_RIGHT|TA_TOP); //設定字型對齊
TextOut(hdc,14*cxCaps+35*cxChar,cyChar*i,szBuffer,wsprintf(szBuffer,TEXT("%5d"),GetDeviceCaps(hdc,devcaps[i].iIndex)));
SetTextAlign(hdc,TA_LEFT|TA_TOP);
}
SetTextColor(hdc,RGB(0,0,0));
ReleaseDC(hwnd,hdc);
return 0;
case WM_RBUTTONDOWN:
hdc=GetDC(hwnd);
TextOut(hdc,0,i*(1+cyChar),TEXT("Test color set function!"),lstrlen("Test color set function!"));
ReleaseDC(hwnd,hdc);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd,message,wParam,lParam);
}
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.