Introduction
I wrote this many years ago for a friend. It is basically just a normal pushbutton, except that when the user tries to click on it, it moves out of the way making it practically un-clickable.
I have no idea what anyone would ever want to use such a control in their app, apart from wanting to be extremely annoying to users (and hey - don't we all get like that on occasion?) :)
The button is just a normal button with OnMouseMove
overridden: (m_nJumpDistance
is the distance in pixels to jump once the mouse has moved over the control).
The WM_SETFOCUS
message has also been handled to bounce the focus back to the window that previously had focus, and PreSubclassWindow
has been overridden to allow the removal of the WS_TABSTOP
window style bit. This ensures that the user can't tab to the control.
The guts of it all
void CTrickButton::OnMouseMove(UINT nFlags, CPoint point)
{
CWnd* pParent = GetParent();
if (!pParent) pParent = GetDesktopWindow();
CRect ParentRect; pParent->GetClientRect(ParentRect);
ClientToScreen(&point); pParent->ScreenToClient(&point);
CRect ButtonRect; GetWindowRect(ButtonRect);
pParent->ScreenToClient(ButtonRect);
CPoint Center = ButtonRect.CenterPoint();
CRect NewButtonRect = ButtonRect;
if (point.x > Center.x) {
if (ButtonRect.left > ParentRect.left + ButtonRect.Width() + m_nJumpDistance)
NewButtonRect -= CSize(ButtonRect.right - point.x + m_nJumpDistance, 0);
else
NewButtonRect += CSize(point.x - ButtonRect.left + m_nJumpDistance, 0);
}
else if (point.x < Center.x) {
if (ButtonRect.right < ParentRect.right - ButtonRect.Width() - m_nJumpDistance)
NewButtonRect += CSize(point.x - ButtonRect.left + m_nJumpDistance, 0);
else
NewButtonRect -= CSize(ButtonRect.right - point.x + m_nJumpDistance, 0);
}
if (point.y > Center.y) {
if (ButtonRect.top > ParentRect.top + ButtonRect.Height() + m_nJumpDistance)
NewButtonRect -= CSize(0, ButtonRect.bottom - point.y + m_nJumpDistance);
else
NewButtonRect += CSize(0, point.y - ButtonRect.top + m_nJumpDistance);
}
else if (point.y < Center.y) {
if (ButtonRect.bottom < ParentRect.bottom - ButtonRect.Height() - m_nJumpDistance)
NewButtonRect += CSize(0, point.y - ButtonRect.top + m_nJumpDistance);
else
NewButtonRect -= CSize(0, ButtonRect.bottom - point.y + m_nJumpDistance);
}
MoveWindow(NewButtonRect);
RedrawWindow();
CButton::OnMouseMove(nFlags, point);
}
void CTrickButton::OnSetFocus(CWnd* pOldWnd)
{
CButton::OnSetFocus(pOldWnd);
if (pOldWnd!=NULL && ::IsWindow(pOldWnd->GetSafeHwnd()))
pOldWnd->SetFocus();
}
void CTrickButton::PreSubclassWindow()
{
ModifyStyle(WS_TABSTOP, 0);
CButton::PreSubclassWindow();
}
History
31 May 2002 - updated to include removal of WM_TABSTOP
, plus minor cleanup.
Chris Maunder is the co-founder of
CodeProject and
ContentLab.com, and has been a prominent figure in the software development community for nearly 30 years. Hailing from Australia, Chris has a background in Mathematics, Astrophysics, Environmental Engineering and Defence Research. His programming endeavours span everything from FORTRAN on Super Computers, C++/MFC on Windows, through to to high-load .NET web applications and Python AI applications on everything from macOS to a Raspberry Pi. Chris is a full-stack developer who is as comfortable with SQL as he is with CSS.
In the late 1990s, he and his business partner David Cunningham recognized the need for a platform that would facilitate knowledge-sharing among developers, leading to the establishment of CodeProject.com in 1999. Chris's expertise in programming and his passion for fostering a collaborative environment have played a pivotal role in the success of CodeProject.com. Over the years, the website has grown into a vibrant community where programmers worldwide can connect, exchange ideas, and find solutions to coding challenges. Chris is a prolific contributor to the developer community through his articles and tutorials, and his latest passion project,
CodeProject.AI.
In addition to his work with CodeProject.com, Chris co-founded ContentLab and DeveloperMedia, two projects focussed on helping companies make their Software Projects a success. Chris's roles included Product Development, Content Creation, Client Satisfaction and Systems Automation.