動的に作成したビットマップへの描画

[戻る]
ター坊 2004/04/28(水) 11:58:11
初めて質問させていただきます。

今作成しているアプリケーションで
ビットマップをリソースやファイルとして
持たずに動的にCreateし、そのCreateした
ビットマップをCImageListに追加し、
そのCImageListをツールバーにわりあてることによって
ツールバーのボタンイメージとして
使おうと思っています。

そのため、
CBitmapの
CreateBitmap()
ないし
CreateCompatibleBitmap()
で作成したビットマップオブジェクトに
CDCのクラスメンバで定義されているような
単純描画関数を使って描画をしたいのですが
その方法がわかりません。

どなたかご存知の方がいらっしゃいましたら
知恵をお貸しください。

開発環境はWindows XP Professional 
VC++ 6.0 SP6 MFC(EXE)  です。

よろしくお願いいたします。

シャノン 2004/04/28(水) 12:55:08
以前どこかで見た例えなのですが、DC がキャンバスでビットマップが画用紙(でしたっ
け?)に相当します。
ビットマップ(画用紙)に絵を描くには、まずビットマップを DC に選択(キャンバス
に乗せる)します。
あとは、その DC に対して描画関数を呼んでやればよい…はずです。

CBitmap::CreateCompatibleBitmap の引数に指定した CDC の CreateCompatibleDC メソ
ッドを呼んで、互換性のあるメモリデバイスコンテキストを作成します。
そこに CDC::SelectObject でビットマップを選択する。
GDI 描画の常套手段ですね。

#ちなみにペンは画用紙の上に線を引いたり文字を書く色鉛筆、ブラシは画用紙を塗る
#絵の具、フォントは文字の書体や大きさ、パレットはそのままパレットですね。
#あと GDI オブジェクトといえば…リージョン。あれは…マスキングテープ?(なんか
違う

n 2004/04/28(水) 13:18:50
あー…いや、DCは「画家」と言った方がいいと思います。
LineTo()等の「絵を描く技能」を持っているのがDC、で、ビットマップが画用紙と。
(横槍失礼しました)

PATIO 2004/04/28(水) 13:31:10
DC   −> 画家
Bitmap −> キャンバス、又は画用紙
GDI   −> 画材

画家(DC)にキャンバス(Bitmap)を渡して画材(GDI)で絵を書いてもらうと。

この例えわかりやすくてグッドです。

ター坊 2004/04/30(金) 17:28:33
[[解決]]
シャノンさん、nさん、PATIOさん、
回答ありがとうございます。

教えていただいた手順で処理することで
動的にビットマップを作成し、
それをボタンイメージとして
使うことができました。

ありがとうございました。

//呼び出し側
int CMyToolBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
  ・
  ・(省略)
  ・
  //通常時のイメージを作成
  m_ImageListCold.Create(30, 30, ILC_COLOR24, 104, 110);
  MakeButtonImage(m_ColdButton, (COLORREF)0x000000);
  m_ImageListCold.Add(&m_ColdButton, (COLORREF)0xFFFFFF);
  ToolCtrl.SetImageList(&m_ImageListCold);

  //マウスカーソルがあたっている時のイメージを作成
  m_ImageListHot.Create(30, 30, ILC_COLOR24, 104, 110);
  MakeButtonImage(m_ColdButton, (COLORREF)0xFFFFFF);
  m_ImageListCold.Add(&m_ColdButton, (COLORREF)0xFFFFFF);
  ToolCtrl.SetHotImageList(&m_ImageListHot);

  //無効時のイメージを作成
  m_ImageListDisable.Create(30, 30, ILC_COLOR24, 104, 110);
  MakeButtonImage(m_ColdButton, (COLORREF)0x808080);
  m_ImageListCold.Add(&m_ColdButton, (COLORREF)0xFFFFFF);
  ToolCtrl.SetDisabledImageList(&m_ImageListDisable);
  ・
  ・(省略)
  ・
}

//描画関数
void CMyToolBar::MakeButtonImage(CBitmap & Bitmap, COLORREF btColor)
{
  CDC dc;

  CBitmap * oldBmp = NULL;
  CDC * pDC = GetDC();
  CRect bmpRect(0, 0, 30 * m_BtNum, 30);
  CBrush bkBrush(btColor);

  dc.CreateCompatibleDC(pDC);

  //m_nButtonNumはint型変数
  Bitmap.CreateCompatibleBitmap(pDC, bmpRect.Width(), bmpRect.Height());
    
  oldBmp = dc.SelectObject(&Bitmap);
    
  //以下、dcに対して描画・・・・

  ・
  ・(省略)
  ・

  dc.SelectObject(oldBmp);
  ReleaseDC(pDC);
}

ター坊 2004/04/30(金) 17:33:09
・・・まちがえちゃった。
正しくは以下です。

//呼び出し側
int CMyToolBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
  CToolBarCtrl & ToolCtrl = GetToolBarCtrl();
  ・
  ・(省略)
  ・
  //通常時のイメージを作成
  m_ImageListCold.Create(30, 30, ILC_COLOR24, 104, 110);
  MakeButtonImage(m_ColdButton, (COLORREF)0x000000);
  m_ImageListCold.Add(&m_ColdButton, (COLORREF)0xFFFFFF);
  ToolCtrl.SetImageList(&m_ImageListCold);

  //マウスカーソルがあたっている時のイメージを作成
  m_ImageListHot.Create(30, 30, ILC_COLOR24, 104, 110);
  MakeButtonImage(m_HotButton, (COLORREF)0xFFFFFF);
  m_ImageListHot.Add(&m_HotButton, (COLORREF)0xFFFFFF);
  ToolCtrl.SetHotImageList(&m_ImageListHot);

  //無効時のイメージを作成
  m_ImageListDisable.Create(30, 30, ILC_COLOR24, 104, 110);
  MakeButtonImage(m_DisableButton, (COLORREF)0x808080);
  m_ImageListDisable.Add(&m_DisableButton, (COLORREF)0xFFFFFF);
  ToolCtrl.SetDisabledImageList(&m_ImageListDisable);
  ・
  ・(省略)
  ・
}

3倍移動 2004/04/30(金) 18:53:34
遅レスだけど、
DC自体は只のハンドルで何もしてくれないのでキャンバスだと思うけど?
CDCなら画家で納得。

シャノン 2004/04/30(金) 21:17:44
じゃあ、HDC はキャンバス、GDI API はキャンバスを持っていない画家、
CDC はキャンバスを用意してくれる画家。

…なんか GDI API がショボい。

3倍移動 2004/05/01(土) 02:17:44
>GDI API はキャンバスを持っていない画家、
HDCを渡されて初めて仕事が出来るので全く違和感無いです。

n 2004/05/01(土) 08:46:10
伸ばしてすいません。

>DC自体は只のハンドルで何もしてくれないのでキャンバスだと思うけど?
>CDCなら画家で納得。
CDCは単なるHDCのラッパですし(CDCの方が多少細かい仕事ができますが)、
またHDCもCDCもビットマップが選択されてなければ描画できない(されない)ですし、
描画の結果が残るのはビットマップの上ですし、
HDC/CDCが画家でビットマップが画用紙でいいんじゃないかなぁ…と。(^^;

とおり 2004/05/02(日) 11:08:49
> CDCは単なるHDCのラッパですし(CDCの方が多少細かい仕事ができますが)、

ただのラッパといえばラッパだけど、上で3倍移動さんが言っているのは、
HDCは本当にただのハンドルなのに対して、クラスであるCDCは、HDCだけでなく、
GDIを使ってBitmapに作用を及ぼす関数群も一緒にラッピングして取り込んでいる
という点が違うと言っているのでは?

PATIO 2004/05/06(木) 11:40:41
かなり細かい話になっていますねぇ。

概念的には、最初のものでもおおはずれではないと思いますけれど。
HDCとは言ってませんから。
DCはデバイスコンテキストですからデバイスによる差分を吸収する部分ですよね。
デバイスコンテキストが画家でも例えとしては問題ないと思いますよ。

古いスレッドには追加発言できません。