描画したBITMAPをオブジェクトとして持つには・・・

[戻る]
モーモー 2003/02/04(火) 13:47:31
度々お世話になっております。

早速質問ですが、
今,裏画面を使ってBITMAPの絵をいっぱい表示する(クリックするたびに)ようにしたのです
が、
貼り付けた絵の一つ一つにIDのような固有名を持たせたく、
また、1つ1つをピックアップできるように、オブジェクト化させたいのですが
どういう実現方法があるのかわかりません。

なにか、いいヒントがあれば教えてください。


開発環境:win98、VC++ver.6.0、SDI

dairygoods 2003/02/04(火) 14:57:56
一番簡単なのは、ビットマップの配列を用意することでしょうか。
この場合、添え字番号がIDになります。

HBITMAP bmps[BITMAP_MAX];

モーモー 2003/02/05(水) 14:15:52
返事遅くなってすみません。

dairygoodsさん、レスありがとうございます。

BITMAP_MAXとありますが、やっぱり個数はある程度限って作った方がいいのでしょうか?
今は、クリックに反応させて何個でもボコボコ絵を表示しているのですが・・・

それと、ちょっと疑問なんですが、この方法では一つ一つを個々の情報を持たすことは可能でも
ピックアップするということはできなくはないですか?

どういうふうに利用すれば良いのかわからないので、
もう少し詳しいヒントをください。
お願いします。

sugar 2003/02/05(水) 14:43:48
モーモーさんの言うピックアップって、どうすることを指すのでしょうか。

らふ 2003/02/05(水) 14:50:33
>BITMAP_MAXとありますが、やっぱり個数はある程度限って作った方がいいのでしょう
か?
配列を定義してしまうならそういうことになります。
可変長にしたいなら std::vector や CArray をつかうといいと思います。

>それと、ちょっと疑問なんですが、この方法では一つ一つを個々の情報を持たす
>ことは可能でもピックアップするということはできなくはないですか?
意味がよくわかりません。どういう風に利用したいのでしょうか?

らふ 2003/02/05(水) 14:51:35
>sugarさん
リロードせずに書き込んだらかぶってしまいました。 すみません <(_ _)>

モーモー 2003/02/05(水) 15:56:07
すみません。。。

えっと、ピックアップする⇒デスクトップにあるアイコンの選択時みたいに、
選択されてますよっていう反応をしたいのですが。。。

n [E-Mail] 2003/02/05(水) 17:15:57
ピックアップ状態にあるビットマップの(配列やvectorやCArrayの)インデックス
を別の変数に保持しておいて、そのビットマップを描画する際には枠を付けて
描くなどすればいいのでは。

dairygoods 2003/02/05(水) 19:59:19
>えっと、ピックアップする⇒デスクトップにあるアイコンの選択時みたいに、
>選択されてますよっていう反応をしたいのですが。。。

つまり、各ビットマップに選択されている/いないの状態が必要ということですね。
複数の情報をまとめて扱いたい時は構造体を利用するのがよいでしょう。

struct BitmapInfo
{
  HBITMAP hbmp;
  BOOL selected;
};
BitmapInfo bmps[BITMAP_MAX];

kazuma 2003/02/06(木) 00:28:20
クラスにしてみてもいいでしょうね。
class CItem
{
private:
    HBITMAP m_hBmp;
    bool m_fSelected;
    CRect m_rect;  // 描画位置
public:
    void Draw(CDC *pDC); // 描画
    bool HitTest(CPoint pt);
    void Select(bool fSelect);
};

kazuma 2003/02/06(木) 00:28:20
クラスにしてみてもいいでしょうね。
class CItem
{
private:
    HBITMAP m_hBmp;
    bool m_fSelected;
    CRect m_rect;  // 描画位置
public:
    void Draw(CDC *pDC); // 描画
    bool HitTest(CPoint pt);
    void Select(bool fSelect);
};

モーモー 2003/02/19(水) 09:01:58
またまたこのログを引っ張り出して、すみませんm(__)m

まだ一つひっかかっていることがあるので、もうすこしお付き合いください。
ItemクラスのDraw関数とSelect関数は大体わかったので
HitTest関数をもう少し具体的に教えていただきたいです。。。

どの絵にマウスがあるかないかをチェックする時というのは、
構造体の配列に溜めたrect内にマウスがあるか(m_rect.PtInRect(pt) == 0こんなの?)
でチェックすると思うんですけど、溜めた分だけfor分などでループさせるのでしょうか?
上のログにもあるように、何個の絵を描くかは決まってないので、
できれば、ループじゃなく一気にチェックしたいんですけど、可能でしょうか?
可能でしたら、どのような実現方法があるか教えてください。


よろしくお願いします。

επιστημη 2003/02/19(水) 09:33:45
> 構造体の配列に溜めたrect内にマウスがあるか(m_rect.PtInRect(pt) == 0こんなの?)
> でチェックすると思うんですけど、溜めた分だけfor分などでループさせるのでしょうか?

なにか不都合があるのかしら?

class in_rect {
  CPoint pt_;
  in_rect(CPoint p) : pt_(p) {}
  bool operator()(const CItem& item) const {
    return item.HitTest(pt_);
  }
};

CItem pictures[N];
int pics; // picturesに格納されたビットマップ数
CPoint mouse_position; // マウスの位置
CItem* found = std::find(pictures, pictures+pics, in_rect(mouse_position));
if ( found != pictures+pics ) {
  // 見つけた!
}

モーモー 2003/02/19(水) 11:13:51
早速、レスを返していただきありがとうございます。

あのー、すごくトンチンカンな質問かもしれませんが、、、
std::find(******)っていうのは、MFC環境でも使えるのでしょうか?
MSDNで検索したところ、STLサンプルしか出てこなかったので・・・

>なにか不都合があるのかしら?
いえ、不都合っていうほどじゃないですが、
上の記述通り複数の絵があり、しかも何個かは決めてないので、
ループさせるとどんどん重くなるんじゃないかという心配をしているだけです。

επιστημη 2003/02/19(水) 13:22:57
> std::find(******)っていうのは、MFC環境でも使えるのでしょうか?

使えます。

> 上の記述通り複数の絵があり、しかも何個かは決めてないので、
> ループさせるとどんどん重くなるんじゃないかという心配をしているだけです。

'複数の絵'っていくつくらいでしょう?
高々数百程度ならばループを回したところでどうってことないのでは?

dairygoods 2003/02/19(水) 13:33:51
> ループさせるとどんどん重くなるんじゃないかという心配をしているだけです。

std::find()を使えば、見た目は一気に出来ているように見えますが、
内部でループしていますので同じ事です。

複数の項目を全て調べる処理はループせずに記述することはできません。

επιστημη 2003/02/19(水) 14:00:25
> 複数の項目を全て調べる処理はループせずに記述することはできません。

いや、モーモーさんの意図としては
"全件検索せずとも見つける手段はないのか?" ってことじゃないかしら?

座標位置でソートしておけば検索対象の'絞込み'ができるでしょう。

モーモー 2003/02/19(水) 14:04:08
そういうことでしたか・・・
納得です。ありがとうございます。

とりあえず、やってみます。

モーモー 2003/02/19(水) 14:26:08
すみません。。。
std::find()の引数ってなんですか?
MSDNで検索したんですけど、出てこないです(T_T)

それと、CItemクラスのHitTest関数は結局のところ、なんて書けばいいんでしょうか?

やっぱり、理解力が無さ過ぎて先に進めなかったです・・・
ごめんなさい。

επιστημη 2003/02/19(水) 15:04:20
> std::find()の引数ってなんですか?
> MSDNで検索したんですけど、出てこないです(T_T)

ごめんなさい'ちょんぼ'です。 findじゃなくfind_ifが正解。
# find_if なら MSDNの検索にヒットすると思う。

> それと、CItemクラスのHitTest関数は結局のところ、なんて書けばいいんでしょうか?

  bool CItem::HitTest(CPoint pt) const {
    ptがm_rectの領域内にあればtrueを返す
  }

επιστημη 2003/02/19(水) 15:09:42
...ってゆーか、std::findがわかんなかったら
いつも使い慣れたfor-loopでぶん回ればいいんじゃないですか?

for ( i = 0; i < N; ++i ) {
  if ( ptがi番目のCItem上にある ) {
    見つかった!
    break;
  }
}

モーモー 2003/02/19(水) 15:16:10
!
そうですね、結局のところループしてるんだったら、for文でも同じことですもんね。
一気にできるかと思って質問したんですけど、、、
わかりました。

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

モーモー 2003/02/21(金) 15:33:47
[[解決]]
レスをくださった皆様、本当にありがとうございます。
どうにかPickup処理は完成しました。

また、行き詰まると質問しにきますので、その時はよろしくお願いしますm(__)m

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