// This is part of the Professional User Interface Suite library.
// Copyright (C) 2001-2002 FOSS Software, Inc.
// All rights reserved.
//
// http://www.fossware.com
// mailto:foss@fossware.com
//
// This source code can be used, modified and redistributed
// under the terms of the license agreement that is included
// in the Professional User Interface Suite package.
//
// Warranties and Disclaimers:
// THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND
// INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
// IN NO EVENT WILL FOSS SOFTWARE INC. BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES,
// INCLUDING DAMAGES FOR LOSS OF PROFITS, LOSS OR INACCURACY OF DATA,
// INCURRED BY ANY PERSON FROM SUCH PERSON'S USAGE OF THIS SOFTWARE
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
#include "stdafx.h"
#include "ExtButton.h"
#include "ExtCmdManager.h"
#include "ExtPaintManager.h"
#include "ExtMemoryDC.h"
#include "ExtPopupMenuWnd.h"
#include "ExtColorDlg.h"
#include "ExtToolControlBar.h"
#if (!defined __AFXPRIV_H__)
#include <AfxPriv.h>
#endif
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CExtButton::CExtButton()
{
// RTF tool tip support
#if (!defined __EXT_MFC_NO_RTF_TOOLTIPS)
m_bToolTipSet = FALSE;
#endif
m_hIconIn = NULL;
m_hIconOut = NULL;
m_hCursor = NULL;
m_bIsFlat = FALSE;
m_bDrawBorder = TRUE;
m_bMouseOver = m_bPushed = m_bPushTracking = m_bKeyTracking = FALSE;
m_nAlign =
CExtPaintManager::e_align_t::__ALIGN_HORIZ_CENTER
|CExtPaintManager::e_align_t::__ALIGN_VERT
;
m_bIsDefault = FALSE;
m_ToolTip.m_hWnd = NULL;
m_dwMenuOpt = TPMX_TOPALIGN;
m_nMenuLeftAreaWidth = 0;
}
CExtButton::~CExtButton()
{
_FreeWinObjects();
}
void CExtButton::_FreeWinObjects()
{
if( m_hIconIn != NULL )
::DestroyIcon( m_hIconIn );
if( m_hIconOut != NULL )
::DestroyIcon( m_hIconOut );
if( m_hCursor != NULL )
::DestroyCursor(m_hCursor);
}
IMPLEMENT_DYNCREATE(CExtButton, CButton);
BEGIN_MESSAGE_MAP(CExtButton, CButton)
//{{AFX_MSG_MAP(CExtButton)
ON_WM_CAPTURECHANGED()
ON_WM_SETCURSOR()
ON_WM_KILLFOCUS()
ON_WM_MOUSEMOVE()
ON_WM_SYSCOLORCHANGE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_WM_ENABLE()
//}}AFX_MSG_MAP
ON_REGISTERED_MESSAGE(
CExtToolControlBar::g_nMsgPutToPopupMenu,
_OnPutToPopupMenuImpl
)
END_MESSAGE_MAP()
LRESULT CExtButton::_OnPutToPopupMenuImpl(WPARAM wParam, LPARAM lParam)
{
lParam;
CExtPopupMenuWnd * pPopup = reinterpret_cast < CExtPopupMenuWnd * > (wParam);
ASSERT_VALID( pPopup );
return OnPutToPopupMenu( pPopup ) ? TRUE : FALSE;
}
bool CExtButton::OnPutToPopupMenu( CExtPopupMenuWnd * pPopup )
{
ASSERT_VALID( pPopup );
//bool bInBar = false;
//CWnd * pWnd = GetParent();
// ASSERT_VALID( pWnd );
// if( pWnd->IsKindOf(RUNTIME_CLASS(CControlBar)) )
// {
// bInBar = true;
// pWnd = pWnd->GetParentFrame();
// ASSERT_VALID( pWnd );
// if( pWnd->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)) )
// {
// pWnd = pWnd->GetParentFrame();
// ASSERT_VALID( pWnd );
// }
// }
if( m_menu.GetSafeHmenu() != NULL )
{
ASSERT( ::IsMenu( m_menu.GetSafeHmenu() ) );
CExtPopupMenuWnd * pPopupIns = new CExtPopupMenuWnd;
VERIFY(
pPopupIns->CreatePopupMenu(
//pWnd->GetSafeHwnd()
pPopup->GetCmdRecieverHWND()
)
);
VERIFY(
pPopupIns->UpdateFromMenu(
pPopup->GetCmdRecieverHWND(),
&m_menu
)
);
HICON hIcon = NULL;
if( m_hIconIn != NULL )
{
CExtCmdManager::icon_t _icon( m_hIconIn, true );
hIcon = _icon.Detach();
}
CString sPopupText( _T("") );
CExtCmdManager::cmd_t * p_cmd =
g_CmdManager->CmdGetPtr(
g_CmdManager->ProfileNameFromWnd( GetSafeHwnd() ),
GetDlgCtrlID()
);
if( p_cmd != NULL )
sPopupText = p_cmd->m_sMenuText;
if( sPopupText.IsEmpty() )
GetWindowText( sPopupText );
VERIFY(
pPopup->ItemInsertSpecPopup(
pPopupIns,
-1,
LPCTSTR( sPopupText ),
hIcon
)
);
return true;
}
return false;
}
void CExtButton::SetIcon(int nIconInId, int nIconOutId)
{
HICON hIconIn;
HICON hIconOut;
HINSTANCE hInstResource =
AfxFindResourceHandle(
MAKEINTRESOURCE(nIconInId),
RT_GROUP_ICON
);
hIconIn = (HICON)::LoadImage(
hInstResource,
MAKEINTRESOURCE(nIconInId),
IMAGE_ICON,
0,
0,
0
);
hIconOut =
(nIconOutId == NULL) ?
NULL
:
(HICON)::LoadImage(
hInstResource,
MAKEINTRESOURCE(nIconOutId),
IMAGE_ICON,
0,
0,
0
);
SetIcon(hIconIn, hIconOut);
}
void CExtButton::SetIcon(HICON hIconIn, HICON hIconOut)
{
if( m_hIconIn != NULL)
::DestroyIcon( m_hIconIn );
if( m_hIconOut != NULL)
::DestroyIcon( m_hIconOut );
m_hIconIn = hIconIn;
m_hIconOut =
(hIconOut == NULL) ?
m_hIconIn : hIconOut;
Invalidate();
UpdateWindow();
}
BOOL CExtButton::SetBtnCursor(int nCursorId)
{
HINSTANCE hInstResource;
if( m_hCursor != NULL )
::DestroyCursor(m_hCursor);
m_hCursor = NULL;
if( nCursorId != -1 )
{
hInstResource =
AfxFindResourceHandle(
MAKEINTRESOURCE(nCursorId),
RT_GROUP_CURSOR
);
m_hCursor =
(HCURSOR)::LoadImage(
hInstResource,
MAKEINTRESOURCE(nCursorId),
IMAGE_CURSOR,
0,
0,
0
);
if( m_hCursor == NULL )
{
m_hCursor =
::LoadCursor(
NULL,
MAKEINTRESOURCE(nCursorId)
);
if( m_hCursor == NULL )
return FALSE;
}
}
return TRUE;
}
void CExtButton::SetFlat(BOOL bState)
{
m_bIsFlat = bState;
Invalidate();
UpdateWindow();
}
BOOL CExtButton::GetFlat()
{
return m_bIsFlat;
}
void CExtButton::SetAlign(int nAlign)
{
switch( nAlign )
{
case CExtPaintManager::e_align_t::__ALIGN_HORIZ_CENTER:
m_nAlign = CExtPaintManager::e_align_t::__ALIGN_HORIZ_CENTER;
break;
case CExtPaintManager::e_align_t::__ALIGN_HORIZ_RIGHT:
m_nAlign = CExtPaintManager::e_align_t::__ALIGN_HORIZ_RIGHT;
break;
case CExtPaintManager::e_align_t::__ALIGN_VERT:
m_nAlign = CExtPaintManager::e_align_t::__ALIGN_VERT;
break;
} // switch( nAlign )
Invalidate();
UpdateWindow();
}
int CExtButton::GetAlign()
{
return m_nAlign;
}
void CExtButton::SetDrawBorder(BOOL bEnable)
{
m_bDrawBorder = bEnable;
Invalidate();
UpdateWindow();
}
bool CExtButton::_IsMouseOnButton()
{
POINT point;
VERIFY( GetCursorPos( &point ) );
CWnd * pWndUnderMouse = WindowFromPoint( point );
if( pWndUnderMouse->GetSafeHwnd() == m_hWnd )
return true;
return false;
}
void CExtButton::OnMouseMove(UINT nFlags, CPoint point)
{
if( m_bKeyTracking )
return;
CButton::OnMouseMove(nFlags, point);
if( _IsMouseOnButton() )
{ // if mouse is really on button
if( GetCapture() != this )
SetCapture();
if( m_bMouseOver )
return;
m_bMouseOver = TRUE;
m_bPushed =
((nFlags & MK_LBUTTON) && m_bPushTracking )
? TRUE : FALSE;
Invalidate();
UpdateWindow();
} // if mouse is really on button
else
{ // if mouse is really NOT on button
if( GetCapture() == this && ( !m_bPushTracking ) )
ReleaseCapture();
if( !m_bMouseOver )
return;
m_bMouseOver = m_bPushed = FALSE;
Invalidate();
UpdateWindow();
} // if mouse is really NOT on button
// RTF tool tip support
#if (!defined __EXT_MFC_NO_RTF_TOOLTIPS)
if( nFlags & MK_LBUTTON )
return;
if( m_bToolTipSet )
m_wndRtfToolTipCtrl.
SetupRtfFromString(
point, m_strToolTip );
#endif
}
void CExtButton::OnKillFocus(CWnd * pNewWnd)
{
CButton::OnKillFocus(pNewWnd);
if( m_bMouseOver || m_bPushed )
{
if( GetCapture() == this )
ReleaseCapture();
m_bMouseOver = m_bPushed = FALSE;
Invalidate();
UpdateWindow();
}
}
void CExtButton::OnCaptureChanged(CWnd *pWnd)
{
if( (m_bMouseOver || m_bPushed)
&& pWnd != this
)
{
// ReleaseCapture();
// RTF tool tip support
#if (!defined __EXT_MFC_NO_RTF_TOOLTIPS)
if( m_bToolTipSet )
m_wndRtfToolTipCtrl.Hide();
#endif
m_bMouseOver = m_bPushed = FALSE;
Invalidate();
UpdateWindow();
}
CButton::OnCaptureChanged(pWnd);
}
void CExtButton::PreSubclassWindow()
{
CButton::PreSubclassWindow();
UINT nBS = GetButtonStyle();
if( nBS & BS_DEFPUSHBUTTON )
m_bIsDefault = TRUE;
if( nBS & BS_OWNERDRAW )
SetButtonStyle( nBS & ~(BS_OWNERDRAW) );
SetFont(
m_bIsDefault?
&g_PaintManager->m_FontBold
:
&g_PaintManager->m_FontNormal
);
}
BOOL CExtButton::PreTranslateMessage(MSG* pMsg)
{
if( !CExtPopupMenuWnd::IsMenuTracking() )
{
InitToolTip();
m_ToolTip.RelayEvent(pMsg);
}
// if( CExtPopupMenuWnd::IsMenuTracking() )
// return TRUE;
if( ( pMsg->message == WM_KEYDOWN
|| pMsg->message == WM_KEYUP
)
&&
( pMsg->wParam == VK_RETURN
|| pMsg->wParam == VK_SPACE
)
)
{
if( IsWindowEnabled() && IsWindowVisible() && (!m_bPushTracking) )
{
if( (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN)
||
(pMsg->message == WM_KEYUP && pMsg->wParam == VK_SPACE)
)
{
if( GetCapture() == this )
ReleaseCapture();
m_bMouseOver = m_bPushed = m_bPushTracking = m_bKeyTracking = FALSE;
Invalidate();
UpdateWindow();
_OnClick();
return TRUE;
}
if(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_SPACE)
{
m_bMouseOver = m_bPushed = m_bKeyTracking = TRUE;
SetCapture();
Invalidate();
UpdateWindow();
return TRUE;
}
} // if( IsWindowEnabled() && IsWindowVisible() && (!m_bPushTracking) )
return TRUE;
}
return CButton::PreTranslateMessage(pMsg);
}
LRESULT CExtButton::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
bool bInvalidate = false;
switch( message )
{
case WM_LBUTTONDBLCLK:
message = WM_LBUTTONDOWN;
break;
case BM_SETCHECK:
case BM_SETSTATE:
case BM_SETSTYLE:
#if (WINVER >= 0x0400)
case BM_CLICK:
case BM_SETIMAGE:
#endif
case WM_SETTEXT:
case WM_SIZE:
case WM_WINDOWPOSCHANGED:
bInvalidate = true;
break;
} // switch( message )
LRESULT lResult =
CButton::DefWindowProc(message, wParam, lParam);
if( bInvalidate )
{
Invalidate();
UpdateWindow();
}
return lResult;
}
BOOL CExtButton::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if( m_hCursor != NULL )
{
::SetCursor(m_hCursor);
return TRUE;
}
return CButton::OnSetCursor(pWnd, nHitTest, message);
}
void CExtButton::SetTooltipText(CString* spText, BOOL bActivate)
{
if( spText == NULL )
return;
InitToolTip();
if( m_ToolTip.GetToolCount() == 0 )
{
CRect rectBtn;
GetClientRect(rectBtn);
m_ToolTip.AddTool(this,(LPCTSTR)*spText,rectBtn,1);
}
m_ToolTip.UpdateTipText((LPCTSTR)*spText,this,1);
m_ToolTip.Activate(bActivate);
}
void CExtButton::SetTooltipText(CString & sText, BOOL bActivate)
{
if( sText.IsEmpty() )
return;
InitToolTip();
if( m_ToolTip.GetToolCount() == 0 )
{
CRect rectBtn;
GetClientRect(rectBtn);
m_ToolTip.AddTool(this,(LPCTSTR)sText,rectBtn,1);
}
m_ToolTip.UpdateTipText((LPCTSTR)sText,this,1);
m_ToolTip.Activate( bActivate );
}
void CExtButton::SetTooltipText(LPCTSTR sText, BOOL bActivate)
{
if( sText == NULL
|| _tcslen( sText ) == 0
)
return;
InitToolTip();
if( m_ToolTip.GetToolCount() == 0 )
{
CRect rectBtn;
GetClientRect(rectBtn);
m_ToolTip.AddTool(this,sText,rectBtn,1);
}
m_ToolTip.UpdateTipText(sText,this,1);
m_ToolTip.Activate(bActivate);
}
void CExtButton::SetTooltipText(int nId, BOOL bActivate)
{
CString sText;
sText.LoadString(nId);
if( !sText.IsEmpty() )
SetTooltipText(&sText, bActivate);
}
void CExtButton::ActivateTooltip(BOOL bActivate)
{
if( m_ToolTip.GetToolCount() == 0 )
return;
m_ToolTip.Activate(bActivate);
}
BOOL CExtButton::GetDefault()
{
return m_bIsDefault;
}
void CExtButton::InitToolTip()
{
if( m_ToolTip.m_hWnd == NULL )
{
m_ToolTip.Create(this);
m_ToolTip.Activate(FALSE);
}
}
void CExtButton::OnSysColorChange()
{
CButton::OnSysColorChange();
g_PaintManager->SyncSysColors();
g_PaintManager->InitTranslatedColors();
}
void CExtButton::OnLButtonDown(UINT nFlags, CPoint point)
{
// RTF tool tip support
#if (!defined __EXT_MFC_NO_RTF_TOOLTIPS)
if( m_bToolTipSet )
m_wndRtfToolTipCtrl.Hide();
#endif
if( m_bKeyTracking )
return;
CButton::OnLButtonDown(nFlags, point);
if( !_IsMouseOnButton() )
return;
m_bMouseOver = m_bPushed = m_bPushTracking = TRUE;
SetCapture();
Invalidate();
UpdateWindow();
}
void CExtButton::OnLButtonUp(UINT nFlags, CPoint point)
{
nFlags;
point;
// RTF tool tip support
#if (!defined __EXT_MFC_NO_RTF_TOOLTIPS)
if( m_bToolTipSet )
m_wndRtfToolTipCtrl.Hide();
#endif
if( m_bKeyTracking )
return;
BOOL bWasPushed = m_bPushed && m_bPushTracking;
m_bMouseOver = m_bPushed = m_bPushTracking = FALSE;
if( GetCapture() == this )
ReleaseCapture();
Invalidate();
UpdateWindow();
if( !bWasPushed )
return;
//CButton::OnLButtonDown(nFlags, point);
if( IsWindowEnabled()
&& IsWindowVisible()
)
_OnClick();
}
void CExtButton::_OnClick()
{
if( _OnTrackPopup() )
return;
CWnd * pWnd = GetParent();
ASSERT( pWnd != NULL );
ASSERT_VALID( pWnd );
if( m_menu.GetSafeHmenu() == NULL )
{
HWND hWndThis = GetSafeHwnd();
pWnd->SendMessage(
WM_COMMAND,
MAKEWPARAM(GetDlgCtrlID(),BN_CLICKED),
(LPARAM)m_hWnd
);
if( ::IsWindow(hWndThis) )
{
Invalidate();
UpdateWindow();
}
return;
}
}
bool CExtButton::_IsMenuAvail()
{
if( m_menu.GetSafeHmenu() == NULL )
return false;
return true;
}
bool CExtButton::_OnTrackPopup()
{
if( m_menu.GetSafeHmenu() == NULL )
return false;
ASSERT( ::IsMenu(m_menu.GetSafeHmenu()) );
VERIFY(
g_CmdManager->UpdateFromMenu(
g_CmdManager->ProfileNameFromWnd( GetSafeHwnd() ),
m_menu.GetSafeHmenu()
)
);
CExtPopupMenuWnd * pPopup = new CExtPopupMenuWnd;
pPopup->SetLeftAreaWidth( m_nMenuLeftAreaWidth );
CWnd * pWnd = GetParent();
ASSERT_VALID( pWnd );
DWORD dwAlignOpt = 0;
DWORD dwMenuOpt = m_dwMenuOpt;
while( pWnd->IsKindOf(RUNTIME_CLASS(CControlBar)) )
{
if( dwAlignOpt == 0 && ((CControlBar *)pWnd)->m_pDockBar != NULL )
{
ASSERT_VALID( ((CControlBar *)pWnd)->m_pDockBar );
dwMenuOpt &= ~TPMX_ALIGN_MASK;
UINT nDockBarID = ((CControlBar *)pWnd)->m_pDockBar->GetDlgCtrlID();
switch( nDockBarID )
{
case AFX_IDW_DOCKBAR_TOP:
dwAlignOpt = TPMX_TOPALIGN;
break;
case AFX_IDW_DOCKBAR_BOTTOM:
dwAlignOpt = TPMX_BOTTOMALIGN;
break;
case AFX_IDW_DOCKBAR_LEFT:
dwAlignOpt = TPMX_LEFTALIGN;
break;
case AFX_IDW_DOCKBAR_RIGHT:
dwAlignOpt = TPMX_RIGHTALIGN;
break;
case AFX_IDW_DOCKBAR_FLOAT:
dwAlignOpt = TPMX_TOPALIGN;
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif // _DEBUG
} // switch( nDockBarID )
} // if( dwAlignOpt == 0 && ((CControlBar *)pWnd)->m_pDockBar != NULL )
pWnd = pWnd->GetParent();
if( pWnd->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)) )
{
pWnd = pWnd->GetParentFrame();
ASSERT_VALID( pWnd );
break;
}
}
ASSERT( pWnd != NULL );
ASSERT_VALID( pWnd );
VERIFY(
pPopup->UpdateFromMenu( pWnd->GetSafeHwnd(), &m_menu )
);
CRect wr;
GetWindowRect( &wr );
CPoint pt = wr.CenterPoint();
SetFocus();
pPopup->TrackPopupMenu(
dwMenuOpt
| dwAlignOpt
| TPMX_SELECT_ANY
//| TPMX_DO_MESSAGE_LOOP
| TPMX_COMBINE_DEFAULT,
pt.x,
pt.y,
&wr,
this,
_CbPaintCombinedContent
);
return true;
}
void CExtButton::_CbPaintCombinedContent(
LPVOID pCookie,
CDC & dc,
const CWnd & refWndMenu,
const CRect & rcExcludeArea, // in screen coords
int eCombineAlign // CExtPopupMenuWnd::e_combine_align_t values
)
{
pCookie;
dc;
refWndMenu;
rcExcludeArea;
eCombineAlign;
ASSERT( dc.GetSafeHdc() != NULL );
ASSERT( refWndMenu.GetSafeHwnd() != NULL );
CExtButton * pBtn = (CExtButton *)pCookie;
ASSERT( pBtn != NULL );
ASSERT_VALID( pBtn );
ASSERT( pBtn->IsKindOf(RUNTIME_CLASS(CExtButton)) );
ASSERT( eCombineAlign != CExtPopupMenuWnd::__CMBA_NONE );
if( rcExcludeArea.IsRectEmpty() )
return;
CRect rcClientBar,rcClientExcludeArea;
pBtn->GetClientRect( &rcClientBar );
pBtn->ClientToScreen( &rcClientBar );
refWndMenu.GetClientRect( &rcClientExcludeArea );
refWndMenu.ClientToScreen( &rcClientExcludeArea );
CPoint ptOffset =
rcClientBar.TopLeft()
- rcClientExcludeArea.TopLeft()
;
CPoint ptViewportOrg = dc.GetViewportOrg();
dc.SetViewportOrg( ptOffset );
pBtn->_RenderImpl(dc,true);
dc.SetViewportOrg( ptViewportOrg );
}
void CExtButton::_RenderImpl(
CDC & dc,
bool bTransparent // = false
)
{
CRect rectClient;
GetClientRect( &rectClient );
CString sWindowText( _T("") );
GetWindowText( sWindowText );
bool bDrawFocusRect = (GetFocus() == this) ? true : false;
bool bDefault = GetDefault() ? true : false;
bool bPushed = (m_bPushed || GetCheck()) ? true : false;
bool bEnabled = IsWindowEnabled() ? true : false;
bool bFlat = GetFlat() ? true : false;
bool bHover =
( m_bMouseOver
&& !CExtPopupMenuWnd::IsMenuTracking() )
? true : false;
HICON hIcon = (bHover) ? m_hIconIn : m_hIconOut;
if( GetParent()->IsKindOf(RUNTIME_CLASS(CControlBar)) )
{
bDrawFocusRect = false;
bFlat = true;
}
g_PaintManager->PaintPushButton(
dc, true, rectClient, (LPCTSTR)sWindowText,
hIcon, bFlat, bHover, bPushed,
false, bEnabled,
m_bDrawBorder ? true : false,
bDrawFocusRect, bDefault, m_nAlign,
NULL, _IsMenuAvail(), 0, bTransparent
);
}
void CExtButton::_DrawImpl(
CDC & dc,
bool bTransparent // = false
)
{
CRect rectClient;
GetClientRect( &rectClient );
CExtMemoryDC dcmm( &dc, &rectClient );
_RenderImpl(dcmm,bTransparent);
}
void CExtButton::OnPaint()
{
CPaintDC dcPaint( this );
_DrawImpl( dcPaint );
}
BOOL CExtButton::OnEraseBkgnd(CDC* pDC)
{
pDC;
return TRUE;
}
void CExtButton::OnEnable(BOOL bEnable)
{
CButton::OnEnable(bEnable);
CClientDC dc(this);
_DrawImpl( dc );
}
CExtColorButton::CExtColorButton()
{
#if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__)
m_bUseStdColorDlg = false;
#else
m_bUseStdColorDlg = true;
#endif // #if (defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__)
m_bEnableBtnColorDefault = true;
m_bEnableBtnColorCustom = true;
m_clrDefault = (COLORREF)(-1); // unexisting
m_clrSelected = RGB(0,0,0);
m_lParamCookie = 0;
m_sBtnTextColorDefault = _T("");
m_sBtnTextColorCustom = _T("");
}
CExtColorButton::~CExtColorButton()
{
_FreeWinObjects();
}
IMPLEMENT_DYNCREATE(CExtColorButton, CExtButton);
BEGIN_MESSAGE_MAP(CExtColorButton, CExtButton)
//{{AFX_MSG_MAP(CExtColorButton)
//}}AFX_MSG_MAP
ON_REGISTERED_MESSAGE(
CExtPopupColorMenuWnd::g_nMsgNotifyColorChanged,
OnColorChanged
)
ON_REGISTERED_MESSAGE(
CExtPopupColorMenuWnd::g_nMsgNotifyColorChangedFinally,
OnColorChangedFinally
)
ON_REGISTERED_MESSAGE(
CExtPopupColorMenuWnd::g_nMsgNotifyCustColor,
OnColorSelectCustom
)
END_MESSAGE_MAP()
bool CExtColorButton::_IsMenuAvail()
{
return true;
}
bool CExtColorButton::_OnTrackPopup()
{
bool bInBar = false;
CWnd * pWnd = GetParent();
ASSERT_VALID( pWnd );
DWORD dwAlignOpt = 0;
DWORD dwMenuOpt = m_dwMenuOpt;
while( pWnd->IsKindOf(RUNTIME_CLASS(CControlBar)) )
{
bInBar = true;
if( dwAlignOpt == 0 && ((CControlBar *)pWnd)->m_pDockBar != NULL )
{
ASSERT_VALID( ((CControlBar *)pWnd)->m_pDockBar );
dwMenuOpt &= ~TPMX_ALIGN_MASK;
UINT nDockBarID = ((CControlBar *)pWnd)->m_pDockBar->GetDlgCtrlID();
switch( nDockBarID )
{
case AFX_IDW_DOCKBAR_TOP:
dwAlignOpt = TPMX_TOPALIGN;
break;
case AFX_IDW_DOCKBAR_BOTTOM:
dwAlignOpt = TPMX_BOTTOMALIGN;
break;
case AFX_IDW_DOCKBAR_LEFT:
dwAlignOpt = TPMX_LEFTALIGN;
break;
case AFX_IDW_DOCKBAR_RIGHT:
dwAlignOpt = TPMX_RIGHTALIGN;
break;
case AFX_IDW_DOCKBAR_FLOAT:
dwAlignOpt = TPMX_TOPALIGN;
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif // _DEBUG
} // switch( nDockBarID )
} // if( dwAlignOpt == 0 && ((CControlBar *)pWnd)->m_pDockBar != NULL )
pWnd = pWnd->GetParent();
if( pWnd->IsKindOf(RUNTIME_CLASS(CMiniFrameWnd)) )
{
pWnd = pWnd->GetParentFrame();
ASSERT_VALID( pWnd );
break;
}
}
CExtPopupColorMenuWnd * pPopup = new CExtPopupColorMenuWnd;
pPopup->SetLeftAreaWidth( m_nMenuLeftAreaWidth );
pPopup->m_lParamCookie = m_lParamCookie;
VERIFY(
pPopup->CreatePopupMenu(
bInBar ? pWnd->GetSafeHwnd() : GetSafeHwnd()
)
);
pPopup->m_bEnableBtnColorDefault =
m_bEnableBtnColorDefault;
pPopup->m_bEnableBtnColorCustom =
m_bEnableBtnColorCustom;
pPopup->m_clrDefault =
m_clrDefault;
pPopup->m_clrInitial =
m_clrSelected;
if( !m_sBtnTextColorDefault.IsEmpty() )
pPopup->m_sBtnTextColorDefault = m_sBtnTextColorDefault;
if( !m_sBtnTextColorCustom.IsEmpty() )
pPopup->m_sBtnTextColorCustom = m_sBtnTextColorCustom;
CRect wr;
GetWindowRect( &wr );
CPoint pt = wr.CenterPoint();
if( bInBar)
pWnd->SetFocus();
else
SetFocus();
pPopup->TrackPopupMenu(
dwMenuOpt
| dwAlignOpt
| TPMX_SELECT_ANY
//| TPMX_DO_MESSAGE_LOOP
| TPMX_COMBINE_DEFAULT,
pt.x,
pt.y,
&wr,
this,
_CbPaintCombinedContent
);
return true;
}
HICON CExtColorButton::GenerateColorIcon(
COLORREF clrIcon
)
{
CWindowDC dc( NULL );
ICONINFO iiNewIcon;
iiNewIcon.fIcon = true; // set that it is an icon
// create DC's
HDC hIconDC = ::CreateCompatibleDC( dc.GetSafeHdc() );
HDC hMaskDC = ::CreateCompatibleDC( dc.GetSafeHdc() );
ASSERT(
hIconDC != NULL && hMaskDC != NULL
);
// load bitmaps
iiNewIcon.hbmColor = ::CreateCompatibleBitmap(
dc.GetSafeHdc(),
16,
16
);
ASSERT( iiNewIcon.hbmColor != NULL );
iiNewIcon.hbmMask = ::CreateCompatibleBitmap(
hMaskDC,
16,
16
);
ASSERT( iiNewIcon.hbmMask != NULL );
HGDIOBJ hOldIconDC =
::SelectObject(
hIconDC,
iiNewIcon.hbmColor
);
ASSERT( hOldIconDC != NULL );
HGDIOBJ hOldMaskDC =
::SelectObject(
hMaskDC,
iiNewIcon.hbmMask
);
ASSERT( hOldMaskDC != NULL );
CBrush brColorItem( clrIcon );
CRect rcColorItem(0,0,16,16);
::FillRect(
hIconDC,
&rcColorItem,
(HBRUSH)brColorItem.GetSafeHandle()
);
::FillRect(
hMaskDC,
&rcColorItem,
(HBRUSH)::GetStockObject(BLACK_BRUSH)
);
::SelectObject(hIconDC,hOldIconDC);
::SelectObject(hMaskDC,hOldMaskDC);
HICON hIcon = CreateIconIndirect(&iiNewIcon);
ASSERT( hIcon != NULL );
// cleanup
DeleteObject(iiNewIcon.hbmColor);
DeleteObject(iiNewIcon.hbmMask);
DeleteDC(hMaskDC);
DeleteDC(hIconDC);
return hIcon;
}
void CExtColorButton::OnGenerateColorBtnIcon(
HICON * p_hIcon,
bool * p_bDestroyIcon
)
{
/*
CClientDC dc( this );
ASSERT( p_hIcon != NULL );
ASSERT( p_bDestroyIcon != NULL );
*p_hIcon = NULL;
*p_bDestroyIcon = false;
ICONINFO iiNewIcon;
iiNewIcon.fIcon = true; // set that it is an icon
// create DC's
HDC hIconDC = ::CreateCompatibleDC( dc.GetSafeHdc() );
HDC hMaskDC = ::CreateCompatibleDC( dc.GetSafeHdc() );
ASSERT(
hIconDC != NULL && hMaskDC != NULL
);
// load bitmaps
iiNewIcon.hbmColor = ::CreateCompatibleBitmap(
dc.GetSafeHdc(),
16,
16
);
ASSERT( iiNewIcon.hbmColor != NULL );
iiNewIcon.hbmMask = ::CreateCompatibleBitmap(
hMaskDC,
16,
16
);
ASSERT( iiNewIcon.hbmMask != NULL );
HGDIOBJ hOldIconDC =
::SelectObject(
hIconDC,
iiNewIcon.hbmColor
);
ASSERT( hOldIconDC != NULL );
HGDIOBJ hOldMaskDC =
::SelectObject(
hMaskDC,
iiNewIcon.hbmMask
);
ASSERT( hOldMaskDC != NULL );
CBrush brColorItem( m_clrSelected );
CRect rcColorItem(0,0,16,16);
::FillRect(
hIconDC,
&rcColorItem,
(HBRUSH)brColorItem.GetSafeHandle()
);
::FillRect(
hMaskDC,
&rcColorItem,
(HBRUSH)::GetStockObject(BLACK_BRUSH)
);
::SelectObject(hIconDC,hOldIconDC);
::SelectObject(hMaskDC,hOldMaskDC);
*p_hIcon = CreateIconIndirect(&iiNewIcon);
ASSERT( *p_hIcon != NULL );
// cleanup
DeleteObject(iiNewIcon.hbmColor);
DeleteObject(iiNewIcon.hbmMask);
DeleteDC(hMaskDC);
DeleteDC(hIconDC);
*/
*p_hIcon = NULL;
*p_bDestroyIcon = false;
*p_hIcon = GenerateColorIcon( m_clrSelected );
ASSERT( *p_hIcon != NULL );
}
void CExtColorButton::_RenderImpl( // non-buffered paint
CDC & dc,
bool bTransparent // = false
)
{
HICON hIcon = NULL;
bool bDestroyIcon = false;
OnGenerateColorBtnIcon( &hIcon, &bDestroyIcon );
CRect rectClient;
GetClientRect( &rectClient );
CString sWindowText( _T("") );
GetWindowText( sWindowText );
bool bDrawFocusRect = (GetFocus() == this) ? true : false;
bool bDefault = GetDefault() ? true : false;
bool bPushed = (m_bPushed || GetCheck()) ? true : false;
bool bEnabled = IsWindowEnabled() ? true : false;
bool bFlat = GetFlat() ? true : false;
bool bHover =
( m_bMouseOver
&& !CExtPopupMenuWnd::IsMenuTracking() )
? true : false;
if( GetParent()->IsKindOf(RUNTIME_CLASS(CControlBar)) )
{
bDrawFocusRect = false;
bFlat = true;
}
g_PaintManager->PaintPushButton(
dc, true, rectClient, (LPCTSTR)sWindowText,
hIcon, bFlat, bHover, bPushed,
false, bEnabled,
(m_bDrawBorder && (!CExtPopupMenuWnd::IsMenuTracking()))
? true : false,
(bDrawFocusRect && (!CExtPopupMenuWnd::IsMenuTracking())
&& (!sWindowText.IsEmpty()) )
? true : false,
bDefault, m_nAlign,
NULL, _IsMenuAvail(), 0, bTransparent
);
if( hIcon != NULL && bDestroyIcon )
{
::DestroyIcon( hIcon );
}
}
LRESULT CExtColorButton::OnColorChanged(WPARAM wParam, LPARAM lParam)
{
wParam;
lParam;
// m_clrSelected = (COLORREF)wParam;
// Invalidate();
// UpdateWindow();
//CExtPopupMenuWnd * pPopup =
// CExtPopupMenuWnd::GetTrackingMenu();
// if( pPopup != NULL
// && pPopup->GetSafeHwnd() != NULL
// )
// pPopup->Invalidate();
return
GetParent()->SendMessage(
CExtPopupColorMenuWnd::g_nMsgNotifyColorChanged,
wParam,
lParam
);
}
LRESULT CExtColorButton::OnColorChangedFinally(WPARAM wParam, LPARAM lParam)
{
lParam;
COLORREF clr = (COLORREF)wParam;
m_clrSelected = (clr == ((COLORREF)(-1))) ? RGB(0,0,0) : clr;
Invalidate();
UpdateWindow();
return
GetParent()->SendMessage(
CExtPopupColorMenuWnd::g_nMsgNotifyColorChangedFinally,
wParam,
lParam
);
}
LRESULT CExtColorButton::OnColorSelectCustom(WPARAM wParam, LPARAM lParam)
{
wParam;
lParam;
if( m_bUseStdColorDlg )
{
CColorDialog dlg(m_clrSelected,CC_FULLOPEN,this);
if( dlg.DoModal() != IDOK )
return 0;
m_clrSelected = dlg.m_cc.rgbResult;
} // if( m_bUseStdColorDlg )
else
{
CExtColorDlg dlg( m_clrSelected,m_clrSelected,this );
if( dlg.DoModal() != IDOK )
return 0;
m_clrSelected = dlg.m_clrNew;
} // else from if( m_bUseStdColorDlg )
GetParent()->SendMessage(
CExtPopupColorMenuWnd::g_nMsgNotifyColorChangedFinally,
WPARAM( m_clrSelected ),
lParam
);
Invalidate();
UpdateWindow();
return 0;
}
LRESULT CExtButton::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if(
message == CExtPopupMenuWnd::g_nMsgPrepareMenu
|| message == CExtPopupMenuWnd::g_nMsgPopupNext
|| message == CExtPopupMenuWnd::g_nMsgPopupPrev
|| message == CExtPopupMenuWnd::g_nMsgNotifyMenuExpanded
|| message == CExtPopupMenuWnd::g_nMsgNotifyMenuClosed
|| message == CExtPopupMenuWnd::g_nMsgPopupDrawItem
|| message == CExtPopupMenuWnd::g_nMsgPopupDrawLeftArea
)
{
CWnd * pParent = GetParent();
if( pParent )
return pParent->SendMessage( message, wParam, lParam );
else
return 0;
}
LRESULT lResult =
CButton::WindowProc( message, wParam, lParam );
// if(
// CExtPopupColorMenuWnd::g_nMsgNotifyColorChanged
// || CExtPopupColorMenuWnd::g_nMsgNotifyColorChangedFinally
// || CExtPopupColorMenuWnd::g_nMsgNotifyCustColor
// )
// {
// CWnd * pParent = GetParent();
// if( pParent )
// pParent->SendMessage( message, wParam, lParam );
// }
return lResult;
}