/*

CIMAGE 안에 있는 JPEG 라이브러리를 이용해서

DC를 캡쳐한것을 JPEG, BMP로 저장하는 소스코드

긁어다 쓰는것도 엄청 복잡하구만 ㅠ.ㅠ



*JPEG 을 컴파일할때 NOT USING MFC 항목을 체크할것

*BMP는 MSDN을 참조

*JPG는 CODEGURU  참조



*ppt 를 전체화면으로 뛰웠을때 파워포인트를 캡쳐해서

저장하는 프로그램이라고 하면 될것임;;

*/

#include <windows.h>
#include <stdio.h>

extern "C" {
#include "jpeglib.h"
}

#include <setjmp.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

struct ima_error_mgr {
struct jpeg_error_mgr pub; /* "public" fields */
 jmp_buf setjmp_buffer; /* for return to caller */
};

typedef ima_error_mgr *ima_error_ptr;

void CreateBMPFile(HWND hwnd, LPTSTR pszFile, PBITMAPINFO pbi, HBITMAP hBMP, HDC hDC) ;
void errhandler(LPTSTR pszFile, HWND hwnd);

////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
//Header file code
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
HANDLE DDBToDIB(HBITMAP bitmap, DWORD dwCompression);

//In the relevant header file (up near the top):
BOOL DibToSamps(HANDLE          hDib,
               int                         nSampsPerRow,
               struct jpeg_compress_struct cinfo,
               JSAMPARRAY                  jsmpPixels,
               LPTSTR                    pcsMsg);

BOOL JpegFromDib( HANDLE    hDib,     //Handle to DIB
                int        nQuality, //JPEG quality (0-100)
                LPTSTR    csJpeg,   //Pathname to target jpeg file
                LPTSTR   pcsMsg);  //Error msg to return

BOOL BuildSamps(HANDLE                      hDib,
               int                         nSampsPerRow,
               struct jpeg_compress_struct cinfo,
               JSAMPARRAY                  jsmpArray,
               LPTSTR                    pcsMsg);

RGBQUAD QuadFromWord(WORD b16);

////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
//Source file code
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////
//This function takes the contents of a DIB
//and turns it into a JPEG file.
//
//The DIB may be monochrome, 16-color, 256-color, or 24-bit color.
//
//Any functions or data items beginning with "jpeg_" belong to jpeg.lib,
//and are not included here.
//
//The function assumes 3 color components per pixel.
/////////////////////////////////////////////////////////////////////////////
BOOL JpegFromDib(HANDLE hDib,     //Handle to DIB
                int        nQuality, //JPEG quality (0-100)
                LPTSTR    csJpeg,   //Pathname to jpeg file
                LPTSTR   pcsMsg)   //Error msg to return
{
   //Basic sanity checks...
   if (nQuality < 0 || nQuality > 100 ||
       hDib   == NULL ||
       pcsMsg == NULL ||
       csJpeg == "")
   {
       if (pcsMsg != NULL)
           pcsMsg = "Invalid input data";

       return FALSE;
   }

   pcsMsg = "";

   LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)hDib;

   byte *buf2 = 0;

   //Use libjpeg functions to write scanlines to disk in JPEG format
   struct jpeg_compress_struct cinfo;
   struct jpeg_error_mgr       jerr;

   FILE*      pOutFile;     //Target file
   int        nSampsPerRow; //Physical row width in image buffer
   JSAMPARRAY jsmpArray;    //Pixel RGB buffer for JPEG file

   cinfo.err = jpeg_std_error(&jerr); //Use default error handling (ugly!)

   jpeg_create_compress(&cinfo);

   if ((pOutFile = fopen(csJpeg, "wb")) == NULL)
   {
       pcsMsg = "Cannot open ";
//  pcsMsg += csJpeg;
       jpeg_destroy_compress(&cinfo);
       return FALSE;
   }

   jpeg_stdio_dest(&cinfo, pOutFile);

   cinfo.image_width      = lpbi->biWidth;  //Image width and height, in pixels
   cinfo.image_height     = lpbi->biHeight;
   cinfo.input_components = 3;              //Color components per pixel
                                            //(RGB_PIXELSIZE - see jmorecfg.h)
   cinfo.in_color_space   = JCS_RGB;       //Colorspace of input image

   jpeg_set_defaults(&cinfo);

   jpeg_set_quality(&cinfo,
                    nQuality, //Quality: 0-100 scale
                    TRUE);    //Limit to baseline-JPEG values

   jpeg_start_compress(&cinfo, TRUE);

   //JSAMPLEs per row in output buffer
   nSampsPerRow = cinfo.image_width * cinfo.input_components;

   //Allocate array of pixel RGB values
   jsmpArray = (*cinfo.mem->alloc_sarray)
               ((j_common_ptr) &cinfo,
                JPOOL_IMAGE,
                nSampsPerRow,
                cinfo.image_height);

   if (DibToSamps(hDib,
                  nSampsPerRow,
                  cinfo,
                  jsmpArray,
                  pcsMsg))
   {
       //Write the array of scan lines to the JPEG file
       (void)jpeg_write_scanlines(&cinfo,
                                  jsmpArray,
                                  cinfo.image_height);
   }

   jpeg_finish_compress(&cinfo); //Always finish

   fclose(pOutFile);

   jpeg_destroy_compress(&cinfo); //Free resources

   if (pcsMsg != "")
       return FALSE;

   else
       return TRUE;
}

////////////////////////////////////////////////////////////////
//This function fills a jsmpArray with the RGB values
//for the CBitmap.
//
//It has been improved to handle all legal bitmap formats.
//
//A jsmpArray is a big array of RGB values, 3 bytes per value.
//
//Note that rows of pixels are processed bottom to top:
//The data in the jsamp array must be arranged top to bottom.
////////////////////////////////////////////////////////////////
BOOL DibToSamps(HANDLE                      hDib,
               int                         nSampsPerRow,
               struct jpeg_compress_struct cinfo,
               JSAMPARRAY                  jsmpPixels,
               LPTSTR                    pcsMsg)
{
  //Sanity...
  if (hDib == NULL    ||
    nSampsPerRow <= 0 || pcsMsg == NULL)
  {
    if (pcsMsg !=NULL)
       pcsMsg="Invalid input data";
    return FALSE;
  }

  int r=0, p=0, q=0, b=0, n=0,
      nUnused=0, nBytesWide=0, nUsed=0, nLastBits=0, nLastNibs=0, nCTEntries=0,
      nRow=0, nByte=0, nPixel=0;
  BYTE bytCTEnt=0;
  LPBITMAPINFOHEADER pbBmHdr= (LPBITMAPINFOHEADER)hDib; //The bit count tells you the format of the bitmap: //Decide how many entries will be in the color table (if any)

  switch (pbBmHdr->biBitCount)
  {
     case 1:
        nCTEntries = 2;   //Monochrome
        break;

     case 4:
        nCTEntries = 16;  //16-color
        break;

     case 8:
        nCTEntries = 256; //256-color
        break;

     case 16:
     case 24:
     case 32:
        nCTEntries = 0;   //No color table needed
        break;

     default:
        pcsMsg = "Invalid bitmap bit count";
        return FALSE; //Unsupported format
  }

  //Point to the color table and pixels
  DWORD     dwCTab = (DWORD)pbBmHdr + pbBmHdr->biSize;
  LPRGBQUAD pCTab  = (LPRGBQUAD)(dwCTab);
  LPSTR     lpBits = (LPSTR)pbBmHdr +
                     (WORD)pbBmHdr->biSize +
                     (WORD)(nCTEntries * sizeof(RGBQUAD));

  //Different formats for the image bits
  LPBYTE   lpPixels = (LPBYTE)  lpBits;
  RGBQUAD* pRgbQs   = (RGBQUAD*)lpBits;
  WORD*    wPixels  = (WORD*)   lpBits;

  //Set up the jsamps according to the bitmap's format.
  //Note that rows are processed bottom to top, because
  //that's how bitmaps are created.
  switch (pbBmHdr->biBitCount)
  {
     case 1:
        nUsed      = (pbBmHdr->biWidth + 7) / 8;
        nUnused    = (((nUsed + 3) / 4) * 4) - nUsed;
        nBytesWide = nUsed + nUnused;
        nLastBits  = 8 - ((nUsed * 8) - pbBmHdr->biWidth);

        for (r=0; r < pbBmHdr->biHeight; r++)
        {
           for (p=0,q=0; p < nUsed; p++)
           {
              nRow=(pbBmHdr->biHeight-r-1) * nBytesWide;
              nByte =  nRow + p;

              int nBUsed = (p <(nUsed -1)) ? 8 : nLastBits;
     
     for(b=0; b < nBUsed;b++)
              {
                 bytCTEnt = lpPixels[nByte] << b;
                 bytCTEnt = bytCTEnt >> 7;

                 jsmpPixels[r][q+0] = pCTab[bytCTEnt].rgbRed;
                 jsmpPixels[r][q+1] = pCTab[bytCTEnt].rgbGreen;
                 jsmpPixels[r][q+2] = pCTab[bytCTEnt].rgbBlue;

                 q += 3;
              }
           }
        }
        break;

     case 4:
        nUsed      = (pbBmHdr->biWidth + 1) / 2;
        nUnused    = (((nUsed + 3) / 4) * 4) - nUsed;
        nBytesWide = nUsed + nUnused;
        nLastNibs  = 2 - ((nUsed * 2) - pbBmHdr->biWidth);

        for (r=0; r < pbBmHdr->biHeight;r++)
        {
           for (p=0,q=0; p < nUsed;p++)
           {
              nRow=(pbBmHdr->biHeight-r-1) * nBytesWide;
              nByte = nRow + p;

              int nNibbles = p;
     for(n=0; n < nNibbles;n++)
              {
                 bytCTEnt=lpPixels[nByte] << (n*4);
     bytCTEnt=bytCTEnt >> (4-(n*4));

                 jsmpPixels[r][q+0] = pCTab[bytCTEnt].rgbRed;
                 jsmpPixels[r][q+1] = pCTab[bytCTEnt].rgbGreen;
                 jsmpPixels[r][q+2] = pCTab[bytCTEnt].rgbBlue;

                 q += 3;
              }
           }
        }
        break;

     default:
     case 8: //Each byte is a pointer to a pixel color
        nUnused = (((pbBmHdr->biWidth + 3) / 4) * 4) -
                  pbBmHdr->biWidth;

        for (r=0;r < pbBmHdr->biHeight; r++)
        {
           for (p=0,q=0; p < pbBmHdr->biWidth; p++,q+=3)
           {
              nRow   = (pbBmHdr->biHeight-r-1) * (pbBmHdr->biWidth + nUnused);
              nPixel =  nRow + p;

              jsmpPixels[r][q+0] = pCTab[lpPixels[nPixel]].rgbRed;
              jsmpPixels[r][q+1] = pCTab[lpPixels[nPixel]].rgbGreen;
              jsmpPixels[r][q+2] = pCTab[lpPixels[nPixel]].rgbBlue;
           }
        }
        break;

     case 16: //Hi-color (16 bits per pixel)
        for (r=0;r < pbBmHdr->biHeight; r++)
        {
           for (p=0,q=0; p < pbBmHdr->biWidth; p++,q+=3)
           {
              nRow    = (pbBmHdr->biHeight-r-1) * pbBmHdr->biWidth;
              nPixel  = nRow + p;

              RGBQUAD quad = QuadFromWord(wPixels[nPixel]);

              jsmpPixels[r][q+0] = quad.rgbRed;
              jsmpPixels[r][q+1] = quad.rgbGreen;
              jsmpPixels[r][q+2] = quad.rgbBlue;
           }
        }
        break;

     case 24:
        nBytesWide =  (pbBmHdr->biWidth*3);
        nUnused    =  (((nBytesWide + 3) / 4) * 4) -
                      nBytesWide;
        nBytesWide += nUnused;

        for (r=0;r < pbBmHdr->biHeight;r++)
        {
           for (p=0,q=0;p < (nBytesWide-nUnused); p+=3,q+=3)
           {
              nRow = (pbBmHdr->biHeight-r-1) * nBytesWide;
              nPixel  = nRow + p;

              jsmpPixels[r][q+0] = lpPixels[nPixel+2]; //Red
              jsmpPixels[r][q+1] = lpPixels[nPixel+1]; //Green
              jsmpPixels[r][q+2] = lpPixels[nPixel+0]; //Blue
           }
        }
        break;

     case 32:
        for (r=0; r < pbBmHdr->biHeight; r++)
        {
           for (p=0,q=0; p < pbBmHdr->biWidth; p++,q+=3)
           {
              nRow    = (pbBmHdr->biHeight-r-1) *
                         pbBmHdr->biWidth;
              nPixel  = nRow + p;

              jsmpPixels[r][q+0] = pRgbQs[nPixel].rgbRed;
              jsmpPixels[r][q+1] = pRgbQs[nPixel].rgbGreen;
              jsmpPixels[r][q+2] = pRgbQs[nPixel].rgbBlue;
           }
        }
        break;
  }   //end switch

return TRUE;
}

////////////////////////////////////////
//This function turns a 16-bit pixel
//into an RGBQUAD value.
////////////////////////////////////////
RGBQUAD QuadFromWord(WORD b16)
{
  BYTE bytVals[] =
  {
    0,  16, 24, 32,  40, 48, 56, 64,
    72, 80, 88, 96, 104,112,120,128,
    136,144,152,160,168,176,184,192,
    200,208,216,224,232,240,248,255
  };

  WORD wR = b16;
  WORD wG = b16;
  WORD wB = b16;

  wR <<= 1; wR >>= 11;
  wG <<= 6; wG >>= 11;
  wB <<= 11; wB >>= 11;

  RGBQUAD rgb;

  rgb.rgbReserved = 0;
  rgb.rgbBlue     = bytVals[wB];
  rgb.rgbGreen    = bytVals[wG];
  rgb.rgbRed      = bytVals[wR];

  return rgb;
}


void main()
{
PBITMAPINFOHEADER pbih;
BITMAP bmp;
   PBITMAPINFO pbmi;
   WORD    cClrBits;
 LPBYTE lpBits;

HWND hPPT;
HDC hdc;
HDC memDC;
HBITMAP  m_Bitmap;


int cx, cy;

printf("dll 파일이 불려 집니다. ");
hPPT=FindWindow("screenClass",NULL);  //파워포인트 전체화면 차일드 윈도우
if (hPPT == NULL) {
 printf("파워포인트가 실행중이지 않습니다 ");
} else {
  hdc=GetDC(hPPT);

cx = GetSystemMetrics(SM_CXSCREEN);
cy = GetSystemMetrics(SM_CYSCREEN);

memDC = CreateCompatibleDC(hdc);
m_Bitmap = CreateCompatibleBitmap(hdc, cx, cy);
SelectObject ( memDC, m_Bitmap );

 StretchBlt(  memDC,
                    0, 0,
                    cx, cy,                    // qt 해상도 width, height
                    hdc,
                    0, 0,
                    cx, cy,                   // cx -> width, cy -> height
                    SRCCOPY);
}

   // Retrieve the bitmap color format, width, and height.
   if (!GetObject(m_Bitmap, sizeof(BITMAP), (LPSTR)&bmp))

   // Convert the color format to a count of bits.
   cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel);
   if (cClrBits == 1)
       cClrBits = 1;
   else if (cClrBits <= 4)
       cClrBits = 4;
   else if (cClrBits <= 8)
       cClrBits = 8;
   else if (cClrBits <= 16)
       cClrBits = 16;
   else if (cClrBits <= 24)
       cClrBits = 24;
   else cClrBits = 32;

   // Allocate memory for the BITMAPINFO structure. (This structure
   // contains a BITMAPINFOHEADER structure and an array of RGBQUAD
   // data structures.)

    if (cClrBits != 24)
        pbmi = (PBITMAPINFO) GlobalAlloc(LPTR,
                   sizeof(BITMAPINFOHEADER) +
                   sizeof(RGBQUAD) * (1<< cClrBits));

    // There is no RGBQUAD array for the 24-bit-per-pixel format.

    else
        pbmi = (PBITMAPINFO) GlobalAlloc(LPTR,
                   sizeof(BITMAPINFOHEADER));

   // Initialize the fields in the BITMAPINFO structure.

   pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
   pbmi->bmiHeader.biWidth = bmp.bmWidth;
   pbmi->bmiHeader.biHeight = bmp.bmHeight;
   pbmi->bmiHeader.biPlanes = bmp.bmPlanes;
   pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel;
   if (cClrBits < 24)
       pbmi->bmiHeader.biClrUsed = (1<<cClrBits);

   // If the bitmap is not compressed, set the BI_RGB flag.
   pbmi->bmiHeader.biCompression = BI_RGB;

   // Compute the number of bytes in the array of color
   // indices and store the result in biSizeImage.
   // For Windows NT, the width must be DWORD aligned unless
   // the bitmap is RLE compressed. This example shows this.
   // For Windows 95/98/Me, the width must be WORD aligned unless the
   // bitmap is RLE compressed.
   pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits +31) & ~31) /8
                                 * pbmi->bmiHeader.biHeight;
   // Set biClrImportant to 0, indicating that all of the
   // device colors are important.
   pbmi->bmiHeader.biClrImportant = 0;

HANDLE  hDib = DDBToDIB(m_Bitmap, BI_RGB);
JpegFromDib(hDib, 75, "test.jpg", " ");
GlobalFree(hDib);

// CreateBMPFile(hPPT, "test.bmp",  pbmi, m_Bitmap, memDC) ;
}

HANDLE DDBToDIB(HBITMAP bitmap, DWORD dwCompression)
{
       // 리턴되는 HANDLE에는
       // "비트맵 정보 -> 팔레트 정보 -> 비트맵 데이터"의 순서로
       // 데이터가 저장된다.
       // 256색 이상의 비트맵은 팔레트 정보가 없다.

       BITMAP                  bm;
       BITMAPINFOHEADER        bi;
       LPBITMAPINFOHEADER      lpbi;
       DWORD                   dwLen;
       HANDLE                  hDIB;
       HANDLE                  handle;
       HDC                     hDC;
       HPALETTE                hPal;

       // The function has no arg for bitfields
       if( dwCompression == BI_BITFIELDS ) return NULL;

       // 팔레트가 없는 경우 디폴트 팔레트를 사용
     
       if (hPal == NULL)
               hPal = (HPALETTE)GetStockObject(DEFAULT_PALETTE);
 

       // 비트맵 정보를 얻어온다.
      GetObject(bitmap, sizeof(BITMAP), (LPSTR)&bm);

       // Initialize the bitmapinfoheader
       bi.biSize               = sizeof(BITMAPINFOHEADER);
       bi.biWidth              = bm.bmWidth;
       bi.biHeight             = bm.bmHeight;
       bi.biPlanes             = 1;
       bi.biBitCount           = bm.bmPlanes * bm.bmBitsPixel;
       bi.biCompression        = dwCompression;
       bi.biSizeImage          = 0;
       bi.biXPelsPerMeter      = 0;
       bi.biYPelsPerMeter      = 0;
       bi.biClrUsed            = 0;
       bi.biClrImportant       = 0;

       // 256색 이하일 경우에만 색상의 수가 의미가 있다.
       // 즉, 256색 이하일 경우에만 팔레트가 주어진다.
       int nColors = 0;
       if(bi.biBitCount <= 8) nColors = (1 << bi.biBitCount);
       
       // 헤더의 크기
       dwLen = bi.biSize + nColors * sizeof(RGBQUAD);

       // We need a device context to get the DIB from
       hDC = ::GetDC(NULL); // Screem DC를 얻음
       // Screen DC에 팔레트를 설정
       hPal = SelectPalette(hDC, hPal, FALSE);
       RealizePalette(hDC);

       // BITMAPINFOHEADER와 팔레트를 위한 메모리 할당
       hDIB = GlobalAlloc(GMEM_FIXED, dwLen);

       if (!hDIB){ // 메모리 할당 실패
               SelectPalette(hDC, hPal, FALSE); // 팔레트 복귀
               ::ReleaseDC(NULL, hDC);
               return NULL;
       }

       lpbi = (LPBITMAPINFOHEADER)hDIB;
       *lpbi = bi;

       // 구조체에 정보를 얻어오기 위해 데이터를 위한 버퍼를 NULL로 준다.
       // 특히 이미지 크기를 나타내는 biSizeImage를 얻어온다.
       GetDIBits(
               hDC,                             // DC 핸들
               bitmap,                          // 비트맵 핸들
               0L,                              // start scan line
               (DWORD)bi.biHeight,              // 줄 수
               (LPBYTE)NULL,                    // 비트맵 데이터를 위한 버퍼
               (LPBITMAPINFO)lpbi,              // 비트맵 정보 구조체에 대한 포인터
               (DWORD)DIB_RGB_COLORS            // 색상 정보
       );

       bi = *lpbi;

       // If the driver did not fill in the biSizeImage field, then compute it
       // Each scan line of the image is aligned on a DWORD (32bit) boundary
       if (bi.biSizeImage == 0){
               bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8)
                       * bi.biHeight;

               // If a compression scheme is used the result may infact be larger
               // Increase the size to account for this.
               if (dwCompression != BI_RGB)
                       bi.biSizeImage = (bi.biSizeImage * 3) / 2;
       }

       // 비트맵 데이터를 저장하기 위해 메모리를 재할당 한다.
       dwLen += bi.biSizeImage;
       if (handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE))
               hDIB = handle;
       else{
               GlobalFree(hDIB);

               // Reselect the original palette
               SelectPalette(hDC,hPal,FALSE);
               ::ReleaseDC(NULL,hDC);
               return NULL;
       }

       // 실제 비트맵의 데이터를 얻어온다.
       lpbi = (LPBITMAPINFOHEADER)hDIB;
       BOOL bGotBits = GetDIBits(
               hDC,                             // DC 핸들
               bitmap,                          // 비트맵 핸들
               0L,                              // start scan line
               (DWORD)bi.biHeight,              // 줄 수
               (LPBYTE)lpbi + (bi.biSize + nColors * sizeof(RGBQUAD)),
                                                // 비트맵 데이터를 위한 버퍼
               (LPBITMAPINFO)lpbi,              // 비트맵 정보 구조체에 대한 포인터
               (DWORD)DIB_RGB_COLORS            // 색상 정보
       );

       if( !bGotBits )
       {
               GlobalFree(hDIB);
               
               SelectPalette(hDC,hPal,FALSE);
               ::ReleaseDC(NULL,hDC);
               return NULL;
       }

       // 팔레트를 복귀
       SelectPalette(hDC,hPal,FALSE);
       ::ReleaseDC(NULL,hDC);

       return hDIB;
       // hDIB에 대해서는 호출한 쪽에서 메모리를 해제해 주어야 한다.
       // GlobalFree(/* HANDLE */ hDIB);
}



void CreateBMPFile(HWND hwnd, LPTSTR pszFile, PBITMAPINFO pbi,
                 HBITMAP hBMP, HDC hDC)
{
   HANDLE hf;                 // file handle
   BITMAPFILEHEADER hdr;       // bitmap file-header
   PBITMAPINFOHEADER pbih;     // bitmap info-header
   LPBYTE lpBits;              // memory pointer
   DWORD dwTotal;              // total count of bytes
   DWORD cb;                   // incremental count of bytes
   BYTE *hp;                   // byte pointer
   DWORD dwTmp;
HANDLE                  hDIB;


   pbih = (PBITMAPINFOHEADER) pbi;
   lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);

   if (!lpBits)
        errhandler("GlobalAlloc", hwnd);

   // Retrieve the color table (RGBQUAD array) and the bits
   // (array of palette indices) from the DIB.
   if (!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi,
       DIB_RGB_COLORS))
   {
       errhandler("GetDIBits", hwnd);
   }

   // Create the .BMP file.
   hf = CreateFile(pszFile,
                  GENERIC_READ | GENERIC_WRITE,
                  (DWORD) 0,
                   NULL,
                  CREATE_ALWAYS,
                  FILE_ATTRIBUTE_NORMAL,
                  (HANDLE) NULL);
   if (hf == INVALID_HANDLE_VALUE)
       errhandler("CreateFile", hwnd);
   hdr.bfType = 0x4d42;        // 0x42 = "B" 0x4d = "M"
   // Compute the size of the entire file.
   hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) +
                pbih->biSize + pbih->biClrUsed
                * sizeof(RGBQUAD) + pbih->biSizeImage);
   hdr.bfReserved1 = 0;
   hdr.bfReserved2 = 0;

   // Compute the offset to the array of color indices.
   hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) +
                   pbih->biSize + pbih->biClrUsed
                   * sizeof (RGBQUAD);

   // Copy the BITMAPFILEHEADER into the .BMP file.
   if (!WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER),
       (LPDWORD) &dwTmp,  NULL))
   {
      errhandler("WriteFile", hwnd);
   }

   // Copy the BITMAPINFOHEADER and RGBQUAD array into the file.
   if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER)
                 + pbih->biClrUsed * sizeof (RGBQUAD),
                 (LPDWORD) &dwTmp, ( NULL)) )
       errhandler("WriteFile", hwnd);

   // Copy the array of color indices into the .BMP file.
   dwTotal = cb = pbih->biSizeImage;
   hp = lpBits;
   if (!WriteFile(hf, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL))
          errhandler("WriteFile", hwnd);

   // Close the .BMP file.
   if (!CloseHandle(hf))
          errhandler("CloseHandle", hwnd);

   // Free memory.
   GlobalFree((HGLOBAL)lpBits);
}

// 윈도우로 짜면 윈도우 화면에 에러를 보여줄 예정
void errhandler(LPTSTR pszFile, HWND hwnd)
{
 printf("pszFile");
}

'프로그래밍 > MFC' 카테고리의 다른 글

MFC 디렉토리 생성  (0) 2013.08.14
쓰레드 생성 (펌글)  (0) 2013.08.14
쓰레드 생성.  (0) 2013.08.14
유니코드  (0) 2013.08.14
CEvent 클래스  (0) 2013.08.14

+ Recent posts