You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1706 lines
35 KiB
C++
1706 lines
35 KiB
C++
// XTPControl.cpp : implementation of the CXTPControl class.
|
|
//
|
|
// This file is a part of the XTREME COMMANDBARS MFC class library.
|
|
// (c)1998-2012 Codejock Software, All Rights Reserved.
|
|
//
|
|
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
|
|
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
|
|
// CONSENT OF CODEJOCK SOFTWARE.
|
|
//
|
|
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
|
|
// IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
|
|
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
|
|
// SINGLE COMPUTER.
|
|
//
|
|
// CONTACT INFORMATION:
|
|
// support@codejock.com
|
|
// http://www.codejock.com
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include "Resource.h"
|
|
#include "Common/Resource.h"
|
|
|
|
#include "Common/XTPResourceManager.h"
|
|
#include "Common/XTPImageManager.h"
|
|
#include "Common/XTPSystemHelpers.h"
|
|
#include "Common/XTPHookManager.h"
|
|
#include "Common/XTPColorManager.h"
|
|
#include "Common/XTPDrawHelpers.h"
|
|
|
|
#include "XTPCommandBarsDefines.h"
|
|
#include "XTPShortcutManager.h"
|
|
#include "XTPControl.h"
|
|
#include "XTPControls.h"
|
|
#include "XTPMouseManager.h"
|
|
#include "XTPCommandBar.h"
|
|
#include "XTPPaintManager.h"
|
|
#include "XTPCommandBars.h"
|
|
#include "XTPPopupBar.h"
|
|
#include "XTPCustomizeTools.h"
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
IMPLEMENT_DYNAMIC(CXTPControlAction, CCmdTarget)
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CXTPControlAction
|
|
|
|
CXTPControlAction::CXTPControlAction(CXTPControlActions* pActions)
|
|
{
|
|
|
|
m_nId = 0;
|
|
m_nIconId = 0;
|
|
m_nHelpId = 0;
|
|
m_nTag = 0;
|
|
m_bVisible = TRUE;
|
|
m_bChecked = FALSE;
|
|
m_bEnabled = TRUE;
|
|
|
|
m_pTarget = NULL;
|
|
|
|
m_pActions = pActions;
|
|
}
|
|
|
|
CXTPControlAction::~CXTPControlAction()
|
|
{
|
|
ASSERT(m_arrControls.GetSize() == 0);
|
|
|
|
if (m_pTarget)
|
|
{
|
|
CMDTARGET_RELEASE(m_pTarget);
|
|
}
|
|
}
|
|
|
|
void CXTPControlAction::AddControl(CXTPControl* pControl)
|
|
{
|
|
for (int i = 0; i < m_arrControls.GetSize(); i++)
|
|
{
|
|
if (m_arrControls[i] == pControl)
|
|
return;
|
|
}
|
|
|
|
m_arrControls.Add(pControl);
|
|
|
|
pControl->m_bEnabled = -1;
|
|
pControl->m_bChecked = -1;
|
|
pControl->m_nId = m_nId;
|
|
|
|
pControl->m_strCaption.Empty();
|
|
pControl->m_strTooltipText.Empty();
|
|
pControl->m_strDescriptionText.Empty();
|
|
pControl->m_strCategory.Empty();
|
|
pControl->m_strShortcutText.Empty();
|
|
pControl->m_strKeyboardTip.Empty();
|
|
}
|
|
|
|
|
|
void CXTPControlAction::RemoveControl(CXTPControl* pControl)
|
|
{
|
|
for (int i = 0; i < m_arrControls.GetSize(); i++)
|
|
{
|
|
if (m_arrControls[i] == pControl)
|
|
{
|
|
m_arrControls.RemoveAt(i);
|
|
|
|
pControl->m_bEnabled = TRUE;
|
|
pControl->m_bChecked = FALSE;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CXTPControlAction::OnChanged(int nProperty)
|
|
{
|
|
for (int i = 0; i < m_arrControls.GetSize(); i++)
|
|
{
|
|
m_arrControls[i]->OnActionChanged(nProperty);
|
|
}
|
|
}
|
|
|
|
void CXTPControlAction::OnChanging(int nProperty)
|
|
{
|
|
for (int i = 0; i < m_arrControls.GetSize(); i++)
|
|
{
|
|
m_arrControls[i]->OnActionChanging(nProperty);
|
|
}
|
|
}
|
|
|
|
void CXTPControlAction::RedrawControls()
|
|
{
|
|
for (int i = 0; i < m_arrControls.GetSize(); i++)
|
|
{
|
|
m_arrControls[i]->RedrawParent();
|
|
}
|
|
}
|
|
|
|
void CXTPControlAction::RepositionControls()
|
|
{
|
|
for (int i = 0; i < m_arrControls.GetSize(); i++)
|
|
{
|
|
m_arrControls[i]->DelayLayoutParent();
|
|
}
|
|
}
|
|
|
|
void CXTPControlAction::OnRemoved()
|
|
{
|
|
while (m_arrControls.GetSize() > 0)
|
|
{
|
|
m_arrControls[0]->SetAction(NULL);
|
|
}
|
|
}
|
|
|
|
void CXTPControlAction::SetCaption(UINT nIDCaption)
|
|
{
|
|
CString strCaption;
|
|
if (strCaption.LoadString(nIDCaption))
|
|
{
|
|
SetCaption(strCaption);
|
|
}
|
|
}
|
|
|
|
void CXTPControlAction::SetCaption(LPCTSTR lpszCaption)
|
|
{
|
|
CString strCaption(lpszCaption);
|
|
int nShortCutPos = strCaption.Find ('\t');
|
|
if (nShortCutPos != -1)
|
|
{
|
|
strCaption.ReleaseBuffer(nShortCutPos);
|
|
}
|
|
|
|
if (m_strCaption != strCaption)
|
|
{
|
|
OnChanging(3);
|
|
m_strCaption = strCaption;
|
|
OnChanged(3);
|
|
|
|
RepositionControls();
|
|
}
|
|
}
|
|
|
|
void CXTPControlAction::SetEditHint(LPCTSTR lpszEditHint)
|
|
{
|
|
CString strEditHint(lpszEditHint);
|
|
|
|
if (m_strEditHint != strEditHint)
|
|
{
|
|
OnChanging(4);
|
|
m_strEditHint = strEditHint;
|
|
OnChanged(4);
|
|
}
|
|
}
|
|
|
|
void CXTPControlAction::SetPrompt(LPCTSTR lpszPrompt)
|
|
{
|
|
if (lpszPrompt == NULL || lpszPrompt[0] == _T('\0'))
|
|
return;
|
|
|
|
if (_tcschr(lpszPrompt, _T('\n')) != NULL)
|
|
{
|
|
AfxExtractSubString(m_strTooltipText, lpszPrompt, 1);
|
|
AfxExtractSubString(m_strDescriptionText, lpszPrompt, 0);
|
|
}
|
|
else
|
|
{
|
|
m_strDescriptionText = m_strTooltipText = lpszPrompt;
|
|
}
|
|
|
|
|
|
if (m_strCaption.IsEmpty())
|
|
{
|
|
AfxExtractSubString(m_strCaption, lpszPrompt, 2);
|
|
}
|
|
|
|
if (m_strKeyboardTip.IsEmpty())
|
|
{
|
|
AfxExtractSubString(m_strKeyboardTip, lpszPrompt, 3);
|
|
}
|
|
}
|
|
|
|
BOOL CXTPControlAction::GetEnabled() const
|
|
{
|
|
if (GetCommandBars()->IsCustomizeMode())
|
|
return TRUE;
|
|
|
|
return m_bEnabled;
|
|
}
|
|
|
|
CXTPCommandBars* CXTPControlAction::GetCommandBars() const
|
|
{
|
|
return m_pActions->m_pCommandBars;
|
|
}
|
|
|
|
CXTPControl* CXTPControlAction::GetControl(int nIndex) const
|
|
{
|
|
return m_arrControls[nIndex];
|
|
}
|
|
|
|
int CXTPControlAction::GetCount() const
|
|
{
|
|
return (int)m_arrControls.GetSize();
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CXTPControlActions
|
|
|
|
CXTPControlActions::CXTPControlActions(CXTPCommandBars* pCommandBars)
|
|
{
|
|
m_pCommandBars = pCommandBars;
|
|
|
|
}
|
|
|
|
CXTPControlActions::~CXTPControlActions()
|
|
{
|
|
RemoveAll();
|
|
}
|
|
|
|
CXTPControlAction* CXTPControlActions::GetAt(int nIndex) const
|
|
{
|
|
return m_arrActions.GetAt(nIndex);
|
|
}
|
|
|
|
int CXTPControlActions::GetCount() const
|
|
{
|
|
return (int)m_arrActions.GetSize();
|
|
}
|
|
|
|
CXTPControlAction* CXTPControlActions::FindAction(int nId) const
|
|
{
|
|
if (nId <= 0 || nId >= 0xFFFFFFF)
|
|
return NULL;
|
|
|
|
int num = GetCount();
|
|
if (num == 0)
|
|
return NULL;
|
|
|
|
CXTPControlAction* const* lo = m_arrActions.GetData();
|
|
CXTPControlAction* const* hi = lo + (num - 1);
|
|
CXTPControlAction* const* mid;
|
|
|
|
while (lo <= hi)
|
|
{
|
|
int half = num / 2;
|
|
if (half)
|
|
{
|
|
mid = lo + (num & 1 ? half : (half - 1));
|
|
|
|
if ((*mid)->GetID() == nId)
|
|
return (*mid);
|
|
|
|
if ((*mid)->GetID() > nId)
|
|
{
|
|
hi = mid - 1;
|
|
num = num & 1 ? half : half - 1;
|
|
}
|
|
else
|
|
{
|
|
lo = mid + 1;
|
|
num = half;
|
|
}
|
|
}
|
|
else if (num)
|
|
return (*lo)->GetID() == nId ? (*lo) : NULL;
|
|
else
|
|
break;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void CXTPControlActions::RemoveAll()
|
|
{
|
|
for (int i = 0; i < GetCount(); i++)
|
|
{
|
|
CXTPControlAction* pAction = GetAt(i);
|
|
|
|
pAction->OnRemoved();
|
|
pAction->InternalRelease();
|
|
}
|
|
m_arrActions.RemoveAll();
|
|
}
|
|
|
|
void CXTPControlActions::Remove(int nId)
|
|
{
|
|
for (int i = 0; i < GetCount(); i++)
|
|
{
|
|
CXTPControlAction* pAction = GetAt(i);
|
|
|
|
if (pAction->GetID() == nId)
|
|
{
|
|
m_arrActions.RemoveAt(i);
|
|
pAction->OnRemoved();
|
|
pAction->InternalRelease();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CXTPControlActions::Insert(CXTPControlAction* pAction)
|
|
{
|
|
int nIndex = 0;
|
|
for (; nIndex < GetCount(); nIndex++)
|
|
{
|
|
if (GetAt(nIndex)->GetID() > pAction->GetID())
|
|
break;
|
|
}
|
|
|
|
m_arrActions.InsertAt(nIndex, pAction);
|
|
}
|
|
|
|
void CXTPControlActions::SetActionId(CXTPControlAction* pAction, int nId)
|
|
{
|
|
ASSERT(FindAction(nId) == NULL);
|
|
pAction->m_nId = nId;
|
|
}
|
|
|
|
CXTPControlAction* CXTPControlActions::Add(int nId, CXTPControlAction* pAction)
|
|
{
|
|
SetActionId(pAction, nId);
|
|
|
|
CString strPrompt;
|
|
if (XTPResourceManager()->LoadString(&strPrompt, nId))
|
|
{
|
|
pAction->SetPrompt(strPrompt);
|
|
}
|
|
|
|
Insert(pAction);
|
|
|
|
return pAction;
|
|
}
|
|
|
|
CXTPControlAction* CXTPControlActions::Add(int nId)
|
|
{
|
|
CXTPControlAction* pAction = FindAction(nId);
|
|
if (pAction)
|
|
return pAction;
|
|
|
|
pAction = new CXTPControlAction(this);
|
|
return Add(nId, pAction);
|
|
}
|
|
|
|
void CXTPControlActions::CreateFromMenu(CMenu* pMenu)
|
|
{
|
|
int nCount = ::GetMenuItemCount(pMenu->m_hMenu);
|
|
|
|
for (int nIndex = 0; nIndex < nCount; nIndex++)
|
|
{
|
|
// Check to see if the item is a separator, we don't want
|
|
// to use GetMenuItemID(i) because it may not equal zero.
|
|
|
|
MENUITEMINFO info = { sizeof(MENUITEMINFO), MIIM_TYPE | MIIM_STATE};
|
|
::GetMenuItemInfo(pMenu->m_hMenu, nIndex, TRUE, &info);
|
|
|
|
int nID = (int)pMenu->GetMenuItemID(nIndex);
|
|
BOOL bSeparator = ((info.fType & MFT_SEPARATOR) == MFT_SEPARATOR) || (nID == 0);
|
|
|
|
if (!bSeparator)
|
|
{
|
|
CMenu* pPopupMenu = pMenu->GetSubMenu(nIndex);
|
|
|
|
CString strCaption;
|
|
XTPResourceManager()->GetMenuLocaleString(pMenu, nIndex, strCaption, MF_BYPOSITION);
|
|
|
|
if (pPopupMenu)
|
|
{
|
|
nID = 0;
|
|
}
|
|
|
|
int iPos = strCaption.Find(_T('\t'));
|
|
if (pPopupMenu && iPos > 0)
|
|
{
|
|
nID = _ttoi(strCaption.Mid(iPos + 1));
|
|
strCaption.ReleaseBuffer(iPos);
|
|
}
|
|
|
|
if (nID > 0)
|
|
{
|
|
CXTPControlAction* pAction = Add(nID);
|
|
|
|
pAction->SetCaption(strCaption);
|
|
|
|
CString strPrompt;
|
|
if (XTPResourceManager()->LoadString(&strPrompt, nID))
|
|
{
|
|
pAction->SetPrompt(strPrompt);
|
|
}
|
|
}
|
|
|
|
if (pPopupMenu)
|
|
{
|
|
CreateFromMenu(pPopupMenu);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CXTPControl
|
|
|
|
CXTPControl::CXTPControl()
|
|
{
|
|
EnableAutomation();
|
|
|
|
|
|
m_nId = 0;
|
|
m_nIconId = 0;
|
|
m_nHelpId = 0;
|
|
m_nCustomIconId = 0;
|
|
m_nTag = 0;
|
|
m_nIndex = 0;
|
|
m_dwFlags = 0;
|
|
m_rcControl.SetRectEmpty();
|
|
m_rcRow.SetRectEmpty();
|
|
|
|
m_pParent = 0;
|
|
m_pControls = 0;
|
|
m_bExpanded = FALSE;
|
|
|
|
m_bChecked = FALSE;
|
|
m_bEnabled = TRUE;
|
|
m_bBeginGroup = FALSE;
|
|
m_bEnabled = TRUE;
|
|
m_bTemporary = FALSE;
|
|
m_bSelected = FALSE;
|
|
m_bPressed = FALSE;
|
|
|
|
m_bWrap = FALSE;
|
|
|
|
m_dwHideFlags = xtpNoHide;
|
|
m_controlType = xtpControlError;
|
|
|
|
m_bDefaultItem = FALSE;
|
|
m_buttonStyle = xtpButtonAutomatic;
|
|
m_buttonCustomStyle = xtpButtonUndefined;
|
|
m_buttonRibbonStyle = xtpButtonAutomatic;
|
|
|
|
m_bCloseSubMenuOnClick = TRUE;
|
|
|
|
m_pRibbonGroup = NULL;
|
|
|
|
m_pAction = 0;
|
|
|
|
m_nWidth = 0;
|
|
m_nHeight = 0;
|
|
m_szIcon = CSize(0, 0);
|
|
|
|
m_nExecuteOnPressInterval = 0;
|
|
}
|
|
|
|
CXTPControl::~CXTPControl()
|
|
{
|
|
if (m_pAction)
|
|
{
|
|
m_pAction->RemoveControl(this);
|
|
m_pAction = NULL;
|
|
}
|
|
}
|
|
|
|
void CXTPControl::SetAction(CXTPControlAction* pAction)
|
|
{
|
|
if (m_pAction)
|
|
{
|
|
m_pAction->RemoveControl(this);
|
|
m_pAction = NULL;
|
|
}
|
|
|
|
if (pAction)
|
|
{
|
|
m_pAction = pAction;
|
|
m_pAction->AddControl(this);
|
|
}
|
|
}
|
|
|
|
void CXTPControl::OnRemoved()
|
|
{
|
|
SetAction(NULL);
|
|
}
|
|
|
|
XTPButtonStyle CXTPControl::GetStyle() const
|
|
{
|
|
return m_buttonCustomStyle != xtpButtonUndefined ? m_buttonCustomStyle :
|
|
m_buttonStyle != xtpButtonAutomatic ? m_buttonStyle :
|
|
m_buttonRibbonStyle != xtpButtonAutomatic || !m_pParent ? m_buttonRibbonStyle : m_pParent->GetDefaultButtonStyle();
|
|
}
|
|
|
|
CSize CXTPControl::GetSize(CDC* pDC)
|
|
{
|
|
return GetPaintManager()->DrawControl(pDC, this, FALSE);
|
|
}
|
|
|
|
void CXTPControl::Draw(CDC* pDC)
|
|
{
|
|
GetPaintManager()->DrawControl(pDC, this);
|
|
}
|
|
|
|
void CXTPControl::DelayRedrawParent()
|
|
{
|
|
if (m_pParent && IsWindow(m_pParent->GetSafeHwnd()))
|
|
((CXTPCommandBar*)m_pParent)->DelayRedraw();
|
|
}
|
|
|
|
void CXTPControl::DelayLayoutParent()
|
|
{
|
|
if (m_pParent) m_pParent->DelayLayout();
|
|
}
|
|
|
|
void CXTPControl::RedrawParent(BOOL bAnimate)
|
|
{
|
|
if (!IsVisible())
|
|
return;
|
|
|
|
if (m_pParent) m_pParent->Redraw(GetRect(), bAnimate);
|
|
}
|
|
|
|
void CXTPControl::ScreenToClient(CPoint* point)
|
|
{
|
|
ASSERT(m_pParent);
|
|
if (m_pParent)
|
|
((CWnd*)m_pParent)->ScreenToClient(point);
|
|
}
|
|
|
|
|
|
BOOL CXTPControl::OnSetSelected(int bSelected)
|
|
{
|
|
if (bSelected == m_bSelected)
|
|
return FALSE;
|
|
|
|
if (IsKeyboardSelected(bSelected) && m_pParent->m_nPopuped != GetIndex())
|
|
m_pParent->SetPopuped(-1);
|
|
|
|
m_bSelected = bSelected;
|
|
|
|
m_pParent->OnControlSelected(bSelected, this);
|
|
|
|
if (GetEnabled() || IsKeyboardSelected(bSelected) || !bSelected)
|
|
RedrawParent(!bSelected);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPControl::OnMouseHover()
|
|
{
|
|
if (m_pParent->SetPopuped(-1))
|
|
{
|
|
if (m_pParent->IsTrackingMode() == TRUE_POPUP && m_pParent->GetPosition() != xtpBarPopup)
|
|
m_pParent->SetTrackingMode(FALSE);
|
|
}
|
|
}
|
|
|
|
void CXTPControl::SetPrompt(LPCTSTR lpszPrompt)
|
|
{
|
|
if (lpszPrompt == NULL || lpszPrompt[0] == _T('\0'))
|
|
return;
|
|
|
|
if (_tcschr(lpszPrompt, _T('\n')) != NULL)
|
|
{
|
|
AfxExtractSubString(m_strTooltipText, lpszPrompt, 1);
|
|
AfxExtractSubString(m_strDescriptionText, lpszPrompt, 0);
|
|
}
|
|
else
|
|
{
|
|
m_strDescriptionText = m_strTooltipText = lpszPrompt;
|
|
}
|
|
|
|
if (m_strCaption.IsEmpty())
|
|
{
|
|
if (!AfxExtractSubString(m_strCaption, lpszPrompt, 2) || m_strCaption.IsEmpty())
|
|
{
|
|
m_strCaption = m_strTooltipText;
|
|
OnCaptionChanged();
|
|
}
|
|
}
|
|
|
|
if (m_strKeyboardTip.IsEmpty())
|
|
{
|
|
AfxExtractSubString(m_strKeyboardTip, lpszPrompt, 3);
|
|
}
|
|
}
|
|
|
|
void CXTPControl::SetID(int nId)
|
|
{
|
|
if (m_nId == nId)
|
|
return;
|
|
|
|
CString strPrompt;
|
|
|
|
if (XTPResourceManager()->LoadString(&strPrompt, nId))
|
|
{
|
|
SetPrompt(strPrompt);
|
|
}
|
|
|
|
m_nId = nId;
|
|
}
|
|
|
|
void CXTPControl::OnActionChanged(int nProperty)
|
|
{
|
|
if (nProperty == 3)
|
|
{
|
|
OnCaptionChanged();
|
|
}
|
|
|
|
if (nProperty == 0)
|
|
{
|
|
OnEnabledChanged();
|
|
}
|
|
}
|
|
|
|
void CXTPControl::SetCaption(UINT nIDCaption)
|
|
{
|
|
CString strCaption;
|
|
if (strCaption.LoadString(nIDCaption))
|
|
{
|
|
SetCaption(strCaption);
|
|
}
|
|
}
|
|
|
|
void CXTPControl::SetCaption(LPCTSTR lpszCaption)
|
|
{
|
|
CString strCaption(lpszCaption);
|
|
BOOL bDelayLayout = FALSE;
|
|
|
|
int nShortCutPos = strCaption.Find ('\t');
|
|
if (nShortCutPos != -1)
|
|
{
|
|
CString strShortcutTextAuto = strCaption.Mid(nShortCutPos + 1);
|
|
|
|
if (m_strShortcutTextAuto != strShortcutTextAuto)
|
|
{
|
|
m_strShortcutTextAuto = strShortcutTextAuto;
|
|
bDelayLayout = TRUE;
|
|
}
|
|
strCaption.ReleaseBuffer(nShortCutPos);
|
|
}
|
|
|
|
if (m_strCaption != strCaption)
|
|
{
|
|
m_strCaption = strCaption;
|
|
OnCaptionChanged();
|
|
bDelayLayout = TRUE;
|
|
}
|
|
|
|
if (bDelayLayout)
|
|
{
|
|
DelayLayoutParent();
|
|
}
|
|
}
|
|
|
|
AFX_INLINE void NotifyExecute(CXTPControl* pControl, CWnd* pOwner)
|
|
{
|
|
NMXTPCONTROL tagNMCONTROL;
|
|
if (pControl->NotifySite(pOwner, CBN_XTP_EXECUTE, &tagNMCONTROL) == 0)
|
|
{
|
|
pOwner->SendMessage(WM_COMMAND, pControl->GetID());
|
|
}
|
|
}
|
|
|
|
//Click Helper
|
|
void CXTPControl::ClickToolBarButton(CRect rcActiveRect)
|
|
{
|
|
#define XTP_TID_CLICKTICK 0x10AD
|
|
|
|
if (rcActiveRect.IsRectEmpty())
|
|
rcActiveRect = m_rcControl;
|
|
|
|
m_pParent->SetPopuped(-1);
|
|
m_pParent->SetSelected(m_nIndex);
|
|
m_bPressed = TRUE;
|
|
RedrawParent();
|
|
|
|
InternalAddRef();
|
|
|
|
BOOL bExecuteOnTimer = m_nExecuteOnPressInterval > 0;
|
|
CWnd* pOwner = m_pParent->GetOwnerSite();
|
|
|
|
m_pParent->SetCapture();
|
|
HWND hWndCapture = m_pParent->GetSafeHwnd();
|
|
CPoint pt(0, 0);
|
|
BOOL bClick = FALSE;
|
|
|
|
if (bExecuteOnTimer)
|
|
{
|
|
m_pParent->SetTimer(XTP_TID_CLICKTICK, m_nExecuteOnPressInterval, NULL);
|
|
NotifyExecute(this, pOwner);
|
|
}
|
|
|
|
while (::GetCapture() == hWndCapture)
|
|
{
|
|
MSG msg;
|
|
VERIFY(::GetMessage(&msg, NULL, 0, 0));
|
|
|
|
if (msg.message == WM_LBUTTONUP)
|
|
{
|
|
bClick = m_bSelected && ((!pt.x && !pt.y) || rcActiveRect.PtInRect(pt));
|
|
break;
|
|
}
|
|
|
|
if (m_pParent == NULL)
|
|
break;
|
|
|
|
if (msg.message == WM_TIMER && msg.wParam == XTP_TID_CLICKTICK)
|
|
{
|
|
if (m_bSelected)
|
|
{
|
|
NotifyExecute(this, pOwner);
|
|
}
|
|
}
|
|
|
|
if (msg.message == WM_MOUSEMOVE)
|
|
{
|
|
pt = CPoint(LOWORD(msg.lParam), HIWORD(msg.lParam));
|
|
if (OnSetSelected(rcActiveRect.PtInRect(pt)))
|
|
{
|
|
RedrawParent();
|
|
}
|
|
continue;
|
|
}
|
|
|
|
DispatchMessage (&msg);
|
|
}
|
|
|
|
if (bExecuteOnTimer && m_pParent->GetSafeHwnd())
|
|
{
|
|
m_pParent->KillTimer(XTP_TID_CLICKTICK);
|
|
}
|
|
|
|
m_bPressed = bClick && !bExecuteOnTimer && NeedPressOnExecute() ? TRUE_KEYBOARD : FALSE;
|
|
|
|
ReleaseCapture();
|
|
|
|
if (!bExecuteOnTimer && m_bSelected && m_pParent)
|
|
{
|
|
m_pParent->SetSelected(-1);
|
|
m_bSelected = FALSE;
|
|
m_pParent->m_nClickedControl = GetIndex();
|
|
}
|
|
|
|
if (bClick && !bExecuteOnTimer)
|
|
{
|
|
OnExecute();
|
|
|
|
if (m_bPressed)
|
|
{
|
|
m_bPressed = FALSE;
|
|
RedrawParent();
|
|
}
|
|
}
|
|
else if (bClick && m_pParent->GetType() == xtpBarTypePopup && m_bCloseSubMenuOnClick)
|
|
{
|
|
m_bPressed = FALSE;
|
|
|
|
OnExecute();
|
|
}
|
|
else
|
|
{
|
|
RedrawParent();
|
|
}
|
|
|
|
InternalRelease();
|
|
}
|
|
|
|
LRESULT CXTPControl::NotifySite(UINT code)
|
|
{
|
|
if (!m_pParent)
|
|
return 0;
|
|
|
|
NMXTPCONTROL tagNMCONTROL;
|
|
return NotifySite(m_pParent->GetOwnerSite(), code, &tagNMCONTROL);
|
|
}
|
|
|
|
LRESULT CXTPControl::NotifySite(UINT code, NMXTPCONTROL* pNM)
|
|
{
|
|
if (!m_pParent)
|
|
return 0;
|
|
|
|
return NotifySite(m_pParent->GetOwnerSite(), code, pNM);
|
|
}
|
|
|
|
LRESULT CXTPControl::NotifySite(CWnd* pSite, UINT code, NMXTPCONTROL* pNM)
|
|
{
|
|
if (pSite == 0)
|
|
{
|
|
if (!m_pParent)
|
|
return 0;
|
|
|
|
pSite = m_pParent->GetOwnerSite();
|
|
}
|
|
|
|
pNM->hdr.code = code ;
|
|
pNM->hdr.idFrom = GetID();
|
|
pNM->hdr.hwndFrom = 0;
|
|
pNM->pControl = this;
|
|
|
|
LRESULT lResult = pSite->SendMessage(WM_XTP_COMMAND, GetID(), (LPARAM)pNM);
|
|
|
|
if (lResult || !m_pParent)
|
|
return lResult;
|
|
|
|
AFX_NOTIFY notify;
|
|
notify.pResult = &lResult;
|
|
notify.pNMHDR = (NMHDR*)pNM;
|
|
|
|
if (pSite->OnCmdMsg(GetID(), MAKELONG(code, WM_NOTIFY), ¬ify, NULL))
|
|
{
|
|
return lResult;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
BOOL CXTPControl::NeedPressOnExecute() const
|
|
{
|
|
if (m_pParent && m_pParent->GetPosition() == xtpBarPopup)
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPControl::OnExecute()
|
|
{
|
|
XTPSoundManager()->PlaySystemSound(xtpSoundMenuCommand);
|
|
|
|
m_bPressed = NeedPressOnExecute() ? TRUE_KEYBOARD : FALSE;
|
|
|
|
CXTPCommandBar* pCommandBar = m_pParent->GetRootParent();
|
|
BOOL bRecursePopup = pCommandBar->m_bRecursePopup;
|
|
|
|
CWnd* pOwner = m_pParent->GetOwnerSite();
|
|
CXTPCommandBars* pCommandBars = m_pParent->GetCommandBars();
|
|
|
|
if (pCommandBars)
|
|
{
|
|
if (m_nId) pCommandBars->SetCommandUsed(m_nId);
|
|
|
|
CXTPPopupBar* pPopupBar = DYNAMIC_DOWNCAST(CXTPPopupBar, m_pParent);
|
|
if (pPopupBar && pPopupBar->GetControlPopup() && ((CXTPControl*)pPopupBar->GetControlPopup())->GetID())
|
|
{
|
|
pCommandBars->SetCommandUsed(((CXTPControl*)pPopupBar->GetControlPopup())->GetID());
|
|
}
|
|
}
|
|
|
|
if (pCommandBar->m_pReturnCmd)
|
|
{
|
|
if (bRecursePopup)
|
|
pCommandBar->OnTrackLost();
|
|
else if (pCommandBars)
|
|
pCommandBars->ClosePopups();
|
|
else
|
|
XTPMouseManager()->SendTrackLost();
|
|
|
|
*pCommandBar->m_pReturnCmd = m_nId;
|
|
return;
|
|
}
|
|
|
|
|
|
InternalAddRef();
|
|
|
|
if (m_bCloseSubMenuOnClick)
|
|
{
|
|
if (bRecursePopup)
|
|
pCommandBar->OnTrackLost();
|
|
else if (pCommandBars)
|
|
pCommandBars->ClosePopups();
|
|
else
|
|
XTPMouseManager()->SendTrackLost();
|
|
}
|
|
|
|
if (m_nId == 0)
|
|
{
|
|
InternalRelease();
|
|
return;
|
|
}
|
|
|
|
NotifyExecute(this, pOwner);
|
|
|
|
if ((!m_bCloseSubMenuOnClick || m_bPressed) && m_pParent)
|
|
{
|
|
m_bPressed = FALSE;
|
|
|
|
m_pParent->OnIdleUpdateCmdUI(0, 0);
|
|
RedrawParent();
|
|
}
|
|
|
|
InternalRelease();
|
|
}
|
|
|
|
BOOL CXTPControl::IsCursorOver() const
|
|
{
|
|
CPoint pt;
|
|
GetCursorPos(&pt);
|
|
m_pParent->ScreenToClient(&pt);
|
|
return m_rcControl.PtInRect(pt);
|
|
}
|
|
|
|
void CXTPControl::Copy(CXTPControl* pControl, BOOL /*bRecursive*/)
|
|
{
|
|
m_nId = pControl->m_nId;
|
|
SetAction(pControl->GetAction());
|
|
|
|
m_nTag = pControl->m_nTag;
|
|
m_dwFlags = pControl->m_dwFlags;
|
|
m_controlType = pControl->m_controlType;
|
|
m_strCaption = pControl->m_strCaption;
|
|
m_strShortcutText = pControl->m_strShortcutText;
|
|
m_strShortcutTextAuto = pControl->m_strShortcutTextAuto;
|
|
m_strTooltipText = pControl->m_strTooltipText;
|
|
m_strDescriptionText = pControl->m_strDescriptionText;
|
|
m_strParameter = pControl->m_strParameter;
|
|
m_strKeyboardTip = pControl->m_strKeyboardTip;
|
|
m_nCustomIconId = pControl->m_nCustomIconId;
|
|
m_nIconId = pControl->m_nIconId;
|
|
m_nHelpId = pControl->m_nHelpId;
|
|
m_bTemporary = pControl->m_bTemporary;
|
|
m_strCustomCaption = pControl->m_strCustomCaption;
|
|
m_strCategory = pControl->m_strCategory;
|
|
m_dwHideFlags = pControl->m_dwHideFlags & ~(xtpHideWrap | xtpHideScroll | xtpHideDockingPosition | xtpHideExpand);
|
|
m_bDefaultItem = pControl->m_bDefaultItem;
|
|
m_bEnabled = pControl->m_bEnabled;
|
|
m_bChecked = pControl->m_bChecked;
|
|
m_buttonCustomStyle = pControl->m_buttonCustomStyle;
|
|
m_buttonStyle = pControl->m_buttonStyle;
|
|
|
|
m_nWidth = max(GetCustomizeMinWidth(), pControl->m_nWidth);
|
|
m_nHeight = pControl->m_nHeight;
|
|
|
|
m_szIcon = pControl->m_szIcon;
|
|
|
|
m_bBeginGroup = pControl->m_bBeginGroup;
|
|
|
|
m_bCloseSubMenuOnClick = pControl->m_bCloseSubMenuOnClick;
|
|
m_nExecuteOnPressInterval = pControl->m_nExecuteOnPressInterval;
|
|
|
|
m_mapDocTemplatesAssigned.Copy(pControl->m_mapDocTemplatesAssigned);
|
|
m_mapDocTemplatesExcluded.Copy(pControl->m_mapDocTemplatesExcluded);
|
|
|
|
OnCaptionChanged();
|
|
}
|
|
|
|
BOOL CXTPControl::Compare(CXTPControl* pOther)
|
|
{
|
|
if (GetStyle() != pOther->GetStyle())
|
|
return FALSE;
|
|
|
|
if (GetType() != pOther->GetType())
|
|
return FALSE;
|
|
|
|
if (GetID() != pOther->GetID())
|
|
return FALSE;
|
|
|
|
if (GetFlags() != pOther->GetFlags())
|
|
return FALSE;
|
|
|
|
if (GetBeginGroup() != pOther->GetBeginGroup())
|
|
return FALSE;
|
|
|
|
if (GetIconId() != pOther->GetIconId())
|
|
return FALSE;
|
|
|
|
if (m_strCaption != pOther->m_strCaption)
|
|
return FALSE;
|
|
|
|
if (m_strTooltipText != pOther->m_strTooltipText)
|
|
return FALSE;
|
|
|
|
if (m_strDescriptionText != pOther->m_strDescriptionText)
|
|
return FALSE;
|
|
|
|
if (m_strCustomCaption != pOther->m_strCustomCaption)
|
|
return FALSE;
|
|
|
|
if (m_buttonCustomStyle != pOther->m_buttonCustomStyle)
|
|
return FALSE;
|
|
|
|
if (m_strParameter != pOther->m_strParameter)
|
|
return FALSE;
|
|
|
|
if ((m_dwHideFlags & xtpHideCustomize) != (pOther->m_dwHideFlags & xtpHideCustomize))
|
|
return FALSE;
|
|
|
|
if (m_nWidth != pOther->m_nWidth)
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
IMPLEMENT_XTP_CONTROL(CXTPControl, CCmdTarget)
|
|
|
|
|
|
BOOL CXTPControl::IsCustomizeMode() const
|
|
{
|
|
return m_pParent ? m_pParent->IsCustomizeMode() : FALSE;
|
|
}
|
|
|
|
void CXTPControl::OnInvertTracker(CDC* pDC, CRect rect)
|
|
{
|
|
ASSERT(!rect.IsRectEmpty());
|
|
|
|
pDC->InvertRect(CRect(rect.left, rect.top, rect.right, rect.top + 2));
|
|
pDC->InvertRect(CRect(rect.left, rect.bottom - 2, rect.right, rect.bottom));
|
|
pDC->InvertRect(CRect(rect.left, rect.top + 2, rect.left + 2, rect.bottom - 2));
|
|
pDC->InvertRect(CRect(rect.right - 2, rect.top + 2, rect.right, rect.bottom - 2));
|
|
|
|
}
|
|
|
|
void CXTPControl::OnCustomizeMouseMove(CPoint point)
|
|
{
|
|
if (IsCustomizeResizeAllow() && m_rcControl.PtInRect(point) && ((point.x - m_rcControl.left <= 2) || (m_rcControl.right - point.x <= 2)))
|
|
{
|
|
::SetCursor(XTPResourceManager()->LoadCursor(XTP_IDC_VRESIZE));
|
|
}
|
|
}
|
|
|
|
BOOL CXTPControl::CustomizeStartResize(CPoint point)
|
|
{
|
|
if (m_rcControl.PtInRect(point) && ((point.x - m_rcControl.left <= 2) || (m_rcControl.right - point.x <= 2)))
|
|
{
|
|
CXTPCommandBars* pCommandBars = m_pParent->GetCommandBars();
|
|
ASSERT(pCommandBars);
|
|
ASSERT(pCommandBars->m_pDragSelected == this);
|
|
pCommandBars->m_pDragSelected = NULL;
|
|
m_pParent->Redraw();
|
|
m_pParent->UpdateWindow();
|
|
|
|
CRect rectTracker = m_rcControl;
|
|
m_pParent->ClientToScreen(rectTracker);
|
|
|
|
m_pParent->SetCapture();
|
|
::SetCursor(XTPResourceManager()->LoadCursor(XTP_IDC_VRESIZE));
|
|
|
|
CDC* pDC = 0;
|
|
|
|
CWnd* pWnd = CWnd::GetDesktopWindow();
|
|
if (pWnd->LockWindowUpdate())
|
|
pDC = pWnd->GetDCEx(NULL, DCX_WINDOW | DCX_CACHE | DCX_LOCKWINDOWUPDATE);
|
|
else
|
|
pDC = pWnd->GetDCEx(NULL, DCX_WINDOW | DCX_CACHE);
|
|
|
|
OnInvertTracker(pDC, rectTracker);
|
|
int nMinWidth = GetCustomizeMinWidth();
|
|
BOOL bLeftAnchor = (point.x - m_rcControl.left <= 2);
|
|
|
|
LONG& lTrackerAnchor = bLeftAnchor ? rectTracker.left : rectTracker.right;
|
|
int nOffset = bLeftAnchor ? m_rcControl.left - point.x : m_rcControl.right - point.x;
|
|
|
|
BOOL bAccept = FALSE;
|
|
while (CWnd::GetCapture() == m_pParent)
|
|
{
|
|
MSG msg;
|
|
if (!GetMessage(&msg, NULL, 0, 0))
|
|
break;
|
|
|
|
if (msg.message == WM_MOUSEMOVE)
|
|
{
|
|
point = CPoint(msg.lParam);
|
|
m_pParent->ClientToScreen(&point);
|
|
point.x += nOffset;
|
|
|
|
point.x = bLeftAnchor ? min(point.x, rectTracker.right - nMinWidth) :
|
|
max(point.x, rectTracker.left + nMinWidth);
|
|
|
|
if (lTrackerAnchor != point.x)
|
|
{
|
|
OnInvertTracker(pDC, rectTracker);
|
|
lTrackerAnchor = point.x;
|
|
OnInvertTracker(pDC, rectTracker);
|
|
}
|
|
}
|
|
else if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE) break;
|
|
else if (msg.message == WM_LBUTTONUP)
|
|
{
|
|
bAccept = TRUE;
|
|
break;
|
|
}
|
|
else ::DispatchMessage(&msg);
|
|
}
|
|
|
|
OnInvertTracker(pDC, rectTracker);
|
|
|
|
if (CWnd::GetCapture() == m_pParent) ReleaseCapture();
|
|
|
|
pWnd->UnlockWindowUpdate();
|
|
if (pDC != NULL)
|
|
{
|
|
pWnd->ReleaseDC(pDC);
|
|
pDC = NULL;
|
|
}
|
|
|
|
pCommandBars->m_pDragSelected = this;
|
|
|
|
int nWidth = rectTracker.Width();
|
|
|
|
if (bAccept && rectTracker.Width() != m_rcControl.Width())
|
|
{
|
|
if (GetParent()->GetType() == xtpBarTypePopup)
|
|
nWidth -= GetPaintManager()->GetPopupBarGripperWidth(GetParent());
|
|
|
|
SetWidth(nWidth);
|
|
m_pParent->OnRecalcLayout();
|
|
}
|
|
m_pParent->Redraw();
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void CXTPControl::CustomizeStartDrag(CPoint pt)
|
|
{
|
|
ASSERT(m_pParent);
|
|
if (!m_pParent)
|
|
return;
|
|
|
|
if (m_pParent->m_nPopuped != m_nIndex)
|
|
{
|
|
m_pParent->SetPopuped(-1);
|
|
m_pParent->SetSelected(-1);
|
|
}
|
|
|
|
CXTPCommandBars* pCommandBars = m_pParent->GetCommandBars();
|
|
ASSERT(pCommandBars);
|
|
if (!pCommandBars)
|
|
return;
|
|
|
|
if ((pCommandBars->m_pDragSelected == this) && IsCustomizeResizeAllow() &&
|
|
CustomizeStartResize(pt))
|
|
{
|
|
return;
|
|
}
|
|
|
|
pCommandBars->SetDragControl(this);
|
|
|
|
if (GetFlags() & xtpFlagNoMovable)
|
|
return;
|
|
|
|
CXTPCustomizeDropSource* pDropSource = pCommandBars->GetDropSource();
|
|
DROPEFFECT dropEffect = pDropSource->DoDragDrop(this);
|
|
|
|
if (dropEffect == DROPEFFECT_NONE || dropEffect == DROPEFFECT_MOVE)
|
|
{
|
|
CXTPCommandBar* pParent = m_pParent;
|
|
pParent->SetPopuped(-1);
|
|
pParent->SetSelected(-1);
|
|
|
|
if (pCommandBars->GetDragControl() == this)
|
|
pCommandBars->SetDragControl(NULL);
|
|
|
|
|
|
if (GetBeginGroup() && m_nIndex < m_pControls->GetCount() - 1)
|
|
m_pControls->GetAt(m_nIndex + 1)->SetBeginGroup(TRUE);
|
|
|
|
if (m_nIndex == 0 && m_pControls->GetCount() > 1)
|
|
m_pControls->GetAt(1)->SetBeginGroup(FALSE);
|
|
|
|
m_pControls->Remove(this);
|
|
|
|
pParent->OnRecalcLayout();
|
|
}
|
|
pCommandBars->SetDragControl(pCommandBars->GetDragControl());
|
|
}
|
|
|
|
void CXTPControl::OnCustomizeDragOver(CXTPControl* /*pDataObject*/, CPoint /*point*/, DROPEFFECT& /*dropEffect*/)
|
|
{
|
|
m_pParent->SetPopuped(-1);
|
|
m_pParent->SetSelected(-1);
|
|
}
|
|
BOOL CXTPControl::IsCustomizeDragOverAvail(CXTPCommandBar* /*pCommandBar*/, CPoint /*point*/, DROPEFFECT& /*dropEffect*/)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CXTPControl::IsCustomizeResizeAllow() const
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
CXTPImageManager* CXTPControl::GetImageManager() const
|
|
{
|
|
if (m_pParent)
|
|
return m_pParent->GetImageManager();
|
|
|
|
if (m_pControls)
|
|
{
|
|
CXTPCommandBars* pCommandBars = m_pControls->GetCommandBars();
|
|
if (pCommandBars)
|
|
return pCommandBars->GetImageManager();
|
|
}
|
|
return XTPImageManager();
|
|
}
|
|
CXTPPaintManager* CXTPControl::GetPaintManager() const
|
|
{
|
|
if (m_pParent)
|
|
return m_pParent->GetPaintManager();
|
|
|
|
if (m_pControls)
|
|
{
|
|
CXTPCommandBars* pCommandBars = m_pControls->GetCommandBars();
|
|
if (pCommandBars)
|
|
return pCommandBars->GetPaintManager();
|
|
}
|
|
return XTPPaintManager();
|
|
|
|
}
|
|
CXTPImageManagerIcon* CXTPControl::GetImage(int nWidth) const
|
|
{
|
|
if (GetIconId() != 0)
|
|
return GetImageManager()->GetImage(GetIconId(), nWidth);
|
|
return NULL;
|
|
|
|
}
|
|
|
|
void CXTPControl::SetExpanded(BOOL bExpanded)
|
|
{
|
|
m_bExpanded = bExpanded;
|
|
if (!bExpanded) SetHideFlags(GetHideFlags() & ~xtpHideExpand);
|
|
}
|
|
|
|
BOOL CXTPControl::IsItemDefault() const
|
|
{
|
|
return m_bDefaultItem;
|
|
}
|
|
|
|
void CXTPControl::SetItemDefault(BOOL bDefault)
|
|
{
|
|
if (bDefault != m_bDefaultItem)
|
|
{
|
|
m_bDefaultItem = bDefault;
|
|
DelayLayoutParent();
|
|
}
|
|
}
|
|
|
|
void CXTPControl::SetFlags(DWORD dwFlags)
|
|
{
|
|
m_dwFlags = dwFlags;
|
|
}
|
|
|
|
DWORD CXTPControl::GetFlags() const
|
|
{
|
|
return m_dwFlags;
|
|
}
|
|
|
|
BOOL CXTPControl::IsCustomizeMovable() const
|
|
{
|
|
if (m_pParent && m_pParent->IsCustomizable() && ((GetFlags() & xtpFlagNoMovable) == 0))
|
|
return TRUE;
|
|
|
|
if (!m_pParent)
|
|
return FALSE;
|
|
CXTPCommandBars* pCommandBars = m_pParent->GetCommandBars();
|
|
|
|
if (pCommandBars && pCommandBars->m_bDesignerMode)
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void CXTPControl::CDocTemplateMap::Copy(CDocTemplateMap& map)
|
|
{
|
|
RemoveAll();
|
|
|
|
UINT nIDResource;
|
|
BOOL bValue;
|
|
POSITION pos = map.GetStartPosition();
|
|
while (pos)
|
|
{
|
|
map.GetNextAssoc(pos, nIDResource, bValue);
|
|
SetAt(nIDResource, bValue);
|
|
}
|
|
}
|
|
|
|
CXTPControl* CXTPControl::FromUI(CCmdUI* pCmdUI)
|
|
{
|
|
CXTPCommandBar* pCommandBar = DYNAMIC_DOWNCAST(CXTPCommandBar, pCmdUI->m_pOther);
|
|
if (!pCommandBar)
|
|
return NULL;
|
|
|
|
CXTPControls* pControls = pCommandBar->GetControls();
|
|
if ((int)pCmdUI->m_nIndex < pControls->GetCount())
|
|
return pControls->GetAt(pCmdUI->m_nIndex);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
void CXTPControl::OnLButtonDown(CPoint point)
|
|
{
|
|
if (!m_pParent->IsCustomizeMode() || IsCustomizeMovable())
|
|
OnClick(FALSE, point);
|
|
}
|
|
|
|
BOOL CXTPControl::OnLButtonDblClk(CPoint point)
|
|
{
|
|
OnClick(FALSE, point);
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPControl::Reset()
|
|
{
|
|
if (m_nCustomIconId != 0 || !m_strCustomCaption.IsEmpty() || m_buttonCustomStyle != xtpButtonUndefined)
|
|
{
|
|
m_nCustomIconId = 0;
|
|
m_buttonCustomStyle = xtpButtonUndefined;
|
|
|
|
if (!m_strCustomCaption.IsEmpty())
|
|
{
|
|
m_strCustomCaption = _T("");
|
|
OnCaptionChanged();
|
|
}
|
|
GetParent()->OnRecalcLayout();
|
|
}
|
|
}
|
|
|
|
void CXTPControl::SetCustomIcon(HICON hIcon)
|
|
{
|
|
CXTPImageManager* pImageManager = GetImageManager();
|
|
if (pImageManager)
|
|
{
|
|
m_nCustomIconId = pImageManager->AddCustomIcon(hIcon);
|
|
}
|
|
}
|
|
|
|
CSize CXTPControl::GetButtonSize() const
|
|
{
|
|
return m_pParent->GetButtonSize();
|
|
}
|
|
|
|
CSize CXTPControl::GetIconSize() const
|
|
{
|
|
if (m_szIcon != CSize(0, 0))
|
|
return m_szIcon;
|
|
|
|
return m_pParent->GetIconSize();
|
|
}
|
|
|
|
|
|
BOOL CXTPControl::GetEnabled() const
|
|
{
|
|
BOOL bEnabled = m_pParent ? m_pParent->IsControlEnabled(this) : -1;
|
|
if (bEnabled != -1)
|
|
return bEnabled;
|
|
|
|
return m_bEnabled == -1 && m_pAction ? m_pAction->GetEnabled() : m_bEnabled;
|
|
}
|
|
|
|
|
|
#ifndef _XTP_INCLUDE_RIBBON
|
|
BOOL CXTPControl::HasDwmCompositedRect() const
|
|
{
|
|
if (!GetParent())
|
|
return FALSE;
|
|
|
|
if (GetParent()->IsDwmEnabled())
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
}
|
|
#endif
|
|
|
|
void CXTPControl::OnUnderlineActivate()
|
|
{
|
|
OnExecute();
|
|
}
|
|
|
|
BOOL CXTPControl::IsCaptionVisible() const
|
|
{
|
|
if (GetParent()->GetType() == xtpBarTypePopup)
|
|
return TRUE;
|
|
|
|
if (GetCaption().IsEmpty())
|
|
return FALSE;
|
|
|
|
XTPButtonStyle buttonStyle = GetStyle();
|
|
|
|
if ((buttonStyle == xtpButtonCaption) || (buttonStyle == xtpButtonIconAndCaption) || (buttonStyle == xtpButtonIconAndCaptionBelow))
|
|
return TRUE;
|
|
|
|
if (buttonStyle == xtpButtonIcon)
|
|
return FALSE;
|
|
|
|
switch (GetType())
|
|
{
|
|
case xtpControlPopup:
|
|
case xtpControlLabel:
|
|
case xtpControlCheckBox:
|
|
case xtpControlRadioButton:
|
|
return TRUE;
|
|
|
|
case xtpControlButton:
|
|
case xtpControlButtonPopup:
|
|
case xtpControlSplitButtonPopup:
|
|
CXTPImageManagerIcon* pImage = GetImage(0);
|
|
return pImage == NULL;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
CCmdTarget* CXTPControl::GetAccessible()
|
|
{
|
|
return this;
|
|
}
|
|
|
|
HRESULT CXTPControl::GetAccessibleParent(IDispatch* FAR* ppdispParent)
|
|
{
|
|
SAFE_MANAGE_STATE(m_pModuleState);
|
|
|
|
*ppdispParent = NULL;
|
|
|
|
if (m_pParent)
|
|
{
|
|
*ppdispParent = m_pParent->GetIDispatch(TRUE);
|
|
return S_OK;
|
|
}
|
|
return E_FAIL;
|
|
}
|
|
|
|
HRESULT CXTPControl::GetAccessibleChildCount(long FAR* pChildCount)
|
|
{
|
|
if (pChildCount == 0)
|
|
return E_INVALIDARG;
|
|
|
|
*pChildCount = GetCommandBar() ? 1 : 0;
|
|
|
|
return S_OK;
|
|
}
|
|
HRESULT CXTPControl::GetAccessibleChild(VARIANT varChild, IDispatch* FAR* ppdispChild)
|
|
{
|
|
SAFE_MANAGE_STATE(m_pModuleState);
|
|
|
|
*ppdispChild = NULL;
|
|
|
|
if (GetChildIndex(&varChild) == 1)
|
|
{
|
|
CXTPCommandBar* pCommandBar = GetCommandBar();
|
|
if (pCommandBar)
|
|
{
|
|
*ppdispChild = pCommandBar->GetIDispatch(TRUE);
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CXTPControl::GetAccessibleName(VARIANT varChild, BSTR* pszName)
|
|
{
|
|
SAFE_MANAGE_STATE(m_pModuleState);
|
|
|
|
if (GetChildIndex(&varChild) != CHILDID_SELF)
|
|
return E_INVALIDARG;
|
|
|
|
CString strCaption = GetCaption();
|
|
CXTPPaintManager::StripMnemonics(strCaption);
|
|
|
|
if (!GetShortcutText().IsEmpty())
|
|
strCaption = strCaption + _T('\t') + GetShortcutText();
|
|
|
|
if (strCaption.IsEmpty())
|
|
{
|
|
strCaption = GetTooltip();
|
|
}
|
|
|
|
*pszName = strCaption.AllocSysString();
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CXTPControl::GetAccessibleKeyboardShortcut(VARIANT varChild, BSTR* pszKeyboardShortcut)
|
|
{
|
|
SAFE_MANAGE_STATE(m_pModuleState);
|
|
|
|
if (GetChildIndex(&varChild) != CHILDID_SELF)
|
|
return E_INVALIDARG;
|
|
|
|
CString strCaption = GetCaption();
|
|
if (strCaption.IsEmpty())
|
|
{
|
|
*pszKeyboardShortcut = SysAllocString(L"");
|
|
}
|
|
else
|
|
{
|
|
int nIndex = CXTPShortcutManager::FindAccelPos(strCaption);
|
|
CString strShortcut = CString(strCaption[nIndex + 1]);
|
|
|
|
*pszKeyboardShortcut = strShortcut.AllocSysString();
|
|
}
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
HRESULT CXTPControl::GetAccessibleDescription(VARIANT varChild, BSTR* pszDescription)
|
|
{
|
|
if (GetChildIndex(&varChild) != CHILDID_SELF)
|
|
return E_INVALIDARG;
|
|
|
|
*pszDescription = GetDescription().AllocSysString();
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CXTPControl::GetAccessibleRole(VARIANT varChild, VARIANT* pvarRole)
|
|
{
|
|
pvarRole->vt = VT_EMPTY;
|
|
|
|
if (m_pParent && m_pParent->GetSafeHwnd() && GetChildIndex(&varChild) == CHILDID_SELF)
|
|
{
|
|
pvarRole->vt = VT_I4;
|
|
pvarRole->lVal = m_pParent->GetType() == xtpBarTypeNormal || m_pParent->GetType() == xtpBarTypeRibbon ?
|
|
GetCommandBar() ? ROLE_SYSTEM_BUTTONMENU: ROLE_SYSTEM_PUSHBUTTON : ROLE_SYSTEM_MENUITEM;
|
|
return S_OK;
|
|
}
|
|
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
HRESULT CXTPControl::AccessibleSelect(long /*flagsSelect*/, VARIANT varChild)
|
|
{
|
|
SAFE_MANAGE_STATE(m_pModuleState);
|
|
|
|
if (GetChildIndex(&varChild) != CHILDID_SELF)
|
|
return E_INVALIDARG;
|
|
|
|
if (m_pParent && m_pParent->GetSafeHwnd())
|
|
{
|
|
m_pParent->SetTrackingMode(TRUE, FALSE);
|
|
m_pParent->SetSelected(m_nIndex, TRUE);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
#ifndef STATE_SYSTEM_HASPOPUP
|
|
#define STATE_SYSTEM_HASPOPUP (0x40000000)
|
|
#endif //STATE_SYSTEM_HASPOPUP
|
|
|
|
|
|
HRESULT CXTPControl::GetAccessibleState(VARIANT varChild, VARIANT* pvarState)
|
|
{
|
|
if (GetChildIndex(&varChild) != CHILDID_SELF)
|
|
return E_INVALIDARG;
|
|
|
|
pvarState->vt = VT_I4;
|
|
pvarState->lVal = STATE_SYSTEM_FOCUSABLE |
|
|
(m_bSelected ? STATE_SYSTEM_FOCUSED | STATE_SYSTEM_SELECTED | STATE_SYSTEM_HOTTRACKED : 0);
|
|
|
|
if (!m_pParent->IsVisible() || !IsVisible())
|
|
pvarState->lVal |= STATE_SYSTEM_INVISIBLE;
|
|
|
|
if (!GetEnabled())
|
|
pvarState->lVal |= STATE_SYSTEM_UNAVAILABLE;
|
|
|
|
if (GetChecked())
|
|
pvarState->lVal |= STATE_SYSTEM_CHECKED;
|
|
|
|
if (GetPressed())
|
|
pvarState->lVal |= STATE_SYSTEM_PRESSED;
|
|
|
|
if (GetCommandBar())
|
|
pvarState->lVal |= STATE_SYSTEM_HASPOPUP;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CXTPControl::GetAccessibleDefaultAction(VARIANT varChild, BSTR* pszDefaultAction)
|
|
{
|
|
if (GetChildIndex(&varChild) != CHILDID_SELF)
|
|
return E_INVALIDARG;
|
|
|
|
*pszDefaultAction = SysAllocString(L"Click");
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CXTPControl::AccessibleDoDefaultAction(VARIANT varChild)
|
|
{
|
|
SAFE_MANAGE_STATE(m_pModuleState);
|
|
|
|
if (GetChildIndex(&varChild) != CHILDID_SELF)
|
|
return E_INVALIDARG;
|
|
|
|
OnClick(TRUE);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
HRESULT CXTPControl::AccessibleLocation(long* pxLeft, long* pyTop, long* pcxWidth, long* pcyHeight, VARIANT varChild)
|
|
{
|
|
*pxLeft = *pyTop = *pcxWidth = *pcyHeight = 0;
|
|
|
|
if (GetChildIndex(&varChild) != CHILDID_SELF)
|
|
return E_INVALIDARG;
|
|
|
|
if (!m_pParent->GetSafeHwnd())
|
|
return S_OK;
|
|
|
|
if (!IsVisible())
|
|
return S_OK;
|
|
|
|
CRect rcControl = GetRect();
|
|
m_pParent->ClientToScreen(&rcControl);
|
|
|
|
*pxLeft = rcControl.left;
|
|
*pyTop = rcControl.top;
|
|
*pcxWidth = rcControl.Width();
|
|
*pcyHeight = rcControl.Height();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CXTPControl::AccessibleHitTest(long xLeft, long yTop, VARIANT* pvarID)
|
|
{
|
|
if (pvarID == NULL)
|
|
return E_INVALIDARG;
|
|
|
|
pvarID->vt = VT_EMPTY;
|
|
|
|
if (!m_pParent->GetSafeHwnd())
|
|
return S_FALSE;
|
|
|
|
if (!CXTPWindowRect(m_pParent).PtInRect(CPoint(xLeft, yTop)))
|
|
return S_FALSE;
|
|
|
|
pvarID->vt = VT_I4;
|
|
pvarID->lVal = 0;
|
|
|
|
CPoint pt(xLeft, yTop);
|
|
m_pParent->ScreenToClient(&pt);
|
|
|
|
if (!GetRect().PtInRect(pt))
|
|
return S_FALSE;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
void CXTPControl::SetVisible(BOOL bVisible)
|
|
{
|
|
DWORD dwHideFlags = m_dwHideFlags;
|
|
if (!bVisible) SetHideFlags(m_dwHideFlags | xtpHideGeneric); else SetHideFlags(m_dwHideFlags & ~xtpHideGeneric);
|
|
if (dwHideFlags != m_dwHideFlags) DelayLayoutParent();
|
|
}
|
|
|
|
BOOL CXTPControl::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
|
|
{
|
|
if (nCode == CN_EVENT && nID == XTP_CN_REDRAWPARENT)
|
|
{
|
|
RedrawParent(FALSE);
|
|
return TRUE;
|
|
}
|
|
return CCmdTarget::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
|
|
}
|
|
|
|
|
|
|
|
BEGIN_INTERFACE_MAP(CXTPControl, CCmdTarget)
|
|
INTERFACE_PART(CXTPControl, IID_IAccessible, ExternalAccessible)
|
|
END_INTERFACE_MAP()
|