|
The article does not have any content nor is anything explained.
|
|
|
|
|
And come to think of it neither do you - go back to hole where thou came from.
|
|
|
|
|
You are a son of a bitch! Mind your language you dick head. If you cannot write good articles stop posting.
|
|
|
|
|
Sheetal_Joshi wrote: You are a son of a bitch! Mind your language you dick head
Okay there, seems somebody needs to take their medication.
Sheetal_Joshi wrote: If you cannot write good articles stop posting.
Jeez I stopped along time ago, thanks to sh*ts like you.
Anyway I eagerly awaiting to see YOUR article, although I could be waiting a long time.
|
|
|
|
|
I dont like how the author flames other developers for no reason other than to be cruel.
|
|
|
|
|
How stupid?! The voting should be based on the quality of the article and not based on how the author communicates with someone else.
It is a crappy thing, but it's life -^ Carlo Pallini
|
|
|
|
|
It was a conflct when somebody else and you've taken up the right to join in, well feel free.
|
|
|
|
|
|
Hi,
Your work offers a great help in my project. Thank you very much.
However, i faced a problem: mislocation of the button when my project is run and tested on other PC.
Scenario:
i created a button in the OnInitialUpdate() and place it on a FormView.
RECT stRect;
stRect.left = 0+454;
stRect.top = 0+197;
stRect.right = 454+74;
stRect.bottom = 197+23;
CRect rect1(stRect);
m_btn.Create("&Settings", WS_TABSTOP | WS_CHILD |WS_VISIBLE, rect1 ,this,IDC_SETTING);
Problem:
When this program is run on other PC, the button is no longer at the place i desired. It jumps to other location! why?
I've tested on windows resolution, but doesn't solve the prolem.
Please advice. Thank you!
|
|
|
|
|
This control was almost exactly what I needed for an application I'm working on. However, I've made a couple of minor additions to the code:
1) By default, the left side of the menu is aligned with the left side of the button. Since this looks a little strange in cases where the button is wider than the menu, I've added a method to specify whether the menu should be right- or left-aligned.
2) Added a method to set a callback function to dynamically create the menu, if desired. (I notice this has already been done by others, but isn't included in the source code from this site)
3) Added a method to set a callback function for handling menu selections, rather than using window messages.
I felt that these changes increased the flexibility of what is already an excellent control . The mods are easy enough to make, but if you want the source just drop me an email.
Cheers,
Dion Campbell
|
|
|
|
|
I've made a few small additions to the code:
- Using OBM_COMBO bitmap arrow
- Enabled use of popup menu resource
- Popup menu using keyboard (VK_DOWN)
The modified project is here: http://www.code.trak.dk
|
|
|
|
|
|
In AddImage the line
ASSERT( m_menu.SetMenuItemBitmaps( nIndex, MF_BYPOSITION, &bmpEnabled, &bmpDisabled ) );
should be
VERIFY( m_menu.SetMenuItemBitmaps( nIndex, MF_BYPOSITION, &bmpEnabled, &bmpDisabled ) );
Best wishes,
Hans
|
|
|
|
|
I have also added two new features to this class: a callback function, which allows you to load the menu at the time the menu is being dropped (for example, for a Back button); and the ability to load the menu from a resource id.
Please let me know if you want me to email the source to you - the CP email form does not allow attachments.
Best wishes,
Hans
hdietrich2@hotmail.com
|
|
|
|
|
Hans
Feel free to email the source I will include and update the article occordingly
|
|
|
|
|
What is your email address? I cannot email via CodeProject - the email form does not allow attachments.
|
|
|
|
|
well, this article should be well descriptive for the beginners. try improving it!!
Muhammad Shoaib Khan
http://geocities.com/lansolution
|
|
|
|
|
Eat my shorts...
|
|
|
|
|
Well, I have looked very much around to find a menu button implementation. This one has following weak points:
- Not visually definable
- Not very well isolated
- Not reusable across applications
Derek Lakin seems to spend much more time on this subject.
See: http://www.salamandersoftware.biz/products/cbuttonssl.htm
CButtonSSL has these advantages:
- Visually definable
- You can define your menu in the VC menu editor with flyouts, check marks etc.
- In completely isolated and reusable class form
- plus much more extras
Suha Aktan
|
|
|
|
|
So - go and use the other button - I'm really not interested on what you think.
|
|
|
|
|
Please do not take it personally, Normski.
My aim is to suggest an alternative to the public.
Let's make peace
|
|
|
|
|
Sorry for being -ne (that's negative) I get a lot of folks saying "if it could just do that" or "these a bug - fix it", one reason why I didn't post updates or fixes to all of my articles.
Apologies accepted!
|
|
|
|
|
but i don't see any support for winxp themeing
and before you say this one neither, watch the thread below
|
|
|
|
|
I fixed up CCoolBtn (as CCoolButton) to work with themes on Win/XP. I also added the ability to have the button only work as a Menu Button (no split) and to have a 2nd ID for the down-arrow part rather than an attached menu. Enjoy.
Leigh Brasington
/* >>>>>>>>>>>>>>>>>>> Here's the CoolButton.h file <<<<<<<<<<<<<<<<<<<< */
#if !defined(AFX_CoolButton_H__3A90681F_CE5F_11D3_808C_005004D6CF90__INCLUDED_)
#define AFX_CoolButton_H__3A90681F_CE5F_11D3_808C_005004D6CF90__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// CoolButton.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CCoolButton window
class CCoolButton : public CButton
{
// Construction
public:
CCoolButton();
BOOL SetIDs(UINT nID1, UINT m_nID2);
BOOL AddMenuItem(UINT nMenuId,const CString strMenu, UINT nMenuFlags);
BOOL SetButtonImage(UINT nResourceId, COLORREF crMask);
void SetSplit(BOOL b) { m_bSplit = b && (m_bMenuLoaded || m_nID2); }
void SetAsDefaultBtn(BOOL b) { m_bDefaultBtn = b; }
void ClearButtonPushed();
// Attributes
protected:
CMenu m_menu;
CBitmap m_btnImage;
CImageList m_IL;
BOOL m_Initialized;
BOOL m_bPushed;
BOOL m_bMenuPushed;
BOOL m_bMenuLoaded;
BOOL m_bLoaded;
BOOL m_bDefaultBtn;
BOOL m_bActAsDefaultBtn;
BOOL m_bSplit;
BITMAP m_bm;
UINT m_nID1;
UINT m_nID2;
COLORREF m_crMask;
HBITMAP m_hbmpDisabled;
HMODULE m_themeLib; // handle to UxTheme.dll
BOOL m_bOverControl; // is the mouse over us?
BOOL m_bTracking; // are we tracking the mouse
// Operations
public:
protected:
void DrawArrow(CDC* pDC,CPoint ArrowTip);
BOOL HitMenuBtn(CPoint point);
BOOL OnMenuBtn();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CCoolButton)
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CCoolButton();
// Generated message map functions
protected:
//{{AFX_MSG(CCoolButton)
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnSetFocus(CWnd* pOldWnd);
afx_msg void OnKillFocus(CWnd* pNewWnd);
afx_msg void OnSysColorChange();
afx_msg void OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg UINT OnGetDlgCode();
afx_msg LRESULT OnMouseHover(WPARAM wparam, LPARAM lparam);
afx_msg LRESULT OnMouseLeave(WPARAM wparam, LPARAM lparam);
afx_msg LRESULT OnSetStyle(WPARAM wParam, LPARAM lParam);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_CoolButton_H__3A90681F_CE5F_11D3_808C_005004D6CF90__INCLUDED_)
/* >>>>>>>>>>>>>>>>>>> Here's the CoolButton.cpp file <<<<<<<<<<<<<<<<<<<< */
// CoolButton.cpp : implementation file
//
#include "stdafx.h"
#include "p4win.h"
#include "CoolBtn.h"
#if _MFC_VER >= 0x0700
#define USE_THEMES
#include <uxtheme.h>
#endif
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
const int nDropBtnWidth = 16;
/////////////////////////////////////////////////////////////////////////////
// CCoolButton
// ========
//
// To Use:
// 1. In the RC file, create the button as BS_OWNERDRAW.
// Optionally, create a Bitmap resource 16x15 Pixels
// - normal default size for a toolbar bitmap.
//
// 2. in the header for the dialog class:
// #include "CoolBtn.h"
// then create the necessary button widgets in the //{{AFX_DATA() section:
// CCoolButton m_DblBtn;
//
// 3. In the InitDialog() for the dialog:
//
// a) Optionally, Call SetButtonImage specificing the
// Transparency color reference.
// (Usally RGB(255, 0, 255) magenta)
// m_DblBtn.SetButtonImage(IDC_BTNIMAGE, RGB(255,0,255));
//
// b) Either call CCoolButton's SetIDs function:
// m_DblBtn.SetIDs(IDC_BTNPUSH, IDC_BTNMENU);
// the first ID must be the same as the ID in the RC file!
// --or--
// Add menu item(s) to the button:
// m_DblBtn.AddMenuItem(nMenuId1, strMenu1, nMenuFlags1);
// m_DblBtn.AddMenuItem(nMenuId2, strMenu2, nMenuFlags2);
//
// If you do both SetIDs() and AddMenuItem()s, only the AddMenuItem
// will be called and the second ID will be ignored.
//
// c) Optionally, call CCoolButton's show split function:
// m_DblBtn.SetSplit(bSplit);
// The default is to show the split (TRUE). If set to FALSE, only
// the AddMenuItem()s or 2nd ID in SetIDs() will be called and the
// base id (1st ID in SetIDs()==ID in RC file) will be ignored.
//
// d) Optionally call m_DblBtn.SetAsDefaultBtn(TRUE) to make the button
// the default button.
//
// 4. Add the appropiate ON_COMMAND handlers in the parent windows message map
//
// 5. You can also call SetIDs() or SetSplit() later to dynamically change the
// button and you can later add more AddMenuItem().
////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION: CCoolButton
//
// DESCRIPTION:
//
// NOTES:
//
// MAINTENANCE:
// Name: Date: Version: Notes:
// NT ALMOND 210100 1.0 Origin as CCoolBtn
// L Brasington 03/06/06 2.0 Rewritten as CCoolButton
//
////////////////////////////////////////////////////////////////////////////////
CCoolButton::CCoolButton()
{
m_nID2 = 0;
m_bPushed = FALSE;
m_bLoaded = FALSE;
m_bMenuPushed = FALSE;
m_bMenuLoaded = FALSE;
m_bDefaultBtn = m_bActAsDefaultBtn = FALSE;
m_bSplit = TRUE;
m_bOverControl = FALSE;
m_bTracking = FALSE;
ZeroMemory(&m_bm, sizeof m_bm);
m_menu.CreatePopupMenu();
m_themeLib = LoadLibrary("UxTheme.dll");
}
////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION: ~CCoolButton
//
// DESCRIPTION:
//
// NOTES:
//
// MAINTENANCE:
// Name: Date: Version: Notes:
// NT ALMOND 210100 1.0 Origin
//
////////////////////////////////////////////////////////////////////////////////
CCoolButton::~CCoolButton()
{
if(m_themeLib)
FreeLibrary(m_themeLib);
}
BEGIN_MESSAGE_MAP(CCoolButton, CButton)
//{{AFX_MSG_MAP(CCoolButton)
ON_WM_SYSKEYDOWN()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_SETFOCUS()
ON_WM_KILLFOCUS()
ON_WM_SYSCOLORCHANGE()
ON_WM_GETDLGCODE()
//}}AFX_MSG_MAP
ON_MESSAGE(BM_SETSTYLE, OnSetStyle)
ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover )
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave )
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCoolButton message handlers
////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION: SetIDs
//
// DESCRIPTION: Set the IDs
//
// NOTES:
//
// MAINTENANCE:
// Name: Date: Version: Notes:
// L Brasington 03/06/06 2.0 Rewritten as CCoolButton
//
////////////////////////////////////////////////////////////////////////////////
BOOL CCoolButton::SetIDs( UINT nID1, UINT nID2 )
{
m_nID1 = nID1;
m_nID2 = nID2;
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////
UINT CCoolButton::OnGetDlgCode()
{
UINT nCode = CButton::OnGetDlgCode();
nCode |= (m_bActAsDefaultBtn ? DLGC_DEFPUSHBUTTON : DLGC_UNDEFPUSHBUTTON);
return nCode;
}
// mask for control's type
#define BS_TYPEMASK SS_TYPEMASK
LRESULT CCoolButton::OnSetStyle(WPARAM wParam, LPARAM lParam)
{
m_bActAsDefaultBtn = wParam & BS_DEFPUSHBUTTON;
// can't change control type after owner-draw is set.
// let the system process changes to other style bits
// and redrawing, while keeping owner-draw style
return DefWindowProc(BM_SETSTYLE,
(wParam & ~BS_TYPEMASK) | BS_OWNERDRAW, lParam);
}
////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION: DrawItem
//
// DESCRIPTION: Called in response to draw the button
//
// NOTES:
//
// MAINTENANCE:
// Name: Date: Version: Notes:
// NT ALMOND 210100 1.0 Origin
// L Brasington 03/06/06 2.0 Rewritten as CCoolButton, Added XP support
//
////////////////////////////////////////////////////////////////////////////////
#ifdef USE_THEMES
typedef HTHEME(__stdcall *PFNOPENTHEMEDATA)(HWND hwnd, LPCWSTR pszClassList);
typedef HRESULT(__stdcall *PFNCLOSETHEMEDATA)(HTHEME hTheme);
typedef HRESULT(__stdcall *PFNDRAWTHEMEBACKGROUND)(HTHEME hTheme, HDC hdc,
int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect);
typedef HRESULT(__stdcall *PFNGETTHEMEBACKGROUNDCONTENTRECT)(HTHEME hTheme, HDC hdc,
int iPartId, int iStateId, const RECT *pRect, RECT *pContentRect);
#endif
void CCoolButton::DrawItem(DRAWITEMSTRUCT* lpDIS)
{
if (lpDIS->CtlType != ODT_BUTTON)
return;
CFont *pFont = CFont::FromHandle((HFONT)GetStockObject(DEFAULT_GUI_FONT));
CDC dcMem;
CBitmap bmp;
CRect btnRect(lpDIS->rcItem);
CRect trueRect(btnRect);
CRect rectFocus(btnRect);
CDC *pDC = CDC::FromHandle(lpDIS->hDC);
BOOL bDisabled = ODS_DISABLED & lpDIS->itemState;
#ifdef USE_THEMES
HTHEME hTheme = 0;
if(m_themeLib)
{
PFNOPENTHEMEDATA pOpenThemeData = (PFNOPENTHEMEDATA)
GetProcAddress(m_themeLib, "OpenThemeData");
if(pOpenThemeData)
hTheme = (pOpenThemeData)(m_hWnd, L"Button");
}
if(hTheme)
{
// attempt to map owner draw states to theme pushbutton states
int iState = PBS_NORMAL;
if(m_bOverControl)//lpDIS->itemState & ODS_HOTLIGHT)
iState = PBS_HOT;
else if(m_bDefaultBtn || m_bActAsDefaultBtn)//lpDIS->itemState & ODS_DEFAULT)
iState = PBS_DEFAULTED;
else if(lpDIS->itemState & ODS_SELECTED)
iState = PBS_PRESSED;
HRESULT hr;
HDC hDC = lpDIS->hDC;
RECT rc = lpDIS->rcItem;
// let theme draw background
PFNDRAWTHEMEBACKGROUND pDrawThemeBackground = (PFNDRAWTHEMEBACKGROUND)
GetProcAddress(m_themeLib, "DrawThemeBackground");
if(!pDrawThemeBackground)
return;
hr = (pDrawThemeBackground)(hTheme, hDC,
BP_PUSHBUTTON, iState, &rc, 0);
if(hr != S_OK)
return;
// get rect to put content in
RECT rcContent;
PFNGETTHEMEBACKGROUNDCONTENTRECT pGetThemeBackgroundContentRect =
(PFNGETTHEMEBACKGROUNDCONTENTRECT)
GetProcAddress(m_themeLib, "GetThemeBackgroundContentRect");
if(!pGetThemeBackgroundContentRect)
return;
hr = (pGetThemeBackgroundContentRect)(hTheme, hDC,
BP_PUSHBUTTON, iState, &rc, &rcContent);
if(hr != S_OK)
return;
rectFocus = rcContent;
if (!m_bMenuPushed)
rectFocus.OffsetRect(m_bPushed,m_bPushed);
if (m_bSplit)
rectFocus.right -= nDropBtnWidth;
if (lpDIS->itemState & ODS_FOCUS || m_bPushed)
{
if (!m_bMenuPushed)
::DrawFocusRect(lpDIS->hDC, &rcContent);
}
}
else
#endif
{
////////////////////////////////////////
// Button Background //
////////////////////////////////////////
CBrush brush(GetSysColor(COLOR_BTNFACE));
pDC->FillRect(trueRect,&brush);
if (m_bDefaultBtn)
btnRect.DeflateRect(1,1);
rectFocus.DeflateRect(4,4);
if (!m_bMenuPushed)
rectFocus.OffsetRect(m_bPushed,m_bPushed);
if (m_bSplit)
rectFocus.right -= nDropBtnWidth;
////////////////////////////////////////
// Button in a normal state //
////////////////////////////////////////
if (!m_bPushed || m_bMenuPushed)
pDC->DrawFrameControl(&btnRect,DFC_BUTTON,DFCS_BUTTONPUSH);
////////////////////////////////////////
// Default Button State //
////////////////////////////////////////
if ((m_bDefaultBtn || m_bPushed) && !bDisabled)
{
pDC->FrameRect(&lpDIS->rcItem,CBrush::FromHandle((HBRUSH)GetStockObject(BLACK_BRUSH)));
if (m_bPushed && !m_bMenuPushed)
pDC->FrameRect(&btnRect,CBrush::FromHandle((HBRUSH)GetStockObject(BLACK_BRUSH)));
}
////////////////////////////////////////
// State Focus //
////////////////////////////////////////
if (lpDIS->itemState & ODS_FOCUS || m_bPushed)
{
pDC->FrameRect(&lpDIS->rcItem,CBrush::FromHandle((HBRUSH)GetStockObject(BLACK_BRUSH)));
if (!m_bMenuPushed)
pDC->DrawFocusRect(&rectFocus);
}
////////////////////////////////////////
// Action Focus //
////////////////////////////////////////
if ((lpDIS->itemAction & ODA_FOCUS))
if (!m_bMenuPushed)
pDC->DrawFocusRect(&rectFocus);
}
////////////////////////////////////////
// Draw out bitmap //
////////////////////////////////////////
// Draw out bitmap
if (m_bLoaded)
{
if (!bDisabled)
{
m_IL.DrawIndirect(pDC,0,CPoint(6+m_bPushed,6+m_bPushed), CSize(m_bm.bmWidth, m_bm.bmHeight), CPoint(0,0),ILD_NORMAL);
}
else
{
pDC->DrawState(CPoint(6+m_bPushed,6+m_bPushed), CSize(m_bm.bmWidth, m_bm.bmHeight), m_hbmpDisabled, DST_BITMAP | DSS_DISABLED);
}
}
////////////////////////////////////////
// Draw out text //
////////////////////////////////////////
pDC->SelectObject(pFont);
CRect rectText(rectFocus);
if (!m_bSplit)
rectText.right -= nDropBtnWidth;
rectText.left += m_bm.bmWidth + 2;
CString strCaption;
GetWindowText(strCaption);
pDC->SetBkMode(TRANSPARENT);
pDC->SetBkColor(GetSysColor(COLOR_BTNFACE));
if (ODS_DISABLED & lpDIS->itemState)
{
rectText.OffsetRect(1,1);
pDC->SetTextColor(GetSysColor(COLOR_WINDOW));
pDC->DrawText(strCaption,rectText,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
rectText.OffsetRect(-1,-1);
pDC->SetTextColor(GetSysColor(COLOR_GRAYTEXT));
pDC->DrawText(strCaption,rectText,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
}
else
{
pDC->SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
pDC->DrawText(strCaption,rectText,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
}
CRect rectSplit(btnRect);
rectSplit.DeflateRect(2,2);
rectSplit.right -= nDropBtnWidth;
////////////////////////////////////////
// Drop down split //
////////////////////////////////////////
if (m_bSplit)
{
CPen brFace(PS_SOLID,1,GetSysColor(COLOR_3DSHADOW));
pDC->SelectObject(&brFace);
pDC->MoveTo(rectSplit.right, rectSplit.top);
pDC->LineTo(rectSplit.right, rectSplit.bottom);
CPen brLite(PS_SOLID,1,GetSysColor(COLOR_3DHILIGHT));
pDC->SelectObject(&brLite);
pDC->MoveTo(rectSplit.right+1 , rectSplit.top);
pDC->LineTo(rectSplit.right+1, rectSplit.bottom);
}
////////////////////////////////////////
// Draw Arrow //
////////////////////////////////////////
rectSplit.left = rectSplit.right;
rectSplit.right += nDropBtnWidth;
CPoint pt(rectSplit.CenterPoint());
pt += CPoint(m_bPushed,m_bPushed);
CPen penBlack(PS_SOLID, 1, bDisabled ? GetSysColor(COLOR_GRAYTEXT) : GetSysColor(COLOR_WINDOWTEXT));
pDC->SelectObject(&penBlack);
DrawArrow(pDC,pt);
////////////////////////////////////////
// Drop down state //
////////////////////////////////////////
if (m_bMenuPushed && !bDisabled)
{
rectSplit.InflateRect(1,1);
pDC->DrawEdge(rectSplit,BDR_SUNKENOUTER, BF_RECT);
}
if(hTheme)
{
PFNCLOSETHEMEDATA pCloseThemeData = (PFNCLOSETHEMEDATA)GetProcAddress(m_themeLib, "CloseThemeData");
if(!pCloseThemeData)
return;
(pCloseThemeData)(hTheme);
}
}
////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION: DrawArrow
//
// DESCRIPTION: Draws drop down arrow, we could use DrawFrameControl - a bit too
// messy
//
// NOTES:
//
// MAINTENANCE:
// Name: Date: Version: Notes:
// NT ALMOND 210100 1.0 Origin
//
////////////////////////////////////////////////////////////////////////////////
void CCoolButton::DrawArrow(CDC* pDC,CPoint ArrowTip)
{
CPoint ptDest;
pDC->SetPixel(ArrowTip,RGB(0,0,0));
ArrowTip -= CPoint(1,1);
pDC->MoveTo(ArrowTip);
ptDest = ArrowTip;
ptDest += CPoint(3,0);
pDC->LineTo(ptDest);
ArrowTip -= CPoint(1,1);
pDC->MoveTo(ArrowTip);
ptDest = ArrowTip;
ptDest += CPoint(5,0);
pDC->LineTo(ptDest);
ArrowTip -= CPoint(1,1);
pDC->MoveTo(ArrowTip);
ptDest = ArrowTip;
ptDest += CPoint(7,0);
pDC->LineTo(ptDest);
}
////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION: OnLButtonDown
//
// DESCRIPTION: handles button pressed state, including drop down menu
//
//
// NOTES:
//
// MAINTENANCE:
// Name: Date: Version: Notes:
// NT ALMOND 210100 1.0 Origin
// L Brasington 03/06/06 2.0 Rewritten as CCoolButton
//
////////////////////////////////////////////////////////////////////////////////
void CCoolButton::OnLButtonDown(UINT nFlags, CPoint point)
{
SetFocus();
if (m_bMenuPushed)
{
m_bMenuPushed = FALSE;
Invalidate();
return;
}
if (!m_bSplit || HitMenuBtn(point))
{
OnMenuBtn();
return;
}
m_bPushed = TRUE;
Invalidate();
CButton::OnLButtonDown(nFlags, point);
}
BOOL CCoolButton::OnMenuBtn()
{
if (!m_bMenuLoaded)
{
if (m_nID2)
{
GetParent()->PostMessage(WM_COMMAND, m_nID2, 0);
m_bMenuPushed = TRUE;
Invalidate();
return TRUE;
}
}
else
{
m_bMenuPushed = TRUE;
Invalidate();
CRect rc;
GetWindowRect(rc);
int x = rc.left;
int y = rc.bottom;
m_menu.TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON,x,y,GetParent());
m_bMenuPushed = FALSE;
Invalidate();
return TRUE;
}
return FALSE;
}
////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION: OnLButtonUp
//
// DESCRIPTION: Redraws button in normal state
//
//
// NOTES:
//
// MAINTENANCE:
// Name: Date: Version: Notes:
// NT ALMOND 210100 1.0 Origin
// L Brasington 03/06/06 2.0 Rewritten as CCoolButton
//
////////////////////////////////////////////////////////////////////////////////
void CCoolButton::ClearButtonPushed()
{
if (m_bPushed)
{
m_bPushed = FALSE;
Invalidate();
}
if (m_bMenuPushed)
{
m_bMenuPushed = FALSE;
Invalidate();
}
}
void CCoolButton::OnLButtonUp(UINT nFlags, CPoint point)
{
ClearButtonPushed();
CButton::OnLButtonUp(nFlags, point);
}
////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION: OnMouseMove
//
// DESCRIPTION: Tracks mouse whilst pressed
//
//
// NOTES:
//
// MAINTENANCE:
// Name: Date: Version: Notes:
// NT ALMOND 210100 1.0 Origin
// L Brasington 03/06/06 2.0 Rewritten as CCoolButton
//
////////////////////////////////////////////////////////////////////////////////
LRESULT CCoolButton::OnMouseHover(WPARAM wparam, LPARAM lparam)
{
m_bOverControl=TRUE;
Invalidate();
return 1;
}
LRESULT CCoolButton::OnMouseLeave(WPARAM wparam, LPARAM lparam)
{
m_bTracking = FALSE;
m_bOverControl = FALSE;
Invalidate(FALSE);
return 0;
}
void CCoolButton::OnMouseMove(UINT nFlags, CPoint point)
{
if (m_bPushed)
{
ClientToScreen(&point);
if (WindowFromPoint(point) != this)
{
m_bPushed = FALSE;
Invalidate();
}
}
if (!m_bTracking)
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.hwndTrack = m_hWnd;
tme.dwFlags = TME_LEAVE|TME_HOVER;
tme.dwHoverTime = 1;
m_bTracking = _TrackMouseEvent(&tme) != FALSE;
}
CButton::OnMouseMove(nFlags, point);
}
////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION: SetButtonImage
//
// DESCRIPTION: Sets the button image, COLORREF crMask specifics the transparency
// color
//
// NOTES:
//
// MAINTENANCE:
// Name: Date: Version: Notes:
// NT ALMOND 210100 1.0 Origin
//
////////////////////////////////////////////////////////////////////////////////
BOOL CCoolButton::SetButtonImage(UINT nResourceId, COLORREF crMask)
{
// The ID must exist also as a bitmap resource!!!
m_btnImage.LoadBitmap(nResourceId);
m_btnImage.GetObject(sizeof m_bm, &m_bm);
m_IL.Create( nResourceId, m_bm.bmWidth, 1, crMask );
m_bLoaded = TRUE;
m_crMask = crMask;
HBITMAP bmTemp;
COLORMAP mapColor;
mapColor.from = crMask;
mapColor.to = RGB(255,255,255);
bmTemp = (HBITMAP)::CreateMappedBitmap(AfxGetApp()->m_hInstance, nResourceId, IMAGE_BITMAP, &mapColor, 1);
m_hbmpDisabled = (HBITMAP)::CopyImage(bmTemp, IMAGE_BITMAP, m_bm.bmWidth, m_bm.bmHeight, LR_COPYDELETEORG);
return m_bLoaded;
}
void CCoolButton::OnSetFocus(CWnd* pOldWnd)
{
CButton::OnSetFocus(pOldWnd);
Invalidate();
}
void CCoolButton::OnKillFocus(CWnd* pNewWnd)
{
CButton::OnKillFocus(pNewWnd);
}
////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION: OnSysColorChange
//
// DESCRIPTION: Called when system colors change, force a button redraw
//
// NOTES:
//
// MAINTENANCE:
// Name: Date: Version: Notes:
// NT ALMOND 210100 1.0 Origin
//
////////////////////////////////////////////////////////////////////////////////
void CCoolButton::OnSysColorChange()
{
CButton::OnSysColorChange();
Invalidate();
}
////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION: HitMenuBtn
//
// DESCRIPTION: Helper function to test for menu button hit...
//
// NOTES:
//
// MAINTENANCE:
// Name: Date: Version: Notes:
// NT ALMOND 210100 1.0 Origin
// L Brasington 03/06/06 2.0 Rewritten as CCoolButton
//
////////////////////////////////////////////////////////////////////////////////
BOOL CCoolButton::HitMenuBtn(CPoint point)
{
if (!m_bMenuLoaded && !m_nID2)
return FALSE; // Don't allow menu button drop down if no menu items are loaded
ClientToScreen(&point);
CRect rect;
GetWindowRect(rect);
rect.left = rect.right - nDropBtnWidth;
return rect.PtInRect(point);
}
////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION: AddMenuItem
//
// DESCRIPTION: Adds a menu item and id to our menu.
//
// NOTES:
//
// MAINTENANCE:
// Name: Date: Version: Notes:
// NT ALMOND 210100 1.0 Origin
//
////////////////////////////////////////////////////////////////////////////////
BOOL CCoolButton::AddMenuItem(UINT nMenuId,const CString strMenu, UINT nMenuFlags)
{
BOOL bRet = m_menu.AppendMenu(nMenuFlags | MF_STRING, nMenuId, (LPCTSTR)strMenu);
m_bMenuLoaded |= bRet;
return bRet;
}
////////////////////////////////////////////////////////////////////////////////
void CCoolButton::OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
switch ( nChar )
{
case VK_DOWN:
OnMenuBtn();
break;
}
CWnd::OnSysKeyDown(nChar, nRepCnt, nFlags);
}
Leigh Brasington
|
|
|
|
|
Thanks Leigh, you could of emailed me the source
Seriously I should get round to getting a new version out.
|
|
|
|
|