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.

1771 lines
41 KiB
C++

// XTPControlComboBox.cpp : implementation of the CXTPControlComboBox 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 "Common/XTPDrawHelpers.h"
#include "Common/XTPColorManager.h"
#include "Common/XTPPropExchange.h"
#include "Common/XTPImageManager.h"
#include "Common/XTPToolTipContext.h"
#include "Common/XTPSystemHelpers.h"
#include "Common/XTPHookManager.h"
#include "XTPCommandBarsDefines.h"
#include "XTPControl.h"
#include "XTPControlButton.h"
#include "XTPControlPopup.h"
#include "XTPCommandBar.h"
#include "XTPPopupBar.h"
#include "XTPControlEdit.h"
#include "XTPControlComboBox.h"
#include "XTPCommandBars.h"
#include "XTPPaintManager.h"
#include "XTPMouseManager.h"
#include "XTPKeyboardManager.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//////////////////////////////////////////////////////////////////////////
// CXTPControlComboBoxAutoCompleteWnd
HHOOK CXTPControlComboBoxAutoCompleteWnd::m_hHookMessage = 0;
CXTPControlComboBoxAutoCompleteWnd* CXTPControlComboBoxAutoCompleteWnd::m_pWndMonitor = 0;
#define WM_XTP_SHELLAUTOCOMPLETESTART (WM_XTP_COMMANDBARS_BASE + 30)
CXTPControlComboBoxAutoCompleteWnd::CXTPControlComboBoxAutoCompleteWnd()
{
m_hWndAutoComplete = 0;
m_hWndEdit = 0;
}
CXTPControlComboBoxAutoCompleteWnd::~CXTPControlComboBoxAutoCompleteWnd()
{
SetupMessageHook(FALSE);
SetAutoCompeteHandle(NULL);
}
BOOL CXTPControlComboBoxAutoCompleteWnd::IsDialogCode(UINT nChar, LPARAM lParam)
{
if (!m_hWndAutoComplete)
return FALSE;
if (! ((nChar == VK_UP || nChar == VK_DOWN || nChar == VK_NEXT || nChar == VK_PRIOR) && (GetKeyState(VK_MENU) >= 0)))
return FALSE;
HWND hWnd = ::GetWindow(m_hWndAutoComplete, GW_CHILD);
hWnd = ::GetWindow(hWnd, GW_HWNDLAST);
MSG msg;
msg.message = WM_KEYDOWN;
msg.hwnd = hWnd;
msg.wParam = (WPARAM)nChar;
msg.lParam = lParam;
if (::IsDialogMessage(m_hWndAutoComplete, &msg))
return TRUE;
return FALSE;
}
HRESULT CXTPControlComboBoxAutoCompleteWnd::ShellAutoComplete(HWND hEdit, DWORD dwFlags)
{
m_hWndEdit = hEdit;
HRESULT hResult = E_FAIL;
HMODULE hLib = LoadLibraryA("shlwapi.dll");
if (hLib)
{
typedef HRESULT (STDAPICALLTYPE *SHAUTOCOMPLETE)(HWND hwndEdit, DWORD dwFlags);
SHAUTOCOMPLETE _SHAutoComplete = NULL;
_SHAutoComplete = (SHAUTOCOMPLETE)GetProcAddress(hLib, "SHAutoComplete");
if (_SHAutoComplete)
{
hResult = _SHAutoComplete(hEdit, dwFlags);
}
FreeLibrary(hLib);
}
return hResult;
}
void CXTPControlComboBoxAutoCompleteWnd::CloseWindow()
{
if (m_hWndAutoComplete)
{
ShowWindow(m_hWndAutoComplete, SW_HIDE);
}
}
void CXTPControlComboBoxAutoCompleteWnd::SetAutoCompeteHandle(HWND hWnd)
{
if (m_hWndAutoComplete == hWnd)
return;
if (hWnd)
{
XTPMouseManager()->AddTrustedWindow(hWnd);
}
else
{
XTPMouseManager()->RemoveTrustedWindow(m_hWndAutoComplete);
}
m_hWndAutoComplete = hWnd;
}
void CXTPControlComboBoxAutoCompleteWnd::SetupMessageHook(BOOL bSetup)
{
if (bSetup && m_hHookMessage == 0)
{
ASSERT(m_pWndMonitor == NULL);
m_hHookMessage = SetWindowsHookEx(WH_CALLWNDPROC, CallWndProc, AfxGetInstanceHandle(), GetCurrentThreadId());
XTPKeyboardManager()->HookKeyboard(this);
m_pWndMonitor = this;
}
if (!bSetup && m_hHookMessage && (m_pWndMonitor == this))
{
UnhookWindowsHookEx(m_hHookMessage);
XTPKeyboardManager()->UnhookKeyboard(m_pWndMonitor);
m_hHookMessage = 0;
m_pWndMonitor = NULL;
}
if (!bSetup)
{
SetAutoCompeteHandle(NULL);
}
}
int CXTPControlComboBoxAutoCompleteWnd::OnHookMessage(HWND /*hWnd*/, UINT nMessage, WPARAM& /*wParam*/, LPARAM& /*lParam*/, LRESULT& /*lResult*/)
{
if (nMessage == WM_MOUSEWHEEL && m_hWndAutoComplete)
return FALSE_EXIT;
return FALSE;
}
LRESULT CALLBACK CXTPControlComboBoxAutoCompleteWnd::CallWndProc(int code, WPARAM wParam, LPARAM lParam)
{
CWPSTRUCT* pMSG = (CWPSTRUCT*)lParam;
if (pMSG && m_pWndMonitor && pMSG->message == WM_WINDOWPOSCHANGING)
{
const HWND& hWndAutoComplete = m_pWndMonitor->m_hWndAutoComplete;
WINDOWPOS* pWindowPos = (WINDOWPOS*)pMSG->lParam;
if ((hWndAutoComplete != 0 && hWndAutoComplete == pWindowPos->hwnd) && (pWindowPos->flags & SWP_HIDEWINDOW))
{
m_pWndMonitor->SetAutoCompeteHandle(NULL);
}
else if ((hWndAutoComplete == 0) && (pWindowPos->flags & SWP_SHOWWINDOW))
{
HWND hWnd = pWindowPos->hwnd;
TCHAR szClassName[255];
::GetClassName(hWnd, szClassName, 255);
if (_tcscmp(szClassName, _T("Auto-Suggest Dropdown")) == 0)
{
m_pWndMonitor->SetAutoCompeteHandle(hWnd);
PostMessage(m_pWndMonitor->m_hWndEdit, WM_XTP_SHELLAUTOCOMPLETESTART, 0, 0);
}
}
}
return CallNextHookEx(m_hHookMessage, code, wParam, lParam);
}
// CXTPControlComboBox
IMPLEMENT_XTP_CONTROL(CXTPControlComboBox, CXTPControlPopup)
CXTPControlComboBox::CXTPControlComboBox(CXTPCommandBars* pCommandBars)
{
EnableAutomation();
m_controlType = xtpControlComboBox;
m_bDropDown = FALSE;
m_comboStyle = xtpComboNormal;
m_nWidth = 100;
m_nLabelWidth = 0;
m_nThumbWidth = 0;
m_pEdit = NULL;
m_strEditText = _T("");
m_nCurSel = m_nLastSel = -1;
m_bDelayReposition = FALSE;
m_bDelayDestroy = FALSE;
m_bIgnoreAutoComplete = m_bAutoComplete = FALSE;
m_bFocused = FALSE;
m_nDropDownItemCount = 12;
m_bIgnoreSelection = FALSE;
m_nTextLimit = 0;
m_pCommandBar = new CXTPControlComboBoxList();
m_pCommandBar->SetCommandBars(pCommandBars);
((CXTPControlComboBoxList*)m_pCommandBar)->CreateListBox();
m_dwShellAutoCompleteFlags = 0;
m_pAutoCompleteWnd = NULL;
m_nEditIconId = 0;
m_bSelEndOk = FALSE;
m_bEditChanged = TRUE;
m_dwEditStyle = 0;
}
CXTPControlComboBox::~CXTPControlComboBox()
{
if (m_pEdit)
{
delete m_pEdit;
}
SAFE_DELETE(m_pAutoCompleteWnd);
}
CString CXTPControlComboBox::GetEditText() const
{
CString strEditText = _GetEditText();
return strEditText == GetEditHint() ? _T("") : strEditText;
}
CString CXTPControlComboBox::_GetEditText() const
{
if (m_pEdit && m_pEdit->GetSafeHwnd() && m_bEditChanged)
{
m_pEdit->GetWindowTextEx(m_strEditText);
m_bEditChanged = FALSE;
}
return m_strEditText;
}
void CXTPControlComboBox::SetEditText(const CString& strText)
{
_SetEditText(strText.IsEmpty() ? GetEditHint() : strText);
}
void CXTPControlComboBox::_SetEditText(const CString& strText)
{
if (m_pEdit && m_pEdit->GetSafeHwnd() && _GetEditText() != strText)
{
m_pEdit->SetWindowTextEx(strText);
}
m_strEditText = strText;
m_bEditChanged = FALSE;
}
void CXTPControlComboBox::SetEditHint(LPCTSTR lpszEditHint)
{
if (!GetEditHint().IsEmpty() && _GetEditText() == GetEditHint())
{
_SetEditText(_T(""));
}
m_strEditHint = lpszEditHint;
if (_GetEditText().IsEmpty() && !GetEditHint().IsEmpty())
{
_SetEditText(GetEditHint());
}
}
void CXTPControlComboBox::SetTextLimit(int nTextLimit)
{
m_nTextLimit = nTextLimit;
if (m_pEdit && m_pEdit->GetSafeHwnd())
m_pEdit->LimitText(m_nTextLimit);
}
int CXTPControlComboBox::GetTextLimit() const
{
return m_nTextLimit;
}
BOOL CXTPControlComboBox::IsImageVisible() const
{
if (GetParent()->GetType() == xtpBarTypePopup)
return GetImage(0) != NULL;
BOOL bImageVisible = (CXTPControl::GetStyle() == xtpButtonIcon || CXTPControl::GetStyle() == xtpButtonIconAndCaption)
&& (GetImage(0) != NULL);
return bImageVisible;
}
BOOL CXTPControlComboBox::IsCaptionVisible() const
{
if (GetParent()->GetType() == xtpBarTypePopup)
return TRUE;
if (GetCaption().IsEmpty())
return FALSE;
XTPButtonStyle buttonStyle = CXTPControl::GetStyle();
if ((buttonStyle == xtpButtonCaption) || (buttonStyle == xtpButtonIconAndCaption) || (buttonStyle == xtpButtonIconAndCaptionBelow))
return TRUE;
return m_comboStyle == xtpComboLabel;
}
CString CXTPControlComboBox::GetEditHint() const
{
return !m_strEditHint.IsEmpty() ? m_strEditHint : m_pAction ? m_pAction->GetEditHint() : _T("");
}
void CXTPControlComboBox::UpdatePopupSelection()
{
CEdit* pEdit = GetEditCtrl();
CXTPControlComboBoxPopupBar* pPopupBar = GetComboBoxPopupBar();
if (!m_bIgnoreSelection && pEdit && pEdit->GetSafeHwnd() && pPopupBar)
{
CString strWindowText = _GetEditText();
int nIndex = pPopupBar->FindStringExact(0, strWindowText);
if (nIndex != LB_ERR)
pPopupBar->SetCurSel(nIndex);
else
{
nIndex = pPopupBar->FindString(0, strWindowText);
pPopupBar->SetTopIndex(nIndex);
pPopupBar->SetCurSel(nIndex);
pPopupBar->SetCurSel(-1);
}
}
}
void CXTPControlComboBox::OnEditChanged()
{
CEdit* pEdit = GetEditCtrl();
CXTPControlComboBoxPopupBar* pPopupBar = GetComboBoxPopupBar();
if (!m_bIgnoreSelection && m_bAutoComplete && !m_bIgnoreAutoComplete && pEdit && pEdit->GetSafeHwnd() && pPopupBar)
{
CString strWindowText = _GetEditText();
int nLength = strWindowText.GetLength();
if (nLength > 0)
{
// Currently selected range
int nStart = 0, nEnd = 0;
pEdit->GetSel(nStart, nEnd);
if (nStart == nEnd && nLength == nEnd)
{
int nIndex = pPopupBar->FindString(0, strWindowText);
if (nIndex != LB_ERR)
{
CString strWindowTextNew;
pPopupBar->GetText(nIndex, strWindowTextNew);
_SetEditText(strWindowTextNew);
pEdit->SetSel(strWindowTextNew.GetLength(), nLength);
}
}
}
m_bIgnoreAutoComplete = TRUE;
}
UpdatePopupSelection();
NotifySite(CBN_EDITCHANGE);
}
void CXTPControlComboBox::OnSelChanged()
{
m_bIgnoreSelection = TRUE;
_SetEditText(GetListBoxText());
m_bIgnoreSelection = FALSE;
RedrawParent(FALSE);
NotifySite(CBN_SELCHANGE);
}
BOOL CXTPControlComboBox::OnHookMouseWheel(UINT /*nFlags*/, short zDelta, CPoint /*pt*/)
{
if (!IsFocused())
return FALSE;
if (GetDroppedState())
return FALSE;
if (m_pAutoCompleteWnd)
return FALSE;
if (!IsValidList())
return FALSE;
((CXTPControlComboBoxPopupBar*)m_pCommandBar)->ProcessHookKeyDown(this, zDelta > 0 ? VK_UP : VK_DOWN, 0);
return TRUE;
}
BOOL CXTPControlComboBox::OnHookKeyDown(UINT nChar, LPARAM lParam)
{
ASSERT(IsFocused());
if (!IsFocused())
return FALSE;
m_bIgnoreAutoComplete = (nChar == VK_DELETE) || (nChar == VK_BACK);
if (m_pEdit && m_pEdit->m_bImeMode)
return FALSE_EXIT;
if (nChar == VK_TAB && ((m_pAutoCompleteWnd == NULL) || ((m_dwShellAutoCompleteFlags & SHACF_USETAB) == 0)))
return FALSE;
if (nChar == VK_RETURN)
return FALSE;
if (nChar == VK_ESCAPE)
{
m_pCommandBar->OnTrackLost();
SetCurSel(m_nLastSel);
SetEditText(m_strLastText);
SetFocused(FALSE);
return GetParent()->GetType() == xtpBarTypePopup;
}
if (m_pEdit && m_pEdit->GetSafeHwnd() && GetKeyState(VK_MENU) < 0 && GetKeyState(VK_CONTROL) >= 0)
{
CXTPCommandBars* pCommandBars = m_pParent->GetCommandBars();
if (pCommandBars && pCommandBars->OnFrameAccel((TCHAR)nChar))
return TRUE;
}
if ((nChar == VK_F4 && GetKeyState(VK_MENU) >= 0) || ((nChar == VK_UP || nChar == VK_DOWN) && GetKeyState(VK_MENU) < 0))
{
OnClick(FALSE);
return TRUE;
}
if (m_pAutoCompleteWnd && m_pAutoCompleteWnd->IsDialogCode(nChar, lParam))
return TRUE;
if ((!m_pEdit || (nChar == VK_UP || nChar == VK_DOWN || nChar == VK_NEXT || nChar == VK_PRIOR) && (GetKeyState(VK_MENU) >= 0)) && IsValidList())
{
((CXTPControlComboBoxPopupBar*)m_pCommandBar)->ProcessHookKeyDown(this, nChar, lParam);
return TRUE;
}
if (m_pEdit && m_pEdit->GetSafeHwnd() && m_pEdit->IsDialogCode(nChar, lParam))
{
return TRUE;
}
return FALSE_EXIT;
}
BOOL CXTPControlComboBox::GetDropDownListStyle() const
{
return m_pEdit != NULL;
}
CXTPControlComboBoxEditCtrl* CXTPControlComboBox::CreateEditControl()
{
return new CXTPControlComboBoxEditCtrl();
}
void CXTPControlComboBox::SetDropDownListStyle(BOOL bSet)
{
m_bDropDown = bSet;
if (bSet && m_pEdit == NULL)
{
m_pEdit = CreateEditControl();
m_pEdit->m_pControl = this;
}
else if (!bSet && m_pEdit != NULL)
{
delete m_pEdit;
m_pEdit = NULL;
}
}
void CXTPControlComboBox::EnableShellAutoComplete(DWORD dwFlags /*= SHACF_FILESYSTEM | SHACF_URLALL*/)
{
m_dwShellAutoCompleteFlags = dwFlags;
SAFE_DELETE(m_pAutoCompleteWnd);
if (m_pEdit->GetSafeHwnd() && dwFlags)
{
m_pAutoCompleteWnd = new CXTPControlComboBoxAutoCompleteWnd();
if (FAILED(m_pAutoCompleteWnd->ShellAutoComplete(m_pEdit->GetSafeHwnd(), m_dwShellAutoCompleteFlags)))
{
SAFE_DELETE(m_pAutoCompleteWnd);
}
}
}
void CXTPControlComboBox::EnableAutoComplete(BOOL bAutoComplete /*= TRUE*/)
{
m_bAutoComplete = bAutoComplete;
}
void CXTPControlComboBox::SetRect(CRect rcControl)
{
CString strEditText = GetEditText();
if (m_bDelayDestroy && m_pEdit && m_pEdit->GetSafeHwnd())
{
m_pEdit->DestroyWindow();
m_bDelayDestroy = FALSE;
}
if (m_pEdit && m_pEdit->GetSafeHwnd() && m_pEdit->GetExStyle() & WS_EX_LAYOUTRTL)
{
m_pEdit->DestroyWindow();
}
if (m_pEdit && m_pEdit->GetSafeHwnd() && m_pEdit->GetParent() != m_pParent)
{
m_pEdit->DestroyWindow();
}
if (m_rcControl == rcControl && !(m_pEdit && !m_pEdit->GetSafeHwnd()) && (m_bDelayReposition == FALSE))
{
if (!(m_pEdit && m_pEdit->GetSafeHwnd() && m_pEdit->GetParent() != m_pParent))
return;
}
m_rcControl = rcControl;
if (m_pEdit)
{
if (!m_pEdit->GetSafeHwnd())
{
m_pEdit->CreateEdit(WS_CHILD | ES_AUTOHSCROLL | m_dwEditStyle, m_pParent);
if (!GetEnabled()) m_pEdit->EnableWindow(FALSE);
if (m_dwShellAutoCompleteFlags != 0) EnableShellAutoComplete(m_dwShellAutoCompleteFlags);
if (m_nTextLimit) m_pEdit->LimitText(m_nTextLimit);
}
m_pEdit->SetFont(GetPaintManager()->GetIconFont(), FALSE);
m_pEdit->SetMargins(0, 0);
m_pEdit->UpdateCharFormat();
if (m_pEdit->GetSafeHwnd() != ::GetFocus()) SetEditText(strEditText);
m_pEdit->m_bComposited = HasDwmCompositedRect();
rcControl.DeflateRect(m_nLabelWidth + 1 + 3, 3, m_nThumbWidth + 3, 3);
if (GetPaintManager()->GetEditHeight() > 0)
rcControl.OffsetRect(0, 1);
DeflateEditRect(rcControl);
m_pEdit->MoveWindow(rcControl);
ShowHideEditControl();
}
m_bDelayReposition = FALSE;
}
void CXTPControlComboBox::ShowHideEditControl()
{
if (m_pEdit && m_pEdit->GetSafeHwnd())
{
m_pEdit->SetWindowPos(0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE
| (m_pControls && m_pParent && IsVisible() && m_pParent->GetSafeHwnd() ? SWP_SHOWWINDOW : SWP_HIDEWINDOW));
}
}
void CXTPControlComboBox::OnRemoved()
{
ShowHideEditControl();
if (!m_pControls && m_pEdit && m_pEdit->GetSafeHwnd())
{
m_pEdit->DestroyWindow();
}
CXTPControlPopup::OnRemoved();
}
void CXTPControlComboBox::OnEnabledChanged()
{
if (m_pEdit && m_pEdit->GetSafeHwnd())
{
m_pEdit->EnableWindow(GetEnabled());
m_pEdit->UpdateCharFormat();
}
}
void CXTPControlComboBox::SetParent(CXTPCommandBar* pParent)
{
if (pParent != m_pParent && pParent)
{
CWnd* pSite = pParent->GetSite();
if (pSite)
SetWindowLongPtr(m_pCommandBar->GetSafeHwnd(), GWLP_HWNDPARENT, (LONG_PTR)pSite->GetSafeHwnd());
}
if (!pParent && m_pEdit && m_pEdit->GetSafeHwnd())
{
m_pEdit->DestroyWindow();
}
CXTPControlPopup::SetParent(pParent);
}
BOOL CXTPControlComboBox::OnSetSelected(int bSelected)
{
if (!CXTPControl::OnSetSelected(bSelected))
return FALSE;
if (!bSelected)
{
SetFocused(FALSE);
}
if (!bSelected && m_bPopup && GetParent()->GetPosition() != xtpBarPopup)
{
m_pParent->SetPopuped(-1);
}
if (m_pEdit->GetSafeHwnd())
{
m_pEdit->UpdateCharFormat();
}
return TRUE;
}
BOOL CXTPControlComboBox::HasFocus() const
{
return IsFocused() || (m_pCommandBar->IsTrackingMode()) || m_pParent->GetCommandBars()->GetMouseManager()->IsMouseLocked();
}
BOOL CXTPControlComboBox::IsFocusable() const
{
return TRUE;
}
void CXTPControlComboBox::OnClick(BOOL bKeyboard , CPoint pt)
{
if (m_pEdit && m_pEdit->m_bImeMode)
return;
if (IsCustomizeMode())
{
m_pParent->SetPopuped(-1);
m_pParent->SetSelected(-1);
CustomizeStartDrag(pt);
}
else if (bKeyboard && GetEnabled())
{
if (IsFocused())
{
OnExecute();
}
else
{
SetFocused(TRUE);
}
}
else if (m_bPopup && IsFocused())
{
m_pParent->SetPopuped(-1);
}
else CXTPControlPopup::OnClick(bKeyboard, pt);
}
void CXTPControlComboBox::OnUnderlineActivate()
{
m_pParent->HideKeyboardTips();
SetFocused(TRUE);
}
void CXTPControlComboBox::OnMouseHover()
{
}
void CXTPControlComboBox::SetHideFlags(DWORD dwFlags)
{
if (m_dwHideFlags != dwFlags)
{
m_dwHideFlags = dwFlags;
ShowHideEditControl();
DelayLayoutParent();
}
}
void CXTPControlComboBox::OnActionChanged(int nProperty)
{
CXTPControl::OnActionChanged(nProperty);
if (nProperty == 2) // Visible
{
ShowHideEditControl();
}
if (nProperty == 4) // EditHint
{
if (_GetEditText().IsEmpty() && !GetEditHint().IsEmpty())
{
_SetEditText(GetEditHint());
}
}
}
void CXTPControlComboBox::OnActionChanging(int nProperty)
{
if (nProperty == 4 && !GetEditHint().IsEmpty() && _GetEditText() == GetEditHint())
{
_SetEditText(_T(""));
}
}
void CXTPControlComboBox::OnCalcDynamicSize(DWORD dwMode)
{
if (dwMode & LM_VERTDOCK) SetHideFlags(m_dwHideFlags | xtpHideDockingPosition);
else SetHideFlags(m_dwHideFlags & ~xtpHideDockingPosition);
}
DWORD CXTPControlComboBox::GetEditStyle() const
{
return m_dwEditStyle;
}
void CXTPControlComboBox::SetEditStyle(DWORD dwStyle)
{
m_dwEditStyle = dwStyle;
if (m_pEdit && m_pEdit->GetSafeHwnd())
{
m_bDelayDestroy = TRUE;
DelayLayoutParent();
}
}
void CXTPControlComboBox::Copy(CXTPControl* pControl, BOOL bRecursive)
{
CXTPControlComboBox* pControlCombo = DYNAMIC_DOWNCAST(CXTPControlComboBox, pControl);
ASSERT(pControlCombo);
if (!pControlCombo)
{
CXTPControlPopup::Copy(pControl, bRecursive);
return;
}
m_dwEditStyle = pControlCombo->m_dwEditStyle;
m_comboStyle = pControlCombo->m_comboStyle;
SetEditText(pControlCombo->GetEditText());
SetEditHint(pControlCombo->m_strEditHint);
SetDropDownListStyle(pControlCombo->m_pEdit != NULL);
m_bAutoComplete = pControlCombo->m_bAutoComplete;
EnableShellAutoComplete(pControlCombo->m_dwShellAutoCompleteFlags);
m_nEditIconId = pControlCombo->m_nEditIconId;
m_nDropDownItemCount = pControlCombo->m_nDropDownItemCount;
m_nTextLimit = pControlCombo->m_nTextLimit;
CXTPControlPopup::Copy(pControl, bRecursive);
}
BOOL CXTPControlComboBox::Compare(CXTPControl* pOther)
{
if (!CXTPControlPopup::Compare(pOther))
return FALSE;
if (!pOther->IsKindOf(RUNTIME_CLASS(CXTPControlComboBox)))
return FALSE;
return TRUE;
}
CString CXTPControlComboBox::GetListBoxText() const
{
CXTPControlComboBoxPopupBar* pPopupBar = GetComboBoxPopupBar();
if (!pPopupBar)
return _T("");
int nSel = pPopupBar->GetCurSel();
CString str;
if (nSel >= 0)
pPopupBar->GetText(nSel, str);
return str;
}
BOOL CXTPControlComboBox::IsValidList() const
{
return GetComboBoxPopupBar() != NULL;
}
CXTPControlComboBoxPopupBar* CXTPControlComboBox::GetComboBoxPopupBar() const
{
return DYNAMIC_DOWNCAST(CXTPControlComboBoxPopupBar, m_pCommandBar);
}
int CXTPControlComboBox::GetCurSel() const
{
CXTPControlComboBoxPopupBar* pPopupBar = GetComboBoxPopupBar();
return pPopupBar ? pPopupBar->GetCurSel() : m_nCurSel;
}
void CXTPControlComboBox::SetCurSel(int nIndex)
{
if ((GetCurSel() != nIndex) || (m_nCurSel != nIndex))
{
m_nCurSel = nIndex;
CXTPControlComboBoxPopupBar* pPopupBar = GetComboBoxPopupBar();
if (pPopupBar)
{
pPopupBar->SetCurSel(nIndex);
}
OnSelChanged();
}
}
BOOL CXTPControlComboBox::IsFocused() const
{
return m_bFocused;
}
void CXTPControlComboBox::SetFocused(BOOL bFocused)
{
if (m_bFocused == bFocused)
return;
m_bFocused = bFocused;
if (bFocused)
{
m_nLastSel = GetCurSel();
m_bSelEndOk = FALSE;
if (m_pEdit->GetSafeHwnd() && ::GetFocus() != m_pEdit->GetSafeHwnd())
m_pEdit->SetFocus();
m_pParent->SetTrackingMode(TRUE, FALSE);
m_pParent->SetSelected(m_nIndex);
XTPMouseManager()->LockMouseMove();
NotifySite(CBN_SETFOCUS);
}
else
{
if (!m_bSelEndOk && !GetDroppedState() && !m_pEdit)
{
SetCurSel(m_nLastSel);
NotifySite(CBN_SELENDCANCEL);
}
if (m_pEdit->GetSafeHwnd() && ::GetFocus() == m_pEdit->GetSafeHwnd())
::SetFocus(m_pParent->GetTrackFocus());
XTPMouseManager()->UnlockMouseMove();
NotifySite(CBN_KILLFOCUS);
}
RedrawParent(FALSE);
}
void CXTPControlComboBox::OnSetFocus(CWnd* pOldWnd)
{
if (!GetEditHint().IsEmpty() && m_pEdit->GetSafeHwnd() && GetEditHint() == _GetEditText())
{
_SetEditText(_T(""));
}
m_strLastText = GetEditText();
m_bIgnoreAutoComplete = TRUE;
UpdatePopupSelection();
if (m_pParent->GetTrackFocus() == 0)
m_pParent->SetTrackFocus(pOldWnd ? pOldWnd->GetSafeHwnd() : m_pParent->GetSite()->GetSafeHwnd());
if (!m_bPopup)
m_pParent->SetPopuped(-1);
SetFocused(TRUE);
if (m_pAutoCompleteWnd) m_pAutoCompleteWnd->SetupMessageHook(TRUE);
}
void CXTPControlComboBox::OnKillFocus()
{
if (!GetEditHint().IsEmpty() && m_pEdit->GetSafeHwnd() && _GetEditText().IsEmpty())
{
_SetEditText(GetEditHint());
}
SetFocused(FALSE);
if (GetDroppedState())
m_pParent->SetPopuped(-1);
if (m_pAutoCompleteWnd) m_pAutoCompleteWnd->SetupMessageHook(FALSE);
}
BOOL CXTPControlComboBox::GetDroppedState() const
{
return m_bPopup;
//return m_pCommandBar->IsTrackingMode() && ((CXTPPopupBar*)m_pCommandBar)->GetControlPopup() == (CXTPControlPopup*)this;
}
BOOL CXTPControlComboBox::OnSetPopup(BOOL bPopup)
{
if (bPopup)
{
m_bSelEndOk = FALSE;
m_nLastSel = GetCurSel();
}
else if (!IsFocused() && m_pEdit == NULL && !m_bSelEndOk)
{
SetCurSel(m_nLastSel);
}
if (!bPopup && !m_bSelEndOk)
{
NotifySite(CBN_SELENDCANCEL);
}
if (m_pAutoCompleteWnd && bPopup) m_pAutoCompleteWnd->CloseWindow();
m_bPopup = bPopup;
if (bPopup && GetEditCtrl()) GetEditCtrl()->SetFocus();
return CXTPControlPopup::OnSetPopup(bPopup);
}
void CXTPControlComboBox::OnExecute()
{
if (GetCurSel() != -1 && (GetDroppedState() || (!m_pEdit && IsFocused())))
NotifySite(CBN_SELENDOK);
m_bSelEndOk = TRUE;
m_nLastSel = GetCurSel();
CXTPControlPopup::OnExecute();
}
CHARFORMAT2 CXTPControlComboBox::GetDefaultCharFormat()
{
CHARFORMAT2 cf;
ZeroMemory(&cf, sizeof(CHARFORMAT2));
cf.dwMask = CFM_COLOR | CFM_BACKCOLOR;
if (GetEnabled())
{
cf.crTextColor = GetXtremeColor(COLOR_WINDOWTEXT);
if (!GetEditHint().IsEmpty() && GetEditHint() == _GetEditText())
{
cf.crTextColor = GetXtremeColor(COLOR_GRAYTEXT);
}
}
else
{
cf.crTextColor = GetXtremeColor(COLOR_GRAYTEXT);
}
cf.crBackColor = GetPaintManager()->GetControlEditBackColor(this);
return cf;
}
void CXTPControlComboBox::ModifyListBoxStyle(DWORD dwRemove, DWORD dwAdd)
{
if (IsValidList())
{
CXTPControlComboBoxList* pComboBoxList = ((CXTPControlComboBoxList*)m_pCommandBar);
pComboBoxList->m_dwStyle |= dwAdd;
pComboBoxList->m_dwStyle &= ~dwRemove;
pComboBoxList->DestroyWindow();
pComboBoxList->CreateListBox();
}
}
//////////////////////////////////////////////////////////////////////////
// CXTPControlComboBoxPopup
IMPLEMENT_XTP_COMMANDBAR(CXTPControlComboBoxPopupBar, CXTPPopupBar)
CXTPControlComboBoxPopupBar::CXTPControlComboBoxPopupBar()
{
m_bComboBar = TRUE;
m_bGrabFocus = FALSE;
}
BOOL CXTPControlComboBoxPopupBar::ProcessHookKeyDown(CXTPControlComboBox* pComboBox, UINT nChar, LPARAM lParam)
{
int nSel = GetCurSel();
if (pComboBox->GetEditCtrl())
{
if ((GetKeyState(VK_MENU) >= 0) && (nChar == VK_UP || nChar == VK_DOWN || nChar == VK_PRIOR || nChar == VK_NEXT))
{
CXTPCommandBar::OnHookKeyDown(nChar, lParam);
}
else
{
return FALSE;
}
}
else
{
if ((nChar == VK_F4 && GetKeyState(VK_MENU) >= 0) || ((nChar == VK_UP || nChar == VK_DOWN) && GetKeyState(VK_MENU) < 0))
{
return FALSE;
}
else
{
CXTPCommandBar::OnHookKeyDown(nChar, lParam);
}
}
if (nSel != GetCurSel())
{
pComboBox->OnSelChanged();
if (pComboBox->GetEditCtrl()->GetSafeHwnd()) pComboBox->GetEditCtrl()->SetSel(0, -1);
}
return TRUE;
}
BOOL CXTPControlComboBoxPopupBar::OnHookKeyDown(UINT nChar, LPARAM lParam)
{
ASSERT(m_pControlPopup);
CXTPControlComboBox* pComboBox = ((CXTPControlComboBox*)m_pControlPopup);
if (!pComboBox)
return CXTPCommandBar::OnHookKeyDown(nChar, lParam);
if (nChar == VK_ESCAPE)
{
if (pComboBox->IsFocused())
return FALSE;
return CXTPCommandBar::OnHookKeyDown(nChar, lParam);
}
if (nChar == VK_TAB) return FALSE;
return ProcessHookKeyDown(pComboBox, nChar, lParam);
}
//////////////////////////////////////////////////////////////////////////
// CXTPControlComboBoxList
CXTPControlComboBoxList::CXTPControlComboBoxList()
{
m_barPosition = xtpBarListBox;
m_nMRUWidth = 0;
m_bGrabFocus = FALSE;
m_dwStyle = 0;
m_nListIconId = -1;
}
BEGIN_MESSAGE_MAP(CXTPControlComboBoxList, CXTPPopupBar)
ON_WM_LBUTTONUP()
ON_WM_NCPAINT()
ON_WM_ERASEBKGND()
ON_WM_PAINT()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_DRAWITEM_REFLECT()
ON_WM_MEASUREITEM_REFLECT()
END_MESSAGE_MAP()
IMPLEMENT_XTP_COMMANDBAR(CXTPControlComboBoxList, CXTPControlComboBoxPopupBar)
void CXTPControlComboBoxList::CreateListBox()
{
DWORD dwStyle = m_dwStyle & ~CBRS_GRIPPER;
CWnd* pSite = GetSite();
if (pSite && ((dwStyle & (LBS_OWNERDRAWFIXED|LBS_OWNERDRAWVARIABLE)) != 0))
{
CreateEx(WS_EX_CLIENTEDGE|WS_EX_TOOLWINDOW, _T("LISTBOX"), _T(""),
WS_CHILD | WS_VSCROLL | WS_CLIPCHILDREN | dwStyle | LBS_NOTIFY,
CRect(0, 0, 0, 50), pSite, 0);
SetWindowLongPtr(m_hWnd, GWLP_HWNDPARENT, 0 );
ModifyStyle(WS_CHILD, WS_POPUP);
SetWindowLongPtr(m_hWnd, GWLP_HWNDPARENT, (LONG_PTR)(pSite->m_hWnd));
}
else
{
CreateEx(WS_EX_CLIENTEDGE | WS_EX_TOOLWINDOW, _T("LISTBOX"), _T(""),
WS_POPUP | WS_VSCROLL | WS_CLIPCHILDREN | dwStyle, CRect(0, 0, 0, 50), 0, 0);
}
if (m_pCommandBars && m_nListIconId != -1)
{
CXTPImageManagerIcon* pIcon = GetImageManager()->GetImage(m_nListIconId, 0);
if (pIcon)
{
((CListBox*)this)->SetItemHeight(-1, pIcon->GetHeight() + 4);
}
}
}
void CXTPControlComboBoxList::DrawItem (LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CXTPControlComboBox* pComboBox = (CXTPControlComboBox*)m_pControlPopup;
if (pComboBox) pComboBox->DrawItem(lpDrawItemStruct);
}
void CXTPControlComboBoxList::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
CXTPControlComboBox* pComboBox = (CXTPControlComboBox*)m_pControlPopup;
if (pComboBox) pComboBox->MeasureItem(lpMeasureItemStruct);
}
void CXTPControlComboBoxList::OnLButtonDown(UINT /*nFlags*/, CPoint /*point*/)
{
// do nothing.
}
int CXTPControlComboBoxList::OnHookMessage(HWND hWnd, UINT nMessage, WPARAM& wParam, LPARAM& lParam, LRESULT& lResult)
{
if (nMessage == WM_MOUSEWHEEL)
{
CWnd::DefWindowProc(WM_MOUSEWHEEL, wParam, lParam);
return TRUE;
}
return CXTPCommandBar::OnHookMessage(hWnd, nMessage, wParam, lParam, lResult);
}
void CXTPControlComboBoxList::OnNcPaint()
{
CXTPPaintManager* pPaintManager = GetPaintManager();
Default();
CWindowDC dc(this);
CXTPWindowRect rc(this);
rc.OffsetRect(-rc.TopLeft());
dc.Draw3dRect(rc, pPaintManager->GetXtremeColor(XPCOLOR_MENUBAR_BORDER), pPaintManager->GetXtremeColor(XPCOLOR_MENUBAR_BORDER));
rc.DeflateRect(1, 1);
dc.Draw3dRect(rc, GetXtremeColor(COLOR_WINDOW), GetXtremeColor(COLOR_WINDOW));
}
BOOL CXTPControlComboBoxList::OnEraseBkgnd(CDC* pDC)
{
return CWnd::OnEraseBkgnd(pDC);
}
void CXTPControlComboBoxList::OnLButtonUp(UINT /*nFlags*/, CPoint /*point*/)
{
CXTPControlComboBox* pComboBox = (CXTPControlComboBox*)m_pControlPopup;
pComboBox->OnSelChanged();
pComboBox->OnExecute();
}
BOOL CXTPControlComboBoxList::SetTrackingMode(int bMode, BOOL bSelectFirst, BOOL bKeyboard)
{
if (!CXTPCommandBar::SetTrackingMode(bMode, bSelectFirst, bKeyboard))
return FALSE;
CXTPControlComboBox* pComboBox = ((CXTPControlComboBox*)m_pControlPopup);
if (!bMode)
{
pComboBox->NotifySite(CBN_CLOSEUP);
XTPMouseManager()->UnlockMouseMove();
ShowWindow(SW_HIDE);
if (GetParentCommandBar())
GetParentCommandBar()->SetPopuped(-1);
m_pControlPopup = 0;
}
else
{
XTPMouseManager()->LockMouseMove();
pComboBox->UpdatePopupSelection();
pComboBox->NotifySite(CBN_DROPDOWN);
}
return TRUE;
}
CListBox* CXTPControlComboBoxList::GetListBoxCtrl() const
{
return (CListBox*)this;
}
BOOL CXTPControlComboBoxList::ProcessHookKeyDown(CXTPControlComboBox* pComboBox, UINT nChar, LPARAM lParam)
{
int nSel = GetCurSel();
if (pComboBox->GetEditCtrl())
{
if ((GetKeyState(VK_MENU) >= 0) && (nChar == VK_UP || nChar == VK_DOWN || nChar == VK_PRIOR || nChar == VK_NEXT))
{
CWnd::DefWindowProc(WM_KEYDOWN, (WPARAM)nChar, lParam);
}
else
{
return FALSE;
}
}
else
{
if ((nChar == VK_F4 && GetKeyState(VK_MENU) >= 0) || ((nChar == VK_UP || nChar == VK_DOWN) && GetKeyState(VK_MENU) < 0))
{
return FALSE;
}
else
{
MSG msg;
msg.message = WM_KEYDOWN;
msg.hwnd = m_hWnd;
msg.wParam = (WPARAM)nChar;
msg.lParam = lParam;
::IsDialogMessage(m_hWnd, &msg);
if (PeekMessage(&msg, m_hWnd, WM_CHAR, WM_CHAR, PM_REMOVE))
{
CWnd::DefWindowProc(WM_CHAR, msg.wParam, msg.lParam);
}
}
}
if (nSel != GetCurSel())
{
pComboBox->OnSelChanged();
if (pComboBox->GetEditCtrl()->GetSafeHwnd()) pComboBox->GetEditCtrl()->SetSel(0, -1);
}
return TRUE;
}
BOOL CXTPControlComboBoxList::OnHookKeyDown(UINT nChar, LPARAM lParam)
{
ASSERT(m_pControlPopup);
CXTPControlComboBox* pComboBox = ((CXTPControlComboBox*)m_pControlPopup);
if (!pComboBox)
return CXTPCommandBar::OnHookKeyDown(nChar, lParam);
if (pComboBox->GetEditCtrl() && pComboBox->GetEditCtrl()->IsImeMode())
return ProcessHookKeyDown(pComboBox, nChar, lParam);
if (nChar == VK_ESCAPE)
{
if (pComboBox->IsFocused())
return FALSE;
return CXTPCommandBar::OnHookKeyDown(nChar, lParam);
}
if (nChar == VK_TAB) return FALSE;
if (nChar == VK_RETURN)
{
m_pControlPopup->OnExecute();
return TRUE;
}
return ProcessHookKeyDown(pComboBox, nChar, lParam);
}
void CXTPControlComboBoxList::OnMouseMove(UINT nFlags, CPoint point)
{
BOOL bOutside;
UINT nItem = GetListBoxCtrl()->ItemFromPoint(point, bOutside);
if (!bOutside && GetCurSel() != (int)nItem)
SetCurSel(nItem);
CXTPPopupBar::OnMouseMove(nFlags, point);
}
BOOL CXTPControlComboBoxList::Popup(CXTPControlPopup* pControlPopup, BOOL /*bSelectFirst*/)
{
m_pControlPopup = pControlPopup;
SetFont(GetPaintManager()->GetIconFont());
CWnd* pWndOwner = GetOwnerSite();
if (pWndOwner) pWndOwner->SendMessage(WM_XTP_INITCOMMANDSPOPUP, 0, (LPARAM)this);
CXTPCommandBars* pCommandBars = GetCommandBars();
if (pCommandBars && pCommandBars->IsLayoutRTL())
ModifyStyleEx(WS_EX_LAYOUTRTL, WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR | WS_EX_RTLREADING);
else ModifyStyleEx(WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR | WS_EX_RTLREADING, 0);
SetTrackingMode(TRUE, FALSE);
UpdateFlags();
CRect rcControl = pControlPopup->GetRect();
int nItemHeight = GetListBoxCtrl()->GetItemHeight(0);
int nHeight = min (((CXTPControlComboBox*)m_pControlPopup)->m_nDropDownItemCount,
max(1, GetListBoxCtrl()->GetCount())) * nItemHeight + 4;
int nWidth = m_nMRUWidth <= 0 ? rcControl.Width() : m_nMRUWidth;
UpdateLocation(CSize(nWidth, nHeight));
EnableWindow();
return TRUE;
}
void CXTPControlComboBoxList::OnPaint()
{
CPaintDC paintDC(this);
CXTPBufferDC memDC(paintDC);
DrawCommandBar(&memDC, CXTPClientRect(this));
}
void CXTPControlComboBoxList::DrawCommandBar(CDC* pDC, CRect /*rcClipBox*/)
{
pDC->FillSolidRect(CXTPClientRect(this), GetXtremeColor(COLOR_WINDOW));
CWnd::DefWindowProc(WM_PAINT, (WPARAM)pDC->m_hDC, 0);
}
//////////////////////////////////////////////////////////////////////////
// CXTPControlComboBoxEditCtrl
BEGIN_MESSAGE_MAP(CXTPControlComboBoxEditCtrl, CXTPCommandBarEditCtrl)
ON_WM_SETFOCUS()
ON_WM_MOUSEMOVE()
ON_WM_KILLFOCUS()
ON_WM_DESTROY()
ON_WM_LBUTTONDOWN()
ON_WM_RBUTTONDOWN()
ON_WM_CONTEXTMENU()
ON_WM_KEYDOWN()
ON_MESSAGE(XTP_TTM_WINDOWFROMPOINT, OnWindowFromPoint)
ON_MESSAGE_VOID(WM_XTP_SHELLAUTOCOMPLETESTART, OnShellAutoCompleteStart)
ON_CONTROL_REFLECT(EN_CHANGE, OnEditChanged)
END_MESSAGE_MAP()
void CXTPControlComboBoxEditCtrl::OnEditChanged()
{
m_pControl->m_bEditChanged = TRUE;
if (::GetFocus() == m_hWnd && !m_bIgonoreEditChanged)
m_pControl->OnEditChanged();
SetMargins(0, 0);
UpdateCharFormat();
}
void CXTPControlComboBoxEditCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (nChar == VK_RETURN && ::GetFocus() == m_hWnd)
{
m_pControl->OnExecute();
return;
}
CXTPCommandBarEditCtrl::OnKeyDown(nChar, nRepCnt, nFlags);
}
void CXTPControlComboBoxEditCtrl::UpdateCharFormat()
{
CHARFORMAT2 cf = m_pControl->GetDefaultCharFormat();
cf.cbSize = GetRichEditContext().m_bRichEdit2 ? sizeof(CHARFORMAT2) : sizeof(CHARFORMAT);
::SendMessage(m_hWnd, EM_SETCHARFORMAT, 0, (LPARAM)&cf);
::SendMessage(m_hWnd, EM_SETBKGNDCOLOR, FALSE, cf.crBackColor);
}
void CXTPControlComboBoxEditCtrl::OnShellAutoCompleteStart()
{
m_pControl->GetCommandBar()->OnTrackLost();
}
void CXTPControlComboBoxEditCtrl::OnContextMenu(CWnd* /*pWnd*/, CPoint /*point*/)
{
}
void CXTPControlComboBoxEditCtrl::OnRButtonDown(UINT nFlags, CPoint point)
{
if (m_pControl->IsCustomizeMode())
{
ClientToScreen(&point);
m_pControl->GetParent()->ScreenToClient(&point);
m_pControl->GetParent()->OnRButtonDown(nFlags, point);
return;
}
m_pControl->GetCommandBar()->OnTrackLost();
m_pControl->SetFocused(TRUE);
if (!ShowContextMenu(m_pControl, point))
CXTPCommandBarEditCtrl::OnRButtonDown(nFlags, point);
}
void CXTPControlComboBoxEditCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
if (m_pControl->IsCustomizeMode())
{
if (m_pControl->IsCustomizeMovable())
m_pControl->OnClick();
}
else CEdit::OnLButtonDown(nFlags, point);
}
void CXTPControlComboBoxEditCtrl::OnDestroy()
{
GetWindowTextEx(m_pControl->m_strEditText);
CEdit::OnDestroy();
}
BOOL CXTPControlComboBoxEditCtrl::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
CXTPCommandBar* pCommandBar = m_pControl->GetParent();
if (pCommandBar)
{
pCommandBar->FilterToolTipMessage(message, wParam, lParam);
}
return CWnd::OnWndMsg(message, wParam, lParam, pResult);
}
LRESULT CXTPControlComboBoxEditCtrl::OnWindowFromPoint(WPARAM, LPARAM)
{
return 1;
}
void CXTPControlComboBoxEditCtrl::OnSetFocus(CWnd* pOldWnd)
{
if (!m_pControl->IsCustomizeMode())
{
m_pControl->OnSetFocus(pOldWnd);
CEdit::OnSetFocus(pOldWnd);
SetSel(0, 0);
::PostMessage(m_hWnd, EM_SETSEL, 0, -1);
}
}
void CXTPControlComboBoxEditCtrl::OnKillFocus(CWnd* pNewWnd)
{
CXTPCommandBarEditCtrl::OnKillFocus(pNewWnd);
m_pControl->OnKillFocus();
}
void CXTPControlComboBoxEditCtrl::OnMouseMove(UINT nFlags, CPoint point)
{
CEdit::OnMouseMove(nFlags, point);
MapWindowPoints(m_pControl->GetParent(), &point, 1);
m_pControl->GetParent()->OnMouseMove(nFlags, point);
}
//////////////////////////////////////////////////////////////////////////
// CXTPControlComboBoxList
void CXTPControlComboBoxList::Copy(CXTPCommandBar* pCommandBar, BOOL bRecursive)
{
CXTPPopupBar::Copy(pCommandBar, bRecursive);
m_nListIconId = ((CXTPControlComboBoxList*)pCommandBar)->m_nListIconId;
if (!m_hWnd)
CreateListBox();
CListBox* pListBox = (CListBox*)(CXTPControlComboBoxList*)pCommandBar;
DWORD dwCount = pListBox->m_hWnd ? pListBox->GetCount() : 0;
for (UINT i = 0; i < dwCount; i++)
{
CString str;
pListBox->GetText(i, str);
DWORD_PTR dwData = pListBox->GetItemData(i);
int nIndex = GetListBoxCtrl()->AddString(str);
GetListBoxCtrl()->SetItemData(nIndex, dwData);
}
}
void CXTPControlComboBoxList::DoPropExchange(CXTPPropExchange* pPX)
{
CXTPPopupBar::DoPropExchange(pPX);
if (pPX->GetSchema() > _XTP_SCHEMA_110)
{
PX_Int(pPX, _T("ListIconId"), m_nListIconId, -1);
}
CListBox* pThis = (CListBox*)this;
CString str;
CXTPPropExchangeSection secItems(pPX->GetSection(_T("Items")));
if (pPX->IsStoring())
{
if (m_hWnd)
{
DWORD dwCount = pThis->GetCount();
secItems->WriteCount(dwCount);
for (int i = 0; i < (int)dwCount; i++)
{
pThis->GetText(i, str);
CString strSection;
strSection.Format(_T("Item%i"), i);
PX_String(&secItems, strSection, str, _T(""));
if (pPX->GetSchema() >= _XTP_SCHEMA_1340)
{
int dwItemData = (int)pThis->GetItemData(i);
strSection.Format(_T("ItemData%i"), i);
PX_Int(&secItems, strSection, dwItemData, 0);
}
}
}
else
{
pPX->WriteCount(0);
}
}
else
{
if (!m_hWnd)
CreateListBox();
int nNewCount = (int)secItems->ReadCount();
for (int i = 0; i < nNewCount; i++)
{
CString strSection;
strSection.Format(_T("Item%i"), i);
PX_String(&secItems, strSection, str, _T(""));
int nIndex = pThis->AddString(str);
if (pPX->GetSchema() >= _XTP_SCHEMA_1340)
{
int dwItemData = 0;
strSection.Format(_T("ItemData%i"), i);
PX_Int(&secItems, strSection, dwItemData, 0);
pThis->SetItemData(nIndex, dwItemData);
}
}
}
}
void CXTPControlComboBox::OnMouseMove(CPoint point)
{
CXTPControlPopup::OnMouseMove(point);
if (GetEnabled() && m_bSelected)
{
CRect rcButon(GetRect());
rcButon.left = rcButon.right - m_nThumbWidth;
if (rcButon.PtInRect(point) && m_bSelected != TRUE_SPLITDROPDOWN)
{
m_bSelected = TRUE_SPLITDROPDOWN;
RedrawParent(FALSE);
}
else if (!rcButon.PtInRect(point) && m_bSelected == TRUE_SPLITDROPDOWN)
{
m_bSelected = TRUE;
RedrawParent(FALSE);
}
}
}
void CXTPControlComboBox::SetListIconId(int nId)
{
if (m_pParent) GetCommandBar()->SetCommandBars(m_pParent->GetCommandBars());
if (IsValidList())
{
CXTPControlComboBoxList* pComboBoxList = ((CXTPControlComboBoxList*)m_pCommandBar);
pComboBoxList->m_nListIconId = nId;
ModifyListBoxStyle(0, LBS_OWNERDRAWFIXED | LBS_HASSTRINGS);
}
}
int CXTPControlComboBox::GetListIconId() const
{
return IsValidList() ? ((CXTPControlComboBoxList*)m_pCommandBar)->m_nListIconId : -1;
}
int CXTPControlComboBox::GetDropDownWidth() const
{
return m_pCommandBar->GetWidth();
}
int CXTPControlComboBox::GetCustomizeMinWidth() const
{
return m_nLabelWidth + m_nThumbWidth + 5;
}
void CXTPControlComboBox::DeflateEditRect(CRect& rcControl)
{
if (m_nEditIconId > 0)
{
CXTPImageManagerIcon* pIcon = m_pParent->GetImageManager()->GetImage(m_nEditIconId, 0);
if (pIcon)
rcControl.left += pIcon->GetWidth() + 2;
}
}
void CXTPControlComboBox::DrawEditText(CDC* pDC, CRect rcText)
{
if (!GetEditCtrl() && GetEnabled() && IsFocused())
{
CRect rcFocus(rcText.left - 1, rcText.top + 1, rcText.right - 1, rcText.bottom - 1);
pDC->FillSolidRect(rcFocus, GetXtremeColor(COLOR_HIGHLIGHT));
}
if (m_nEditIconId > 0)
{
CXTPImageManagerIcon* pIcon = m_pParent->GetImageManager()->GetImage(m_nEditIconId, 0);
if (pIcon)
{
pIcon->Draw(pDC, CPoint(rcText.left, rcText.CenterPoint().y - pIcon->GetHeight() / 2), GetEnabled() ? pIcon->GetIcon() : pIcon->GetDisabledIcon());
rcText.left += pIcon->GetWidth() + 2;
}
}
if (GetEditCtrl())
return;
CString strListBoxText = GetListBoxText();
if (!strListBoxText.IsEmpty())
{
pDC->SetTextColor(GetXtremeColor(!GetEnabled() ? COLOR_GRAYTEXT: IsFocused() ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT));
pDC->DrawText(strListBoxText, rcText, DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX);
}
else if (!GetEditHint().IsEmpty() && GetEnabled() && !IsFocused())
{
pDC->SetTextColor(GetXtremeColor(COLOR_GRAYTEXT));
pDC->DrawText(GetEditHint(), rcText, DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX);
}
}
void CXTPControlComboBox::MeasureItem(LPMEASUREITEMSTRUCT /*lpMeasureItemStruct*/)
{
}
void CXTPControlComboBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CString strText;
GetLBText(lpDrawItemStruct->itemID, strText);
CRect rc(&lpDrawItemStruct->rcItem);
ASSERT(lpDrawItemStruct->CtlType == ODT_LISTBOX);
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
BOOL bSelected = lpDrawItemStruct->itemState & ODS_SELECTED;
CXTPPaintManager* pPaintManager = GetPaintManager();
COLORREF crOldTextColor = pDC->SetTextColor(pPaintManager->GetRectangleTextColor(bSelected, FALSE, TRUE, FALSE, FALSE, xtpBarTypePopup, xtpBarPopup));
if (bSelected)
pPaintManager->DrawRectangle(pDC, rc, TRUE, FALSE, TRUE, FALSE, FALSE, xtpBarTypePopup, xtpBarPopup);
else
pDC->FillSolidRect(rc, pPaintManager->GetXtremeColor(COLOR_WINDOW));
int nListIconId = GetListIconId();
if (nListIconId != -1)
{
CXTPImageManager* pImageManager = GetCommandBar()->GetImageManager();
CXTPImageManagerIcon* pImage = pImageManager->GetImage(nListIconId + lpDrawItemStruct->itemID, 0);
if (pImage)
{
pImage->Draw(pDC, CPoint(rc.left + 2, (rc.top + rc.bottom - pImage->GetHeight()) / 2),
pImage->GetIcon(bSelected ? xtpImageHot : xtpImageNormal));
rc.left += pImage->GetWidth() + 2;
}
}
CXTPFontDC font(pDC, pPaintManager->GetIconFont());
pDC->SetBkMode(TRANSPARENT);
rc.left += 3;
pDC->DrawText(strText, rc, DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX);
pDC->SetTextColor(crOldTextColor);
}