ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 컴퓨터 화면 캡쳐 - Win32
    GUI/GDI 2009. 6. 4. 23:18
    void SetCapture(CRect &rc)
    {
            CDC ScreenDC;
            ScreenDC.CreateDC("DISPLAY", NULL, NULL, NULL);
            CDC memDC;
            CSize s = CSize(rc.Size());
            CBitmap bm;

            memDC.CreateCompatibleDC(&ScreenDC);
            bm.CreateCompatibleBitmap(&ScreenDC, s.cx, s.cy);
            memDC.SelectObject(&bm);
            memDC.BitBlt(0,0,s.cx, s.cy,&ScreenDC, rc.left, rc.top,SRCCOPY);

            HBITMAP hbit = (HBITMAP)bm;

            if (hbit == NULL)
                ::MessageBox(NULL, "bmp파일 생성이 실패하였습니다.", "CapAndShow", MB_ICONSTOP);
            else
            {
                BITMAPFILEHEADER fh;
                BITMAPINFOHEADER ih;
                BITMAP bit;
                BITMAPINFO *pih;
                int PalSize;
                HANDLE hFile;
                DWORD dwWritten, Size;
                HDC hdc;

                // 전체화면에 대한 DC를 구한다.
                hdc = ::GetDC(NULL);

                // 비트맵 정보로 부터 정보 구조체를 초기화한다.
                GetObject(hbit, sizeof(BITMAP), &bit);
                ih.biSize            = sizeof(BITMAPINFOHEADER);
                ih.biWidth            = bit.bmWidth;
                ih.biHeight            = bit.bmHeight;
                ih.biPlanes            = 1;
                ih.biBitCount        = bit.bmPlanes * bit.bmBitsPixel;
                if(ih.biBitCount > 8) ih.biBitCount = 24;
                ih.biCompression    = BI_RGB;
                ih.biSizeImage        = 0;
                ih.biXPelsPerMeter    = 0;
                ih.biYPelsPerMeter    = 0;
                ih.biClrUsed        = 0;
                ih.biClrImportant    = 0;

                // 정보 구조체 + 팔레트 크기만큼 메모리를 할당하고 이 버퍼에 정보 구조체를 복사한다.
                PalSize = (ih.biBitCount==24 ? 0:1 << ih.biBitCount) * sizeof(RGBQUAD);
                pih = (BITMAPINFO*)malloc(ih.biSize + PalSize);
                pih->bmiHeader = ih;

                // 비트맵의 크기를 구한다.
                GetDIBits(hdc, hbit, 0, bit.bmHeight, NULL, pih, DIB_RGB_COLORS);
                ih = pih->bmiHeader;

                // 비트맵의 크기가 구해지지 않았을 경우 수작업으로 직접 계산한다.
                if(ih.biSizeImage==0) {
                    ih.biSizeImage = ((((ih.biWidth*ih.biBitCount)+31) & ~31) >> 3) * ih.biHeight;
                }

                // 래스터 데이터를 읽기위해 메모리를 재할당한다.
                Size = ih.biSize + PalSize + ih.biSizeImage;
                pih = (BITMAPINFO *) realloc(pih, Size);

                // 래스터 데이터를 읽어들인다.
                GetDIBits(hdc, hbit, 0, bit.bmHeight, (PBYTE)pih+ih.biSize+PalSize, pih, DIB_RGB_COLORS);

                // 파일 헤더를 만든다.
                fh.bfOffBits    = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+PalSize;
                fh.bfReserved1    = 0;
                fh.bfReserved2    = 0;
                fh.bfSize        = Size+sizeof(BITMAPFILEHEADER);
                fh.bfType        = 0x4d42;

                // 파일을 생성하고 파일 헤더와 정보 구조체, 팔레트, 래스터 데이터를 출력한다.
                char path[200];
                sprintf(path,"d:\\test%d.bmp", m_iSeq);

                hFile = CreateFile(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
                WriteFile(hFile, &fh, sizeof(fh), &dwWritten, NULL);
                WriteFile(hFile, pih, Size, &dwWritten, NULL);

                ::ReleaseDC(NULL, hdc);
                CloseHandle(hFile);

                // 메모리 반환
                //free(pih);
                DeleteObject(hbit);
            }

            bm.DeleteObject();
    }


    참조 사이트:
Designed by Tistory.