#include <stdio.h>#include <tchar.h>//WINAPI 拷貝指定的hDC的lpRect部分到檔案Dstfile中(BMP檔案格式)BOOL SaveHDCToFile(HDC hDC, LPRECT lpRect, LPCTSTR Dstfile){ int Width = lpRect->right - lpRect->left; int Height = lpRect->bottom - lpRect->top; HDC memDC = CreateCompatibleDC(hDC);//記憶體DC HBITMAP memBitmap = CreateCompatibleBitmap(hDC, Width, Height); //建立和螢幕相容的bitmap HBITMAP hOldBitmap = (HBITMAP)SelectObject(memDC, memBitmap);//將memBitmap選入記憶體DC BitBlt(memDC, 0, 0, Width, Height, hDC, lpRect->left, lpRect->top, SRCCOPY);//複製螢幕映像到記憶體DC //以下代碼儲存memDC中的位元影像到檔案 BITMAP bmpInfo; GetObject(memBitmap, sizeof(bmpInfo), &bmpInfo);//獲得位元影像資訊 DWORD bmpBytesSize = bmpInfo.bmWidthBytes * bmpInfo.bmHeight; BITMAPFILEHEADER bfh = {0};//位元影像檔案頭 bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);//到位元影像資料的位移量 bfh.bfSize = bfh.bfOffBits + bmpBytesSize ;//檔案總的大小 bfh.bfType = (WORD)0x4d42; BITMAPINFOHEADER bih = {0};//位元影像資訊頭 bih.biBitCount = bmpInfo.bmBitsPixel;//每個像素位元組大小 bih.biCompression = BI_RGB; bih.biHeight = bmpInfo.bmHeight;//高度 bih.biPlanes = 1; bih.biSize = sizeof(BITMAPINFOHEADER); bih.biSizeImage = bmpBytesSize;//映像資料大小 bih.biWidth = bmpInfo.bmWidth;//寬度 BYTE * p = new BYTE[bmpBytesSize];//申請記憶體儲存位元影像資料 GetDIBits(memDC, memBitmap, 0, Height, p,(LPBITMAPINFO) &bih, DIB_RGB_COLORS);//擷取位元影像資料 //正常的還要對256及以下的顏色加顏色映射表, // 但是現在的顯示模式基本上都是真彩(24或32位)顯示,因此忽略此項 //儲存到檔案 HANDLE hFile = CreateFile(Dstfile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); if(hFile != INVALID_HANDLE_VALUE) { DWORD dwBytesWritten; WriteFile(hFile, &bfh, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);//寫入位元影像檔案頭 WriteFile(hFile, &bih, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);//寫入位元影像資訊頭 WriteFile(hFile, p, bmpInfo.bmWidthBytes * bmpInfo.bmHeight, &dwBytesWritten, NULL);//寫入位元影像資料 CloseHandle(hFile); } else { TCHAR szMsg[256]; _stprintf_s(szMsg, _T("CreateFile error=%lu"), GetLastError()); MessageBox(NULL, szMsg, _T("Error"), MB_OK); } //結束清理工作 delete [] p; SelectObject(memDC, hOldBitmap); DeleteObject(memBitmap); DeleteDC(memDC); return(true);}
//測試案例,按下任意鍵時儲存成為位元影像LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ switch (message) { case WM_PAINT: //繪圖代碼 { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); TextOut(hdc, 0, 0, _T("ABCD"), 4); EndPaint(hWnd, &ps); break; } case WM_KEYDOWN: //按下一個按鍵的時候儲存成位元影像檔案 { LPCTSTR szFileName = _T("C:\\test.bmp"); HDC hDC = GetDC(hWnd); RECT rcRect; GetClientRect(hWnd, &rcRect); SaveHDCToFile(hDC, &rcRect, szFileName); ReleaseDC(hWnd, hDC); //ShellExecute(NULL, _T("open"), szFileName, NULL, NULL, SW_SHOWNORMAL);//開啟圖片查看 break; } case WM_DESTROY: { PostQuitMessage(0); break; } default: { return DefWindowProc(hWnd, message, wParam, lParam); } } return 0;}