概要

  • 画面をキャプチャしファイルとして保存する。
  • 処理結果をイベントログに記録する。
  • 環境によってハングアップするのはどうしたもんかな。

起動オプション

-a

  • アクティブウィンドウをキャプチャする。(デフォルト: 全画面をキャプチャする)

-i

  • 対話的に保存する。
  • ファイル名を指定しなかった場合、自動的にこのモードになる。

-w

  • キャプチャ開始前の待ち時間(ミリ秒単位)。

ソース

CaptureScreen.h

すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
/**
	@mainpage スクリーンキャプチャをファイルとして保存する。
*/
#pragma once
 
#include "resource.h"
#include "GdiHelper.h"
 
#define    INITIAL_WINDOW_W    (500)    ///< 初期ウィンドウ幅
#define    INITIAL_WINDOW_H    (200)    ///< 初期ウィンドウ高さ
 
extern HINSTANCE hInst;                ///< 現在のインターフェイス
extern TCHAR szTitle[];                ///< タイトル バーのテキスト
extern TCHAR szFileName[];            ///< 保存するファイル名
extern int nWaitMilliSec;            ///< キャプチャ前の待ち時間
extern bool bActiveWindow;            /**< キャプチャ対象
											- false: 全画面
											- true: アクティブウィンドウ */
extern bool bInteractive;            ///< 対話的操作を行う
extern TCHAR *szHelpMessage;        ///< ヘルプとして表示されるメッセージ
extern TakeAsh::GdiHelper *helper;    ///< GDI+ Helper オブジェクト
extern Gdiplus::Bitmap *bitmap;        ///< キャプチャされたビットマップ
 
/**
	メイン ウィンドウのメッセージを処理します。
 
	<table>
	<tr><th>WM_COMMAND</th><td>アプリケーション メニューの処理</td></tr>
	<tr><th>WM_PAINT</th><td>メイン ウィンドウの描画</td></tr>
	<tr><th>WM_DESTROY</th><td>中止メッセージを表示して戻る</td></tr>
	</table>
*/
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
 
/**
	バージョン情報ボックスのメッセージ ハンドラーです。
*/
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
 
/**
	コマンドラインオプションの解析
*/
void initOptions();
 
/**
	スクリーンキャプチャ処理を行う
*/
void capture_screen( HWND hWnd );
 
/**
	キャプチャされたBitmapをファイルとして保存
	@retval	true	保存成功
	@retval	false	保存失敗
*/
bool save( wchar_t *szFileName );
 
// EOF

capture_screen.cpp

すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
 
 
 
 
 
 
 
 
 
 
 
-
|
|
!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
-
|
|
-
-
-
-
|
|
|
|
|
|
|
-
|
-
|
|
!
-
|
!
|
!
-
|
!
!
|
!
-
|
!
!
 
 
-
-
|
|
!
-
|
|
|
|
!
|
|
|
|
|
|
-
|
!
|
|
|
|
|
|
|
-
|
|
!
|
|
-
-
|
!
-
|
|
!
|
!
|
-
-
|
!
|
|
|
!
-
|
|
-
|
!
!
 
 
-
|
|
|
-
|
|
|
|
|
|
|
|
|
!
|
!
 
 
#include "stdafx.h"
#include <stdlib.h>
#include "EventLogger.h"
#include "GdiHelper.h"
#include "CaptureScreen.h"
 
#define    WAIT_DEFAULT    (200)    ///< 既定キャプチャ前待ち時間(ms)
 
/**
	キーシーケンス登録用構造体
*/
typedef struct {
    WORD    wVk;        ///< 仮想キーコード
    DWORD    dwFlags;    ///< 動作指定フラグ
} KBInput;
 
/**
	キー登録マクロ
*/
#define    setInputKey( input, vkey, flag )            \
    input.ki.wVk        = vkey;                        \
    input.ki.wScan        = MapVirtualKey(vkey, 0);    \
    input.ki.dwFlags    = flag;
 
TCHAR szFileName[MAX_PATH];
int nWaitMilliSec = WAIT_DEFAULT;
bool bActiveWindow = false;
bool bInteractive = false;
TCHAR *szHelpMessage =
    L"usage: CaptureScreen [options] <FileName>\r\n"
    L"function: save the screen as <FileName>.\r\n"
    L"options:\r\n"
    L"\t-a\tcapture active window. (default: full screen)\r\n"
    L"\t-i\tsave interactively.\r\n"
    L"\t-w<ms>\twait <ms> millisec after capturing.\r\n";
TakeAsh::GdiHelper *helper = NULL;
Gdiplus::Bitmap *bitmap = NULL;
 
void initOptions()
{
    int nArgs;
    LPWSTR *szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);
    if ( szArglist ){
        for( int i=1; i<nArgs; ++i ){
            if ( szArglist[i][0] == L'-' ){
                switch( szArglist[i][1] ){
                case L'a':
                    bActiveWindow = true;
                    break;
                case L'i':
                    bInteractive = true;
                    break;
                case L'w':
                    if ( szArglist[i][2] ){
                        nWaitMilliSec = _tstoi( &szArglist[i][2] );
                    } else {
                        nWaitMilliSec = _tstoi( szArglist[i+1] );
                        ++i;
                    }
                    if ( nWaitMilliSec < 0 ){
                        nWaitMilliSec = WAIT_DEFAULT;
                    }
                    break;
                }
            } else {
                _tcscpy_s( szFileName, szArglist[i] );
            }
        }
        LocalFree( szArglist );
    }
    if ( _tcsnlen( szFileName, _countof(szFileName) ) == 0 ){
        bInteractive = true;
    }
}
 
void capture_screen(HWND hWnd)
{
    KBInput    inpFull[] = {
        { VK_SNAPSHOT,    0 },    // key press
        { VK_SNAPSHOT,    KEYEVENTF_KEYUP },
    };
    KBInput inpActive[] = {
        { VK_LMENU,        0 },    // key press
        { VK_SNAPSHOT,    0 },    // key press
        { VK_SNAPSHOT,    KEYEVENTF_KEYUP },
        { VK_LMENU,        KEYEVENTF_KEYUP },
    };
    INPUT    input;
 
    input.type            = INPUT_KEYBOARD;
    input.ki.time        = 0;
    input.ki.dwExtraInfo = NULL;
 
    while( !OpenClipboard(hWnd) ){
        Sleep( WAIT_DEFAULT );
    }
    EmptyClipboard();
    CloseClipboard();
 
    int nCount = ( !bActiveWindow ) ? _countof(inpFull) : _countof(inpActive);
    KBInput *kbip = ( !bActiveWindow ) ? inpFull : inpActive;
 
    Sleep( nWaitMilliSec );
    for( int i=0; i<nCount; ++i ){
        setInputKey(input, kbip[i].wVk, kbip[i].dwFlags);
        SendInput(1, &input, sizeof(INPUT));
    }
    Sleep( WAIT_DEFAULT );
 
    while( !IsClipboardFormatAvailable( CF_BITMAP ) ){
        if ( GetAsyncKeyState( VK_ESCAPE ) ){
            break;
        }
        for( int i=0; i<nCount; ++i ){
            setInputKey(input, kbip[i].wVk, kbip[i].dwFlags);
            SendInput(1, &input, sizeof(INPUT));
        }
        Sleep( nWaitMilliSec );
    }
 
    if ( IsClipboardFormatAvailable( CF_BITMAP ) ){
        while( !OpenClipboard(hWnd) ){
            Sleep( WAIT_DEFAULT );
        }
        HBITMAP hBitmap = (HBITMAP)GetClipboardData( CF_BITMAP );
        bitmap = helper->newBitmap( hBitmap );
        CloseClipboard();
    }
    if ( bInteractive ){
        ShowWindow( hWnd, SW_SHOW);
        MoveWindow( hWnd, 0, 0, INITIAL_WINDOW_W, INITIAL_WINDOW_H, true );
    } else {
        save( szFileName );
    }
}
 
bool save( wchar_t *szFileName )
{
    bool bResult = false;
    wchar_t    szLogMessage[ MAX_PATH * 2 ] = L"";
    wchar_t *wsptr = wcsrchr( szFileName, L'.' );
    if ( wsptr != NULL ){
        bResult = helper->saveBitmap( szFileName, wsptr + 1, bitmap );
        wsprintf( szLogMessage, L"%s: [%s]%s -w %d %s",
            szTitle,
            ( bResult ? L"Success" : L"Failure"),
            ( bActiveWindow ? L" -a" : L""),
            nWaitMilliSec,
            szFileName
        );
        logMessage( ( bResult ? EVENTLOG_INFORMATION_TYPE : EVENTLOG_ERROR_TYPE ), 0, szLogMessage );
    }
    return bResult;
}
 
// EOF

WndProc.cpp

すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
 
 
 
 
 
 
-
|
|
|
|
|
|
|
|
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-
|
!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
!
|
|
|
|
|
|
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-
|
!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-
|
|
!
|
|
|
|
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
!
|
|
-
|
|
|
!
|
|
|
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
!
|
|
-
|
|
|
!
|
|
-
|
!
-
|
!
|
|
|
|
!
|
!
 
 
#include "stdafx.h"
#include "EventLogger.h"
#include "GdiHelper.h"
#include "CaptureScreen.h"
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;
    static HWND hwHelp;
    RECT rect;
    OPENFILENAME ofn = {0};
    static SCROLLINFO siH = {0};
    static SCROLLINFO siV = {0};
    static UINT uiImgW;
    static UINT uiImgH;
    int nPrevPos;
 
    switch (message)
    {
    case WM_COMMAND:
        wmId    = LOWORD(wParam);
        wmEvent = HIWORD(wParam);
        // 選択されたメニューの解析:
        switch (wmId)
        {
        case IDM_ABOUT:
            DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
            break;
        case IDM_EXIT:
            DestroyWindow(hWnd);
            break;
        case IDM_SAVE:
            ofn.lStructSize = sizeof(ofn);
            ofn.hwndOwner = hWnd;
            ofn.hInstance = hInst;
            ofn.lpstrFilter = 
                L"PNG(*.png)\0*.png\0"
                L"BMP(*.bmp)\0*.bmp\0"
                L"GIF(*.gif)\0*.gif\0"
                L"JPEG(*.jpg)\0*.jpg\0"
                L"TIFF(*.tif)\0*.tif\0"
                L"\0";
            ofn.lpstrFile = szFileName;
            ofn.nMaxFile = MAX_PATH;
            ofn.Flags = OFN_OVERWRITEPROMPT;
            ofn.lpstrDefExt = L"png";
            if ( GetSaveFileName( &ofn ) ){
                save( szFileName );
            }
            break;
        case IDM_SHOW_HIDE_HELP:
            ShowWindow(hwHelp, (IsWindowVisible(hwHelp) ? SW_HIDE : SW_SHOW));
            UpdateWindow(hwHelp);
            break;
        case IDM_GO_LEFT:
            SendMessage( hWnd, WM_HSCROLL, SB_TOP, 0 );
            break;
        case IDM_GO_RIGHT:
            SendMessage( hWnd, WM_HSCROLL, SB_BOTTOM, 0 );
            break;
        case IDM_GO_TOP:
            SendMessage( hWnd, WM_VSCROLL, SB_TOP, 0 );
            break;
        case IDM_GO_BOTTOM:
            SendMessage( hWnd, WM_VSCROLL, SB_BOTTOM, 0 );
            break;
        case IDM_PAGE_UP:
            SendMessage( hWnd, WM_VSCROLL, SB_PAGEUP, 0 );
            break;
        case IDM_PAGE_DOWN:
            SendMessage( hWnd, WM_VSCROLL, SB_PAGEDOWN, 0 );
            break;
        case IDM_PAGE_LEFT:
            SendMessage( hWnd, WM_HSCROLL, SB_PAGEUP, 0 );
            break;
        case IDM_PAGE_RIGHT:
            SendMessage( hWnd, WM_HSCROLL, SB_PAGEDOWN, 0 );
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        break;
    case WM_CREATE:
        helper = new TakeAsh::GdiHelper();
        capture_screen( hWnd );
        uiImgW = bitmap->GetWidth();
        uiImgH = bitmap->GetHeight();
        if ( bInteractive ){
            GetClientRect( hWnd, &rect );
            hwHelp = CreateWindow(
                TEXT("EDIT") , szHelpMessage , 
                WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL 
                    | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_LEFT | ES_MULTILINE ,
                rect.left, rect.top, rect.right, rect.bottom, hWnd , (HMENU)1 ,
                ((LPCREATESTRUCT)(lParam))->hInstance , NULL
            );
            ShowWindow( hwHelp, SW_HIDE );
            siH.cbSize    = sizeof(siH);
            siH.fMask    = SIF_ALL;    // | SIF_DISABLENOSCROLL;
            siH.nMin    = 0;
            siH.nMax    = uiImgW;
            siH.nPage    = rect.right;
            siH.nPos    = 0;
            SetScrollInfo( hWnd, SB_HORZ, &siH, true );
            siV.cbSize    = sizeof(siV);
            siV.fMask    = SIF_ALL;    // | SIF_DISABLENOSCROLL;
            siV.nMin    = 0;
            siV.nMax    = uiImgH;
            siV.nPage    = rect.bottom;
            siV.nPos    = 0;
            SetScrollInfo( hWnd, SB_VERT, &siV, true );
        } else {
            SendMessage( hWnd, WM_DESTROY, 0, 0 );
        }
        break;
    case WM_SIZE:
        MoveWindow( hwHelp, 0, 0, LOWORD(lParam), HIWORD(lParam), true );
        siH.nPage = LOWORD(lParam);
        siH.nPos = max(siH.nMin, min(siH.nMax - (signed)siH.nPage, siH.nPos));
        SetScrollInfo( hWnd, SB_HORZ, &siH, true );
        siV.nPage = HIWORD(lParam);
        siV.nPos = max(siV.nMin, min(siV.nMax - (signed)siV.nPage, siV.nPos));
        SetScrollInfo( hWnd, SB_VERT, &siV, true );
        InvalidateRect( hWnd,  NULL, true );
        UpdateWindow( hWnd );
        break;
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        // TODO: 描画コードをここに追加してください...
        {
            Gdiplus::Graphics graphics( hdc );
            graphics.DrawImage( bitmap, -siH.nPos, -siV.nPos );
        }
        EndPaint(hWnd, &ps);
        break;
    case WM_HSCROLL:
        nPrevPos = siH.nPos;
        switch( LOWORD(wParam) ){
        case SB_LINEUP:
            siH.nPos -= 16;
            break;
        case SB_LINEDOWN:
            siH.nPos += 16;
            break;
        case SB_PAGEUP:
            siH.nPos -= (int)(siH.nPage * 0.9);
            break;
        case SB_PAGEDOWN:
            siH.nPos += (int)(siH.nPage * 0.9);
            break;
        case SB_THUMBPOSITION: 
        case SB_THUMBTRACK:
            siH.nPos = HIWORD(wParam);
            break;
        case SB_TOP:
            siH.nPos = 0;
            break;
        case SB_BOTTOM:
            siH.nPos = siH.nMax;
            break;
        }
        siH.nPos = max( siH.nMin, min( siH.nMax - (signed)siH.nPage, siH.nPos ) );
        // ちらつき防止のため、nPos が変わっていた時だけ更新する
        if ( nPrevPos != siH.nPos ){
            SetScrollInfo( hWnd, SB_HORZ, &siH, true );
            InvalidateRect( hWnd,  NULL, true );
            UpdateWindow( hWnd );
        }
        break;
    case WM_VSCROLL:
        nPrevPos = siV.nPos;
        switch( LOWORD(wParam) ){
        case SB_LINEUP:
            siV.nPos -= 16;
            break;
        case SB_LINEDOWN:
            siV.nPos += 16;
            break;
        case SB_PAGEUP:
            siV.nPos -= (int)(siV.nPage * 0.9);
            break;
        case SB_PAGEDOWN:
            siV.nPos += (int)(siV.nPage * 0.9);
            break;
        case SB_THUMBPOSITION: 
        case SB_THUMBTRACK:
            siV.nPos = HIWORD(wParam);
            break;
        case SB_TOP:
            siV.nPos = 0;
            break;
        case SB_BOTTOM:
            siV.nPos = siV.nMax;
            break;
        }
        siV.nPos = max( siV.nMin, min( siV.nMax - (signed)siV.nPage, siV.nPos ) );
        // ちらつき防止のため、nPos が変わっていた時だけ更新する
        if ( nPrevPos != siV.nPos ){
            SetScrollInfo( hWnd, SB_VERT, &siV, true );
            InvalidateRect( hWnd,  NULL, true );
            UpdateWindow( hWnd );
        }
        break;
    case WM_DESTROY:
        if ( bitmap ){
            delete bitmap;
        }
        if ( helper ){
            delete helper;
        }
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}
 
// EOF

添付ファイル: fileCaptureScreen_exe.zip 197件 [詳細]

リロード   新規 下位ページ作成 編集 凍結 差分 添付 コピー 名前変更   ホーム 一覧 検索 最終更新 バックアップ リンク元   ヘルプ   最終更新のRSS
Last-modified: Wed, 01 May 2013 09:49:18 JST (1722d)