仲澤@失業者さんレスありがとうございます。
StretchDIBits()をしらべていますが、
int StretchDIBits(
:
CONST VOID *lpBits, // address of bitmap bits
:
:
);
lpBits・・・DIB の色データが入ったバイト配列へのポインタを指定します。
という引数があります。外部ファイルをイメージしていると、これをread()などで
ヘッダーなどから順次読んでいく必要があるようですね。
いしださん、レスありがとうございます
試してみましたが、コンパイルエラーが出力されました。
protected:
CImage m_image ;
error C2146: 構文エラー : ';' が、識別子 'm_image' の前に必要です。
error C2501: 'CImage' : 識別名を宣言するのに、型が指定されていません。
> 試してみましたが、コンパイルエラーが出力されました
VC6の頃には無いクラスだったようです。失礼しました。
ちなみに、リソース内のビットマップ画像をそのまま表示するのであれば、
イメージリストにしてしまうという方法を自分はたまに使います。
基本的には複数の画像をまとめて扱うものですが、
DCに直接描画できますし、透過処理も可能です。
CImageList m_imageList;
CBitmap bitmap;
bitmap.LoadBitmap(IDB_BITMAP1);
m_imageList.Create(100, 100, ILC_COLOR24 | ILC_MASK, 0, 1);
m_imageList.Add(&bitmap, RGB(255, 0, 255));
CPaintDC dc(this);
m_imageList.Draw(&dc, 0, CPoint(50, 50), ILD_TRANSPARENT);
前のスレッドを読んでいない人には流れが分からないような気がします。
前のスレッドの内容で今回の質問に必要な前提があるのなら、手短に説明を
行なってから質問にはいるか、前のスレッドにリンクを張るべきでしょう。
(個人的にはリンクで済ませてしまうとスレッド全体に目を通さなくては
ならなくなるので質問する方で要約して説明すべきだと思ってます)
派生させたクラスを作成して対応する必要があるのは、
読み込んだ画像の上にGDIで描画して表示したいからだったと思いますが、
その部分は変わっていないのですよね?
であれば、その部分の説明が無いと話が通りません。
仮に特定の画像をCStaticに表示させたいだけの話なら
自分で描画するまでも無く、仲澤さん、hiroccoさんが書かれている
通りの話になります。その方が無駄にコードを書く必要が有りません。
CStaticの機能を使って表示させた方が簡単ですし、確実です。
LordBitmapで読み込んだCBitmapを画面に表示する為に
一旦、画面とコンパチブルなDCを作成した上でそこに選択状態にして
画面のDCに転送するのはDDBを画面のデバイスに適合させて
それを画面に転送するという手続き上必要な操作なので無駄では有りません。
この部分はなぜそうする必要があるのかと言う部分まで学ぶ事ができれば、
ベストですが、理解しきれない場合は一先ず手続きとして納得するしか
ありません。但し、毎回DCを作成してビットマップをロードしてを
繰り返すのは非効率なので効率の良い実装を考える必要はあると思います。
しなくても良い処理をせずに済ませられるようにするのは当然必要です。
いろいろな情報が入ってきているのでご自身で一度整理された方が良いと
思います。その上で自分がやりたい事にあった方法を選ぶ必要があると思います。
hirocco さん、レスありがとうございます。
LoadImageはあります。
::LoadImage()からStretchDIBits() につなげれるのでは?
という予想を立てています。
現在、調査中です。
いしださん、レスありがとうございます。
以下のようにコーディングして、表示されました。
メンバ変数の宣言
protected:
CImageList m_imageList;
ソースファイル
int CXXXXX::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialog::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: この位置に固有の作成用コードを追加してください
CBitmap bitmap;
bitmap.LoadBitmap(IDB_BITMAP1);
m_imageList.Create(100, 100, ILC_COLOR24 | ILC_MASK, 0, 1);
m_imageList.Add(&bitmap, RGB(255, 0, 255));
bitmap.DeleteObject() ;
return 0;
}
void CXXXXX::OnPaint()
{
CPaintDC dc(this); // 描画用のデバイス コンテキスト
// TODO: この位置にメッセージ ハンドラ用のコードを追加してください
m_imageList.Draw(&dc, 0, CPoint(50, 50), ILD_TRANSPARENT);
// 描画用メッセージとして CDialog::OnPaint() を呼び出してはいけません
}
PATIO さん、レスありがとうございます。
前レスからの流れをくみますが、今回は、
”ビットマップを画面に表示するだけなのに、もうすこし、簡単にできないのかな?”
という疑問がありましたので、UPしてみました。
いろいろ、みなさんからご意見をいただき、メモリデバイスコンテキストをとって、
そこに、書き込んで、W_PAINTが送られるたびにBitBlt()で再表示するのが、無駄ではな
いということがわかりました。
また、CBitmapは、デバイスコンテキストにsetobjectすることで、デバイスコンテキス
トのフォーマットを決め、データを書き込むということも・・
いろいろ勉強になりました。
みなさん、ありがとうございました。
ヘッダファイル(クラス宣言)での記述
protected:
CDC m_mDC ;
CBitmap m_Bitmap ;
BITMAP m_BitmapStruct ;
CBitmap *m_pPrevBitmap ;
ソースファイル
int CDerivationOfCDialog::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialog::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: この位置に固有の作成用コードを追加してください
CDC *dc = this->GetDC();
ASSERT(m_Bitmap.LoadBitmap(IDB_CURIELOGO)) ;
ASSERT(m_mDC.CreateCompatibleDC(dc)) ;//メモリデバイスコンテキストを作
成
ASSERT(m_pPrevBitmap = m_mDC.SelectObject(&m_Bitmap)) ;
ASSERT(m_Bitmap.GetBitmap(&m_BitmapStruct)) ;
this->ReleaseDC(dc) ;
return 0;
}
void CDerivationOfCDialog::OnPaint()
{
CPaintDC dc(this); // 描画用のデバイス コンテキスト
dc.BitBlt(0, 0, m_BitmapStruct.bmWidthBytes, m_BitmapStruct.bmHeight,
&m_mDC, 0, 0, SRCCOPY) ;
// 描画用メッセージとして CDialog::OnPaint() を呼び出してはいけません
}
void CDerivationOfCDialog::OnDestroy()
{
CDialog::OnDestroy();
// TODO: この位置にメッセージ ハンドラ用のコードを追加してください
ASSERT(m_mDC.SelectObject(m_pPrevBitmap)) ;
ASSERT(m_Bitmap.DeleteObject()) ;
ASSERT(m_mDC.DeleteDC()) ;
}