Windows位元影像Bitmap和調色盤Palette

來源:互聯網
上載者:User

導讀:
  Windows位元影像(Bitmap)和調色盤(Palette)
  1.位元影像和調色盤的概念
  如今Windows(3.x以及95,NT)系列已經成為決大多數使用者使用的作業系統。它比DOS成
  功的一個重要因素是它可視化的漂亮介面,例如你可以在案頭上鋪上你喜歡的牆紙。那
  麼Windows是如何顯示圖象的呢?這就要談到位元影像(Bitmap)。
  我們知道,普通的顯示器螢幕是由許許多多的點構成的,我們稱之為象素。顯示時採用
  掃描的方法:電子槍每次從左至右掃描一行,為每個象素著色,然後從上到下這樣掃描
  若干行,就掃過了一屏。為了防止閃爍,每秒要重複上述過程幾十次。例如我們常說的
  螢幕解析度為640*480,重新整理頻率為70Hz,意思是說每行要掃描640個象素,一共有480行
  ,每秒重複掃描螢幕70次。我們稱這種顯示器為位映象裝置。所謂位映象,就是指一個
  二維的象素矩陣,而位元影像就是採用位映象方法顯示和儲存的圖象。舉個例子,1是一
  幅普通的黑白位元影像,圖2是被放大後的圖,圖中每個方格代表了一個象素,我們可以看到
  :整個骷髏就是由這樣一些黑點和白點組成的。
  
  圖1.骷髏(左)                                                                                 圖2.放大後的骷髏位元影像(右)
  那麼,彩色圖是怎麼回事呢?
  我們先來說說三元色RGB概念。我們知道,自然界中的所有顏色都可以由紅,綠,藍(R
  ,G,B)組合而成。有的顏色含有紅色成分多一些,如深紅;有的含有紅色成分少一些
  ,如淡紅。針對含有紅色成分的多少,可以分成0到255共256個等級,0級表示不含紅色
  成分,255級表示含有100%的紅色成分。同樣,綠色和藍色也被分成256級。這種分級的
  概念被稱作量化。這樣,根據紅,綠,藍各種不同的組合我們就能表示出256*256*256,
  約1千6百萬種顏色。這麼多顏色對於我們人眼來已經足夠了。
  下表是常見的一些顏色的RGB組合值。
  顏色        R                G                B
  紅                255        0                0
  藍                0                0                255
  綠                0                255        0
  黃                255        255        0
  紫                255        0                255
  青                0                255        255
  白                255        255        255
  黑                0                0                0
  灰                128        128        128
  你大概已經明白了,當一幅圖中每個象素賦予不同的RGB值時,就能呈現出五彩繽紛的顏
  色了,這樣就形成了彩色圖。對,是這樣的,但實際上的做法還有些差別。
  讓我們來看看下面的例子。
  有一個長寬各為200個象素,顏色數為16色的彩色圖,每一個象素都用R,G,B三個分量
  表示,因為每個分量有256個層級,要用8位(bit),即一個位元組(byte)來表示,所以
  每個象素需要用3個位元組。整個圖象要用200*200*3,約120k位元組,可不是一個小數目呀
  !如果我們用下面的方法,就能省的多。 因為是一個16色圖,也就是說這幅圖中最多隻
  有16種顏色,我們可以用一個表:表中的每一行記錄一種顏色的R,G,B值。這樣當我們
  表示一個象素的顏色時,只需要指出該顏色是在第幾行,即該顏色在表中的索引值。舉
  個例子,如果表的第0行為255,0,0(紅色),那麼當某個象素為紅色時,只需要標明
  0即可。 讓我們再來計算一下:16種狀態可以用4位(bit)表示,所以一個象素要用半
  個位元組。整個圖象要用200*200*0.5,約20k位元組,再加上表佔用的位元組為3*16=48位元組.
  整個佔用的位元組數約為前面的1/6,省很多吧。
  這張RGB的表,即是我們常說的調色盤(Palette),另一種叫法是顏色尋找表LUT(LookUp
  Table),似乎更確切一些。Windows位元影像中便用到了調色盤技術.其實是不光是Windows位
  圖,許多圖象檔案格式如pcx,tif,gif等都用到了。所以很好地掌握調色盤的概念是十
  分重要的.
  有一種圖,它的顏色數高達256*256*256種,也就是說包含我們上述提到的R,G,B顏色
  表示方法中所有的顏色,這種圖叫做真彩色圖(TrueColor)。真彩色圖並不是說一幅圖包
  含了所有的顏色,而是說它具有顯示所有顏色的能力,即最多可以包含所有的顏色。表
  示真彩色圖時,每個象素直接用R,G,B三個分量位元組表示,而不採用調色盤技術,原因
  很明顯:如果用調色盤,表示一個象素也要用24位,這是因為每種顏色的索引要用24位
  (因為總共有2的24次方種顏色,即調色盤有2的24次方行),和直接用R,G,B三個分量
  表示用的位元組數一樣,不但沒有任何便宜,還要加上一個256*256*256*3個位元組的大調色
  板。所以真彩色圖直接用R,G,B三個分量表示,它又叫做24位色圖。
  2.Bmp檔案格式
  介紹完位元影像和調色盤的概念,下面就讓我們來看一看Windows的位元影像檔案(.bmp檔案)的
  格式是什麼樣子的。 bmp檔案大體上分成四個部分,3所示。
  圖3.Windows位元影像檔案結構(右)
  第一部分為位元影像檔案頭BITMAPFILEHEADER,是一個結構,其定義如下:
  typedefstructtagBITMAPFILEHEADER{
  WORD bfType;
  DWORD bfSize;
  WORD bfReserved1;
  WORD bfReserved2;
  DWORD bfOffBits;
  } BITMAPFILEHEADER;
  這個結構的長度是固定的,為14個位元組(WORD為無符號16位整數,DWORD為無符號32位整
  數),各個域的說明如下:
  bfType
  指定檔案類型,必須是0x424D,即字串"BM",也就是說所有.bmp檔案的頭兩個位元組都
  是"BM"
  bfSize
  指定檔案大小,包括這14個位元組
  bfReserved1,bfReserved2
  為保留字,不用考慮
  bfOffBits
  為從檔案頭到實際的位元影像資料的位移位元組數,即圖3中前三個部分的長度之和。
  第二部分為位元影像資訊頭BITMAPINFOHEADER,也是一個結構,其定義如下:
  typedef struct tagBITMAPINFOHEADER{
  DWORD biSize;
  LONG biWidth;
  LONG biHeight;
  WORD biPlanes;
  WORD biBitCount;
  DWORD biCompression;
  DWORD biSizeImage;
  LONG biXPelsPerMeter;
  LONG biYPelsPerMeter;
  DWORD biClrUsed;
  DWORD biClrImportant;
  } BITMAPINFOHEADER; 這個結構的長度是固定的,為40個位元組(WORD為無符號16位整數
  ,DWORD無符號32位整數,LONG為32位整數),各個域的說明如下:
  biSize
  指定這個結構的長度,為40
  biWidth
  指定圖象的寬度,單位是象素
  biHeight
  指定圖象的高度,單位是象素
  biPlanes
  必須是1,不用考慮
  biBitCount
  指定表示顏色時要用到的位元,常用的值為1(黑白二色圖),4(16色圖),8(256色)
  ,24(真彩色圖)(新的.bmp格式支援32位色,這裡就不做討論了)。
  biCompression
  指定位元影像是否壓縮,有效值為BI_RGB,BI_RLE8,BI_RLE4,BI_BITFIELDS(都是一些
  Windows定義好的常量)。要說明的是,Windows位元影像可以採用RLE4,和RLE8的壓縮格式
  ,但用的不多。我們今後所討論的只有第一種不壓縮的情況,即biCompression為BI_RG
  B的情況。
  biSizeImage
  指定實際的位元影像資料佔用的位元組數,其實也可以從以下的公式中計算出來:
  biSizeImage=biWidth'*biHeight
  要注意的是:上述公式中的biWidth'必須是4的整倍數(所以不是biWidth,而是biWidt
  h',表示大於或等於biWidth的,離4最近的整倍數。舉個例子,如果biWidth=240,則b
  iWidth'=240;如果biWidth=241,biWidth'=244)如果biCompression為BI_RGB,則該項
  可能為零
  biXPelsPerMeter
  指定目標裝置的水平解析度,單位是每米的象素個數,關於解析度的概念,我們將在打
  印部分詳細介紹。
  biYPelsPerMeter
  指定目標裝置的垂直解析度,單位同上。
  biClrUsed
  指定本圖象實際用到的顏色數,如果該值為零,則用到的顏色數為2的biBitCount次方。
  biClrImportant
  指定本圖象中重要的顏色數,如果該值為零,則認為所有的顏色都是重要的。
  第三部分為調色盤(Palette),當然,這裡是對那些需要調色盤的位元影像檔案而言的。有些
  位元影像,如真彩色圖,前面已經講過,是不需要調色盤的,BITMAPINFOHEADER後直接是位
  圖資料。
  調色盤實際上是一個數組,共有biClrUsed個元素(如果該值為零,則有2的biBitCount
  次方個元素)。數組中每個元素的類型是一個RGBQUAD結構,佔4個位元組,其定義如下:
  typedef struct tagRGBQUAD{
  BYTE rgbBlue; //該顏色的藍色分量
  BYTE rgbGreen; //該顏色的綠色分量
  BYTE rgbRed; //該顏色的紅色分量
  BYTE rgbReserved; //保留值
  } RGBQUAD;
  第四部分就是實際的圖象資料了。對於用到調色盤的位元影像,圖象資料就是該像素顏在調
  色板中的索引值,對於真彩色圖,圖象資料就是實際的R,G,B值。下面就2色,16色,25
  6色位元影像和真彩色位元影像分別介紹。
  對於2色位元影像,用1位就可以表示該像素的顏色(一般0表示黑,1表示白),所以一個字
  節可以表示8個像素。
  對於16色位元影像,用4位可以表示一個像素的顏色,所以一個位元組可以表示2個像素。
  對於256色位元影像,一個位元組剛好可以表示1個像素。
  對於真彩色圖,三個位元組才能表示1個像素。
  要注意兩點:
  1.每一行的位元組數必須是4的整倍數,如果不是,則需要補齊。這在前面介紹biSizeIm
  age時已經提到了。
  2.一般來說,.BMP檔案的資料從下到上,從左至右的。也就是說,從檔案中最先讀到的
  是圖象最下面一行的左邊第一個像素,然後是左邊第二個像素…接下來是倒數第二行左
  邊第一個像素,左邊第二個像素…依次類推,最後得到的是最上面一行的最右一個像素
  。
  好了,終於介紹完bmp檔案結構了,是不是覺得頭有些大?別著急,對照著下面的程式,
  你就會很清楚了.
  3.顯示一個bmp檔案的C程式
  下面的函數LoadBmpFile,其功能是從一個.bmp檔案中讀取資料(包括BITMAPINFOHEADE
  R,調色盤和實際圖象資料)將其儲存在一個全域記憶體控制代碼hImgData中,這個hImgData將
  在以後的圖象處理常式中用到。同時填寫一個類型為HBITMAP的全域變數hBitmap和一個
  類型為HPALETTE的全域變數hPalette。這兩個變數將在處理WM_PAINT訊息時用到,用來
  顯示出位元影像。該函數的兩個參數分別是用來顯示位元影像的視窗控制代碼,和.bmp檔案名稱(全路
  徑),當函數成功時,返回TRUE,否則返回FALSE.
  BITMAPFILEHEADER bf;
  BITMAPINFOHEADER bi;
  BOOL LoadBmpFile(HWND hWnd,char* BmpFileName)
  {
  HFILE hf; //檔案控制代碼
  LPBITMAPINFOHEADER lpImgData; //指向BITMAPINFOHEADER結構的指標
  LOGPALETTE *pPal; //指向邏輯調色盤結構的指標
  LPRGBQUAD lpRGB; //指向RGBQUAD結構的指標
  HPALETTE hPrevPalette;//用來儲存裝置中原來的調色盤
  HDC hDc; //裝置控制代碼
  HLOCAL hPal; //儲存調色盤的局部記憶體控制代碼
  DWORD LineBytes; //每一行的位元組數
  DWORD ImgSize; //實際的圖象資料佔用的位元組數
  DWORD NumColors; //實際用到的顏色數,即調色盤數組中的顏色個數
  DWORD i;
  if((hf=_lopen(BmpFileName,OF_READ))==HFILE_ERROR){
  MessageBox (hWnd,"Filec://test.bmpnotfound!","ErrorMessage",
  MB_OK|MB_ICONEXCLAMATION);
  return FALSE;//開啟檔案錯誤,返回
  }
  //將BITMAPFILEHEADER結構從檔案中讀出,填寫到bf中
  _lread(hf,(LPSTR)&bf,sizeof(BITMAPFILEHEADER));
  //將BITMAPINFOHEADER結構從檔案中讀出,填寫到bi中
  _lread(hf,(LPSTR)&bi,sizeof(BITMAPINFOHEADER));
  /*我們定義了一個宏#define WIDTHBYTES(i) ((i+31)/32*4),上面曾經提到過,每一行
  的位元組數必須是4的整倍數,只要調用WIDTHBYTES(bi.biWidth*bi.biBitCount)就能完成
  這一換算.舉一個例子,對於2色圖,如果圖象寬是31,則每一行需要31位儲存,合3個字
  節加7位,因為位元組數必須是4的整倍數,所以應該是4,而此時的biWidth=31,biBitCou
  nt=1,WIDTHBYTES(31*1)=4,和我們設想的一樣。再舉一個256色的例子,如果圖象寬是
  31,則每一行需要31個位元組儲存,因為位元組數必須是4的整倍數,所以應該是32,而此時
  的biWidth=31,biBitCount=8,WIDTHBYTES(31*8)=32,和我們設想的一樣。你可以多舉幾
  個例子來驗證一下*/
  //LineBytes為每一行的位元組數
  LineBytes=(DWORD)WIDTHBYTES(bi.biWidth*bi.biBitCount);
  //ImgSize為實際的圖象資料佔用的位元組數
  ImgSize=(DWORD)LineBytes*bi.biHeight;
  //NumColors為實際用到的顏色數,即調色盤數組中的顏色個數
  if(bi.biClrUsed!=0)
  NumColors=(DWORD)bi.biClrUsed;//如果bi.biClrUsed不為零,就是本圖象實際
  //用到的顏色數
  else//否則,用到的顏色數為2的biBitCount次方。
  switch(bi.biBitCount){
  case1:
  NumColors=2;
  break;
  case4:
  NumColors=16;
  break;
  case8:
  NumColors=256;
  break;
  case24:
  NumColors=0;//對於真彩色圖,沒用到調色盤
  break;
  default:
  //不處理其它的顏色數,認為出錯。
  MessageBox(hWnd,"Invalidcolornumbers!","ErrorMessage",
  MB_OK|MB_ICONEXCLAMATION);
  _lclose(hf);
  return FALSE;//關閉檔案,返回FALSE
  }
  if(bf.bfOffBits!=(DWORD)(NumColors*sizeof(RGBQUAD)+sizeof(BITMAPFILEHEADER)
  +sizeof(BITMAPINFOHEADER)))
  {
  //計算出的位移量與實際位移量不符,一定是顏色數出錯
  MessageBox(hWnd,"Invalidcolornumbers!","ErrorMessage",
  MB_OK|MB_ICONEXCLAMATION);
  _lclose(hf);
  return FALSE;//關閉檔案,返回FALSE
  }
  bf.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+NumColors
  *sizeof(RGBQUAD)+ImgSize;
  //分配記憶體,大小為BITMAPINFOHEADER結構長度加調色盤+實際位元影像資料
  if((hImgData=GlobalAlloc(GHND,(DWORD)(sizeof(BITMAPINFOHEADER)+
  NumColors*sizeof(RGBQUAD)+ImgSize)))==NULL)
  {
  //分配記憶體錯誤
  MessageBox(hWnd,"Errorallocmemory!","ErrorMessage",
  MB_OK|MB_ICONEXCLAMATION);
  _lclose(hf);
  return FALSE;//關閉檔案,返回FALSE
  }
  //指標lpImgData指向該記憶體區
  lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);
  //檔案指標重新置放到BITMAPINFOHEADER開始處
  _llseek(hf,sizeof(BITMAPFILEHEADER),SEEK_SET);
  //將檔案內容讀入lpImgData
  _hread(hf,(char*)lpImgData,(long)sizeof(BITMAPINFOHEADER)
  +(long)NumColors*sizeof(RGBQUAD)+ImgSize);
  _lclose(hf);//關閉檔案
  if(NumColors!=0) //NumColors不為零,說明用到了調色盤
  {
  //為邏輯調色盤分配局部記憶體,大小為邏輯調色盤結構長度加NumColors個
  //PALETTENTRY大小
  hPal=LocalAlloc(LHND,sizeof(LOGPALETTE)+NumColors*sizeof(PALETTEENTRY));
  //指標pPal指向該記憶體區
  pPal=(LOGPALETTE*)LocalLock(hPal);
  //填寫邏輯調色盤結構的頭
  pPal->palNumEntries=NumColors;
  pPal->palVersion=0x300;
  //lpRGB指向的是調色盤開始的位置
  lpRGB=(LPRGBQUAD)((LPSTR)lpImgData+(DWORD)sizeof(BITMAPINFOHEADER));
  //填寫每一項
  for(i=0;i  {
  pPal->palPalEntry[i].peRed=lpRGB->rgbRed;
  pPal->palPalEntry[i].peGreen=lpRGB->rgbGreen;
  pPal->palPalEntry[i].peBlue=lpRGB->rgbBlue;
  pPal->palPalEntry[i].peFlags=(BYTE)0;
  lpRGB++;//指標移到下一項
  }
  //產生邏輯調色盤,hPalette是一個全域變數
  hPalette=CreatePalette(pPal);
  //釋放局部記憶體
  LocalUnlock(hPal);
  LocalFree(hPal);
  }
  //獲得裝置上下文控制代碼
  hDc=GetDC(hWnd);
  if(hPalette)//如果剛才產生了邏輯調色盤
  {
  //將新的邏輯調色盤選入DC,將舊的邏輯調色盤控制代碼儲存在hPrevPalette
  hPrevPalette=SelectPalette(hDc,hPalette,FALSE);
  RealizePalette(hDc);
  }
  //產生位元影像控制代碼
  hBitmap=CreateDIBitmap(hDc, (LPBITMAPINFOHEADER)lpImgData,(LONG)CBM_INIT,
  (LPSTR)lpImgData+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD),
  (LPBITMAPINFO)lpImgData,DIB_RGB_COLORS);
  //將原來的調色盤(如果有的話)選入裝置上下文控制代碼
  if(hPalette&&hPrevPalette)
  {
  SelectPalette(hDc,hPrevPalette,FALSE);
  RealizePalette(hDc);
  }
  ReleaseDC(hWnd,hDc); //釋放裝置上下文
  GlobalUnlock(hImgData); //解鎖記憶體區
  Return TRUE; //成功返回
  }
  上面的程式中,要說明的有兩點:
  第一,對於需要調色盤的圖,要想正確的顯示,必鬚根據.bmp檔案,產生邏輯調色盤。
  產生的方法是:1.為邏輯調色盤指標分配記憶體,大小為邏輯調色盤結構(LOGPALETTE)
  長度加NumColors個PALETTENTRY大小。(調色盤的每一項都是一個PALETTEENTRY結構)
  ,2.填寫邏輯調色盤結構的頭pPal->palNumEntries=NumColors;pPal->palVersion=0x3
  00;3.從檔案中讀取調色盤的RGB值,填寫到每一項中。4,產生邏輯調色盤:hPalette=
  CreatePalette(pPal)
  第二,產生位元影像(BITMAP)控制代碼,該項工作由函數CreateDIBitmap來完成。hBitmap=Cr
  eateDIBitmap(hDc,LPBITMAPINFOHEADER)lpImgData,(LONG)CBM_INIT, (LPSTR)lpImgDa
  ta+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD), (LPBITMAPINFO)lpImgDa
  ta,DIB_RGB_COLORS); CreateDIBitmap的作用是產生一個和Windows裝置無關的位元影像。該
  函數的第一項參數為裝置上下文控制代碼,如果位元影像用到了調色盤,要在調用CreateDIBitm
  ap之前將邏輯調色盤選入該裝置上下文中,產生hBitmap後,再把原調色盤選入該裝置上
  下文中,並釋放該上下文;第二項為指向BITMAPINFOHEADER的指標;第三項就用常量CB
  M_INI,不用考慮;第四項為指向調色盤的指標;第五項為指向BITMAPINFO(包括BITMA
  PINFOHEADER,調色盤,及實際的圖象資料)的指標;第六項就用常量DIB_RGB_COLORS,不
  用考慮。
  上面提到了裝置上下文,相信編過Windows程式的讀者對它並不陌生,這裡再簡單的介紹
  一下。Windows作業系統統一管理著諸如顯示,列印等操作,將它們看作是一個個的裝置
  ,每一個裝置都有一個複雜的資料結構來維護。所謂裝置上下文就是指這個資料結構。
  然而,我們不能直接和這些裝置上下文打交道,只能通過引用標識它的控制代碼(實際上是
  一個整數),讓Windows去做相應的處理。產生的邏輯調色盤控制代碼hPalette和位元影像控制代碼h
  Bitmap要在處理WM_PAINT訊息時使用,這樣才能在螢幕上顯示出來,處理過程如下面的
  程式。
  StaticHDC hDC,hMemDC;
  PAINTSTRUCT ps;
  case WM_PAINT:
  {
  hDC=BeginPaint(hwnd,&ps);//獲得螢幕裝置上下文
  if(hBitmap)//hBitmap一開始是NULL,當不為NULL時表示有圖
  {
  hMemDC=CreateCompatibleDC(hDC);//建立一個記憶體裝置上下文
  if(hPalette)//有調色盤
  {
  //將調色盤選入螢幕裝置上下文
  SelectPalette(hDC,hPalette,FALSE);
  //將調色盤選入記憶體裝置上下文
  SelectPalette(hMemDC,hpalette,FALSE);
  RealizePalette(hDC);
  }
  //將位元影像選入記憶體裝置上下文
  SelectObject(hMemDC,hBitmap);
  //顯示位元影像
  BitBlt(hDC,0,0,bi.biWidth,bi.biHeight,hMemDC,0,0,SRCCOPY);
  //釋放記憶體裝置上下文
  DeleteDC(hMemDC);
  }
  //釋放螢幕裝置上下文
  EndPaint(hwnd,&ps);
  break;
  }
  在上面的程式中,我們調用CreateCompatibleDC建立一個記憶體裝置上下文。SelectObje
  ct函數將於裝置無關的位元影像選入記憶體裝置上下文中。然後我們調用BitBlt函數在記憶體設
  備上下文和螢幕裝置上下文中進行位拷貝。由於所有操作都是在記憶體中進行,所以是最
  快的。
  BitBlt函數的參數分別為:1.目標裝置上下文,在上面的程式裡,為螢幕裝置上下文,
  如果改成列印裝置上下文,就不是顯示位元影像,而是列印;2.目標矩形左上方點x座標;3
  .目標矩形左上方點y座標,在上面的程式中,2和3為(0,0),表示顯示在視窗的左上
  角;4.目標矩形的寬度;5.目標矩形的高度;6.源裝置上下文,在上面的程式裡,為內
  存裝置上下文;7.源矩形左上方點x座標;8.源矩形左上方點y座標;9.操作方式,在這
  裡為SRCCOPY,表示直接將源矩形拷貝到目標矩形。還可以是反色,擦除,做"與"運算等
  操作,具體細節見VC++協助。你可以試著改改第2,3,4,5,7,8,9項參數,就能體會
  到它們的含義了。
  終於講完了。是不是覺得有點枯燥?這一講是有點兒枯燥,特別是當你對Windows的編程
  並不很清楚時,就更覺得如此。不過,當一幅漂亮的bmp圖顯示在螢幕上時,你還是會興
  奮的大叫"Yeah",至少當年我是這樣。
  最後,再介紹一個命令列編譯的竅門。為什麼要用命令列編譯呢?主要有兩個好處:
  第一,不用進入IDE(整合式開發環境),節省了時間,而且編譯速度也比較快。
  第二,對於簡單的程式,不用產生專案檔.mdp或.mak,直接就能產生.exe檔案,這一
  點,在下面的例子中可以看到。
  在安裝VisualC++完畢時,在bin目錄下會產生一個VCVARS32.BAT檔案,它的作用是在命
  令行編譯時間設定正確的環境變數,如存放標頭檔的INCLUDE目錄,存放庫檔案的LIB目錄
  等,如果你沒找到這個批次檔,可以參考下面的例子,自己做一個批處理。
  @echo off
  set MSDevDir=d:/MSDEV
  set VcOsDir=WIN95
  set PATH="%MSDevDir%/BIN";"%MSDevDir%/BIN/%VcOsDir%";"%PATH%"
  set INCLUDE=%MSDevDir%/INCLUDE;%MSDevDir%/MFC/INCLUDE;%INCLUDE%
  set LIB=%MSDevDir%/LIB;%MSDevDir%/MFC/LIB;%LIB%
  set VcOsDir=
  只要把上面的"d:/MSDEV"改成你自己的VC目錄就可以了。在DOSPROMPT下執行該批處理文
  件,執行set命令,你就能看到新設定的環境變數了。如下所示:
  PATH=D:/MSDEV/BIN;D:/MSDEV/BIN/WIN95;C:/WIN95;C:/WIN95/COMMAND;C:/WIN95/SYST
  EM;
  INCLUDE=d:/msdev/INCLUDE;d:/msdev/MFC/INCLUDE;
  LIB=d:/msdev/LIB;d:/msdev/MFC/LIB;
  現在我們就可以進行命令列編譯了。(當然,你也可以使用IDE,先new一個project,然
  後把.c和.rc檔案插入到project中,編譯運行。)
  首先編譯資源檔,輸入rc bmp.rc,將產生bmp.res檔案,接著輸入cl bmp.c bmp.res
  user32.lib gdi32.lib,就產生bmp.exe了。可以看到,我們並沒有用到專案檔,所
  以,對於這種簡單的程式來說,使用命令列編譯還是非常方便的。好了,運行bmp.exe,
  欣賞一下你今天的勞動成果。
  注意事項:
  命令列編譯過程如下:
  vcvars32
  rc bmp.rc
  cl bmp.c bmp.res user32.lib gdi32.lib
  發表於: 2006-10-19,修改於: 2006-10-19 14:07 已瀏覽305次,有評論0條推薦投訴

本文轉自
http://blog.chinaunix.net/u/19671/showart_187280.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.