ホームに戻る
 矩形キャプチャー

/*
*   ボタンを押してから画面を四角で囲うとその範囲をビットマップで保存します
*   ビットマップの保存先は15行目を書き換えてください
*   保存先のディレクトリはあらかじめ作成しておく必要があります
*   また、マルチディスプレイには対応していません
*   bcc32 -W nmCapture.cpp でコンパイルできることを確認しています
*/

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

#define ID_B1 1000

// ファイルの保存先
static char *fileName = "c:\\cap\\cap.bmp";

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK PopupProc(HWND hPopup, UINT msg, WPARAM wparam, LPARAM lparam);

// DC をビットマップで保存 ファイル名、DC、x座標、y座標、幅、高さ
static int funcSaveRect(LPCTSTR lpFname, HDC hDC, LONG x, LONG y, LONG w, LONG h)
{
  HANDLE hFile = CreateFile(lpFname, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

  if(hFile != INVALID_HANDLE_VALUE){
    LONG lHeadSize = (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFO));
    LONG lWidthSize = (w * sizeof(DWORD));
    LONG lImageSize = (lWidthSize * h);
    DWORD dwSize;

    BITMAPFILEHEADER bmpHead = {0};
    bmpHead.bfType  = 0x4D42;  // 識別子 BM
    bmpHead.bfSize  = lHeadSize + lImageSize;
    bmpHead.bfReserved1 = 0;
    bmpHead.bfReserved2 = 0;
    bmpHead.bfOffBits = lHeadSize;

    BITMAPINFO bmpInfo = {0};
    bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmpInfo.bmiHeader.biWidth = w;
    bmpInfo.bmiHeader.biHeight = h;
    bmpInfo.bmiHeader.biPlanes = 1;
    bmpInfo.bmiHeader.biBitCount = 32;
    bmpInfo.bmiHeader.biCompression = BI_RGB;
    bmpInfo.bmiHeader.biSizeImage = 0;
    bmpInfo.bmiHeader.biXPelsPerMeter = 0;
    bmpInfo.bmiHeader.biYPelsPerMeter = 0;
    bmpInfo.bmiHeader.biClrUsed = 0;
    bmpInfo.bmiHeader.biClrImportant = 0;

    HDC hSaveDC;
    LPDWORD lpPixel;
    HBITMAP hBitmap;

    hBitmap = CreateDIBSection(NULL, &bmpInfo, DIB_RGB_COLORS, (LPVOID*)&lpPixel, NULL, 0);
    hSaveDC = CreateCompatibleDC(hDC);
    SelectObject(hSaveDC, hBitmap);

    BitBlt(hSaveDC, 0, 0, w, h, hDC, x, y, SRCCOPY);

    WriteFile(hFile, &bmpHead, sizeof(BITMAPFILEHEADER), &dwSize, NULL);
    WriteFile(hFile, &bmpInfo, sizeof(BITMAPINFO), &dwSize, NULL);
    WriteFile(hFile, lpPixel, lImageSize, &dwSize, NULL);

    DeleteDC(hSaveDC);
    DeleteObject(hBitmap);
    CloseHandle(hFile);

    return 1;
  }

  return 0;
}

/*
*  ポップアップ関連
*/

// ウィンドウクラスの登録
static bool RegisteredPopupClass = false;
static const char* ClassNamePopup = "nmPopup";
static WNDCLASSEX PopupClassEx;
static void RegisterPopupClass(){
  HINSTANCE hinst = GetModuleHandle(NULL);
  WNDCLASSEX* wc = &PopupClassEx;
  wc->cbSize = sizeof(WNDCLASSEX);
  wc->style = CS_CLASSDC | CS_DBLCLKS;
  wc->lpfnWndProc = PopupProc;
  wc->cbClsExtra = 0L;
  wc->cbWndExtra = 0L;
  wc->hInstance = hinst;
  wc->hIcon = LoadIcon(hinst, "MYICON");
  wc->hCursor = LoadCursor(NULL, IDC_ARROW);
  wc->hbrBackground = NULL;
  wc->lpszMenuName = NULL;
  wc->lpszClassName = ClassNamePopup;
  wc->hIconSm = LoadIcon(hinst, MAKEINTRESOURCE(1));
  RegisterClassEx(wc);
  RegisteredPopupClass = true;
}

// ポップアップ用のプロシージャ
LRESULT CALLBACK PopupProc(HWND hPopup, UINT msg, WPARAM wparam, LPARAM lparam)
{
  static BOOL bDrag;
  static BOOL bDraw;
  static POINT ptCurrent, ptNew;

  static RECT rect;
  static POINT point;

  switch(msg){
    case WM_LBUTTONDOWN:
      {
        SetCapture(hPopup);
        bDrag = TRUE;
      }
      break;
    case WM_MOUSEMOVE:
      {
        if(bDrag){
          bDraw = TRUE;
          ptCurrent.x = ptNew.x = LOWORD(lparam);
          ptCurrent.y = ptNew.y = HIWORD(lparam);
          ClientToScreen(hPopup,&ptCurrent);
          ClientToScreen(hPopup,&ptNew);
          bDrag = FALSE;
        }
        else if(bDraw){
          HDC hdc = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
          SetROP2(hdc, R2_NOTXORPEN);
          Rectangle(hdc, ptCurrent.x, ptCurrent.y, ptNew.x, ptNew.y);
          ptNew.x = LOWORD(lparam);
          ptNew.y = HIWORD(lparam);
          ClientToScreen(hPopup,&ptNew);
          Rectangle(hdc, ptCurrent.x, ptCurrent.y, ptNew.x, ptNew.y);
          DeleteDC(hdc);
        }
      }
      break;
    case WM_LBUTTONUP:
      {
        if(bDraw){
          HDC hdc;
          bDrag = FALSE;
          bDraw = FALSE;
          ReleaseCapture();
          hdc = CreateDC (TEXT("DISPLAY"), NULL, NULL, NULL);
          SetROP2(hdc, R2_NOTXORPEN);
          Rectangle(hdc, ptCurrent.x, ptCurrent.y, ptNew.x, ptNew.y);
          DeleteDC(hdc);

          HDC hDC = GetWindowDC(hPopup);

          POINT p;
          RECT rect;

          GetWindowRect(hPopup, &rect);

          p.x = rect.left;
          p.y = rect.top;
          ScreenToClient(hPopup, &p);
          funcSaveRect(fileName, hDC, ptCurrent.x - p.x, ptCurrent.y - p.y, ptNew.x - ptCurrent.x, ptNew.y - ptCurrent.y);
          ReleaseDC(hPopup, hDC);

          bDraw = FALSE;
          bDrag = FALSE;

          ReleaseCapture();

          ShowWindow(hPopup, SW_HIDE);
          HWND hWnd = GetParent(hPopup);
          SetActiveWindow(hWnd);
        }
        else if(bDrag){
          bDraw = FALSE;
          bDrag = FALSE;
          ReleaseCapture();
        }
      }
      break;
    case WM_CREATE:
      {
        rect.left = 0;
        rect.top = 0;
        rect.right = GetSystemMetrics(SM_CXSCREEN);
        rect.bottom = GetSystemMetrics(SM_CYSCREEN);

        AdjustWindowRect(&rect, WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE, FALSE);

        MoveWindow(hPopup, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE);
      }
      break;
    default:
      break;
  }

  return DefWindowProc(hPopup, msg, wparam, lparam);
}

// ポップアップウィンドウ
HWND createPopup(HWND hWnd)
{
  HWND hPopup;

  if(RegisteredPopupClass){
    return NULL;
  }

  RegisterPopupClass();

  hPopup = CreateWindowEx(
    NULL,
    ClassNamePopup, "",
    WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE | WS_EX_TRANSPARENT,
    0, 0, 300, 200, hWnd, NULL,
    GetModuleHandle(NULL), NULL);

  return hPopup;
}

/*
*  メインウィンドウ関連
*/

// メインウィンドウのプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  static HWND hButton1;
  static HWND hPopup = NULL;

  switch(message){
    case WM_CREATE:
      {
        HINSTANCE hInst = GetModuleHandle(NULL);

        hButton1 = CreateWindow(
          "BUTTON",
          "Button1",
          WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
          0,
          0,
          100,
          50,
          hWnd,
          (HMENU)ID_B1,
          hInst
          ,NULL);
      }
      break;
    case WM_COMMAND:
      switch(LOWORD(wParam)){
        case ID_B1:
          {
            if(hPopup == NULL){
              hPopup = createPopup(hWnd);
            }

            ShowWindow(hPopup, SW_SHOW);
          }
        default:
          return DefWindowProc(hWnd, message, wParam, lParam);
      }
      break;
    case WM_DESTROY:
      if(IsWindow(hPopup)){
        DestroyWindow(hPopup);
      }
      PostQuitMessage(0);
      break;
    default:
      return DefWindowProc(hWnd, message, wParam, lParam);
  }

  return 0L;
}

// メインウィンドウ
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR cmdLine, int cmdShow)
{
  WNDCLASS wd;
  char *wdName = "window00";

  if(!hPreInstance){
    wd.style = CS_HREDRAW | CS_VREDRAW;
    wd.lpfnWndProc = (WNDPROC)WndProc;
    wd.cbClsExtra = 0;
    wd.cbWndExtra = 0;
    wd.hInstance = hInstance;
    wd.hIcon = NULL;
    wd.hCursor = LoadCursor(NULL, IDC_ARROW);
    wd.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wd.lpszMenuName = NULL;
    wd.lpszClassName = wdName;

    if(!RegisterClass(&wd)){
      return FALSE;
    }
  }

  HWND form00 = CreateWindowEx(
    NULL,
    wdName,
    "nm_rect_capture",
    WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    300,
    200,
    NULL,
    NULL,
    hInstance,
    NULL);

  ShowWindow(form00, cmdShow);
  UpdateWindow(form00);

  MSG msg;

  while(GetMessage(&msg, NULL, NULL, NULL))
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }

  return msg.wParam;
}

inserted by FC2 system