weidagang2046的專欄

          物格而后知致
          隨筆 - 8, 文章 - 409, 評論 - 101, 引用 - 0
          數據加載中……

          用VC進行屏幕截取編程

          ---- 屏幕截取是令人比較感興趣的事情.雖然現在有不少應用程序如HYPERSNAP等可以用來截取你所喜歡的屏幕畫面,但是如果能把這個功能加到自己的程序中,就更能利用它強大的作用.

          ---- 下面用VC來逐步介紹在Windows95下的實現過程.首先我們要確定屏幕截取的區域,用LPRECT結構來定義.可以截取一個窗口,或整個屏幕.以下代碼把選定的屏幕區域拷貝到位圖中.

          HBITMAP CopyScreenToBitmap(LPRECT lpRect)
          //lpRect 代表選定區域
          {
          HDC???????hScrDC, hMemDC;??????
          // 屏幕和內存設備描述表
          HBITMAP????hBitmap, hOldBitmap;???
          // 位圖句柄
          int???????nX, nY, nX2, nY2;??????
          // 選定區域坐標
          int???????nWidth, nHeight;??????
          // 位圖寬度和高度
          int???????xScrn, 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 = SelectObject(hMemDC, hBitmap);
          ???// 把屏幕設備描述表拷貝到內存設備描述表中
          BitBlt(hMemDC, 0, 0, nWidth, nHeight,
          hScrDC, nX, nY, SRCCOPY);
          ???//得到屏幕位圖的句柄
          ???hBitmap = SelectObject(hMemDC, hOldBitmap);
          ???//清除
          ???DeleteDC(hScrDC);
          ???DeleteDC(hMemDC);
          ???// 返回位圖句柄
          ???return hBitmap;
          }
          ???
          得到屏幕位圖句柄以后,我們
          可以把屏幕內容粘貼到剪貼板上.
          ????if (OpenClipboard(hWnd))
          ?????//hWnd為程序窗口句柄
          ??????{
          ????????//清空剪貼板
          ????????EmptyClipboard();
          ????????//把屏幕內容粘貼到剪貼板上,
          ????????hBitmap 為剛才的屏幕位圖句柄
          ????????SetClipboardData(CF_BITMAP, hBitmap);
          ????????//關閉剪貼板
          ????????CloseClipboard();
          ??????}
          ???我們也可以把屏幕內容以位圖格式存到磁盤文件上.
          ??????
          int SaveBitmapToFile(HBITMAP hBitmap ,
          LPSTR lpFileName) //hBitmap 為剛才的屏幕位圖句柄
          {???? ?//lpFileName 為位圖文件名
          HDC????????????hDC;?????????
          ?? ?//設備描述表
          ??????int????????????iBits;??????
          ? //當前顯示分辨率下每個像素所占字節數
          WORD????????????wBitCount;???
          ??? //位圖中每個像素所占字節數
          ??????//定義調色板大小, 位圖中像素字節大小 ,
          ??????位圖文件大小 , 寫入文件字節數
          DWORD???????????dwPaletteSize=0,
          dwBmBitsSize,
          ?dwDIBSize, dwWritten;
          BITMAP??????????Bitmap;????????
          //位圖屬性結構
          BITMAPFILEHEADER???bmfHdr;????????
          //位圖文件頭結構
          ??????BITMAPINFOHEADER???bi;????????????
          //位圖信息頭結構
          LPBITMAPINFOHEADER lpbi;??????????
          //指向位圖信息頭結構
          ??????HANDLE??????????fh, hDib, hPal,hOldPal=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;
          ???//計算調色板大小
          ???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, hPal, FALSE);
          ??????RealizePalette(hDC);
          ???}
          ???// 獲取該調色板下新的像素值
          ???GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight,
          ?(LPSTR)lpbi + sizeof(BITMAPINFOHEADER)
          ????+dwPaletteSize,
          ?(BITMAPINFOHEADER *)
          ????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);
          }

          from: http://www.cnsdn.com.cn/inc/show.asp?id=3472

          posted on 2006-10-01 23:36 weidagang2046 閱讀(267) 評論(0)  編輯  收藏 所屬分類: Windows

          主站蜘蛛池模板: 星座| 土默特右旗| 清原| 广丰县| 集贤县| 合江县| 仪征市| 吉首市| 特克斯县| 汉川市| 南澳县| 湾仔区| 二手房| 平定县| 菏泽市| 龙海市| 讷河市| 白沙| 阜平县| 无极县| 皋兰县| 佛冈县| 富裕县| 麟游县| 黎川县| 赫章县| 瑞安市| 桑日县| 漳州市| 海南省| 湘西| 霍山县| 屏山县| 安国市| 左云县| 庄河市| 肇州县| 汪清县| 兰溪市| 当涂县| 鄱阳县|