• ベストアンサー

bitbltからの画像保存ができません。;;(Delphi

dc := getdc(0) ; bitblt( bmp.Canvas.Handle, //転送先デバイスコンテキスト(hdc) 0, //転送先左端の座標(int) 0, //転送先上端の座標(int) 100,      //転送先横の幅(int) 100,      //転送先縦の幅(int) dc, //転送元デバイスコンテキスト(hdc) 0, //転送元左端の座標(int) 0, //転送元上端の座標(int) srccopy) ; //ラスタオペレーション bmp.SaveToFile('C:\cap.bmp'); releasedc(0,dc); bmp.free; 画面の位置をキャプチャーし、ビットマップにしたいのですが、これだけでは足りないのでしょうか? コンパイルは成功するし、BMPはできるのですが、0バイト。 例外処理、tryでくくったり、多少条件文はありますが、基本これが中心の処理です。 親切な方、どうかよろしくお願いします。

noname#49406
noname#49406

質問者が選んだベストアンサー

  • ベストアンサー
  • SHIMAPEE
  • ベストアンサー率75% (154/203)
回答No.2

あまり経験はないのですが、bmpのWidthとHeightを指定するとよさそうです。 Windows XP Pro SP2 + Delphi2007で確認しました。 -- var dc: HDC; bmp: TBitmap; begin dc := getdc(0) ; bmp := TBitmap.Create; bmp.Width:=100; bmp.Height:=100; bitblt( bmp.Canvas.Handle, //転送先デバイスコンテキスト(hdc) 0, //転送先左端の座標(int) 0, //転送先上端の座標(int) bmp.Width, //転送先横の幅(int) bmp.Height, //転送先縦の幅(int) dc, //転送元デバイスコンテキスト(hdc) 0, //転送元左端の座標(int) 0, //転送元上端の座標(int) srccopy) ; //ラスタオペレーション bmp.SaveToFile('C:\cap.bmp'); releasedc(0,dc); bmp.free; end; --

noname#49406
質問者

お礼

あ、そういえば、ヴァージョンを書いていませんでした。^^ delphi6でした。w2kです。 結局、理由は、分かりませんでした。 hWndAll := GetDesktopWindow(); hWndDC := GetDC(hWndAll); ReleaseDC(hWndAll, hWndDC); で、問題は解決しました。 HPをまるパクリしてできなかったので、もしかしたら、ヴァージョンやOSによるのかもしれません。 ありがとうございます。

その他の回答 (1)

  • ggaogg
  • ベストアンサー率43% (38/88)
回答No.1

Delphiは全く知らないのですが、Win32APIなら少し・・。 しかし回答数が0なので、とりあえず助言程度ですがためになればと思います。 bitbltで問題が発生しているのか、SaveToFileで問題が発生しているのかで調べ方が変わってきますよね。 (ようはbitbltでコピーできていないのか、SaveToFileが正しく書き込んでいないのか。) というわけで、BitBltの前後でbmp変数の内容をダンプしてみると、問題解決の糸口になると思います。

noname#49406
質問者

お礼

どうやら、コピーできていなかったようです。 デバッグの方法を教えて頂き、ありがとうございます。

関連するQ&A

  • [Active Basic]BitBltで画像を表示

    ActiveBasicでプログラムを書いています。 少しずつデバイスコンテキストが使えるようになってきて、簡単なブロック崩しを作ってみようと思い、作り始めました。 以前、デバイスコンテキストを使えるようになろうと、上から物体が降ってきて、それを避けるというゲームを書いてみたのですが、画像(ビットマップ)の表示方法が分からず、すべて MainWnd_Paint(hDC As HDC) に中に書きました。 すると、処理ごとにいらないものまで描写されるので画面がかなりちらついてしまいました。 ActiveBasicのヘルプ(http://www.activebasic.com/help_center/articles/win32/step16/index.html)を参考にして、プログラムを書いてみたのですが、背景が描写されません。 コードを下に書きますので、すみませんが添削の方をお願いします。 まだ、プログラムを始めたばかりのほやほやですので、なるべくやさしくお願いします。 '------------グローバル------------ Dim ImgBack As HBITMAP '背景画像 Dim hBackDC As HDC '背景画像用デバイスコンテキスト Dim hMemDC As HDC 'BitBlt用のデバイスコンテキスト '------------グローバル------------ Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT) Dim hDC As HDC 'イメージを読み込んでいく ImgBack = LoadImage(0,".\pic\back.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE) 'デバイスコンテキストをそれぞれ作成 hDC = GetDC(hMainWnd) hBackDC = CreateCompatibleDC(hDC)'背景用DC hMemDC = CreateCompatibleDC(hDC)'BitBlt用DC '背景を描写 SelectObject(hBackDC,ImgBack) BitBlt(hMemDC,0,0,640,480,hBackDC,0,0,SRCCOPY) '最後にhDCだけ開放 ReleaseDC(hMainWnd,hDC) End Sub Sub MainWnd_Paint(hDC As HDC) End Sub 後、BitBltを MainWnd_Paint(hDC As HDC) の中に表記すると、画像が表示されます。 何故か、いまいち分かっていません・・・ すみませんが、ご教授ください。

  • PlgBltのマスク処理

    VC++2005、Win32APIで開発を行っています。 ビットマップを回転、反転させながら描画を行うときの処理について、画像の背景を透過させたいのですが、マスクの処理がうまくいきません。 BOOL PlgBlt( HDC hdcDest, // 転送先のデバイスコンテキストのハンドル CONST POINT *lpPoint, // 転送先平行四辺形の頂点 HDC hdcSrc, // 転送元のデバイスコンテキストのハンドル int nXSrc, // 転送元長方形の左上隅の x 座標 int nYSrc, // 転送元長方形の左上隅の y 座標 int nWidth, // 転送元長方形の幅 int nHeight, // 転送元長方形の高さ HBITMAP hbmMask, // ビットマスクのハンドル int xMask, // ビットマスク長方形の左上隅の x 座標 int yMask // ビットマスク長方形の左上隅の y 座標 ); 上記パラメータの、ビットマップマスク部分で指定したのですが、画像自体が表示されません。 用意したマスク画像の色の設定が間違っているような気がするのですが、元画像の背景および、マスク画像の背景と画像の下地部分は何色で設定するといったようなきまりはあるのでしょうか。 ご存知の方、よろしくお願いします。

  • SetDIBitsToDeviceでpngを

    描画する際に int SetDIBitsToDevice( HDC hdc, // デバイスコンテキストのハンドル int XDest, // 転送先長方形の左上隅の x 座標 int YDest, // 転送先長方形の左上隅の y 座標 DWORD dwWidth, // 転送元長方形の幅 DWORD dwHeight, // 転送元長方形の高さ int XSrc, // 転送元長方形の左下隅の x 座標 int YSrc, // 転送元長方形の左下隅の y 座標 UINT uStartScan, // 配列内の最初の走査行 UINT cScanLines, // 走査行の数 CONST VOID *lpvBits, // DIB ビットからなる配列 CONST BITMAPINFO *lpbmi, // ビットマップ情報 UINT fuColorUse // RGB 値またはパレットインデックス ); を指定しないといけないのですが png画像の縦幅と png画像の横幅と png画像のビットマップ情報が分からないとこの関数の引数を指定できません。 どのようにそれらの情報を知ればよいのでしょうか?

  • ビットマップ画像表示

    いつもお世話になっております。 VS2005でC++を用いてWindowsアプリケーションの作成をしています。 子ウィンドウにビットマップ画像(ファイル名:HELP.bmp)を 表示させようとプログラムを組んだのですが、 子ウィンドウを出してもビットマップ画像が表示されません。 以下のようなプログラムを追加しました。 --------------------------------- ///リソーススクリプト/////////////////////////////////  IDB_BITMAP1  BITMAP DISCARDABLE  "HELP.bmp" ///ヘッダースクリプト/////////////////////////////////  #define IDB_BITMAP1   3000 ///ソーススクリプト/////////////////////////////////// void ShowMyBMP(HWND hWnd, HDC hdc){   HDC hmdc;   HBITMAP hBitmap;   BITMAP bmp;   HINSTANCE hInst;   int BMP_W, BMP_H;   hInst = (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE);   hBitmap = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP1));  //インスタンスハンドル取得   GetObject(hBitmap, sizeof(BITMAP), &bmp);  //ビットマップの情報を得る   BMP_W = (int)bmp.bmWidth;  //画像の幅   BMP_H = (int)bmp.bmHeight;  //画像の高さ   hmdc = CreateCompatibleDC(hdc);  //メモリデバイスコンテキストハンドルを取得   SelectObject(hmdc, hBitmap);   BitBlt(hdc, 0, 0, BMP_W, BMP_H, hmdc, 0, 0, SRCCOPY);   StretchBlt(hdc, 0, BMP_H, BMP_W / 2, BMP_H / 2, hmdc, 0, 0, BMP_W, BMP_H, SRCCOPY);   DeleteDC(hmdc); //デバイスコンテキストハンドルを開放   DeleteObject(hBitmap);   return; } --------------------------------- ShowMyBMP関数は子ウィンドウを表示するときに実行されます。 全て載せられないので追加した部分のみプログラムを載せましたが、 この部分だけでも、プログラムの間違い等はありませんでしょうか。 ご教授お願いいたします。

  • 特定座標のRGB値取得について

    kimarioと申します。 実行中の、あるアプリケーションの任意座標位置のRGB値を取得し、その結果を メッセージボックスにて表示させたいと考えております。 しかし下記のプログラムを実行すると、どの座標位置でもすべて(-1)で返ってき てしまいます。 getDCの戻り値が(0)ではないことを確認しているので、デバイスコンテキストの ハンドルは取得できているものと思われます。 API初心者です。よろしくお願いいたします。 補足) アプリケーションのウィンドウタイトルが「XXYYZZ」 色を特定したい座標を(60, 60)としています。 ############################################################################ public partial class Form1 : Form { [DllImport("user32.dll")] static extern IntPtr GetDC(IntPtr hWnd); [DllImport( "user32.dll" )] static extern int ReleaseDC( IntPtr hWnd, IntPtr hDC ); [DllImport( "gdi32.dll" )] static extern int GetPixel( IntPtr hDC, int x, int y ); public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { foreach (Process p in Process.GetProcesses()) { if (p.MainWindowHandle != IntPtr.Zero) { if (p.MainWindowTitle == "XXYYZZ") { IntPtr dc = GetDC(p.MainWindowHandle); MessageBox.Show(GetPixel(dc, 60, 60).ToString()); } } } } }

  • WinAPIでスクリーン画像を映し続けるプログラムその2

    タイマー1秒ごとに画面を更新させたいのですが、リージョンの範囲しか更新されないため、ウインドウを最上層に置いておくと、画面がかわりません。下記ソースはそれを確かめるため、タイマーで更新する画面を100×100pixlから1秒ごとに徐々に大きくしていったところ、やはりペイントが違う画面で覆った部分しかそのとおり更新されていませんでした。参考書だとこんな感じでできる気がするのですが、InvalidateRect( hwnd, NULL, TRUE );のところでウインドウ全体を更新しなければいけない範囲にするべきだと思うのですが、具体的な解決策がわかりません。 お力を貸していただけると助かります。 #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); void getScreenShot(HBITMAP hBmpShot, int iX, int iY, int iWidth, int iHeight) ; /*ビットマップハンドル*/ static HBITMAP _bmpShot = 0; int popo=100; int _iWidth=1024, _iHeight=400; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; /* ウインドウクラス設定 */ wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = "vcshot"; RegisterClass(&wndclass); /* メインウインドウ作成 */ HWND hwMain = CreateWindow("vcshot", "", WS_POPUP | WS_VISIBLE , 0,0, _iWidth, _iHeight, NULL, NULL, hInstance, NULL); ShowWindow(hwMain, iCmdShow); /* メッセージループ */ while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int)msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { switch (iMsg) { case WM_CREATE: { /*先に外側で作成してしまう方が得策かもしれない*/ HDC hDC = ::GetDC(0); _bmpShot = ::CreateCompatibleBitmap(hDC, _iWidth, _iHeight); ::ReleaseDC(0, hDC); /* スクリーンショット取得 */ getScreenShot(_bmpShot, 0, 0, _iWidth, _iHeight); SetTimer(hwnd , 1 , 1000 , NULL); return 0; } case WM_TIMER:{ popo=popo+20; getScreenShot(_bmpShot, 0, 0, popo, popo); InvalidateRect( hwnd, NULL, TRUE ); return 0;} case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); /* ビットマップが作成されていれば描画 */ if(_bmpShot != NULL) { BITMAP bmp; /*この関数でビットマップから、詳細を知る事が出来る*/ ::GetObject(_bmpShot, sizeof(BITMAP), &bmp); /*以下決まり文句*/ HDC _hdcShot = ::CreateCompatibleDC(0); ::SelectObject(_hdcShot, _bmpShot); BitBlt(hdc, 0, 0, _iWidth, _iHeight, _hdcShot, 0, 0, SRCCOPY); /*使い終えたら直に閉じる*/ ::DeleteDC(_hdcShot); } EndPaint(hwnd, &ps); return 0; } case WM_DESTROY : /* ビットマップが作成されていたら関連リソースを削除 */ if(_bmpShot != NULL) { /*SelectObject(_hdcShot, _bmpOld);*/ DeleteObject(_bmpShot); /*DeleteObject(_hdcShot);←よく見ると、デバイスコンテキストに対してDeleteObjectを使用しています。*/ } PostQuitMessage(0); return 0; } return DefWindowProc (hwnd, iMsg, wParam, lParam); } void getScreenShot(HBITMAP hBmpShot, int iX, int iY, int iWidth, int iHeight) { /* キャプチャサイズを保存 _iWidth = iWidth; _iHeight = iHeight; */ /* 画面のデバイスコンテキスト取得 */ HDC hdcScreen = GetDC(0); /* ビットマップ描画用デバイスコンテキスト作成 */ HDC _hdcShot = CreateCompatibleDC(hdcScreen); /* スクリーンショット保存用ビットマップ作成 */ /*_bmpShot = CreateCompatibleBitmap(hdcScreen, iWidth, iHeight);*/ /* デバイスコンテキストにビットマップを設定 */ /*_bmpOld = (HBITMAP)*/SelectObject(_hdcShot, hBmpShot); /* 画面上の領域をビットマップに描く */ BitBlt(_hdcShot, 0, 0, iWidth, iHeight, hdcScreen, 0, 0, SRCCOPY); /* 画面のデバイスコンテキスト解放 */ ReleaseDC(0, hdcScreen); /*使用したら直に閉じる*/ ::DeleteDC(_hdcShot); }

  • c言語を使いダイアログにbmpを表示したい 

    はじめまして、 私は、c言語は初心者なのでが、ダイアログボックスに、画像(bmp)が表示することができません。 ソースは、 hdc = BeginPaint(hDlg, &ps); //指定ウィンドウ内での描写準備 // ビットマップをファイルからロードする hBitmap = ::LoadBitmap( NULL, _T("test.bmp") ); // ウィンドウのデバイスコンテキストハンドルを取得する hDC = GetDC( hDlg ); // メモリデバイスコンテキストを作成する hCompatDC = CreateCompatibleDC( hDC ); // ロードしたビットマップを選択する GetObject(hBitmap, sizeof(BITMAP), &bmp); // ビットマップをウィンドウに転送する(表示する) if(hBitmap != NULL){ StretchBlt( hDC, 0, 0, 100, 100, hCompatDC, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY ); SendDlgItemMessage( hDlg, IDC_STATIC, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBitmap); } なのですが、これはメインウィンドウでは動くのですが、ダイアログボックスでは動かずこまっています。 どうか、助言のほどよろしくお願いします。

  • 透過済み画像を作りたい

    プログラムを始めたところの初心者です。 画像を透過し、ウインドウに表示させたいので、いろいろ探してみたところ、 マスクを自動で作成すると言う物があったので、参考にさせてもらいました。 さらに、その中に、『同じように透過済み画像を作れる』とあったので、いろいろ試したのですが、ダメでした・・・ よろしければ、やり方を教えていただけないでしょうか。 http://oshiete1.goo.ne.jp/qa5254128.html 上を参考にさせていただきました Dim hDC as HDC, hTemp As HDC, hDest as HDC,hOriDC As HDC Dim hBmpTemp as HBITMAP, dummy(3) as HBITMAP,hOriBmp As HBITMAP Dim bmp as BITMAP Dim hMemDC As HDC,hMemBmp As HBITMAP hDC=GetDC(NULL) hTemp=CreateCompatibleDC(hDC) hDest=CreateCompatibleDC(hDC) hOriDC=CreateCompatibleDC(hDC) hMemDC=CreateCompatibleDC(hDC) ReleaseDC(NULL,hDC) ' 元画像の情報の取得 GetObject(hBmp,Len(bmp),bmp) ' モノクロBITMAPの生成 hBmpTemp=CreateCompatibleBitmap(hDest,bmp.bmWidth,bmp.bmHeight) hOriBmp=CreateCompatibleBitmap(hOriDC,bmp.bmWidth,bmp.bmHeight) hMemBmp=hBmp dummy(0)=SelectObject(hTemp,hBmp) dummy(1)=SelectObject(hDest,hBmpTemp) dummy(2)=SelectObject(hOriDC,hOriBmp) dummy(3)=SelectObject(hMemDC,hMemBmp) SetBkColor(hTemp,GetPixel(hTemp,0,0)) ' 背景マスクの生成 BitBlt(hDest,0,0,bmp.bmWidth,bmp.bmHeight,hTemp,0,0,SRCCOPY) 'スプライト BitBlt(hOriDC,0,0,bmp.bmWidth,bmp.bmHeight,hDest,0,0,NOTSRCCOPY) BitBlt(hOriDC,0,0,bmp.bmWidth,bmp.bmHeight,hTemp,0,0,SRCAND) '透過 BitBlt(hMemDC,0,0,bmp.bmWidth,bmp.bmHeight,hDest,0,0,SRCAND) BitBlt(hMemDC,0,0,bmp.bmWidth,bmp.bmHeight,hOriDC,0,0,SRCPAINT) ' HBITMAPの切り離し SelectObject(hTemp,dummy(0)) SelectObject(hDest,dummy(1)) SelectObject(hOriDC,dummy(2)) SelectObject(hMemDC,dummy(2)) ' HDCの後始末 DeleteDC(hTemp) DeleteDC(hDest) DeleteDC(hOriDC) DeleteDC(hMemDC) ' 呼び出し元への返り値 MakeMaskWith=hMemBmp

  • Bitmap表示について WIN32

    「猫でもわかるwindowsプログラミング 第4版」を参考にして、ビットマップを表示するプログラムを作っています。 開発環境はVisual Studio Express 2015(Visual C++)です。 読み込んだビットマップを表示させようと、下記のように(本の内容をそっくりそのまま)コードとリソースを書いてみたのですがデバッグすると何も表示されないウィンドウが出てしまいます。 メッセージボックスで確かめてみると、 ビットマップリソースを読み込んだ際、hBmpにNULLが返っていました。 コードもリソースも本の通りに書いたので間違いはないと思います。 となると、うまくいかない理由はリソースとビットマップをプロジェクトに追加させるまでの過程にあると考えます。 本で扱っている環境はVisual c++ 2010 だったのですが、リソースの追加に関してバージョンの差が関係しているのでしょうか? リソースの追加に関してはネットや本にたくさん説明がありますが、それらの通り書いてもうまくいきません。 どうか、リソースのプロジェクトへの追加方法を教えていただけないでしょうか。 また、ソースコード・リソースに関して間違いがあるのならばアドバイスもらえるとありがたいです。 // ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { HDC hdc, hdc_mem; PAINTSTRUCT ps; HBITMAP hBmp; BITMAP bmp_info; int w, h; switch (msg) { case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // ビットマップリソース「MYBMP」を読み込む hBmp = LoadBitmap(hInst, TEXT("MYBMP")); // ビットマップの情報を取得し、幅と高さを変数に保管 GetObject(hBmp, (int)sizeof(BITMAP), &bmp_info); w = bmp_info.bmWidth; h = bmp_info.bmHeight; // メモリデバイスコンテキストを作成 hdc_mem = CreateCompatibleDC(hdc); // メモリデバイスコンテキストにビットマップを選択 SelectObject(hdc_mem, hBmp); // ビットマップを転送 BitBlt(hdc, 0, 0, w, h, hdc_mem, 0, 0, SRCCOPY); StretchBlt(hdc, w, 0, w * 2, h * 2, hdc_mem, 0, 0, w, h, SRCCOPY); DeleteDC(hdc_mem); // メモリデバイスコンテキストを破棄 DeleteObject(hBmp); // ビットマップオブジェクトを破棄 EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0; } //リソース MYBMP BITMAP "bitmap1.bmp"

  • スクリーンキャプチャをウインドウで更新し続けるアプリ

    スクリーンキャプチャを0.1秒ごとに ウインドウで更新し続けるアプリケーションを 作りたいのですが、うまくいきません。 昨日別の質問欄にてアドバイスいただいたのですが、 当方の力及ばず解決に至れない状況です。 下記のソースを実行すると スクリーンキャプチャをしなおす関数をおいたつもりなのですが、case WM_TIMER:の更新をしてくれません。 また case WM_PAINT:も部分的にウインドウが隠れた場合、 再描画するビットマップがずれてイレゴのようになってしまいます。 WinAPIの参考書をみながら、Web上のサンプルなどを組み合わせて 作ったので、本質的な原因を追及できなくなってしまいました。 アドバイスいただけると助かります。 #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); void getScreenShot(HBITMAP hBmpShot, int iX, int iY, int iWidth, int iHeight) ; /*ビットマップハンドル*/ static HBITMAP _bmpShot = 0; static HDC _hdcShot = 0; int _iWidth, _iHeight; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ MSG msg; WNDCLASS wndclass; /* ウインドウクラス設定 */ wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = "vcshot"; RegisterClass(&wndclass); /* メインウインドウ作成 */ HWND hwMain = CreateWindow("vcshot", "", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 800, 680, NULL, NULL, hInstance, NULL); ShowWindow(hwMain, iCmdShow); /* メッセージループ */ while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int)msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { switch (iMsg) { case WM_CREATE: { /*先に外側で作成してしまう方が得策かもしれない*/ HDC hDC = ::GetDC(0); _bmpShot = ::CreateCompatibleBitmap(hDC, 600, 480); ::ReleaseDC(0, hDC); /* スクリーンショット取得 */ getScreenShot(_bmpShot, 0, 0, 600, 480); SetTimer(hwnd , 1 , 100 , NULL); return 0; } case WM_TIMER:{ getScreenShot(_bmpShot, 0, 0, 600, 480); return 0;} case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); /* ビットマップが作成されていれば描画 */ if(_bmpShot != NULL) { BITMAP bmp; /*この関数でビットマップから、詳細を知る事が出来る*/ ::GetObject(_bmpShot, sizeof(BITMAP), &bmp); /*以下決まり文句*/ HDC _hdcShot = ::CreateCompatibleDC(0); ::SelectObject(_hdcShot, _bmpShot); BitBlt(hdc, 0, 0, bmp.bmWidth, bmp.bmHeight, _hdcShot, 0, 0, SRCCOPY); /*使い終えたら直に閉じる*/ ::DeleteDC(_hdcShot); } EndPaint(hwnd, &ps); return 0; } case WM_DESTROY : /* ビットマップが作成されていたら関連リソースを削除 */ if(_bmpShot != NULL) { /*SelectObject(_hdcShot, _bmpOld);*/ DeleteObject(_bmpShot); /*DeleteObject(_hdcShot);←よく見ると、デバイスコンテキストに対してDeleteObjectを使用しています。*/ } PostQuitMessage(0); return 0; } return DefWindowProc (hwnd, iMsg, wParam, lParam); } void getScreenShot(HBITMAP hBmpShot, int iX, int iY, int iWidth, int iHeight) { /* キャプチャサイズを保存 _iWidth = iWidth; _iHeight = iHeight; */ /* 画面のデバイスコンテキスト取得 */ HDC hdcScreen = GetDC(0); /* ビットマップ描画用デバイスコンテキスト作成 */ HDC _hdcShot = CreateCompatibleDC(hdcScreen); /* スクリーンショット保存用ビットマップ作成 */ /*_bmpShot = CreateCompatibleBitmap(hdcScreen, iWidth, iHeight);*/ /* デバイスコンテキストにビットマップを設定 */ /*_bmpOld = (HBITMAP)*/SelectObject(_hdcShot, hBmpShot); /* 画面上の領域をビットマップに描く */ BitBlt(_hdcShot, 0, 0, iWidth, iHeight, hdcScreen, 0, 0, SRCCOPY); /* 画面のデバイスコンテキスト解放 */ ReleaseDC(0, hdcScreen); /*使用したら直に閉じる*/ ::DeleteDC(_hdcShot); }

専門家に質問してみよう