OnDraw以外でクライアント領域をBMPに保存できない

このQ&Aのポイント
  • MFCでクライアント領域の画像をBMPファイルに保存する方法はOnDraw以外で実現できないのか?
  • OnDraw関数に記述すると最初の1ステップ目のみファイルが出力される現象が発生している
  • 有用なライブラリや参考URLなどがあれば教えてほしい
回答を見る
  • ベストアンサー

OnDraw以外でクライアント領域をBMPに保存できない

いつもお世話になっています。 MFCでシミュレーション計算プログラムを作っていて クライアント領域の画像をBMPファイルに落とすため 下記サブルーチンを作成しましたが、 ファイルができません。 OnDraw関数に記述すると、 最初の1ステップ目のみファイルが出力されます??? どなたかアドバイス・参考URL等ご教示お願い致します。 また、他に有用なライブラリ等ありましたら、 URL等ご紹介いただければありがたいです。 void CMPSView::SaveBMP(HWND hwnd, char* filename) { DWORD dwSize,dwFSize,dwWidth,dwHeight,dwLength; HANDLE fh; LPBITMAPFILEHEADER lpHead; LPBITMAPINFOHEADER lpInfo; LPBYTE lpBuf,lpPixel; RECT rec; HDC hdc,hdcMem; HBITMAP hBMP,hOld; (中略:バッファ確保、ヘッダ作成) hdc = this->GetDC()->m_hDC; hBMP=CreateCompatibleBitmap(hdc,dwWidth,dwHeight); hdcMem=CreateCompatibleDC(hdc); hOld=(HBITMAP)SelectObject(hdcMem,hBMP); BitBlt(hdcMem,0,0,dwWidth,dwHeight,hdc,0,0,SRCCOPY); SelectObject(hdcMem,hOld); GetDIBits(hdc,hBMP,0,dwHeight,lpPixel,(LPBITMAPINFO)lpInfo,DIB_RGB_COLORS); ReleaseDC(this->GetDC()); DeleteObject(hBMP); DeleteObject(hdcMem); fh=CreateFile(filename, GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); WriteFile(fh,lpBuf,dwFSize,&dwSize,NULL); CloseHandle(fh); GlobalFree(lpBuf); }

  • zico2
  • お礼率79% (27/34)

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

  • ベストアンサー
  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.1

>下記サブルーチンを作成しましたが、 C++なんだからサブルーチンだなんていわないで・・・ >ファイルができません。 どうやってここの処理を呼び出しているのでしょう? あと、エラー処理が何にも無いんですが、どこで エラーになっているか位調べましたか? 1ステップ目だけでも描画した結果が取得できて ビットマップファイルが作成できることがあるという のであれば、ファイルを作成して保存している個所の ソースを挙げられても意味が無いのでは?

zico2
質問者

補足

ご教示ありがとうございます。 10ステップ毎の書き出しは 下記のメンバ関数で行っています。 また、ファイル作成時のソースを記述しましたのは、 1回目の処理にメモリ上なんらかのミスがあったために、 2回目以降に書き出しが行われないのではないかと 推測したためです(ReleaseDC,DeleteObject等)。 しかし、マウスクリック(View::OnLbuttonDown) とbmp書きだしをリンクさせたところ、何枚でも書き出せることが分かりました。 ということは、whileループでだけ 書き出しできていないことになります。 トレースしたところ、書き出しルーチンには入っており、 エラーは出ていません。 よろしくお願いします。 bool MyView::ViewResult(char* filename1) { fp=fopen(filename1,"r"); fgets(buff,255,fp); while(fgets(buff,255,fp) != NULL){ sscanf(buff,"%2s%2s%15le",&dum1,&dum2,&(pDoc->m_MPSM.m_time)); fscanf(fp,"%15d\n",&(pDoc->m_MPSM.m_NP)); int fout; for( i = 0 ; i < pDoc->m_MPSM.m_NP ; i++){ fgets(buff,255,fp); fout = sscanf(buff,"%15i,%15le,%15le,%15le,%15le,%15le,%15le,%15le,%15le,%15i", &(pDoc->m_MPSM.m_p[i].m_Velocity.x), &(pDoc->m_MPSM.m_p[i].m_Velocity.y), &(pDoc->m_MPSM.m_p[i].m_Velocity.z), }   //画面更新 this->Invalidate(true); this->UpdateWindow(); sprintf(filename2, "Auto%.0lf.bmp", pDoc->m_MPSM.m_time*1000); if(int(pDoc->m_MPSM.m_time * 1000) % 10 == 0){ //bmpファイル書き出し WriteWindowToDIB( filename2, this); } }//while loop fclose(fp); }

その他の回答 (1)

  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.2

>OnDraw関数に記述すると、 >最初の1ステップ目のみファイルが出力されます??? >  //画面更新 > this->Invalidate(true); > this->UpdateWindow(); 原因はこの2行、特にUpdateWindow()だと思います。 UpdateWindowは、呼びだされたら即座に描画を行います。 MFCでは、OnDrawが直接呼び出されます。 このため、最初の1ステップ目のみしか記録されていないファイルが出来ます。 というか、OnDrawの中でInvalidate()もUpdateWindow()も呼んではいけません。OnDrawは、描画をするためのハンドラです。描画をするハンドラの中で無効領域を作ったり再描画の指示なんて出したら無限ループの元です。

zico2
質問者

お礼

ご教示ありがとうございます。 私の説明が舌足らずですみません。 この2行は、OnDraw関数の中で呼んでいません。 Viewの他のメンバ関数内で呼び出しています。 今まで、bmp書きだしルーチンに問題があると ばかり思いこんでいたのですが、 ご指摘を受けて、View周りを注意深くトレースして チェックしていましたら、 bmpファイルがアプリケーション起動ディレクトリ以外の ディレクトリに書き出されていることが分かりました。 最初の1枚だけカレントディレクトリに書き出されて、後は、他のディレクトリにありました。 途中で、CFileDialogを使ったことにより、 カレントディレクトリが変わってしまったようです。 bmpの書き出しルーチン自体は問題なかったようなのです。 この数日間悩み続けていたことが解決できました。 1人で悩んでいても3日も4日も解決しなかったのですが、ご指摘頂いたことが解決への糸口となりました。 本当にどうもありがとうございました。

関連するQ&A

  • BMPの保存

    プリントスクリーンをして、それをBMP形式で保存しようとしているのですが、保存後のファイルを開いてウィンドウを動かすと、それにつれ逐次、画像が更新されていきます。 この問題の原因がわかる方、助言をお願いします。 プログラムはC++で作成しています。 下にソースを載せています。 宜しくお願いします。 #include<windows.h> LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; static BITMAPINFO bmpInfo; static LPDWORD lpPixel; static HBITMAP hBitmap; static HDC hMemDC; HWND desktop; RECT rc; static int width,height; switch(uMsg) { case WM_CREATE: //スクリーンの情報を得る desktop=GetDesktopWindow(); GetWindowRect(desktop,&rc); width=rc.right; height=rc.bottom; //DIBの情報を設定する bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); bmpInfo.bmiHeader.biWidth=width; bmpInfo.bmiHeader.biHeight=height; bmpInfo.bmiHeader.biPlanes=1; bmpInfo.bmiHeader.biBitCount=32; bmpInfo.bmiHeader.biCompression=BI_RGB; //DIBSection作成 hdc=GetDC(hWnd); hBitmap=CreateDIBSection(hdc,&bmpInfo,DIB_RGB_COLORS,(void**)&lpPixel,NULL,0); hMemDC=CreateCompatibleDC(hdc); SelectObject(hMemDC,hBitmap); ReleaseDC(hWnd,hdc); //スクリーンをDIBSectionにコピー hdc=GetDC(desktop); BitBlt(hMemDC,0,0,width,height,hdc,0,0,SRCCOPY); ReleaseDC(desktop,hdc); return 0; case WM_DESTROY: //自らlpPixelを解放するべからず DeleteDC(hMemDC); DeleteObject(hBitmap); //BMPを削除した時、lpPixelも自動的に解放される PostQuitMessage(0); return 0; case WM_PAINT: hdc=BeginPaint(hWnd,&ps); //表画面へ転送 BitBlt(hdc,0,0,width,height,hMemDC,0,0,SRCCOPY); EndPaint(hWnd,&ps); return 0; } SaveBitmap((HWND)hWnd,"PrintScreen.BMP"); return DefWindowProc(hWnd,uMsg,wParam,lParam); } int WINAPI WinMain( HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR lpCmdLine,int nCmdShow) { WNDCLASS wc; MSG msg; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL,IDI_APPLICATION); wc.hCursor = LoadCursor(NULL,IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = __FILE__; if(!RegisterClass(&wc)) return 0; HWND hWnd=CreateWindow( __FILE__,"スクリーンキャプチャ", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, NULL,NULL,hInstance,NULL); if(hWnd==NULL) return 0; BOOL bRet; while((bRet=GetMessage(&msg,NULL,0,0))!=0){ if(bRet==-1) break; DispatchMessage(&msg); } return (int)msg.wParam; }

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

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

  • win32apiでbmpを表示する関数についてです

    bmpを表示する関数と処理する関数を別々のファイルにしたいのですが、表示されません・・・。エラー、警告はありませんでした。VC++2008を使用しています。ソースは以下のようになっています。よろしくお願い致します。 ~ 処理部分 load_bmp.cpp ~ #include <windows.h> #include <stdio.h> #include <tchar.h> extern HINSTANCE hinst; extern HWND hwnd; int Load_Bmp( HDC hdc, char *f_name_of_BMP) { HBITMAP hbmp; HDC work_DC; hbmp=(HBITMAP)LoadImage(hinst,_T ("f_name_of_BMP"),IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION | LR_LOADFROMFILE); if( hbmp == NULL ){ MessageBox(hwnd, _T("ビットマップを表示できません"), _T("エラー"),MB_OK | MB_ICONWARNING); return 0; } work_DC = CreateCompatibleDC( hdc ); SelectObject( work_DC, hbmp ); BitBlt(hdc,0,0,640,480,work_DC,0,0,SRCCOPY); ReleaseDC( hwnd,work_DC ); DeleteObject( hbmp ); return 0; } ~ヘッダファイル load_bmp.h ~ int Load_Bmp( HDC hdc,char *f_name_of_BMP); ~処理部分 main.cpp ~ #include <windows.h> #include <tchar.h> #include "load_bmp.h" HWND hwnd; HDC win_hdc; HINSTANCE hinst; void init_game() { Load_Bmp( win_hdc,"test.bmp"); } LRESULT WndProc(HWND hwnd,UINT msg,WPARAM wprm,LPARAM lprm) { switch(msg){ case WM_CREATE: break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd,msg,wprm,lprm); } return 0; } int APIENTRY WinMain(HINSTANCE hIns,HINSTANCE hPI,LPSTR lpArg,int nCmdShow) { MSG msg; WNDCLASS wc; hinst=hIns; wc.hInstance=hIns; wc.lpszClassName=_T("test"); wc.lpfnWndProc=(WNDPROC)WndProc; wc.style=0; wc.hIcon=LoadIcon((HINSTANCE)NULL,IDI_APPLICATION); wc.hCursor=LoadCursor((HINSTANCE)NULL,IDC_ARROW); wc.lpszMenuName=0; wc.cbClsExtra=0; wc.cbWndExtra=0; wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); if(RegisterClass(&wc)==0)return 0; hwnd=CreateWindowEx( 0, wc.lpszClassName, _T("test"), WS_OVERLAPPEDWINDOW, 20,20,640,480, NULL, NULL, hIns, NULL     ); if(!hwnd) return 0; ShowWindow(hwnd,nCmdShow); UpdateWindow(hwnd); win_hdc=GetDC(hwnd); init_game(); while(1){  if(PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)){ (!GetMessage(&msg,(HWND)NULL,0,0));break; TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; }

  • 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 などは使えません。

  • OnPaint() とOnDraw()の違いについて

    OnPaint内に記述した下記コードでビットマップが描画されますが、OnDraw内だと描画されません。 どうしてなのか教えてください。 お願いします。 void CAbcView::OnPaint() { HBITMAP myDIB; // ビットマップのハンドル HBITMAP oldDIB; HDC hDC; // デバイスコンテキストのハンドル HDC hCompatiDC; // メモリデバイスコンテキスト PAINTSTRUCT ps; // クライアント領域の描画に使う情報を保持 if(!m_BmpInfo) return; hDC = ::GetDC(m_hWnd);//これでもOK ::BeginPaint(m_hWnd,&ps); hCompatiDC = ::CreateCompatibleDC(hDC);//hDC); myDIB = ::CreateDIBitmap(hDC,&m_BmpInfo->bmiHeader, CBM_INIT,m_BmpImage,m_BmpInfo,DIB_RGB_COLORS); oldDIB=(HBITMAP)::SelectObject(hCompatiDC,myDIB); BitBlt(hDC,5,25,m_BmpInfo->bmiHeader.biWidth, m_BmpInfo->bmiHeader.biHeight,hCompatiDC,0,0,SRCCOPY); 略 } 環境 WIN98 VC++6.0 MFC にて

  • c++ ダブルバッファリング、以下のコードでできず

    こんばんわ。visual studio express 2013でC++を勉強している者です。 ダブルバッファリングをしたいのですが、チラつきが改善しません。 どう書けばダブルバッファリングを実現できるのか、ご教授ください。 以下は私が書いたコードの一部です。よろしくお願いします。 (要は、hdc_mem1のビットマップを、hdc_mem0(白紙のビットマップ)に読み込み、hdc_mem0のみを画面に表示しようとしています。 いずれは用意したすべての種類のビットマップをhdc_mem0に読み込み、hdc_mem0のみ画面に表示させることによってチラつきを抑えようと考えています) case WM_CREATE:  hdc = GetDC(hWnd);  hBmp0 = LoadBitmap(hInst, TEXT("MYBMP0"));  GetObject(hBmp0, (int)sizeof(BITMAP), &bmp_info0);  hdc_mem0 = CreateCompatibleDC(hdc);  SelectObject(hdc_mem0, hBmp0);  hBmp1 = LoadBitmap(hInst, TEXT("MYBMP1"));  GetObject(hBmp1, (int)sizeof(BITMAP), &bmp_info1);  hdc_mem1 = CreateCompatibleDC(hdc);  SelectObject(hdc_mem1, hBmp1);  DeleteObject(hBmp0);  DeleteObject(hBmp1);  ReleaseDC(hWnd, hdc);  break; case WM_PAINT:  hdc = BeginPaint(hWnd, &ps);  BitBlt(hdc_mem0, 0, 0, bmp_info1.bmWidth, bmp_info1.bmHeight, hdc_mem1, 0, 0, SRCCOPY);  BitBlt(hdc, 0, 0, bmp_info0.bmWidth, bmp_info0.bmHeight, hdc_mem0, 0, 0, SRCCOPY);  EndPaint(hWnd, &ps);  break; case WM_DESTROY:  DeleteDC(hdc_mem0);  DeleteDC(hdc_mem1);  PostQuitMessage(0);  break;

  • 画面の更新

    開発環境 XP Home Edtion Microsoft Visual C++ 2008 Express Edition SQL Server2005 Express Edtion ボタンを押すと画像を画面に表示させるというものを作っています、実行時は白紙の状態で、ボタンを押すとその値の画像が表示されるというものです。 HDC hMdc; HBITMAP hbmp = (HBITMAP)LoadImage( NULL, dstLPCSTR3, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION ); hMdc= CreateCompatibleDC(hdc ); SelectObject(hMdc, hbmp ); BitBlt(hdc, 0, 0, 2000, 5000, hMdc, 0, 0, SRCCOPY); DeleteDC(hMdc); DeleteObject(hbmp); これはボタンを押されたときの処理です。 判りにくいところもあると思いますがどうかよろしくお願いいたします。

  • PrintScreenしたあとに画像を保存する方法

    LRESULT CALLBACK WndProcScreenCapture(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { // MMTIME mm; // CommonClass Common; static int id,x,y; HDC hdc; PAINTSTRUCT ps; static HBRUSH hBrush; HWND desktop; RECT rc; static int width,height; static BITMAPINFO bmpInfo; static LPDWORD lpPixel; static HBITMAP hBitmap; static HDC hMemDC; FILE *fpt; int i,j; //clock_t start,end; switch (message) { case WM_CREATE: desktop=GetDesktopWindow();//デスクトップのハンドルを取得 GetWindowRect(desktop,&rc);//デスクトップのRECT情報を取得 width=rc.right; height=rc.bottom; //DIBの情報を設定する bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); bmpInfo.bmiHeader.biWidth=width; bmpInfo.bmiHeader.biHeight=height; bmpInfo.bmiHeader.biPlanes=1; bmpInfo.bmiHeader.biBitCount=32; bmpInfo.bmiHeader.biCompression=BI_RGB; //DIBSection作成 hdc=GetDC(hWnd); hBitmap=CreateDIBSection(hdc,&bmpInfo,DIB_RGB_COLORS,(void**)&lpPixel,NULL,0); hMemDC=CreateCompatibleDC(hdc); SelectObject(hMemDC,hBitmap); ReleaseDC(hWnd,hdc); fopen_s(&fpt,"20090715.raw","wb"); fwrite((void**)&lpPixel[0],sizeof(unsigned char),width*height,fpt); /* DIBSectionにグラデーション描画 */ for (i = 0;i < height;i++) { for (j = 0;j <width;j++) { #if 0 /* DIBピクセル列に直接アクセス */ lpPixel[i + j * 256] = (i << 16); lpPixel[i + (j + 32) * 256] = (i << 8); lpPixel[i + (j + 64) * 256] = i; lpPixel[i + (j + 96) * 256] = (i << 16) | (i << 8) | i; /* GDI経由で描画 */ SetPixel(hMemDC, i, j + 128, RGB(i, 0, 0)); SetPixel(hMemDC, i, j + 128 + 32, RGB(0, i, 0)); SetPixel(hMemDC, i, j + 128 + 64, RGB(0, 0, i)); SetPixel(hMemDC, i, j + 128 + 96, RGB(i, i, i)); #endif } } //fwrite(&(bmpInfo.bmiHeader),sizeof(unsigned char),40,fpt); //fwrite((void**)&lpPixel,sizeof(unsigned char),width*height,fpt); //fwrite(&(bmpInfo.bmiColors),sizeof(unsigned char),width*height,fpt); fclose(fpt); //スクリーンをDIBSectionにコピー hdc=GetDC(desktop); BitBlt(hMemDC,0,0,width,height,hdc,0,0,SRCCOPY); ReleaseDC(desktop,hdc); break; case WM_DESTROY: //自らlpPixelを解放するべからず DeleteDC(hMemDC); DeleteObject(hBitmap); //BMPを削除した時、lpPixelも自動的に解放される PostQuitMessage(0); break; case WM_PAINT: hdc=BeginPaint(hWnd,&ps); BitBlt(hdc,0,0,width,height,hMemDC,0,0,SRCCOPY); EndPaint(hWnd,&ps); break; case WM_CHAR: の様に書いて、windowにキャプチャ画像を表示することは できたのですが、 この画像の画像情報のピクセルのポインタはどれなのでしょうか? 画像をraw形式でもいいので保存したいのですが、 どうしたら、キャプチャした画像を ファイルとして保存 できますか? //fwrite((void**)&lpPixel,sizeof(unsigned char),width*height,fpt); ではうまくいきませんでした。

  • CreateCompatibleDCが返した値の開放

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

  • 画像を切り替えるプログラムで悩んでいます。

    C言語で、ビットマップを『2枚』表示した後、メニューの選択により、どちらかの画像だけを表示したいのです、色々試して見たのですが、うまく行きません。ヒント、アドバイスをお願いします。 本当は『2枚』だけでなく、スキャンして、保存した画像を全て表示したいのですが、まだその方法が出来ません。 1、グローバルな変数として、   HDC hdc_mem1, hdc_mem2;//2種類のメモリデバイスコンテキストハ  ンドルを格納  int show_no = 1;//画像選択のための変数1で初期化 2、/*ウィンドウプロシージャ*/ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { HDC hdc; static DWORD dwRop;   PAINTSTRUCT ps; HBITMAP hBmp; HDC hdc_memx; switch(msg){ case WM_CREATE: hdc = GetDC(hWnd); hdc_mem1, hdc_mem2; dwRop = SRCCOPY; hBmp = LoadBitmap(hInst, "MYBMP1"); if(hBmp == NULL){ MessageBox(hWnd, "画像1のロードに失敗しました", "エラー", MB_OK | MB_ICONWARNING); return 0; } hdc_mem1 = CreateCompatibleDC(hdc); SelectObject(hdc_mem1, hBmp); hBmp = LoadBitmap(hInst, "MYBMP2"); if(hBmp == NULL){ MessageBox(hWnd, "画像2のロードに失敗しました", "エラー", MB_OK | MB_ICONWARNING); return 0; } hdc_mem2 = CreateCompatibleDC(hdc); SelectObject(hdc_mem2, hBmp); ReleaseDC(hWnd, hdc); break; case WM_PAINT: BeginPaint(hWnd, &ps); hdc_memx = hdc_mem1, hdc_mem2; if(show_no == 1) hdc_memx = hdc_mem1; //変化なし hdc_memx != hdc_mem2;//変化なし if(show_no == 2) hdc_memx = hdc_mem2; /変化なし  hdc_memx != hdc_mem1;/変化なし BitBlt(ps.hdc, ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top, hdc_mem1, ps.rcPaint.left, ps.rcPaint.top, dwRop); BitBlt(ps.hdc, 400,200, ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top, hdc_mem2, ps.rcPaint.left, ps.rcPaint.top, dwRop); EndPaint(hWnd, &ps); break; case WM_COMMAND: switch (LOWORD(wp)){ case IDM_PICT1: show_no = 1; InvalidateRect(hWnd, NULL, TRUE); break; case IDM_PICT2: show_no = 2; InvalidateRect(hWnd, NULL, TRUE); break; case IDM_SRCCOPY: dwRop = SRCCOPY; InvalidateRect(hWnd, NULL, TRUE); break; case IDM_NOTSRCCOPY: dwRop = NOTSRCCOPY; InvalidateRect(hWnd, NULL, TRUE); break; case IDM_SRCAND: dwRop = SRCAND; InvalidateRect(hWnd, NULL, TRUE); break; case IDM_SRCPAINT: dwRop = SRCPAINT; InvalidateRect(hWnd, NULL, TRUE); break; case IDM_END: SendMessage(hWnd, WM_CLOSE, 0, 0); break; } break; case WM_DESTROY: DeleteObject(hBmp); DeleteObject(hBmp); DeleteDC(hdc_mem1); DeleteDC(hdc_mem2); PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0; } 3、if文のところを色々と変えたのですが、うまく切り替わってくれません。   if(show_no == 1) hdc_memx = hdc_mem1; hdc_memx != hdc_mem2; if(show_no == 2) hdc_memx = hdc_mem2;  hdc_memx != hdc_mem1;

専門家に質問してみよう