Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Enfekted

Rollover Button in MFC

This topic is 5318 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I was hoping someone here could help me. I'm trying to create a menu system for my game and I've run into a couple of snags. I'd like to use a dialog with the draw commands overloaded to create a graphic menu. Everything has worked fine so far until I got to the rollover buttons. Ideally, I would like my button class (CHotButton) to set m_CurrentState=0 when the button is UP, m_CurrentState=1 when the mouse is over the button (not necessarily having focus), and m_CurrentState=2 when the left mouse button is pressed while over the button. I've overloaded the CButton class, but I can't figure out how to determine if the mouse has moved out of the button's client area to return the button to the original state. I'll post what I have so far.
// HotButton.h


class CHotButton : public CButton
{
	DECLARE_DYNAMIC(CHotButton)

public:
	CHotButton();
	virtual ~CHotButton();

	BOOL LoadBitmaps( UINT nIDUp, UINT nIDOver=0, UINT nIDDown=0 );
	
protected:
	DECLARE_MESSAGE_MAP()
	
private:
	CBitmap m_BMP[3];
	UINT m_CurrentState;
public:
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnPaint();
};
// HotButton.cpp


IMPLEMENT_DYNAMIC(CHotButton, CButton)
CHotButton::CHotButton()
{
	m_CurrentState = 0;
}

CHotButton::~CHotButton()
{
}

BEGIN_MESSAGE_MAP(CHotButton, CButton)
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONDOWN()
	ON_WM_PAINT()
END_MESSAGE_MAP()

BOOL CHotButton::LoadBitmaps( UINT nIDUp, UINT nIDOver, UINT nIDDown )
{
	if ( !nIDOver ) nIDOver = nIDUp;
	if ( !nIDDown ) nIDDown = nIDUp;

	if ( !m_BMP[0].LoadBitmap( nIDUp ) ) return FALSE;
	if ( !m_BMP[1].LoadBitmap( nIDOver ) ) return FALSE;
	if ( !m_BMP[2].LoadBitmap( nIDDown ) ) return FALSE;

return TRUE;
}

// CHotButton message handlers

void CHotButton::OnMouseMove(UINT nFlags, CPoint point)
{
	m_CurrentState = 1;
	InvalidateRect( NULL );

	CButton::OnMouseMove(nFlags, point);
}

void CHotButton::OnLButtonDown(UINT nFlags, CPoint point)
{
	m_CurrentState = 2;
	InvalidateRect( NULL );

	CButton::OnLButtonDown(nFlags, point);
}

void CHotButton::OnPaint()
{
	CPaintDC dc(this); // device context for painting

	CDC dcMemory;
	CRect r;
	
	dcMemory.CreateCompatibleDC( &dc );
	dcMemory.SelectObject( m_BMP[m_CurrentState] );
	
	GetClientRect( &r );
	dc.BitBlt( 0, 0, r.Width(), r.Height(), &dcMemory, 0, 0, SRCCOPY );		
}
Any help would be greatly appreciated. Thanks in advance. [edited by - enfekted on February 29, 2004 1:29:40 PM]

Share this post


Link to post
Share on other sites
Advertisement
The following code is an example of how to do rollover buttons. First it checks if the mouse pointer was in the client area of the button, then it checks if it is in the button now. If the mouse pointer status has changed with regards to the button, one of the two booleans will be false and the other will be true.


//GLOBALS


//CPoint to hold mouse coordinates

CPoint ptMouse;

void CHotButton::OnMouseMove(UINT nFlags, CPoint point)
{
//CRect to hold client area of rectangle

CRect clientArea;
this->GetClientRect(&clientArea);

//bool to tell if mouse is inside rect

bool InRect = false;
//bool to tell if mouse moved inside rect

bool MovedInRect = false;

//check if mouse is in rect

if (ptMouse.x > clientArea.left &&
ptMouse.x < clientArea.right &&
ptMouse.y > clientArea.top &&
ptMouse.y < clientArea.bottom)
{
InRect = true;
}

ptMouse = point;

//check if mouse moved inside rect

if (ptMouse.x > clientArea.left &&
ptMouse.x < clientArea.right &&
ptMouse.y > clientArea.top &&
ptMouse.y < clientArea.bottom)
{
MovedInRect = true;
}

//check if it needs to redraw

if ((InRect == false && MovedInRect == true) ||
(InRect == true && MovedInRect == false))
{
Invalidate();
}
}

Hope this helps!

Share this post


Link to post
Share on other sites
Thanks for your input the_dannobot. You''re correct as far as determining if the mouse is over the button. Unfortunatly, OnMouseMove() will only be called if the mouse is over the button.

I am having problems determining if the mouse is not over the window. There doesn''t seem to be anything in MFC that is similar to Javascript''s OnMouseOut() function, therfore I have no way of changing the button''s state back to normal (Up).

Share this post


Link to post
Share on other sites
You can get a OnMouseLeave call, but you do it in kind of an odd fashion. In your OnMouseMove add this:


::TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(::TRACKMOUSEEVENT);
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = m_hWnd;
tme.dwHoverTime = HOVER_DEFAULT;
::_TrackMouseEvent( &tme );


Then just implement the OnMouseLeave function and you should be good to go

-John

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!