オーナードローって何ですか?おいしいんですか?


さて、MFCのCButtonBitmapの実装をヒントにCButtonのオーナードローをさくせいちゅう。
ボタンの上にマウスあわせると貼り付けたビットマップが変わるようなやつ。
これめんどくさいわー。MSDN見ても実際試してみないとわかんなかったし。
GetSafeHandle()ってこれthis==NULL判定を内部で使ってたのか。
キモイので使うのやめようw(良い子は使ってください。)
まぁ実体の無い状態でm_hWnd触るのは良くないけど
どうせそんな状況になった時はバグでしょうし(^-^;
あとボタンの凹凸も自分で書いてやらないといけない。
処理入れてもビットマップだとボタン押したときの凹凸が微妙に判りにくかった。
なんかもっと良いGUIライブラリないかなー?
とりあえずマウスオーバーイベントの拾い方が結構苦戦したのでメモ。


BEGIN_MESSAGE_MAP(CButtonMouseOverBitmap, CButton)
ON_WM_MOUSEMOVE()
ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
END_MESSAGE_MAP()

上記3つのイベントを受け取れるようにする。


void CButtonMouseOverBitmap::OnMouseMove(UINT nFlags, CPoint point)
{
if (!m_MouseEnterdCtrl) // マウスがボタンの上を動いてる間よばれるので
{ // 一度通知したらマウスが抜けるまではTrackMouseEventを呼ばない
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.hwndTrack = m_hWnd;
tme.dwFlags = TME_LEAVE | TME_HOVER;
tme.dwHoverTime = 1;
m_MouseEnterdCtrl = _TrackMouseEvent(&tme); // マウスがボタンの上に入ったか出たかの
// メッセージを受けれるようにする。
}
CButton::OnMouseMove(nFlags, point); // これはたぶん呼ばなくても良い
}

LRESULT CButtonMouseOverBitmap::OnMouseHover(WPARAM /*wparam*/, LPARAM /*lparam*/)
{
m_hover = TRUE;// マウスがボタンの上にある間はTRUE
Invalidate(); // これを呼ばないと誤動作した理由はまだ不明。
return FALSE;
}

LRESULT CButtonMouseOverBitmap::OnMouseLeave(WPARAM /*wparam*/, LPARAM /*lparam*/)
{
m_hover = FALSE; //マウスがボタンの上から出たのでFALSE
m_MouseEnterdCtrl = FALSE; // 再度ボタンの上にマウスが来たときに通知を受けれるようにする
Invalidate(); // これを呼ばないと誤動作した理由はまだ不明。
return FALSE;
}

OnMouseHoverとOnMouseLeaveでInvalidateを呼ばないと
クリックした時にしか表示が代わらなかったのが一番はまったー。
あんまりInvalidate関数を呼ぶようにしてるサイトが無かったしなぁ。
なんかプロパティの設定とかし忘れてたのかな?