• 締切済み

GetDC()とCreateCompatibleDC()

お世話になっています。 GetDC(NULL)とCreateCompatibleDC(NULL)で得られるhdcの違いがよくわかりません。 以下のプログラムA,Bで得られるのhDCw1,hDCw2に違いはありますか? A: hDCw1 = CreateCompatibleDC(NULL); //現在の画面と互換性のあるメモリデバイスコンテキスト hDCw2 = CreateCompatibleDC(NULL); <<hDCw1,hDCw2を使用>> DeleteDC(hDCw1); DeleteDC(hDCw2); B: hdc = GetDC( NULL ); // 画面全体を表すデバイスコンテキスト hDCw1 = CreateCompatibleDC(hdc); hDCw2 = CreateCompatibleDC(hdc); <<hDCw1,hDCw2を使用>> ReleaseDC( NULL, hdc ); // 取得した HDCの開放 DeleteDC(hDCw1); DeleteDC(hDCw2);

みんなの回答

回答No.2

 こんばんは。御礼頂き感謝いたします。 >>プログラムAとBは「常に同じ」ということでしょうか、それとも、「xxxという環境では同じ」ということでしょうか?たとえば、「xxx」は24ビットカラーとか、1024x768などの制約があるのでしょうか?  私のディスプレイは1440x900x32でしたが、両方同じでした。  ただ、もう一度立ち戻って調べ直しましたが、「常に同じ」とは断言出来なさそうです。と言うのも、  A: ・hDCw1 = CreateCompatibleDC(NULL); //現在の画面と互換性のあるメモリデバイスコンテキスト  ↑「現在の画面」と言うのが「現在のデスクトップ」である事を意味しているのならば、B:とまったく同じになる筈です。  B:ではGetDC(NULL)でデスクトップのデバイスコンテキストを取っているからです。  しかし、気になったのは「現在の~」と付くからには「現在ではない~」のも有る様で、  「マルチモニター」  http://ww8.tiki.ne.jp/~elbe2/sumai/dell3.html  の様な状況も含めると、私にも分かりません。  「CreateCompatibleDCに対する議論」  http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200611/06110034.txt  どちらかと言えば、HDCの中身を知るよりも、使う手順を覚えて使う事に徹して来ましたので、厳密な意味でHDCがどうなっているのかは、チョッと私には分かりませんな。

usatan2
質問者

お礼

>ただ、もう一度立ち戻って調べ直しましたが、「常に同じ」とは断言出来なさそうです。 実験ありがとうございます。また、有用なページのご紹介ありがとうございます。 >「CreateCompatibleDCに対する議論」 >http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200611/06... 難しくて私には、何が違うのか、よくわかりませんが、とにかく ・何かしら違う。 ・でもどちらでも問題なく動く場合が多く、実際に差がない場合もある。 ということですね(苦笑)。

回答No.1

 こんばんは。試して見ましたが、違いは無い様です。  HDCに対してGetDeviceCaps()を使うと、HDCの詳細を確認出来ます。  「GetDeviceCaps」  http://msdn.microsoft.com/ja-jp/library/cc428670.aspx  以下参考に #include<windows.h> #define ARRAYCOUNT(a) (sizeof(a)/sizeof(a[0])) //両方のデバイスコンテキストから詳細を取ってみる void Check(HDC hDC_A, HDC hDC_B) { //適当な項目を調べてみる const int arr[] = { HORZRES, VERTRES, BITSPIXEL }; for(int i = 0; i < ARRAYCOUNT(arr); ++i) { const int nA = GetDeviceCaps(hDC_A, arr[i]); const int nB = GetDeviceCaps(hDC_B, arr[i]); } } //お試し void main() { //現在の画面と互換性のあるメモリデバイスコンテキスト HDC hDC_A = CreateCompatibleDC(NULL); //画面全体を表すデバイスコンテキスト HDC hDC_w = ::GetDC(NULL); HDC hDC_B = CreateCompatibleDC(hDC_w); Check(hDC_A, hDC_B); //後始末は忘れずに }

usatan2
質問者

お礼

回答ありがとうございます。 >こんばんは。試して見ましたが、違いは無い様です。 テストありがとうございます。ところで、プログラムAとBは「常に同じ」ということでしょうか、それとも、「xxxという環境では同じ」ということでしょうか?たとえば、「xxx」は24ビットカラーとか、1024x768などの制約があるのでしょうか?もしも、ご存知でしたらお教えください。 >HDCに対してGetDeviceCaps()を使うと、HDCの詳細を確認出来ます。 便利な関数があるんですね。勉強になりました。

関連するQ&A

  • GetPixelに使うHDCの作り方

    ビットマップハンドルhBitmap の(x,y)の画素の色を読み取るプログラムに使うデバイスコンテキストとして、  hDC = CreateCompatibleDC(NULL);  SelectObject(hDC, hBitmap);  rgb = GetPixel(hDC, x,y);  DeleteDC(hDC); のように、NULL を指定して、画面と互換性のあるメモリデバイスコンテキストを指定したのですが、正しい色が読み出せません。hDC = GetDC(NULL);でも同じく駄目でした。hDCはどのように作ったらよいのでしょう。 なお、関数の中でGetPixel()を使いたいので、hWnd などは使えません。

  • CreateCompatibleDCが返した値の開放

    hdc = CreateCompatibleDC( GetDC(hWnd) ); //色々な条件による処理 SelectObject( hdc, hbitmap ); //hdcを使った処理 DeleteDC( hdc ); というソースで、「色々な条件による処理」によって処理を中止する場合 つまり、SelectObject()は実行していないけど、CreateCompatibleDC()は 実行済みの場合、DeleteDC(hdc);は必要ですか? もし必要でない場合、DeleteDC(hdc);を実行してはいけないですか?

  • [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) の中に表記すると、画像が表示されます。 何故か、いまいち分かっていません・・・ すみませんが、ご教授ください。

  • メモリデバイスコンテキスト&ビットマップハンドル

    static VOID _SetSize(pLayer object, LONG w, LONG h) { LayerEx * obj; obj = (LayerEx *)object; obj->size.x = w; obj->size.y = h; if(obj->hBitmap){ HDC hdc , hNewDC; HBITMAP hNewBitmap; hdc = object->GetDC(object); hNewDC = CreateCompatibleDC(hdc); hNewBitmap = CreateCompatibleBitmap(hdc , w , h); SelectObject(hNewDC , hNewBitmap); BitBlt(hNewDC , 0 , 0 , w , h , hdc , 0 , 0 , SRCCOPY); DeleteObject(hNewDC); object->DeleteDC(object , hdc); DeleteObject(obj->hBitmap); obj->hBitmap = hNewBitmap; } 一度生成したビットマップのサイズを変更してもう一度ビットマップを生成するプログラムらしいのですが、 BitBlt(hNewDC , 0 , 0 , w , h , hdc , 0 , 0 , SRCCOPY); ↑なぜBitBltで転送しているのかわかりません。 新しく生成したビットマップをSelectObjectで登録したらいいような感じがするんですが・・・ DeleteObject(hNewDC); ↑あとこれはDeleteDC(hNewDC)の間違いなのでしょうか?ここも何しているか分かりません。 分かる人いたら教えてください。説明足りなかったらごめんなさい^^; ↓一応object->GetDC(object)のソースです。 static HDC _GetDC(pLayer layer) { LayerEx * obj; HDC hResult; obj = (LayerEx *)layer; if(obj->hBitmap == NULL){ HDC hdc; hdc = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL); obj->hBitmap = CreateCompatibleBitmap(hdc, obj->size.x, obj->size.y); hResult = CreateCompatibleDC(hdc); SelectObject(hResult, obj->hBitmap); DeleteDC(hdc); } else{ hResult = CreateCompatibleDC(NULL); SelectObject(hResult, obj->hBitmap); } return hResult; }

  • 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); }

  • ウインドウ内全体を一定時間で更新したいWinAPI

    ウインドウ内全体をWM_TIMERを使って一定時間毎に更新したいのですが、うまくいきません。資料・アドバイスを参考にここまで作ったのですが、おそらくWM_PAINTのところでリージョン領域しか更新していないのかと思います。そこでInvalidateRect( hwnd, NULL, NULL ); をウインドウ内全体をリージョンする関数、たとえはRedrawWindow などを使ってみたのですが、正しくできていないためか状況が変わりません。 毎度のことで申し訳ありませんがアドバイスお願いします。 #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 _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 , 16 , NULL); return 0; } case WM_TIMER:{ getScreenShot(_bmpShot, 0, 0, _iWidth, _iHeight); InvalidateRect( hwnd, NULL, NULL ); 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); }

  • 画像の転送処理について

    前後の処理は省くとして 1.CreateCompatibleDCでメモリデバイスコンテキスト作成 2.SelectObjectでビットマップオブジェクトを選択 3.BitBltで画像を転送 4.SelectObjectで元のオブジェクトを選択 5.DeleteDCでメモリデバイスコンテキストを削除 サンプルを公開されているサイトここのような書き方になっているのですが 5. の段階で削除するのであれば 4. の元に戻す処理の必要性がわかりません。 ※BitBltの直後にSelectObjectで戻し、DeleteDCで削除しており、  間に余計な処理は入っていません。 上記の処理を行う場合、 1.CreateCompatibleDCでメモリデバイスコンテキスト作成 2.SelectObjectでビットマップオブジェクトを選択 3.BitBltで画像を転送 4.DeleteDCでメモリデバイスコンテキストを削除 このようなやり方だと問題ありますでしょうか?

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

    スクリーンキャプチャを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); }

  • 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