ディスク上のビットマップをフォームへ表示


//-----------------------------------------
public:
	char* m_BmpImage;
	LPBITMAPINFO m_BmpInfo;
	BITMAPFILEHEADER m_BmpFileHdr;

COpenfrmsapDlg::COpenfrmsapDlg(CWnd* pParent /*=NULL*/)
	: CDialog(COpenfrmsapDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(COpenfrmsapDlg)
		// メモ: この位置に ClassWizard によってメンバの初期化が追加されます。
	//}}AFX_DATA_INIT
	// メモ: LoadIcon は Win32 の DestroyIcon のサブシーケンスを要求しません。
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

	//---------------------------------
	//初期化
	m_BmpInfo = NULL;
	m_BmpImage = NULL;
}

void COpenfrmsapDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 描画用のデバイス コンテキスト

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// クライアントの矩形領域内の中央
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// アイコンを描画します。
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
		//--------------------------------
		HBITMAP myDIB;			//ビットマップのハンドル
		HDC hDC;				//デバイスコンテキストのハンドル
		HDC hCompatiDC;			//メモリデバイスコンテキスト
		PAINTSTRUCT ps;			//クライアント領域の描画に使う情報を保持

		//-----------------------------------------
		//画像の準備が出来ていなければ関数を抜ける
		if(!m_BmpInfo) return;

		//------------------------------------------------------------
		//m_hWndで示す現在のウィンドウのデバイスコンテキストを取得
		//(注)このデバイスコンテキストは描画終了後にReleseDCで解放する必要あり

		hDC = ::GetDC(m_hWnd);

		//---------------------------------------------------
		//描画の準備をする
		//(注)描画が終了したら必ずEndPaintを実行する必要がある

		::BeginPaint(m_hWnd,&ps);

		//---------------------------------------------------
		//hDCと互換性のあるメモリデバイスコンテキストを作成

		hCompatiDC = ::CreateCompatibleDC(hDC);

		//------------------------------------------------------------
		//DIB形式ビットマップからDDB(デバイス依存)形式ビットマップ作成

		myDIB = ::CreateDIBitmap(hDC,&m_BmpInfo->bmiHeader,
				CBM_INIT,m_BmpImage,m_BmpInfo,DIB_RGB_COLORS);

		//----------------------------------------------------------
		//hCompatiDCでmyDIBの示すオブジェクトを使用できるようにする

		::SelectObject(hCompatiDC,myDIB);

		//---------------------------------------------------
		//hCompatiDCにある画像をhDCに表示する

		BitBlt(hDC,5,35,m_BmpInfo->bmiHeader.biWidth,
			m_BmpInfo->bmiHeader.biHeight,hCompatiDC,0,0,SRCCOPY);

		//------------------------------------------------
		//BeginPaint対応処理

		::EndPaint(m_hWnd,&ps);

		//-------------------------
		//オブジェクト

		::DeleteObject(myDIB);
		::DeleteObject(hCompatiDC);
		::ReleaseDC(m_hWnd,hDC);

	}
}

//描画するビットマップを描画用デバイスコンテキストへ出力
void COpenfrmsapDlg::OnButton1() 
{
	// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
	
	//-------------------------------
	CString filename;
	CFile file;
	BITMAPINFOHEADER myBmpInfoHdr;

	//----------------------------------------------
	//ファイルダイアログを表示してファイル指定する
	CFileDialog myDLG(TRUE,NULL,NULL,
					OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
					"ビットマップ(*.BMP)|*.BMP||");
	if(myDLG.DoModal() != IDOK)return;

	//----------------------------
	//取得したファイルをオープン
	filename = myDLG.GetPathName();
	if(!file.Open(filename,CFile::modeRead|CFile::typeBinary)){
		return;
	}

	//--------------------------------
	//タイトルバーにファイル名を表示
	SetWindowText(filename);

	//ファイルヘッダ部とインフォヘッダ
	file.Read(&m_BmpFileHdr,sizeof(BITMAPFILEHEADER));
	file.Read(&myBmpInfoHdr,sizeof(BITMAPINFOHEADER));

	//---------------------------------------
	//前回使用していれば、一旦メモリ解放する
	if(m_BmpInfo) delete[] m_BmpInfo;

	if(myBmpInfoHdr.biBitCount >= 16){
		m_BmpInfo = (LPBITMAPINFO)new char[sizeof(BITMAPINFO)];
	}
	else{
		m_BmpInfo = (LPBITMAPINFO)new char[sizeof(BITMAPINFOHEADER) +
					(1 << myBmpInfoHdr.biBitCount) * sizeof(RGBQUAD)];
		file.Read(m_BmpInfo->bmiColors,
					(1 << myBmpInfoHdr.biBitCount) * sizeof(RGBQUAD));
	}

	//-------------------------------------
	//カラー情報がRGB値であることを表明
	
	//m_BmpInfo(LPBITMAPINFO型)のmyBmpInfoHdrメンバに設定
	m_BmpInfo->bmiHeader = myBmpInfoHdr;

	//-----------------------------------------------
	//ファイル内のビットマップ実データ位置に合わせる
	file.Seek(m_BmpFileHdr.bfOffBits,CFile::begin);

	//----------------------------------
	//前回の画像イメージを一旦解放
	if(m_BmpImage) delete[] m_BmpImage;

	//--------------------------------------
	//実画像データ分のバイト数を確保
	//bfsize ビットマップファイルの全サイズ
	//bfOffBits先頭にあるヘッダ情報サイズ
	//m_BmpImage = new char(m_BmpFileHdr.bfSize - m_BmpFileHdr.bfOffBits);
	m_BmpImage = (char *)malloc(m_BmpFileHdr.bfSize - m_BmpFileHdr.bfOffBits);

	//------------------------------------------
	//ビットマップ実データを読み込み格納
	file.Read(m_BmpImage,m_BmpFileHdr.bfSize - m_BmpFileHdr.bfOffBits);
	file.Close();

	//------------------
	//再描画
	Invalidate();

}