CBitmapButtonを継承してマウスオーバー時に画像を変化させるようにする。
Posted on Sun 30 August 2009 in Windows
デフォルトのCBitmapButtonだとマウスオーバー時の画像を読み込んで
表示させてくれないので、CBitmapButtonを継承して機能を付け足しました。
Create()で作成して、LoadBitmapsで画像を読み込みます。
その他のAutoLoadなどには対応していません。
ヘッダー
#pragma once
class CHoverBitmapButton :
public CBitmapButton
{
public:
CHoverBitmapButton() : m_isHover(false) {};
~CHoverBitmapButton(){};
BOOL LoadBitmaps(
UINT nIDBitmapResource,
UINT nIDBitmapResourceHov,
UINT nIDBitmapResourceSel=0,
UINT nIDBitmapResourceFocus=0,
UINT nIDBitmapResourceDisabled=0);
void DrawItem(LPDRAWITEMSTRUCT lpDis);
protected:
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
LRESULT OnMouseHover(WPARAM wp, LPARAM lp);
LRESULT OnMouseLeave(WPARAM wp, LPARAM lp);
DECLARE_MESSAGE_MAP();
private:
bool m_isHover;
CBitmap m_bitmapHov;
};
ソース
LoadBitmapsは、読み込み時に呼ばれる関数です。
一つリソースIDを受け取る引数を増やして、画像をリソースから読み込んでいます。
OnMouseMove()が呼び出されたときに、
WM_MOUSEHOVERとWM_MOUSELEAVEメッセージが来るように、
TrackMouseEvent()を呼び出しています。
DrawItem()は、描画時に呼ばれる関数です。
DrawItem()内では、マウスオーバー時、ボタンが押されていなければ、
読み込んだ画像を表示させています。
#include "HoverBitmapButton.h"
BOOL CHoverBitmapButton::LoadBitmaps(
UINT nIDBitmapResource,
UINT nIDBitmapResourceHov,
UINT nIDBitmapResourceSel,
UINT nIDBitmapResourceFocus,
UINT nIDBitmapResourceDisabled)
{
m_bitmapHov.DeleteObject();
if(!m_bitmapHov.LoadBitmap(nIDBitmapResourceHov)){
return FALSE;
}
return CBitmapButton::LoadBitmaps(
nIDBitmapResource,
nIDBitmapResourceSel,
nIDBitmapResourceFocus);
}
void CHoverBitmapButton::DrawItem(LPDRAWITEMSTRUCT lpDis)
{
if(m_isHover && !(lpDis->itemState & ODS_SELECTED)){
CDC* pDC = CDC::FromHandle(lpDis->hDC);
CDC memDC;
memDC.CreateCompatibleDC(pDC);
CBitmap* pOld = memDC.SelectObject(&m_bitmapHov);
if (pOld == NULL)
return; //destructors will clean up
CRect rect;
rect.CopyRect(&lpDis->rcItem);
pDC->BitBlt(rect.left, rect.top, rect.Width(), rect.Height(),
&memDC, 0, 0, SRCCOPY);
memDC.SelectObject(pOld);
}
else{
CBitmapButton::DrawItem(lpDis);
}
}
BEGIN_MESSAGE_MAP(CHoverBitmapButton, CBitmapButton)
ON_WM_MOUSEMOVE()
ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
END_MESSAGE_MAP()
void CHoverBitmapButton::OnMouseMove(UINT nFlags, CPoint point)
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.dwFlags = TME_HOVER | TME_LEAVE;
tme.hwndTrack = this->GetSafeHwnd();
tme.dwHoverTime = 1;
::TrackMouseEvent(&tme);
CBitmapButton::OnMouseMove(nFlags, point);
}
LRESULT CHoverBitmapButton::OnMouseHover(WPARAM wp, LPARAM lp)
{
m_isHover = true;
this->Invalidate(FALSE);
return FALSE;
}
LRESULT CHoverBitmapButton::OnMouseLeave(WPARAM wp, LPARAM lp)
{
m_isHover = false;
this->Invalidate(FALSE);
return FALSE;
}
参考URL