본문 바로가기

API

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

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
반응형

'API' 카테고리의 다른 글

디렉토리 생성  (0) 2010.03.27
Win API Timer  (0) 2010.03.21
캡쳐 화면 BMP로 저장하기  (0) 2010.03.14
메뉴의 단축키, 액셀러레이터 생성  (0) 2010.03.12
메뉴 만들기  (1) 2010.03.11
포커스가 있는 윈도우 캡쳐  (0) 2010.03.10
API로 구현한 전체화면 캡쳐 소스  (0) 2010.03.09
DC 구조체에 관해....  (1) 2010.03.09
버튼 생성  (0) 2010.03.06
API의 첫 시작  (0) 2010.03.05