API

1초에 한번씩 캡쳐 화면 파일로 저장하기

엔젤루스 2010. 3. 27. 12:26
728x90
반응형

이번에는 지금까지 공부했던 함수들을 모아모아 1초에 한번씩 화면을 캡쳐해서 그 화면을 파일로 해당 폴더에 저장해주는 프로그램을 만들어 보았습니다. 뭐 지금까지 공부했던 걸 그냥 모아서 만든 프로그램이라 그렇게 어려운 부분은 없었던거 같습니다. 이번에는 유니코드를 다 지원해주고 하느라 좀 골치가 아팠었는데요. 덕분에 유니코드에 대해서 좀 많이 알수 있었던 것 같습니다~
혹시 위 함수들에 대해서 잘 모르겠다 싶으신분들은 이전 포스트들에 적혀져 있는 것을 보시면 자세히 알수 있을 것입니다~


#include
<windows.h>

#include <shlwapi.h>

#include "Resource.h"

 

#pragma comment(lib, "shlwapi"

 

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

void CALLBACK TimeProc(HWND, UINT, UINT, DWORD);

void SaveBitmap(HBITMAP, LPCTSTR);

BOOL CreateDirectoryFunc(LPCTSTR);

HINSTANCE g_hInst;

LPCTSTR lpszClass = TEXT("ScreenCapturForTimer");

HBITMAP FullScreenCapture(HWND);

HBITMAP g_hBit;

 

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)

{

  HWND hWnd;

  MSG Message;

  WNDCLASS WndClass;

  g_hInst = hInstance;

 

  WndClass.cbClsExtra = 0;

  WndClass.cbWndExtra = 0;

  WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);

  WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);

  WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);

  WndClass.hInstance = hInstance;

  WndClass.lpfnWndProc = WndProc;

  WndClass.lpszClassName = lpszClass;

  WndClass.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);

  WndClass.style = CS_HREDRAW | CS_VREDRAW;

  RegisterClass(&WndClass);

 

  hWnd=CreateWindow(lpszClass, lpszClass, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 200, 100, NULL, (HMENU)NULL, hInstance, NULL);

  ShowWindow(hWnd, nCmdShow);

 

  HACCEL hAccel;

 

  hAccel=LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1));

  while(GetMessage(&Message, 0, 0, 0))

  {

    if(!TranslateAccelerator(hWnd, hAccel, &Message))

    {

      TranslateMessage(&Message);

      DispatchMessage(&Message);

    }

  }

  return (int)Message.wParam;

}

 

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)

{

  HMENU hMenu = GetMenu(hWnd);

  TCHAR szPath[] = TEXT("D:\\CaptureTest1\\test\\test\\");          //파일을 저장할 폴더

 

  switch(iMessage)

  {

  case WM_CREATE:

    CreateDirectoryFunc(szPath);              //폴더 생성 함수

  case WM_COMMAND:

    switch(LOWORD(wParam))

    {

    case ID_MENU_CAPTURESTART:

      SetTimer(hWnd, 1, 1000, TimeProc);          //1초에 한번씩 TimeProc를 호출

      EnableMenuItem(hMenu, ID_MENU_CAPTUREEND, MF_ENABLED);

      EnableMenuItem(hMenu, ID_MENU_CAPTURESTART, MF_GRAYED);

      break;

    case ID_MENU_CAPTUREEND:

      EnableMenuItem(hMenu, ID_MENU_CAPTURESTART, MF_ENABLED);

      EnableMenuItem(hMenu, ID_MENU_CAPTUREEND, MF_GRAYED);

      KillTimer(hWnd, 1);                          //타이머를 없앰..

      break;

    case ID_MENU_EXIT:

      DestroyWindow(hWnd);

      break;

    }

    return 0;

  case WM_DESTROY:

    PostQuitMessage(0);

    return 0;

  }

  return(DefWindowProc(hWnd, iMessage, wParam, lParam));

}

// 초당 화면캡쳐 함수와 파일 저장함수를 호출해주는 콜백 함수

void CALLBACK TimeProc(HWND hWnd, UINT uMsg, UINT idEvent, DWORD dwTime)

{

  SYSTEMTIME st;

  GetLocalTime(&st);

  TCHAR str[MAX_PATH];

  wsprintf(str, TEXT("D:\\CaptureTest1\\test\\test\\%d%d%d%d%d%d.BMP"), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);

  g_hBit = FullScreenCapture(hWnd);

  SaveBitmap(g_hBit , str);

}

// 폴더를 생성하는 함수

// 경로로 지정한 모든 폴더를 생성함

BOOL CreateDirectoryFunc(LPCTSTR path)

{

  TCHAR szPathBuffer[MAX_PATH];

 

  UINT len = lstrlen(path);

  for(UINT i = 0; i < len; i++)

  {

    szPathBuffer[i] = *(path + i);

    if(szPathBuffer[i] == TEXT('\\') || szPathBuffer[i] == TEXT('/'))

    {

      szPathBuffer[i + 1] = NULL;

      if(!PathFileExists(szPathBuffer))

      {

        if(!CreateDirectory(szPathBuffer, NULL))

        {

          if(GetLastError() != ERROR_ALREADY_EXISTS)

            return FALSE;

        }

      }

    }

  }

  return TRUE;

}

// 캡쳐한 화면을 BITMAP 파일로 저장함

void SaveBitmap(HBITMAP hBit, LPCTSTR path)

{

  BITMAPFILEHEADER bFile;

  BITMAPINFOHEADER bInfo;

  BITMAP bit;

  BITMAPINFO *pih;

 

  int PalSize;

  HANDLE  hFile;

  DWORD dwWritten,Size;

  HDC hdc;

 

  hdc = GetDC(NULL);

 

  GetObject(hBit, sizeof(BITMAP), &bit);

  bInfo.biSize=sizeof(BITMAPINFOHEADER);

  bInfo.biWidth=bit.bmWidth;

  bInfo.biHeight=bit.bmHeight;

  bInfo.biPlanes=1;

  bInfo.biBitCount=bit.bmPlanes*bit.bmBitsPixel;

  if(bInfo.biBitCount>8) bInfo.biBitCount=24;

  bInfo.biCompression=BI_RGB;

  bInfo.biSizeImage=0;

  bInfo.biXPelsPerMeter=0;

  bInfo.biYPelsPerMeter=0;

  bInfo.biClrUsed=0;

  bInfo.biClrImportant=0;

 

  PalSize=(bInfo.biBitCount==24?0:1 << bInfo.biBitCount)*sizeof(RGBQUAD);

  pih=(BITMAPINFO *)malloc(bInfo.biSize+PalSize);

  pih->bmiHeader=bInfo;

 

  GetDIBits(hdc,hBit,0,bit.bmHeight, NULL,pih,DIB_RGB_COLORS);

  bInfo=pih->bmiHeader;

 

  if(bInfo.biSizeImage==0)

  {

    bInfo.biSizeImage=((((bInfo.biWidth*bInfo.biBitCount) +31 ) & ~31) >> 3) * bInfo.biHeight;

  }

 

  Size = bInfo.biSize+PalSize+bInfo.biSizeImage;

  pih=(BITMAPINFO *)realloc(pih,Size);

 

  GetDIBits(hdc,hBit,0,bit.bmHeight,(PBYTE)pih+bInfo.biSize+PalSize,pih,DIB_RGB_COLORS);

 

  bFile.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+PalSize;

  bFile.bfReserved1=0;

  bFile.bfReserved2=0;

  bFile.bfSize=Size+sizeof(BITMAPFILEHEADER);

  bFile.bfType=0x4d42;

 

  hFile=CreateFile(path,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);

  WriteFile(hFile,&bFile,sizeof(bFile),&dwWritten,NULL);

  WriteFile(hFile,pih,Size,&dwWritten,NULL);

 

  ReleaseDC(NULL,hdc);

  CloseHandle(hFile);

}

//전체 화면을 캡쳐해 주는 함수

HBITMAP FullScreenCapture(HWND hWnd)

{

  int ScreenWidth = GetSystemMetrics(SM_CXSCREEN);

  int ScreenHeight = GetSystemMetrics(SM_CYSCREEN);

 

  HDC hScrDC, hMemDC;

  HBITMAP hBitmap;

 

  hScrDC=CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL);

  hMemDC=CreateCompatibleDC(hScrDC);

  hBitmap=CreateCompatibleBitmap(hScrDC, ScreenWidth, ScreenHeight);

  SelectObject(hMemDC, hBitmap);

 

  BitBlt(hMemDC,0,0,ScreenWidth,ScreenHeight,hScrDC,0,0,SRCCOPY);

 

  DeleteDC(hMemDC);

  DeleteDC(hScrDC);

 

  return hBitmap;

}

Resource.h 파일의 내용입니다

#define IDR_MENU1                      101

#define IDR_ACCELERATOR1                102

#define ID_MENU_CAPTURESTART            40001

#define ID_MENU_CAPTUREEND              40002

#define ID_MENU_EXIT                    40003


메뉴는 캡쳐시작과 캡쳐 끝내기, 프로그램 끝내기 메뉴로 구성되고 액셀러레이터는 저 3 메뉴에 대해서 다 걸려 있습니다

이프로그램을 실행시켜보면 다음과 같이 나올꺼에요...

엄청작죠?? ㅎ 화면에 뭘 출력할게 아니라 그냥 귀엽게 작게 만들어주었고요 메뉴에는 아까 위에서 말한 3가지 메뉴컨트롤들이 나올꺼에요. 저 프로그램이 생성될때 D 드라이브에 D:\CaptureTest1\test\test\ 폴더를 생성하게 될것입니다. 그리고 스타트 버튼을 누르게 되면 현재 화면을 열심시 1초에 한번씩 캡쳐해서 파일로 저장 시켜주는 것이죠. 한번 실행시켜보시고 확인해 보세요 ^^

참 허접한 내용이지만 끝까지 봐주셔서 감사하고요. 혹시 문제 되는 점이나 이해가 안가는 부분은 덧글 남겨주시면 또 열심히 알아보고 답변해드리겠습니다~
감사합니다`~^^

728x90
반응형