posts - 495,comments - 227,trackbacks - 0

          下面是一段屏幕拷貝的代碼,共兩個功能函數,其中一個函數可以把 HBITMAP 保存為 BMP 文件

          // scr2bmp.cpp : Defines the entry point for the application.
          //

          #include "stdafx.h"
          #include "resource.h"


          LRESULT CALLBACKAbout(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
          HBITMAP WINAPIcopyScreenToBitmap(LPRECT lpRect);
          BOOL WINAPIsaveBitmapToFile(HBITMAP hBitmap,LPSTR lpFileName);


          int APIENTRY WinMain(HINSTANCE hInstance,
                               HINSTANCE hPrevInstance,
                               LPSTR lpCmdLine,
                               int nCmdShow)
          {
          DialogBox(hInstance,(LPCTSTR)IDD_ABOUTBOX,NULL,(DLGPROC)About);

          return 0;
          }

          LRESULT CALLBACK About(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
          {
          RECTrc;

          switch(uMsg)
          {
          case WM_INITDIALOG:
          return TRUE;

          case WM_COMMAND:
          switch(LOWORD(wParam))
          {
          case IDOK:
          GetWindowRect(hwnd,&rc);
          saveBitmapToFile(copyScreenToBitmap(&rc),"D:\\1.bmp");
          EndDialog(hwnd,LOWORD(wParam));
          break;

          case IDCANCEL:
          EndDialog(hwnd,LOWORD(wParam));
          break;
          }
          return TRUE;
          }

          return FALSE;
          }

          HBITMAP WINAPI copyScreenToBitmap(LPRECT lpRect)// lpRect 代表選定區域
          {
          HDChScrDC, hMemDC;// 屏幕和內存設備描述表
          HBITMAPhBitmap,hOldBitmap;// 位圖句柄
          intnX, nY, nX2, nY2;// 選定區域坐標
          intnWidth, nHeight;// 位圖寬度和高度
          intxScrn, yScrn;// 屏幕分辨率

          // 確保選定區域不為空矩形
          if(IsRectEmpty(lpRect))return NULL;

          // 為屏幕創建設備描述表
          hScrDC = CreateDC("DISPLAY",NULL,NULL,NULL);

          // 為屏幕設備描述表創建兼容的內存設備描述表
          hMemDC = CreateCompatibleDC(hScrDC);

          // 獲得選定區域坐標
          nX = lpRect->left;
          nY = lpRect->top;
          nX2 = lpRect->right;
          nY2 = lpRect->bottom;

          // 獲得屏幕分辨率
          xScrn = GetDeviceCaps(hScrDC,HORZRES);
          yScrn = GetDeviceCaps(hScrDC,VERTRES);

          // 確保選定區域是可見的
          if(nX < 0)nX = 0;
          if(nY < 0)nY = 0;
          if(nX2 > xScrn)nX2 = xScrn;
          if(nY2 > yScrn)nY2 = yScrn;

          nWidth = nX2 - nX;
          nHeight = nY2 - nY;

          // 創建一個與屏幕設備描述表兼容的位圖
          hBitmap = CreateCompatibleBitmap(hScrDC,nWidth,nHeight);

          // 把新位圖選到內存設備描述表中
          hOldBitmap = (HBITMAP)SelectObject(hMemDC,hBitmap);

          // 把屏幕設備描述表拷貝到內存設備描述表中
          BitBlt(hMemDC,0,0,nWidth,nHeight,hScrDC,nX,nY,SRCCOPY);

          // 得到屏幕位圖的句柄
          hBitmap = (HBITMAP)SelectObject(hMemDC,hOldBitmap);

          // 清除
          DeleteDC(hScrDC);
          DeleteDC(hMemDC);

          // 返回位圖句柄
          return hBitmap;
          }  

          BOOL WINAPI saveBitmapToFile(HBITMAP hBitmap,// hBitmap 為剛才的屏幕位圖句柄
           LPSTR lpFileName)// lpFileName 為位圖文件名
          {
          HDChDC;// 設備描述表
          intiBits;// 當前顯示分辨率下每個像素所占字節數
          WORDwBitCount;// 位圖中每個像素所占字節數
          DWORDdwPaletteSize = 0,// 定義調色板大小
          dwBmBitsSize,// 位圖中像素字節大小
          dwDIBSize,// 位圖文件大小
          dwWritten;// 寫入文件字節數
          BITMAPBitmap;// 位圖屬性結構
          BITMAPFILEHEADERbmfHdr;// 位圖文件頭結構
          BITMAPINFOHEADERbi;// 位圖信息頭結構
          LPBITMAPINFOHEADERlpbi;// 指向位圖信息頭結構
          HANDLEfh,// 定義文件
          hDib,// 分配內存句柄
          hPal;// 調色板句柄
          HPALETTEhOldPal = NULL;

          // 計算位圖文件每個像素所占字節數
          hDC = CreateDC("DISPLAY",NULL,NULL,NULL);
          iBits = GetDeviceCaps(hDC,BITSPIXEL) * GetDeviceCaps(hDC,PLANES);
          DeleteDC(hDC);

          if(iBits <= 1)wBitCount = 1;
          else if(iBits <= 4)wBitCount = 4;
          else if(iBits <= 8)wBitCount = 8;
          else if(iBits <= 24)wBitCount = 24;
          else wBitCount = 24;

          // 計算調色板大小
          if(wBitCount <= 8)dwPaletteSize = (1 << wBitCount) * sizeof(RGBQUAD);

          // 設置位圖信息頭結構
          GetObject(hBitmap,sizeof(BITMAP),(LPSTR)&Bitmap);

          bi.biSize = sizeof(BITMAPINFOHEADER);
          bi.biWidth = Bitmap.bmWidth;
          bi.biHeight = Bitmap.bmHeight;
          bi.biPlanes = 1;
          bi.biBitCount = wBitCount;
          bi.biCompression = BI_RGB;
          bi.biSizeImage = 0;
          bi.biXPelsPerMeter = 0;
          bi.biYPelsPerMeter = 0;
          bi.biClrUsed = 0;
          bi.biClrImportant = 0;

          dwBmBitsSize = ((Bitmap.bmWidth * wBitCount + 31) / 32) * 4 * Bitmap.bmHeight;

          // 為位圖內容分配內存
          hDib = GlobalAlloc(GHND,dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));
          lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
          *lpbi = bi;

          // 處理調色板
          hPal = GetStockObject(DEFAULT_PALETTE);
          if(hPal)
          {
          hDC = GetDC(NULL);
          hOldPal = SelectPalette(hDC,(HPALETTE)hPal,FALSE);
          RealizePalette(hDC);
          }

          // 獲取該調色板下新的像素值
          GetDIBits(hDC,hBitmap,0,(UINT)Bitmap.bmHeight,(LPSTR)lpbi + sizeof(BITMAPINFOHEADER) + dwPaletteSize,(BITMAPINFO*)lpbi,DIB_RGB_COLORS);

          // 恢復調色板
          if(hOldPal)
          {
          SelectPalette(hDC,hOldPal,TRUE);
          RealizePalette(hDC);
          ReleaseDC(NULL,hDC);
          }

          // 創建位圖文件
          fh = CreateFile(lpFileName,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,NULL);
          if(fh == INVALID_HANDLE_VALUE)return FALSE;

          // 設置位圖文件頭
          bmfHdr.bfType = 0x4D42;// "BM"
          dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize;
          bmfHdr.bfSize = dwDIBSize;
          bmfHdr.bfReserved1 = 0;
          bmfHdr.bfReserved2 = 0;
          bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize;

          // 寫入位圖文件頭
          WriteFile(fh,(LPSTR)&bmfHdr,sizeof(BITMAPFILEHEADER),&dwWritten,NULL);

          // 寫入位圖文件其余內容
          WriteFile(fh,(LPSTR)lpbi,dwDIBSize,&dwWritten,NULL);

          // 清除
          GlobalUnlock(hDib);
          GlobalFree(hDib);
          CloseHandle(fh);

          return TRUE;
          }
          /////////////////////////////////////////////////////////////////////////////////////////////
          CPaintDC dc(this);
           CDC cdcMem;
           CBitmap m_bitmap;
           cdcMem.CreateCompatibleDC(&dc);
           m_bitmap.CreateCompatibleBitmap(&cdcMem, 100, 100);
           cdcMem.SelectObject(&m_bitmap);
           cdcMem.LineXY(100,100);

           在上面代碼中,象訪問數組一樣訪問cdcMem的內存塊,并取得象素的數據,該如何操作?
          //////////////////////////////////////////////////////
          // 獲取位圖信息大小
          BITMAPINFO bmpInfo;
          ZeroMemory(&bmpInfo, sizeof(BITMAPINFO));
          bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
          int nRet = GetDIBits(dc.m_hDC, m_bitmap, 0, 0, NULL, &bmpInfo, DIB_RGB_COLORS);
          if (nRet == 0)
          {
           return;
          }
          if (bmpInfo.bmiHeader.biSizeImage <= 0)
          {
           bmpInfo.bmiHeader.biSizeImage = bmpInfo.bmiHeader.biWidth * abs     (bmpInfo.bmiHeader.biHeight) * (bmpInfo.bmiHeader.biBitCount+7)/8;
          }

          // 開辟位圖數據占用的空間
          LPVOID lpvBits = malloc(bmpInfo.bmiHeader.biSizeImage);
          if (lpvBits == NULL)
          {
           return;
          }

          // 獲取位圖數據信息
          bmpInfo.bmiHeader.biCompression = BI_RGB;
          nRet = GetDIBits(hDC, hBitmap, 0, bmpInfo.bmiHeader.biHeight, lpvBits, &bmpInfo, DIB_RGB_COLORS);
          if (nRet == 0)
          {
           return;
          }
          // 對位圖信息lpvBits的操作。。。。。
          // ......
          // 釋放開辟的空間
          free(lpvBits);
          lpvBits = NULL;

          posted on 2007-09-29 17:42 SIMONE 閱讀(2080) 評論(0)  編輯  收藏 所屬分類: C++
          主站蜘蛛池模板: 阳曲县| 银川市| 朝阳县| 晋宁县| 荆门市| 化德县| 曲松县| 安远县| 伊吾县| 曲阜市| 镇安县| 岫岩| 牡丹江市| 通许县| 胶州市| 青岛市| 栖霞市| 汝阳县| 拜泉县| 夏津县| 永州市| 开封县| 临安市| 延庆县| 盐源县| 高台县| 楚雄市| 会同县| 抚顺县| 尼勒克县| 且末县| 黄梅县| 连山| 东兰县| 缙云县| 始兴县| 平昌县| 景宁| 图片| 北票市| 大同市|