XTPControlComboBox.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:47k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // XTPControlComboBox.cpp : implementation of the CXTPControlComboBox class.
  2. //
  3. // This file is a part of the XTREME COMMANDBARS MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include "Common/XTPDrawHelpers.h"
  22. #include "Common/XTPColorManager.h"
  23. #include "Common/XTPPropExchange.h"
  24. #include "Common/XTPVC80Helpers.h"
  25. #include "Common/XTPImageManager.h"
  26. #include "Common/XTPToolTipContext.h"
  27. #include "XTPControlComboBox.h"
  28. #include "XTPCommandBar.h"
  29. #include "XTPToolBar.h"
  30. #include "XTPCommandBars.h"
  31. #include "XTPPaintManager.h"
  32. #include "XTPMouseManager.h"
  33. #include "XTPControls.h"
  34. #include "XTPKeyboardManager.h"
  35. #ifdef _DEBUG
  36. #define new DEBUG_NEW
  37. #undef THIS_FILE
  38. static char THIS_FILE[] = __FILE__;
  39. #endif
  40. CXTPEdit::CRichEditContext::CRichEditContext()
  41. {
  42. m_hInstance = LoadLibraryA("RICHED20.DLL");
  43. m_bRichEdit2 = TRUE;
  44. if (m_hInstance)
  45. {
  46. #ifdef _UNICODE
  47. m_strClassName = _T("RichEdit20W");
  48. #else
  49. m_strClassName = _T("RichEdit20A");
  50. #endif
  51. }
  52. else
  53. {
  54. m_hInstance = LoadLibraryA("RICHED32.DLL");
  55. m_strClassName = _T("RICHEDIT");
  56. m_bRichEdit2 = FALSE;
  57. }
  58. }
  59. CXTPEdit::CRichEditContext::~CRichEditContext()
  60. {
  61. }
  62. CXTPEdit::CRichEditContext& CXTPEdit::GetRichEditContext()
  63. {
  64. static CRichEditContext s_RichContext;
  65. return s_RichContext;
  66. }
  67. // CXTPEdit
  68. IMPLEMENT_DYNCREATE(CXTPEdit, CEdit)
  69. CXTPEdit::CXTPEdit()
  70. {
  71. m_bImeMode = FALSE;
  72. m_bComposited = FALSE;
  73. m_bIgonoreEditChanged = FALSE;
  74. }
  75. BOOL CXTPEdit::IsCommandEnabled(UINT nID)
  76. {
  77. if (nID == ID_EDIT_PASTE)
  78. {
  79. return ((GetStyle() & (ES_READONLY | WS_DISABLED)) == 0) && ::IsClipboardFormatAvailable(CF_TEXT);
  80. }
  81. else if (nID == ID_EDIT_CUT || nID == ID_EDIT_COPY)
  82. {
  83. int nStartChar, nEndChar;
  84. GetSel(nStartChar, nEndChar);
  85. return (nStartChar != nEndChar) && ((nID == ID_EDIT_COPY) || ((GetStyle() & (ES_READONLY | WS_DISABLED)) == 0));
  86. }
  87. return TRUE;
  88. }
  89. BOOL CXTPEdit::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* /*pHandlerInfo*/)
  90. {
  91. if ((nID == ID_EDIT_PASTE || nID == ID_EDIT_CUT || nID == ID_EDIT_COPY) && (nCode == CN_UPDATE_COMMAND_UI))
  92. {
  93. CCmdUI* pCmdUI = (CCmdUI*)pExtra;
  94. pCmdUI->Enable(IsCommandEnabled(nID));
  95. return TRUE;
  96. }
  97. return FALSE;
  98. }
  99. BOOL CXTPEdit::OnCommand(WPARAM wParam, LPARAM)
  100. {
  101. UINT nID = LOWORD(wParam);
  102. if (nID == ID_EDIT_PASTE) Paste();
  103. else if (nID == ID_EDIT_COPY) Copy();
  104. else if (nID == ID_EDIT_CUT) Cut();
  105. else return FALSE;
  106. return TRUE;
  107. }
  108. BOOL CXTPEdit::ShowContextMenu(CXTPControl* pControl, CPoint point)
  109. {
  110. CString strPrompt;
  111. if (!strPrompt.LoadString(ID_EDIT_CUT))
  112. return FALSE;
  113. CXTPCommandBar* pParentBar = pControl->GetParent();
  114. CXTPCommandBars* pCommandBars = pParentBar->GetCommandBars();
  115. CXTPMouseManager* pMouseManager = pCommandBars ? pCommandBars->GetMouseManager() : XTPMouseManager();
  116. pMouseManager->UnlockMouseMove();
  117. ClientToScreen(&point);
  118. MSG msg;
  119. if (PeekMessage(&msg, m_hWnd, EM_SETSEL, EM_SETSEL, PM_NOREMOVE))
  120. {
  121. SendMessage(EM_SETSEL, 0, -1);
  122. }
  123. CXTPPopupBar* pPopupBar = CXTPPopupBar::CreatePopupBar(pCommandBars);
  124. CXTPControl* pControlCut = pPopupBar->GetControls()->Add(xtpControlButton, ID_EDIT_CUT);
  125. pControlCut->SetEnabled(IsCommandEnabled(ID_EDIT_CUT));
  126. CXTPControl* pControlCopy = pPopupBar->GetControls()->Add(xtpControlButton, ID_EDIT_COPY);
  127. pControlCopy->SetEnabled(IsCommandEnabled(ID_EDIT_COPY));
  128. CXTPControl* pControlPaste = pPopupBar->GetControls()->Add(xtpControlButton, ID_EDIT_PASTE);
  129. pControlPaste->SetEnabled(IsCommandEnabled(ID_EDIT_PASTE));
  130. pPopupBar->SetGrabFocus(FALSE);
  131. int nAlign = pControl->GetParent()->GetExStyle() & (WS_EX_LAYOUTRTL | WS_EX_RIGHT) ? TPM_RIGHTALIGN : TPM_LEFTALIGN;
  132. int nCommand = CXTPCommandBars::TrackPopupMenu(pPopupBar, TPM_NONOTIFY | TPM_RECURSE | TPM_RETURNCMD | nAlign, point.x, point.y, this, NULL, this);
  133. if (nCommand > 0)
  134. {
  135. OnCommand(nCommand, 0);
  136. }
  137. pMouseManager->LockMouseMove();
  138. pPopupBar->InternalRelease();
  139. if (pParentBar->GetSafeHwnd())
  140. {
  141. pParentBar->Redraw();
  142. pParentBar->UpdateWindow();
  143. }
  144. return TRUE;
  145. }
  146. BOOL CXTPEdit::CreateEdit(DWORD dwStyle, CWnd* pParentWnd)
  147. {
  148. if (GetRichEditContext().m_hInstance)
  149. {
  150. BOOL bResult = CWnd::Create(GetRichEditContext().m_strClassName, 0, dwStyle, CRect(0, 0, 0, 0), pParentWnd, 0);
  151. SendMessage(EM_SETEVENTMASK, 0, ENM_CHANGE);
  152. SendMessage(EM_SETTEXTMODE, TM_PLAINTEXT | TM_SINGLELEVELUNDO);
  153. return bResult;
  154. }
  155. return Create(dwStyle, CRect(0, 0, 0, 0), pParentWnd, 0);
  156. }
  157. BOOL CXTPEdit::IsDialogCode(UINT nChar, LPARAM lParam)
  158. {
  159. const BOOL bNavigateKeys = (nChar == VK_BACK) || (nChar >= VK_PRIOR && nChar <= VK_DELETE) ||
  160. ((nChar == 'C' || nChar == 'V' || nChar == 'X' || nChar == 'Z') && (GetKeyState(VK_CONTROL) < 0));
  161. if (!bNavigateKeys)
  162. return FALSE;
  163. MSG msg;
  164. msg.message = WM_KEYDOWN;
  165. msg.hwnd = m_hWnd;
  166. msg.wParam = (WPARAM)nChar;
  167. msg.lParam = lParam;
  168. if (IsDialogMessage(&msg))
  169. return TRUE;
  170. return FALSE;
  171. }
  172. void CXTPEdit::SetWindowTextEx(LPCTSTR lpszString)
  173. {
  174. m_bIgonoreEditChanged = TRUE;
  175. SetWindowText(0);
  176. m_bIgonoreEditChanged = FALSE;
  177. SetWindowText(lpszString);
  178. }
  179. void CXTPEdit::GetWindowTextEx(CString& rString)
  180. {
  181. #ifdef _UNICODE
  182. if (GetRichEditContext().m_bRichEdit2)
  183. {
  184. GETTEXTLENGTHEX gtl =
  185. {
  186. GTL_DEFAULT, 1200
  187. };
  188. int nLen = (int)SendMessage(EM_GETTEXTLENGTHEX, (WPARAM)&gtl);
  189. if (nLen > 0)
  190. {
  191. GETTEXTEX gt =
  192. {
  193. (nLen + 1) * sizeof(TCHAR), GT_DEFAULT, 1200, 0, 0
  194. };
  195. SendMessage(EM_GETTEXTEX, (WPARAM)&gt, (LPARAM)rString.GetBufferSetLength(nLen));
  196. rString.ReleaseBuffer();
  197. }
  198. else
  199. {
  200. rString.Empty();
  201. }
  202. }
  203. else
  204. #endif
  205. {
  206. GetWindowText(rString);
  207. }
  208. }
  209. BEGIN_MESSAGE_MAP(CXTPEdit, CEdit)
  210. ON_MESSAGE_VOID(WM_IME_STARTCOMPOSITION, OnImeStartComposition)
  211. ON_MESSAGE_VOID(WM_IME_ENDCOMPOSITION, OnImeEndComposition)
  212. ON_WM_KILLFOCUS()
  213. ON_WM_PAINT()
  214. END_MESSAGE_MAP()
  215. void CXTPEdit::OnImeStartComposition()
  216. {
  217. Default();
  218. m_bImeMode = TRUE;
  219. }
  220. void CXTPEdit::OnImeEndComposition()
  221. {
  222. Default();
  223. m_bImeMode = FALSE;
  224. }
  225. void CXTPEdit::OnKillFocus(CWnd* pNewWnd)
  226. {
  227. CEdit::OnKillFocus(pNewWnd);
  228. m_bImeMode = FALSE;
  229. }
  230. void CXTPEdit::OnPaint()
  231. {
  232. Default();
  233. if (m_bComposited)
  234. {
  235. CClientDC dc(this);
  236. CXTPPaintManager::FillCompositeAlpha(&dc, CXTPClientRect(this));
  237. }
  238. }
  239. //////////////////////////////////////////////////////////////////////////
  240. // CXTPControlComboBoxAutoCompleteWnd
  241. HHOOK CXTPControlComboBoxAutoCompleteWnd::m_hHookMessage = 0;
  242. CXTPControlComboBoxAutoCompleteWnd* CXTPControlComboBoxAutoCompleteWnd::m_pWndMonitor = 0;
  243. #define WM_XTP_SHELLAUTOCOMPLETESTART (WM_XTP_COMMANDBARS_BASE + 30)
  244. CXTPControlComboBoxAutoCompleteWnd::CXTPControlComboBoxAutoCompleteWnd()
  245. {
  246. m_hWndAutoComplete = 0;
  247. m_hWndEdit = 0;
  248. }
  249. CXTPControlComboBoxAutoCompleteWnd::~CXTPControlComboBoxAutoCompleteWnd()
  250. {
  251. SetupMessageHook(FALSE);
  252. SetAutoCompeteHandle(NULL);
  253. }
  254. BOOL CXTPControlComboBoxAutoCompleteWnd::IsDialogCode(UINT nChar, LPARAM lParam)
  255. {
  256. if (!m_hWndAutoComplete)
  257. return FALSE;
  258. if (! ((nChar == VK_UP || nChar == VK_DOWN || nChar == VK_NEXT || nChar == VK_PRIOR) && (GetKeyState(VK_MENU) >= 0)))
  259. return FALSE;
  260. HWND hWnd = ::GetWindow(m_hWndAutoComplete, GW_CHILD);
  261. hWnd = ::GetWindow(hWnd, GW_HWNDLAST);
  262. MSG msg;
  263. msg.message = WM_KEYDOWN;
  264. msg.hwnd = hWnd;
  265. msg.wParam = (WPARAM)nChar;
  266. msg.lParam = lParam;
  267. if (::IsDialogMessage(m_hWndAutoComplete, &msg))
  268. return TRUE;
  269. return FALSE;
  270. }
  271. HRESULT CXTPControlComboBoxAutoCompleteWnd::ShellAutoComplete(HWND hEdit, DWORD dwFlags)
  272. {
  273. m_hWndEdit = hEdit;
  274. HRESULT hResult = E_FAIL;
  275. HMODULE hLib = LoadLibraryA("shlwapi.dll");
  276. if (hLib)
  277. {
  278. typedef HRESULT (STDAPICALLTYPE *SHAUTOCOMPLETE)(HWND hwndEdit, DWORD dwFlags);
  279. SHAUTOCOMPLETE _SHAutoComplete = NULL;
  280. _SHAutoComplete = (SHAUTOCOMPLETE)GetProcAddress(hLib, "SHAutoComplete");
  281. if (_SHAutoComplete)
  282. {
  283. hResult = _SHAutoComplete(hEdit, dwFlags);
  284. }
  285. FreeLibrary(hLib);
  286. }
  287. return hResult;
  288. }
  289. void CXTPControlComboBoxAutoCompleteWnd::CloseWindow()
  290. {
  291. if (m_hWndAutoComplete)
  292. {
  293. ShowWindow(m_hWndAutoComplete, SW_HIDE);
  294. }
  295. }
  296. void CXTPControlComboBoxAutoCompleteWnd::SetAutoCompeteHandle(HWND hWnd)
  297. {
  298. if (m_hWndAutoComplete == hWnd)
  299. return;
  300. if (hWnd)
  301. {
  302. XTPMouseManager()->AddTrustedWindow(hWnd);
  303. }
  304. else
  305. {
  306. XTPMouseManager()->RemoveTrustedWindow(m_hWndAutoComplete);
  307. }
  308. m_hWndAutoComplete = hWnd;
  309. }
  310. void CXTPControlComboBoxAutoCompleteWnd::SetupMessageHook(BOOL bSetup)
  311. {
  312. if (bSetup && m_hHookMessage == 0)
  313. {
  314. ASSERT(m_pWndMonitor == NULL);
  315. m_hHookMessage = SetWindowsHookEx(WH_CALLWNDPROC, CallWndProc, AfxGetInstanceHandle(), GetCurrentThreadId());
  316. XTPKeyboardManager()->HookKeyboard(this);
  317. m_pWndMonitor = this;
  318. }
  319. if (!bSetup && m_hHookMessage && (m_pWndMonitor == this))
  320. {
  321. UnhookWindowsHookEx(m_hHookMessage);
  322. XTPKeyboardManager()->UnhookKeyboard(m_pWndMonitor);
  323. m_hHookMessage = 0;
  324. m_pWndMonitor = NULL;
  325. }
  326. if (!bSetup)
  327. {
  328. SetAutoCompeteHandle(NULL);
  329. }
  330. }
  331. int CXTPControlComboBoxAutoCompleteWnd::OnHookMessage(HWND /*hWnd*/, UINT nMessage, WPARAM& /*wParam*/, LPARAM& /*lParam*/, LRESULT& /*lResult*/)
  332. {
  333. if (nMessage == WM_MOUSEWHEEL && m_hWndAutoComplete)
  334. return FALSE_EXIT;
  335. return FALSE;
  336. }
  337. LRESULT CALLBACK CXTPControlComboBoxAutoCompleteWnd::CallWndProc(int code, WPARAM wParam, LPARAM lParam)
  338. {
  339. CWPSTRUCT* pMSG = (CWPSTRUCT*)lParam;
  340. if (pMSG && m_pWndMonitor && pMSG->message == WM_WINDOWPOSCHANGING)
  341. {
  342. const HWND& hWndAutoComplete = m_pWndMonitor->m_hWndAutoComplete;
  343. WINDOWPOS* pWindowPos = (WINDOWPOS*)pMSG->lParam;
  344. if ((hWndAutoComplete != 0 && hWndAutoComplete == pWindowPos->hwnd) && (pWindowPos->flags & SWP_HIDEWINDOW))
  345. {
  346. m_pWndMonitor->SetAutoCompeteHandle(NULL);
  347. }
  348. else if ((hWndAutoComplete == 0) && (pWindowPos->flags & SWP_SHOWWINDOW))
  349. {
  350. HWND hWnd = pWindowPos->hwnd;
  351. TCHAR szClassName[255];
  352. ::GetClassName(hWnd, szClassName, 255);
  353. if (_tcscmp(szClassName, _T("Auto-Suggest Dropdown")) == 0)
  354. {
  355. m_pWndMonitor->SetAutoCompeteHandle(hWnd);
  356. PostMessage(m_pWndMonitor->m_hWndEdit, WM_XTP_SHELLAUTOCOMPLETESTART, 0, 0);
  357. }
  358. }
  359. }
  360. return CallNextHookEx(m_hHookMessage, code, wParam, lParam);
  361. }
  362. // CXTPControlComboBox
  363. IMPLEMENT_XTP_CONTROL(CXTPControlComboBox, CXTPControlPopup)
  364. CXTPControlComboBox::CXTPControlComboBox(CXTPCommandBars* pCommandBars)
  365. {
  366. EnableAutomation();
  367. m_controlType = xtpControlComboBox;
  368. m_bDropDown = FALSE;
  369. m_comboStyle = xtpComboNormal;
  370. m_nWidth = 100;
  371. m_nLabelWidth = 0;
  372. m_nThumbWidth = 0;
  373. m_pEdit = NULL;
  374. m_strEditText = _T("");
  375. m_nCurSel = m_nLastSel = -1;
  376. m_bDelayReposition = FALSE;
  377. m_bDelayDestroy = FALSE;
  378. m_bIgnoreAutoComplete = m_bAutoComplete = FALSE;
  379. m_bFocused = FALSE;
  380. m_nDropDownItemCount = 12;
  381. m_bIgnoreSelection = FALSE;
  382. m_pCommandBar = new CXTPControlComboBoxList();
  383. m_pCommandBar->SetCommandBars(pCommandBars);
  384. ((CXTPControlComboBoxList*)m_pCommandBar)->CreateListBox();
  385. m_dwShellAutoCompleteFlags = 0;
  386. m_pAutoCompleteWnd = NULL;
  387. m_nEditIconId = 0;
  388. m_bSelEndOk = FALSE;
  389. m_bEditChanged = TRUE;
  390. m_dwEditStyle = 0;
  391. }
  392. CXTPControlComboBox::~CXTPControlComboBox()
  393. {
  394. if (m_pEdit)
  395. {
  396. delete m_pEdit;
  397. }
  398. SAFE_DELETE(m_pAutoCompleteWnd);
  399. }
  400. CString CXTPControlComboBox::GetEditText() const
  401. {
  402. CString strEditText = _GetEditText();
  403. return strEditText == GetEditHint() ? _T("") : strEditText;
  404. }
  405. CString CXTPControlComboBox::_GetEditText() const
  406. {
  407. if (m_pEdit && m_pEdit->GetSafeHwnd() && m_bEditChanged)
  408. {
  409. m_pEdit->GetWindowTextEx(m_strEditText);
  410. m_bEditChanged = FALSE;
  411. }
  412. return m_strEditText;
  413. }
  414. void CXTPControlComboBox::SetEditText(const CString& strText)
  415. {
  416. _SetEditText(strText.IsEmpty() ? GetEditHint() : strText);
  417. }
  418. void CXTPControlComboBox::_SetEditText(const CString& strText)
  419. {
  420. if (m_pEdit && m_pEdit->GetSafeHwnd() && _GetEditText() != strText)
  421. {
  422. m_pEdit->SetWindowTextEx(strText);
  423. }
  424. m_strEditText = strText;
  425. m_bEditChanged = FALSE;
  426. }
  427. void CXTPControlComboBox::SetEditHint(LPCTSTR lpszEditHint)
  428. {
  429. if (!GetEditHint().IsEmpty() && _GetEditText() == GetEditHint())
  430. {
  431. _SetEditText(_T(""));
  432. }
  433. m_strEditHint = lpszEditHint;
  434. if (_GetEditText().IsEmpty() && !GetEditHint().IsEmpty())
  435. {
  436. _SetEditText(GetEditHint());
  437. }
  438. }
  439. BOOL CXTPControlComboBox::IsImageVisible() const
  440. {
  441. if (GetParent()->GetType() == xtpBarTypePopup)
  442. return GetImage(0) != NULL;
  443. BOOL bImageVisible = (CXTPControl::GetStyle() == xtpButtonIcon || CXTPControl::GetStyle() == xtpButtonIconAndCaption)
  444. && (GetImage(0) != NULL);
  445. return bImageVisible;
  446. }
  447. BOOL CXTPControlComboBox::IsCaptionVisible() const
  448. {
  449. if (GetParent()->GetType() == xtpBarTypePopup)
  450. return TRUE;
  451. if (GetCaption().IsEmpty())
  452. return FALSE;
  453. XTPButtonStyle buttonStyle = CXTPControl::GetStyle();
  454. if ((buttonStyle == xtpButtonCaption) || (buttonStyle == xtpButtonIconAndCaption) || (buttonStyle == xtpButtonIconAndCaptionBelow))
  455. return TRUE;
  456. return m_comboStyle == xtpComboLabel;
  457. }
  458. CString CXTPControlComboBox::GetEditHint() const
  459. {
  460. return !m_strEditHint.IsEmpty() ? m_strEditHint : m_pAction ? m_pAction->GetEditHint() : _T("");
  461. }
  462. void CXTPControlComboBox::UpdatePopupSelection()
  463. {
  464. CEdit* pEdit = GetEditCtrl();
  465. CXTPControlComboBoxPopupBar* pPopupBar = GetComboBoxPopupBar();
  466. if (!m_bIgnoreSelection && pEdit && pEdit->GetSafeHwnd() && pPopupBar)
  467. {
  468. CString strWindowText = _GetEditText();
  469. int nIndex = pPopupBar->FindStringExact(0, strWindowText);
  470. if (nIndex != LB_ERR)
  471. pPopupBar->SetCurSel(nIndex);
  472. else
  473. {
  474. nIndex = pPopupBar->FindString(0, strWindowText);
  475. pPopupBar->SetTopIndex(nIndex);
  476. pPopupBar->SetCurSel(nIndex);
  477. pPopupBar->SetCurSel(-1);
  478. }
  479. }
  480. }
  481. void CXTPControlComboBox::OnEditChanged()
  482. {
  483. CEdit* pEdit = GetEditCtrl();
  484. CXTPControlComboBoxPopupBar* pPopupBar = GetComboBoxPopupBar();
  485. if (!m_bIgnoreSelection && m_bAutoComplete && !m_bIgnoreAutoComplete && pEdit && pEdit->GetSafeHwnd() && pPopupBar)
  486. {
  487. CString strWindowText = _GetEditText();
  488. int nLength = strWindowText.GetLength();
  489. if (nLength > 0)
  490. {
  491. // Currently selected range
  492. int nStart = 0, nEnd = 0;
  493. pEdit->GetSel(nStart, nEnd);
  494. if (nStart == nEnd && nLength == nEnd)
  495. {
  496. int nIndex = pPopupBar->FindString(0, strWindowText);
  497. if (nIndex != LB_ERR)
  498. {
  499. CString strWindowTextNew;
  500. pPopupBar->GetText(nIndex, strWindowTextNew);
  501. _SetEditText(strWindowTextNew);
  502. pEdit->SetSel(strWindowTextNew.GetLength(), nLength);
  503. }
  504. }
  505. }
  506. m_bIgnoreAutoComplete = TRUE;
  507. }
  508. UpdatePopupSelection();
  509. NotifySite(CBN_EDITCHANGE);
  510. }
  511. void CXTPControlComboBox::OnSelChanged()
  512. {
  513. m_bIgnoreSelection = TRUE;
  514. _SetEditText(GetListBoxText());
  515. m_bIgnoreSelection = FALSE;
  516. RedrawParent(FALSE);
  517. NotifySite(CBN_SELCHANGE);
  518. }
  519. BOOL CXTPControlComboBox::OnHookMouseWheel(UINT /*nFlags*/, short zDelta, CPoint /*pt*/)
  520. {
  521. if (!IsFocused())
  522. return FALSE;
  523. if (GetDroppedState())
  524. return FALSE;
  525. if (m_pAutoCompleteWnd)
  526. return FALSE;
  527. if (!IsValidList())
  528. return FALSE;
  529. ((CXTPControlComboBoxPopupBar*)m_pCommandBar)->ProcessHookKeyDown(this, zDelta > 0 ? VK_UP : VK_DOWN, 0);
  530. return TRUE;
  531. }
  532. BOOL CXTPControlComboBox::OnHookKeyDown(UINT nChar, LPARAM lParam)
  533. {
  534. ASSERT(IsFocused());
  535. if (!IsFocused())
  536. return FALSE;
  537. m_bIgnoreAutoComplete = (nChar == VK_DELETE) || (nChar == VK_BACK);
  538. if (m_pEdit && m_pEdit->m_bImeMode)
  539. return FALSE_EXIT;
  540. if (nChar == VK_TAB && ((m_pAutoCompleteWnd == NULL) || ((m_dwShellAutoCompleteFlags & SHACF_USETAB) == 0)))
  541. return FALSE;
  542. if (nChar == VK_RETURN)
  543. return FALSE;
  544. if (nChar == VK_ESCAPE)
  545. {
  546. m_pCommandBar->OnTrackLost();
  547. SetCurSel(m_nLastSel);
  548. SetEditText(m_strLastText);
  549. SetFocused(FALSE);
  550. return GetParent()->GetType() == xtpBarTypePopup;
  551. }
  552. if (m_pEdit && m_pEdit->GetSafeHwnd() && GetKeyState(VK_MENU) < 0 && GetKeyState(VK_CONTROL) >= 0)
  553. {
  554. CXTPCommandBars* pCommandBars = m_pParent->GetCommandBars();
  555. if (pCommandBars && pCommandBars->OnFrameAccel((TCHAR)nChar))
  556. return TRUE;
  557. }
  558. if ((nChar == VK_F4 && GetKeyState(VK_MENU) >= 0) || ((nChar == VK_UP || nChar == VK_DOWN) && GetKeyState(VK_MENU) < 0))
  559. {
  560. OnClick(FALSE);
  561. return TRUE;
  562. }
  563. if (m_pAutoCompleteWnd && m_pAutoCompleteWnd->IsDialogCode(nChar, lParam))
  564. return TRUE;
  565. if ((!m_pEdit || (nChar == VK_UP || nChar == VK_DOWN || nChar == VK_NEXT || nChar == VK_PRIOR) && (GetKeyState(VK_MENU) >= 0)) && IsValidList())
  566. {
  567. ((CXTPControlComboBoxPopupBar*)m_pCommandBar)->ProcessHookKeyDown(this, nChar, lParam);
  568. return TRUE;
  569. }
  570. if (m_pEdit && m_pEdit->GetSafeHwnd() && m_pEdit->IsDialogCode(nChar, lParam))
  571. {
  572. return TRUE;
  573. }
  574. return FALSE_EXIT;
  575. }
  576. BOOL CXTPControlComboBox::GetDropDownListStyle() const
  577. {
  578. return m_pEdit != NULL;
  579. }
  580. CXTPControlComboBoxEditCtrl* CXTPControlComboBox::CreateEditControl()
  581. {
  582. return new CXTPControlComboBoxEditCtrl();
  583. }
  584. void CXTPControlComboBox::SetDropDownListStyle(BOOL bSet)
  585. {
  586. m_bDropDown = bSet;
  587. if (bSet && m_pEdit == NULL)
  588. {
  589. m_pEdit = CreateEditControl();
  590. m_pEdit->m_pControl = this;
  591. }
  592. else if (!bSet && m_pEdit != NULL)
  593. {
  594. delete m_pEdit;
  595. m_pEdit = NULL;
  596. }
  597. }
  598. void CXTPControlComboBox::EnableShellAutoComplete(DWORD dwFlags /*= SHACF_FILESYSTEM | SHACF_URLALL*/)
  599. {
  600. m_dwShellAutoCompleteFlags = dwFlags;
  601. SAFE_DELETE(m_pAutoCompleteWnd);
  602. if (m_pEdit->GetSafeHwnd() && dwFlags)
  603. {
  604. m_pAutoCompleteWnd = new CXTPControlComboBoxAutoCompleteWnd();
  605. if (FAILED(m_pAutoCompleteWnd->ShellAutoComplete(m_pEdit->GetSafeHwnd(), m_dwShellAutoCompleteFlags)))
  606. {
  607. SAFE_DELETE(m_pAutoCompleteWnd);
  608. }
  609. }
  610. }
  611. void CXTPControlComboBox::EnableAutoComplete(BOOL bAutoComplete /*= TRUE*/)
  612. {
  613. m_bAutoComplete = bAutoComplete;
  614. }
  615. void CXTPControlComboBox::SetRect(CRect rcControl)
  616. {
  617. CString strEditText = GetEditText();
  618. if (m_bDelayDestroy && m_pEdit && m_pEdit->GetSafeHwnd())
  619. {
  620. m_pEdit->DestroyWindow();
  621. m_bDelayDestroy = FALSE;
  622. }
  623. if (m_pEdit && m_pEdit->GetSafeHwnd() && m_pEdit->GetExStyle() & WS_EX_LAYOUTRTL)
  624. {
  625. m_pEdit->DestroyWindow();
  626. }
  627. if (m_pEdit && m_pEdit->GetSafeHwnd() && m_pEdit->GetParent() != m_pParent)
  628. {
  629. m_pEdit->DestroyWindow();
  630. }
  631. if (m_rcControl == rcControl && !(m_pEdit && !m_pEdit->GetSafeHwnd()) && (m_bDelayReposition == FALSE))
  632. {
  633. if (!(m_pEdit && m_pEdit->GetSafeHwnd() && m_pEdit->GetParent() != m_pParent))
  634. return;
  635. }
  636. m_rcControl = rcControl;
  637. if (m_pEdit)
  638. {
  639. if (!m_pEdit->GetSafeHwnd())
  640. {
  641. m_pEdit->CreateEdit(WS_CHILD | ES_AUTOHSCROLL | m_dwEditStyle, m_pParent);
  642. if (!GetEnabled()) m_pEdit->EnableWindow(FALSE);
  643. if (m_dwShellAutoCompleteFlags != 0) EnableShellAutoComplete(m_dwShellAutoCompleteFlags);
  644. }
  645. m_pEdit->SetFont(GetPaintManager()->GetIconFont(), FALSE);
  646. m_pEdit->SetMargins(0, 0);
  647. m_pEdit->UpdateCharFormat();
  648. if (m_pEdit->GetSafeHwnd() != ::GetFocus()) SetEditText(strEditText);
  649. m_pEdit->m_bComposited = HasDwmCompositedRect();
  650. rcControl.DeflateRect(m_nLabelWidth + 1 + 3, 3, m_nThumbWidth + 3, 3);
  651. DeflateEditRect(rcControl);
  652. m_pEdit->MoveWindow(rcControl);
  653. ShowHideEditControl();
  654. }
  655. m_bDelayReposition = FALSE;
  656. }
  657. void CXTPControlComboBox::ShowHideEditControl()
  658. {
  659. if (m_pEdit && m_pEdit->GetSafeHwnd())
  660. {
  661. m_pEdit->SetWindowPos(0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE
  662. | (m_pControls && m_pParent && IsVisible() && m_pParent->GetSafeHwnd() ? SWP_SHOWWINDOW : SWP_HIDEWINDOW));
  663. }
  664. }
  665. void CXTPControlComboBox::OnRemoved()
  666. {
  667. ShowHideEditControl();
  668. if (!m_pControls && m_pEdit && m_pEdit->GetSafeHwnd())
  669. {
  670. m_pEdit->DestroyWindow();
  671. }
  672. CXTPControlPopup::OnRemoved();
  673. }
  674. void CXTPControlComboBox::SetEnabled(BOOL bEnabled)
  675. {
  676. if (bEnabled != m_bEnabled)
  677. {
  678. m_bEnabled = bEnabled;
  679. if (m_pEdit && m_pEdit->GetSafeHwnd())
  680. {
  681. m_pEdit->EnableWindow(GetEnabled());
  682. m_pEdit->UpdateCharFormat();
  683. }
  684. RedrawParent();
  685. }
  686. }
  687. void CXTPControlComboBox::SetParent(CXTPCommandBar* pParent)
  688. {
  689. if (pParent != m_pParent && pParent)
  690. {
  691. CWnd* pSite = pParent->GetSite();
  692. if (pSite)
  693. SetWindowLongPtr(m_pCommandBar->GetSafeHwnd(), GWLP_HWNDPARENT, (LONG_PTR)pSite->GetSafeHwnd());
  694. }
  695. if (!pParent && m_pEdit && m_pEdit->GetSafeHwnd())
  696. {
  697. m_pEdit->DestroyWindow();
  698. }
  699. CXTPControlPopup::SetParent(pParent);
  700. }
  701. BOOL  CXTPControlComboBox::OnSetSelected(int bSelected)
  702. {
  703. if (!CXTPControl::OnSetSelected(bSelected))
  704. return FALSE;
  705. if (!bSelected)
  706. {
  707. SetFocused(FALSE);
  708. }
  709. if (!bSelected && m_bPopup && GetParent()->GetPosition() != xtpBarPopup)
  710. {
  711. m_pParent->SetPopuped(-1);
  712. }
  713. if (m_pEdit->GetSafeHwnd())
  714. {
  715. m_pEdit->UpdateCharFormat();
  716. }
  717. return TRUE;
  718. }
  719. BOOL CXTPControlComboBox::HasFocus() const
  720. {
  721. return IsFocused() || (m_pCommandBar->IsTrackingMode()) || m_pParent->GetCommandBars()->GetMouseManager()->IsMouseLocked();
  722. }
  723. BOOL CXTPControlComboBox::IsFocusable() const
  724. {
  725. return TRUE;
  726. }
  727. void CXTPControlComboBox::OnClick(BOOL bKeyboard , CPoint pt)
  728. {
  729. if (m_pEdit && m_pEdit->m_bImeMode)
  730. return;
  731. if (IsCustomizeMode())
  732. {
  733. m_pParent->SetPopuped(-1);
  734. m_pParent->SetSelected(-1);
  735. CustomizeStartDrag(pt);
  736. }
  737. else if (bKeyboard && GetEnabled())
  738. {
  739. if (IsFocused())
  740. {
  741. OnExecute();
  742. }
  743. else
  744. {
  745. SetFocused(TRUE);
  746. }
  747. }
  748. else if (m_bPopup && IsFocused())
  749. {
  750. m_pParent->SetPopuped(-1);
  751. }
  752. else CXTPControlPopup::OnClick(bKeyboard, pt);
  753. }
  754. void CXTPControlComboBox::OnUnderlineActivate()
  755. {
  756. m_pParent->HideKeyboardTips();
  757. SetFocused(TRUE);
  758. }
  759. void CXTPControlComboBox::OnMouseHover()
  760. {
  761. }
  762. void CXTPControlComboBox::SetHideFlags(DWORD dwFlags)
  763. {
  764. if (m_dwHideFlags != dwFlags)
  765. {
  766. m_dwHideFlags = dwFlags;
  767. ShowHideEditControl();
  768. DelayLayoutParent();
  769. }
  770. }
  771. void CXTPControlComboBox::OnActionChanged(int nProperty)
  772. {
  773. if (nProperty == 2)    // Visible
  774. {
  775. ShowHideEditControl();
  776. }
  777. if (nProperty == 0 && m_pEdit && m_pEdit->GetSafeHwnd())    // Enabled
  778. {
  779. m_pEdit->EnableWindow(GetEnabled());
  780. m_pEdit->UpdateCharFormat();
  781. }
  782. if (nProperty == 4) // EditHint
  783. {
  784. if (_GetEditText().IsEmpty() && !GetEditHint().IsEmpty())
  785. {
  786. _SetEditText(GetEditHint());
  787. }
  788. }
  789. }
  790. void CXTPControlComboBox::OnActionChanging(int nProperty)
  791. {
  792. if (nProperty == 4 && !GetEditHint().IsEmpty() && _GetEditText() == GetEditHint())
  793. {
  794. _SetEditText(_T(""));
  795. }
  796. }
  797. void CXTPControlComboBox::OnCalcDynamicSize(DWORD dwMode)
  798. {
  799. if (dwMode & LM_VERTDOCK) SetHideFlags(m_dwHideFlags | xtpHideDockingPosition);
  800. else SetHideFlags(m_dwHideFlags & ~xtpHideDockingPosition);
  801. }
  802. DWORD CXTPControlComboBox::GetEditStyle() const
  803. {
  804. return m_dwEditStyle;
  805. }
  806. void CXTPControlComboBox::SetEditStyle(DWORD dwStyle)
  807. {
  808. m_dwEditStyle = dwStyle;
  809. if (m_pEdit && m_pEdit->GetSafeHwnd())
  810. {
  811. m_bDelayDestroy = TRUE;
  812. DelayLayoutParent();
  813. }
  814. }
  815. void CXTPControlComboBox::Copy(CXTPControl* pControl, BOOL bRecursive)
  816. {
  817. CXTPControlComboBox* pControlCombo = DYNAMIC_DOWNCAST(CXTPControlComboBox, pControl);
  818. ASSERT(pControlCombo);
  819. if (!pControlCombo)
  820. {
  821. CXTPControlPopup::Copy(pControl, bRecursive);
  822. return;
  823. }
  824. m_dwEditStyle = pControlCombo->m_dwEditStyle;
  825. m_comboStyle = pControlCombo->m_comboStyle;
  826. SetEditText(pControlCombo->GetEditText());
  827. SetEditHint(pControlCombo->m_strEditHint);
  828. SetDropDownListStyle(pControlCombo->m_pEdit != NULL);
  829. m_bAutoComplete = pControlCombo->m_bAutoComplete;
  830. EnableShellAutoComplete(pControlCombo->m_dwShellAutoCompleteFlags);
  831. m_nEditIconId = pControlCombo->m_nEditIconId;
  832. m_nDropDownItemCount = pControlCombo->m_nDropDownItemCount;
  833. CXTPControlPopup::Copy(pControl, bRecursive);
  834. }
  835. BOOL CXTPControlComboBox::Compare(CXTPControl* pOther)
  836. {
  837. if (!CXTPControlPopup::Compare(pOther))
  838. return FALSE;
  839. if (!pOther->IsKindOf(RUNTIME_CLASS(CXTPControlComboBox)))
  840. return FALSE;
  841. return TRUE;
  842. }
  843. CString CXTPControlComboBox::GetListBoxText() const
  844. {
  845. CXTPControlComboBoxPopupBar* pPopupBar = GetComboBoxPopupBar();
  846. if (!pPopupBar)
  847. return _T("");
  848. int nSel = pPopupBar->GetCurSel();
  849. CString str;
  850. if (nSel >= 0)
  851. pPopupBar->GetText(nSel, str);
  852. return str;
  853. }
  854. BOOL CXTPControlComboBox::IsValidList() const
  855. {
  856. return GetComboBoxPopupBar() != NULL;
  857. }
  858. CXTPControlComboBoxPopupBar* CXTPControlComboBox::GetComboBoxPopupBar() const
  859. {
  860. return DYNAMIC_DOWNCAST(CXTPControlComboBoxPopupBar, m_pCommandBar);
  861. }
  862. int CXTPControlComboBox::GetCurSel() const
  863. {
  864. CXTPControlComboBoxPopupBar* pPopupBar = GetComboBoxPopupBar();
  865. return pPopupBar ? pPopupBar->GetCurSel() : m_nCurSel;
  866. }
  867. void CXTPControlComboBox::SetCurSel(int nIndex)
  868. {
  869. if ((GetCurSel() != nIndex) || (m_nCurSel != nIndex))
  870. {
  871. m_nCurSel = nIndex;
  872. CXTPControlComboBoxPopupBar* pPopupBar = GetComboBoxPopupBar();
  873. if (pPopupBar)
  874. {
  875. pPopupBar->SetCurSel(nIndex);
  876. }
  877. OnSelChanged();
  878. }
  879. }
  880. BOOL CXTPControlComboBox::IsFocused() const
  881. {
  882. return m_bFocused;
  883. }
  884. void CXTPControlComboBox::SetFocused(BOOL bFocused)
  885. {
  886. if (m_bFocused == bFocused)
  887. return;
  888. m_bFocused = bFocused;
  889. if (bFocused)
  890. {
  891. m_nLastSel = GetCurSel();
  892. m_bSelEndOk = FALSE;
  893. if (m_pEdit->GetSafeHwnd() && ::GetFocus() != m_pEdit->GetSafeHwnd())
  894. m_pEdit->SetFocus();
  895. m_pParent->SetTrackingMode(TRUE, FALSE);
  896. m_pParent->SetSelected(m_nIndex);
  897. XTPMouseManager()->LockMouseMove();
  898. NotifySite(CBN_SETFOCUS);
  899. }
  900. else
  901. {
  902. if (!m_bSelEndOk && !GetDroppedState() && !m_pEdit)
  903. {
  904. SetCurSel(m_nLastSel);
  905. NotifySite(CBN_SELENDCANCEL);
  906. }
  907. if (m_pEdit->GetSafeHwnd() && ::GetFocus() == m_pEdit->GetSafeHwnd())
  908. ::SetFocus(m_pParent->GetTrackFocus());
  909. XTPMouseManager()->UnlockMouseMove();
  910. NotifySite(CBN_KILLFOCUS);
  911. }
  912. RedrawParent(FALSE);
  913. }
  914. void CXTPControlComboBox::OnSetFocus(CWnd* pOldWnd)
  915. {
  916. if (!GetEditHint().IsEmpty() && m_pEdit->GetSafeHwnd() && GetEditHint() == _GetEditText())
  917. {
  918. _SetEditText(_T(""));
  919. }
  920. m_strLastText = GetEditText();
  921. m_bIgnoreAutoComplete = TRUE;
  922. UpdatePopupSelection();
  923. if (m_pParent->GetTrackFocus() == 0)
  924. m_pParent->SetTrackFocus(pOldWnd ? pOldWnd->GetSafeHwnd() : m_pParent->GetSite()->GetSafeHwnd());
  925. if (!m_bPopup)
  926. m_pParent->SetPopuped(-1);
  927. SetFocused(TRUE);
  928. if (m_pAutoCompleteWnd) m_pAutoCompleteWnd->SetupMessageHook(TRUE);
  929. }
  930. void CXTPControlComboBox::OnKillFocus()
  931. {
  932. if (!GetEditHint().IsEmpty() && m_pEdit->GetSafeHwnd() && _GetEditText().IsEmpty())
  933. {
  934. _SetEditText(GetEditHint());
  935. }
  936. SetFocused(FALSE);
  937. if (GetDroppedState())
  938. m_pParent->SetPopuped(-1);
  939. if (m_pAutoCompleteWnd) m_pAutoCompleteWnd->SetupMessageHook(FALSE);
  940. }
  941. BOOL CXTPControlComboBox::GetDroppedState() const
  942. {
  943. return m_bPopup;
  944. //return m_pCommandBar->IsTrackingMode() && ((CXTPPopupBar*)m_pCommandBar)->GetControlPopup() == (CXTPControlPopup*)this;
  945. }
  946. BOOL CXTPControlComboBox::OnSetPopup(BOOL bPopup)
  947. {
  948. if (bPopup)
  949. {
  950. m_bSelEndOk = FALSE;
  951. m_nLastSel = GetCurSel();
  952. }
  953. else if (!IsFocused() && m_pEdit == NULL && !m_bSelEndOk)
  954. {
  955. SetCurSel(m_nLastSel);
  956. }
  957. if (!bPopup && !m_bSelEndOk)
  958. {
  959. NotifySite(CBN_SELENDCANCEL);
  960. }
  961. if (m_pAutoCompleteWnd && bPopup) m_pAutoCompleteWnd->CloseWindow();
  962. m_bPopup = bPopup;
  963. if (bPopup && GetEditCtrl()) GetEditCtrl()->SetFocus();
  964. return CXTPControlPopup::OnSetPopup(bPopup);
  965. }
  966. void CXTPControlComboBox::OnExecute()
  967. {
  968. if (GetCurSel() != -1 && (GetDroppedState() || (!m_pEdit && IsFocused())))
  969. NotifySite(CBN_SELENDOK);
  970. m_bSelEndOk = TRUE;
  971. m_nLastSel = GetCurSel();
  972. CXTPControlPopup::OnExecute();
  973. }
  974. CHARFORMAT2 CXTPControlComboBox::GetDefaultCharFormat()
  975. {
  976. CHARFORMAT2 cf;
  977. ZeroMemory(&cf, sizeof(CHARFORMAT2));
  978. cf.dwMask = CFM_COLOR | CFM_BACKCOLOR;
  979. if (GetEnabled())
  980. {
  981. cf.crTextColor = GetXtremeColor(COLOR_WINDOWTEXT);
  982. if (!GetEditHint().IsEmpty() && GetEditHint() == _GetEditText())
  983. {
  984. cf.crTextColor = GetXtremeColor(COLOR_GRAYTEXT);
  985. }
  986. }
  987. else
  988. {
  989. cf.crTextColor = GetXtremeColor(COLOR_GRAYTEXT);
  990. }
  991. cf.crBackColor = GetPaintManager()->GetControlEditBackColor(this);
  992. return cf;
  993. }
  994. void CXTPControlComboBox::ModifyListBoxStyle(DWORD dwRemove, DWORD dwAdd)
  995. {
  996. if (IsValidList())
  997. {
  998. CXTPControlComboBoxList* pComboBoxList = ((CXTPControlComboBoxList*)m_pCommandBar);
  999. pComboBoxList->m_dwStyle |= dwAdd;
  1000. pComboBoxList->m_dwStyle &= ~dwRemove;
  1001. pComboBoxList->DestroyWindow();
  1002. pComboBoxList->CreateListBox();
  1003. }
  1004. }
  1005. //////////////////////////////////////////////////////////////////////////
  1006. // CXTPControlComboBoxPopup
  1007. IMPLEMENT_XTP_COMMANDBAR(CXTPControlComboBoxPopupBar, CXTPPopupBar)
  1008. CXTPControlComboBoxPopupBar::CXTPControlComboBoxPopupBar()
  1009. {
  1010. m_bComboBar = TRUE;
  1011. m_bGrabFocus = FALSE;
  1012. }
  1013. BOOL CXTPControlComboBoxPopupBar::ProcessHookKeyDown(CXTPControlComboBox* pComboBox, UINT nChar, LPARAM lParam)
  1014. {
  1015. int nSel = GetCurSel();
  1016. if (pComboBox->GetEditCtrl())
  1017. {
  1018. if ((GetKeyState(VK_MENU) >= 0) && (nChar == VK_UP || nChar == VK_DOWN || nChar == VK_PRIOR || nChar == VK_NEXT))
  1019. {
  1020. CXTPCommandBar::OnHookKeyDown(nChar, lParam);
  1021. }
  1022. else
  1023. {
  1024. return FALSE;
  1025. }
  1026. }
  1027. else
  1028. {
  1029. if ((nChar == VK_F4 && GetKeyState(VK_MENU) >= 0) || ((nChar == VK_UP || nChar == VK_DOWN) && GetKeyState(VK_MENU) < 0))
  1030. {
  1031. return FALSE;
  1032. }
  1033. else
  1034. {
  1035. CXTPCommandBar::OnHookKeyDown(nChar, lParam);
  1036. }
  1037. }
  1038. if (nSel != GetCurSel())
  1039. {
  1040. pComboBox->OnSelChanged();
  1041. if (pComboBox->GetEditCtrl()->GetSafeHwnd()) pComboBox->GetEditCtrl()->SetSel(0, -1);
  1042. }
  1043. return TRUE;
  1044. }
  1045. BOOL CXTPControlComboBoxPopupBar::OnHookKeyDown(UINT nChar, LPARAM lParam)
  1046. {
  1047. ASSERT(m_pControlPopup);
  1048. CXTPControlComboBox* pComboBox = ((CXTPControlComboBox*)m_pControlPopup);
  1049. if (!pComboBox)
  1050. return CXTPCommandBar::OnHookKeyDown(nChar, lParam);
  1051. if (nChar == VK_ESCAPE)
  1052. {
  1053. if (pComboBox->IsFocused())
  1054. return FALSE;
  1055. return CXTPCommandBar::OnHookKeyDown(nChar, lParam);
  1056. }
  1057. if (nChar == VK_TAB) return FALSE;
  1058. return ProcessHookKeyDown(pComboBox, nChar, lParam);
  1059. }
  1060. //////////////////////////////////////////////////////////////////////////
  1061. // CXTPControlComboBoxList
  1062. CXTPControlComboBoxList::CXTPControlComboBoxList()
  1063. {
  1064. m_barPosition = xtpBarListBox;
  1065. m_nMRUWidth = 0;
  1066. m_bGrabFocus = FALSE;
  1067. m_dwStyle = 0;
  1068. m_nListIconId = -1;
  1069. }
  1070. BEGIN_MESSAGE_MAP(CXTPControlComboBoxList, CXTPPopupBar)
  1071. ON_WM_LBUTTONUP()
  1072. ON_WM_NCPAINT()
  1073. ON_WM_ERASEBKGND()
  1074. ON_WM_MOUSEMOVE()
  1075. ON_WM_LBUTTONDOWN()
  1076. ON_WM_DRAWITEM_REFLECT()
  1077. ON_WM_MEASUREITEM_REFLECT()
  1078. END_MESSAGE_MAP()
  1079. IMPLEMENT_XTP_COMMANDBAR(CXTPControlComboBoxList, CXTPControlComboBoxPopupBar)
  1080. void CXTPControlComboBoxList::CreateListBox()
  1081. {
  1082. DWORD dwStyle = m_dwStyle & ~CBRS_GRIPPER;
  1083. CWnd* pSite = GetSite();
  1084. if (pSite && ((dwStyle & (LBS_OWNERDRAWFIXED|LBS_OWNERDRAWVARIABLE)) != 0))
  1085. {
  1086. CreateEx(WS_EX_CLIENTEDGE|WS_EX_TOOLWINDOW, _T("LISTBOX"), _T(""),
  1087. WS_CHILD | WS_VSCROLL | WS_CLIPCHILDREN | dwStyle | LBS_NOTIFY,
  1088. CRect(0, 0, 0, 0), pSite, 0);
  1089. SetWindowLongPtr(m_hWnd, GWLP_HWNDPARENT, 0 );
  1090. ModifyStyle(WS_CHILD, WS_POPUP);
  1091. SetWindowLongPtr(m_hWnd, GWLP_HWNDPARENT, (LONG_PTR)(pSite->m_hWnd));
  1092. }
  1093. else
  1094. {
  1095. CreateEx(WS_EX_CLIENTEDGE | WS_EX_TOOLWINDOW, _T("LISTBOX"), _T(""),
  1096. WS_POPUP | WS_VSCROLL | WS_CLIPCHILDREN | dwStyle, CRect(0, 0, 0, 0), 0, 0);
  1097. }
  1098. if (m_pCommandBars && m_nListIconId != -1)
  1099. {
  1100. CXTPImageManagerIcon* pIcon = GetImageManager()->GetImage(m_nListIconId, 0);
  1101. if (pIcon)
  1102. {
  1103. ((CListBox*)this)->SetItemHeight(-1, pIcon->GetHeight() + 4);
  1104. }
  1105. }
  1106. }
  1107. void CXTPControlComboBoxList::DrawItem (LPDRAWITEMSTRUCT lpDrawItemStruct)
  1108. {
  1109. CXTPControlComboBox* pComboBox = (CXTPControlComboBox*)m_pControlPopup;
  1110. if (pComboBox) pComboBox->DrawItem(lpDrawItemStruct);
  1111. }
  1112. void CXTPControlComboBoxList::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
  1113. {
  1114. CXTPControlComboBox* pComboBox = (CXTPControlComboBox*)m_pControlPopup;
  1115. if (pComboBox) pComboBox->MeasureItem(lpMeasureItemStruct);
  1116. }
  1117. void CXTPControlComboBoxList::OnLButtonDown(UINT /*nFlags*/, CPoint /*point*/)
  1118. {
  1119. // do nothing.
  1120. }
  1121. int CXTPControlComboBoxList::OnHookMessage(HWND hWnd, UINT nMessage, WPARAM& wParam, LPARAM& lParam, LRESULT& lResult)
  1122. {
  1123. if (nMessage == WM_MOUSEWHEEL)
  1124. {
  1125. CWnd::DefWindowProc(WM_MOUSEWHEEL, wParam, lParam);
  1126. return TRUE;
  1127. }
  1128. return CXTPCommandBar::OnHookMessage(hWnd, nMessage, wParam, lParam, lResult);
  1129. }
  1130. void CXTPControlComboBoxList::OnNcPaint()
  1131. {
  1132. CXTPPaintManager* pPaintManager = GetPaintManager();
  1133. Default();
  1134. CWindowDC dc(this);
  1135. CXTPWindowRect rc(this);
  1136. rc.OffsetRect(-rc.TopLeft());
  1137. dc.Draw3dRect(rc, pPaintManager->GetXtremeColor(XPCOLOR_MENUBAR_BORDER), pPaintManager->GetXtremeColor(XPCOLOR_MENUBAR_BORDER));
  1138. rc.DeflateRect(1, 1);
  1139. dc.Draw3dRect(rc, GetXtremeColor(COLOR_WINDOW), GetXtremeColor(COLOR_WINDOW));
  1140. }
  1141. BOOL CXTPControlComboBoxList::OnEraseBkgnd(CDC* pDC)
  1142. {
  1143. return CWnd::OnEraseBkgnd(pDC);
  1144. }
  1145. void CXTPControlComboBoxList::OnLButtonUp(UINT /*nFlags*/, CPoint /*point*/)
  1146. {
  1147. CXTPControlComboBox* pComboBox = (CXTPControlComboBox*)m_pControlPopup;
  1148. pComboBox->OnSelChanged();
  1149. pComboBox->OnExecute();
  1150. }
  1151. BOOL CXTPControlComboBoxList::SetTrackingMode(int bMode, BOOL bSelectFirst, BOOL bKeyboard)
  1152. {
  1153. if (!CXTPCommandBar::SetTrackingMode(bMode, bSelectFirst, bKeyboard))
  1154. return FALSE;
  1155. CXTPControlComboBox* pComboBox = ((CXTPControlComboBox*)m_pControlPopup);
  1156. if (!bMode)
  1157. {
  1158. pComboBox->NotifySite(CBN_CLOSEUP);
  1159. XTPMouseManager()->UnlockMouseMove();
  1160. ShowWindow(SW_HIDE);
  1161. if (GetParentCommandBar())
  1162. GetParentCommandBar()->SetPopuped(-1);
  1163. m_pControlPopup = 0;
  1164. }
  1165. else
  1166. {
  1167. XTPMouseManager()->LockMouseMove();
  1168. pComboBox->UpdatePopupSelection();
  1169. pComboBox->NotifySite(CBN_DROPDOWN);
  1170. }
  1171. return TRUE;
  1172. }
  1173. CListBox* CXTPControlComboBoxList::GetListBoxCtrl() const
  1174. {
  1175. return (CListBox*)this;
  1176. }
  1177. BOOL CXTPControlComboBoxList::ProcessHookKeyDown(CXTPControlComboBox* pComboBox, UINT nChar, LPARAM lParam)
  1178. {
  1179. int nSel = GetCurSel();
  1180. if (pComboBox->GetEditCtrl())
  1181. {
  1182. if ((GetKeyState(VK_MENU) >= 0) && (nChar == VK_UP || nChar == VK_DOWN || nChar == VK_PRIOR || nChar == VK_NEXT))
  1183. {
  1184. CWnd::DefWindowProc(WM_KEYDOWN, (WPARAM)nChar, lParam);
  1185. }
  1186. else
  1187. {
  1188. return FALSE;
  1189. }
  1190. }
  1191. else
  1192. {
  1193. if ((nChar == VK_F4 && GetKeyState(VK_MENU) >= 0) || ((nChar == VK_UP || nChar == VK_DOWN) && GetKeyState(VK_MENU) < 0))
  1194. {
  1195. return FALSE;
  1196. }
  1197. else
  1198. {
  1199. MSG msg;
  1200. msg.message = WM_KEYDOWN;
  1201. msg.hwnd = m_hWnd;
  1202. msg.wParam = (WPARAM)nChar;
  1203. msg.lParam = lParam;
  1204. ::IsDialogMessage(m_hWnd, &msg);
  1205. if (PeekMessage(&msg, m_hWnd, WM_CHAR, WM_CHAR, PM_REMOVE))
  1206. {
  1207. CWnd::DefWindowProc(WM_CHAR, msg.wParam, msg.lParam);
  1208. }
  1209. }
  1210. }
  1211. if (nSel != GetCurSel())
  1212. {
  1213. pComboBox->OnSelChanged();
  1214. if (pComboBox->GetEditCtrl()->GetSafeHwnd()) pComboBox->GetEditCtrl()->SetSel(0, -1);
  1215. }
  1216. return TRUE;
  1217. }
  1218. BOOL CXTPControlComboBoxList::OnHookKeyDown(UINT nChar, LPARAM lParam)
  1219. {
  1220. ASSERT(m_pControlPopup);
  1221. CXTPControlComboBox* pComboBox = ((CXTPControlComboBox*)m_pControlPopup);
  1222. if (!pComboBox)
  1223. return CXTPCommandBar::OnHookKeyDown(nChar, lParam);
  1224. if (nChar == VK_ESCAPE)
  1225. {
  1226. if (pComboBox->IsFocused())
  1227. return FALSE;
  1228. return CXTPCommandBar::OnHookKeyDown(nChar, lParam);
  1229. }
  1230. if (nChar == VK_TAB) return FALSE;
  1231. if (nChar == VK_RETURN)
  1232. {
  1233. m_pControlPopup->OnExecute();
  1234. return TRUE;
  1235. }
  1236. return ProcessHookKeyDown(pComboBox, nChar, lParam);
  1237. }
  1238. void CXTPControlComboBoxList::OnMouseMove(UINT nFlags, CPoint point)
  1239. {
  1240. BOOL bOutside;
  1241. UINT nItem = GetListBoxCtrl()->ItemFromPoint(point, bOutside);
  1242. if (!bOutside && GetCurSel() != (int)nItem)
  1243. SetCurSel(nItem);
  1244. CXTPPopupBar::OnMouseMove(nFlags, point);
  1245. }
  1246. BOOL CXTPControlComboBoxList::Popup(CXTPControlPopup* pControlPopup, BOOL /*bSelectFirst*/)
  1247. {
  1248. m_pControlPopup = pControlPopup;
  1249. SetFont(GetPaintManager()->GetIconFont());
  1250. CWnd* pWndOwner = GetOwnerSite();
  1251. if (pWndOwner) pWndOwner->SendMessage(WM_XTP_INITCOMMANDSPOPUP, 0, (LPARAM)this);
  1252. CXTPCommandBars* pCommandBars = GetCommandBars();
  1253. if (pCommandBars && pCommandBars->IsLayoutRTL())
  1254. ModifyStyleEx(WS_EX_LAYOUTRTL, WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR | WS_EX_RTLREADING);
  1255. else ModifyStyleEx(WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR | WS_EX_RTLREADING, 0);
  1256. SetTrackingMode(TRUE, FALSE);
  1257. UpdateFlags();
  1258. CRect rcControl = pControlPopup->GetRect();
  1259. int nItemHeight = GetListBoxCtrl()->GetItemHeight(0);
  1260. int nHeight = min (((CXTPControlComboBox*)m_pControlPopup)->m_nDropDownItemCount,
  1261. max(1, GetListBoxCtrl()->GetCount())) * nItemHeight + 4;
  1262. int nWidth = m_nMRUWidth <= 0 ? rcControl.Width() : m_nMRUWidth;
  1263. UpdateLocation(CSize(nWidth, nHeight));
  1264. EnableWindow();
  1265. return TRUE;
  1266. }
  1267. void CXTPControlComboBoxList::DrawCommandBar(CDC* pDC, CRect /*rcClipBox*/)
  1268. {
  1269. pDC->FillSolidRect(CXTPClientRect(this), GetXtremeColor(COLOR_WINDOW));
  1270. CWnd::DefWindowProc(WM_PAINT, (WPARAM)pDC->m_hDC, 0);
  1271. }
  1272. //////////////////////////////////////////////////////////////////////////
  1273. // CXTPControlComboBoxEditCtrl
  1274. BEGIN_MESSAGE_MAP(CXTPControlComboBoxEditCtrl, CXTPEdit)
  1275. ON_WM_SETFOCUS()
  1276. ON_WM_MOUSEMOVE()
  1277. ON_WM_KILLFOCUS()
  1278. ON_WM_DESTROY()
  1279. ON_WM_LBUTTONDOWN()
  1280. ON_WM_RBUTTONDOWN()
  1281. ON_WM_CONTEXTMENU()
  1282. ON_WM_KEYDOWN()
  1283. ON_MESSAGE(XTP_TTM_WINDOWFROMPOINT, OnWindowFromPoint)
  1284. ON_MESSAGE_VOID(WM_XTP_SHELLAUTOCOMPLETESTART, OnShellAutoCompleteStart)
  1285. ON_CONTROL_REFLECT(EN_CHANGE, OnEditChanged)
  1286. END_MESSAGE_MAP()
  1287. void CXTPControlComboBoxEditCtrl::OnEditChanged()
  1288. {
  1289. m_pControl->m_bEditChanged = TRUE;
  1290. if (::GetFocus() == m_hWnd && !m_bIgonoreEditChanged)
  1291. m_pControl->OnEditChanged();
  1292. SetMargins(0, 0);
  1293. UpdateCharFormat();
  1294. }
  1295. void CXTPControlComboBoxEditCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  1296. {
  1297. if (nChar == VK_RETURN && ::GetFocus() == m_hWnd)
  1298. {
  1299. m_pControl->OnExecute();
  1300. return;
  1301. }
  1302. CXTPEdit::OnKeyDown(nChar, nRepCnt, nFlags);
  1303. }
  1304. void CXTPControlComboBoxEditCtrl::UpdateCharFormat()
  1305. {
  1306. CHARFORMAT2 cf = m_pControl->GetDefaultCharFormat();
  1307. cf.cbSize = GetRichEditContext().m_bRichEdit2 ? sizeof(CHARFORMAT2) : sizeof(CHARFORMAT);
  1308. ::SendMessage(m_hWnd, EM_SETCHARFORMAT, 0, (LPARAM)&cf);
  1309. ::SendMessage(m_hWnd, EM_SETBKGNDCOLOR, FALSE, cf.crBackColor);
  1310. }
  1311. void CXTPControlComboBoxEditCtrl::OnShellAutoCompleteStart()
  1312. {
  1313. m_pControl->GetCommandBar()->OnTrackLost();
  1314. }
  1315. void CXTPControlComboBoxEditCtrl::OnContextMenu(CWnd* /*pWnd*/, CPoint /*point*/)
  1316. {
  1317. }
  1318. void CXTPControlComboBoxEditCtrl::OnRButtonDown(UINT nFlags, CPoint point)
  1319. {
  1320. if (m_pControl->IsCustomizeMode())
  1321. {
  1322. ClientToScreen(&point);
  1323. m_pControl->GetParent()->ScreenToClient(&point);
  1324. m_pControl->GetParent()->OnRButtonDown(nFlags, point);
  1325. return;
  1326. }
  1327. m_pControl->GetCommandBar()->OnTrackLost();
  1328. m_pControl->SetFocused(TRUE);
  1329. if (!ShowContextMenu(m_pControl, point))
  1330. CXTPEdit::OnRButtonDown(nFlags, point);
  1331. }
  1332. void CXTPControlComboBoxEditCtrl::OnLButtonDown(UINT nFlags, CPoint point)
  1333. {
  1334. if (m_pControl->IsCustomizeMode())
  1335. {
  1336. if (m_pControl->IsCustomizeMovable())
  1337. m_pControl->OnClick();
  1338. }
  1339. else CEdit::OnLButtonDown(nFlags, point);
  1340. }
  1341. void CXTPControlComboBoxEditCtrl::OnDestroy()
  1342. {
  1343. GetWindowTextEx(m_pControl->m_strEditText);
  1344. CEdit::OnDestroy();
  1345. }
  1346. BOOL CXTPControlComboBoxEditCtrl::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
  1347. {
  1348. CXTPCommandBar* pCommandBar = m_pControl->GetParent();
  1349. if (pCommandBar)
  1350. {
  1351. pCommandBar->FilterToolTipMessage(message, wParam, lParam);
  1352. }
  1353. return CWnd::OnWndMsg(message, wParam, lParam, pResult);
  1354. }
  1355. LRESULT CXTPControlComboBoxEditCtrl::OnWindowFromPoint(WPARAM, LPARAM)
  1356. {
  1357. return 1;
  1358. }
  1359. void CXTPControlComboBoxEditCtrl::OnSetFocus(CWnd* pOldWnd)
  1360. {
  1361. if (!m_pControl->IsCustomizeMode())
  1362. {
  1363. m_pControl->OnSetFocus(pOldWnd);
  1364. CEdit::OnSetFocus(pOldWnd);
  1365. SetSel(0, 0);
  1366. ::PostMessage(m_hWnd, EM_SETSEL, 0, -1);
  1367. }
  1368. }
  1369. void CXTPControlComboBoxEditCtrl::OnKillFocus(CWnd* pNewWnd)
  1370. {
  1371. CXTPEdit::OnKillFocus(pNewWnd);
  1372. m_pControl->OnKillFocus();
  1373. }
  1374. void CXTPControlComboBoxEditCtrl::OnMouseMove(UINT nFlags, CPoint point)
  1375. {
  1376. CEdit::OnMouseMove(nFlags, point);
  1377. MapWindowPoints(m_pControl->GetParent(), &point, 1);
  1378. m_pControl->GetParent()->OnMouseMove(nFlags, point);
  1379. }
  1380. //////////////////////////////////////////////////////////////////////////
  1381. // CXTPControlComboBoxList
  1382. void CXTPControlComboBoxList::Copy(CXTPCommandBar* pCommandBar, BOOL bRecursive)
  1383. {
  1384. CXTPPopupBar::Copy(pCommandBar, bRecursive);
  1385. m_nListIconId = ((CXTPControlComboBoxList*)pCommandBar)->m_nListIconId;
  1386. if (!m_hWnd)
  1387. CreateListBox();
  1388. CListBox* pListBox = (CListBox*)(CXTPControlComboBoxList*)pCommandBar;
  1389. DWORD dwCount = pListBox->m_hWnd ? pListBox->GetCount() : 0;
  1390. for (UINT i = 0; i < dwCount; i++)
  1391. {
  1392. CString str;
  1393. pListBox->GetText(i, str);
  1394. GetListBoxCtrl()->AddString(str);
  1395. }
  1396. }
  1397. void CXTPControlComboBoxList::DoPropExchange(CXTPPropExchange* pPX)
  1398. {
  1399. CXTPPopupBar::DoPropExchange(pPX);
  1400. if (pPX->GetSchema() > _XTP_SCHEMA_110)
  1401. {
  1402. PX_Int(pPX, _T("ListIconId"), m_nListIconId, -1);
  1403. }
  1404. CListBox* pThis = (CListBox*)this;
  1405. CString str;
  1406. CXTPPropExchangeSection secItems(pPX->GetSection(_T("Items")));
  1407. if (pPX->IsStoring())
  1408. {
  1409. if (m_hWnd)
  1410. {
  1411. DWORD dwCount = pThis->GetCount();
  1412. secItems->WriteCount(dwCount);
  1413. for (int i = 0; i < (int)dwCount; i++)
  1414. {
  1415. pThis->GetText(i, str);
  1416. CString strSection;
  1417. strSection.Format(_T("Item%i"), i);
  1418. PX_String(&secItems, strSection, str, _T(""));
  1419. }
  1420. }
  1421. else
  1422. {
  1423. pPX->WriteCount(0);
  1424. }
  1425. }
  1426. else
  1427. {
  1428. if (!m_hWnd)
  1429. CreateListBox();
  1430. DWORD nNewCount = secItems->ReadCount();
  1431. for (DWORD i = 0; i < nNewCount; i++)
  1432. {
  1433. CString strSection;
  1434. strSection.Format(_T("Item%i"), i);
  1435. PX_String(&secItems, strSection, str, _T(""));
  1436. pThis->AddString(str);
  1437. }
  1438. }
  1439. }
  1440. void CXTPControlComboBox::OnMouseMove(CPoint point)
  1441. {
  1442. CXTPControlPopup::OnMouseMove(point);
  1443. if (GetEnabled() && m_bSelected)
  1444. {
  1445. CRect rcButon(GetRect());
  1446. rcButon.left = rcButon.right - m_nThumbWidth;
  1447. if (rcButon.PtInRect(point) && m_bSelected != TRUE_SPLITDROPDOWN)
  1448. {
  1449. m_bSelected = TRUE_SPLITDROPDOWN;
  1450. RedrawParent(FALSE);
  1451. }
  1452. else if (!rcButon.PtInRect(point) && m_bSelected == TRUE_SPLITDROPDOWN)
  1453. {
  1454. m_bSelected = TRUE;
  1455. RedrawParent(FALSE);
  1456. }
  1457. }
  1458. }
  1459. void CXTPControlComboBox::SetListIconId(int nId)
  1460. {
  1461. if (m_pParent) GetCommandBar()->SetCommandBars(m_pParent->GetCommandBars());
  1462. if (IsValidList())
  1463. {
  1464. CXTPControlComboBoxList* pComboBoxList = ((CXTPControlComboBoxList*)m_pCommandBar);
  1465. pComboBoxList->m_nListIconId = nId;
  1466. ModifyListBoxStyle(0, LBS_OWNERDRAWFIXED | LBS_HASSTRINGS);
  1467. }
  1468. }
  1469. int CXTPControlComboBox::GetListIconId() const
  1470. {
  1471. return IsValidList() ?  ((CXTPControlComboBoxList*)m_pCommandBar)->m_nListIconId : -1;
  1472. }
  1473. int CXTPControlComboBox::GetDropDownWidth() const
  1474. {
  1475. return m_pCommandBar->GetWidth();
  1476. }
  1477. int CXTPControlComboBox::GetCustomizeMinWidth() const
  1478. {
  1479. return m_nLabelWidth + m_nThumbWidth + 5;
  1480. }
  1481. void CXTPControlComboBox::DeflateEditRect(CRect& rcControl)
  1482. {
  1483. if (m_nEditIconId > 0)
  1484. {
  1485. CXTPImageManagerIcon* pIcon = m_pParent->GetImageManager()->GetImage(m_nEditIconId, 0);
  1486. if (pIcon)
  1487. rcControl.left += pIcon->GetWidth() + 2;
  1488. }
  1489. }
  1490. void CXTPControlComboBox::DrawEditText(CDC* pDC, CRect rcText)
  1491. {
  1492. if (!GetEditCtrl() && GetEnabled() && IsFocused())
  1493. {
  1494. CRect rcFocus(rcText.left - 1, rcText.top + 1, rcText.right - 1, rcText.bottom - 1);
  1495. pDC->FillSolidRect(rcFocus, GetXtremeColor(COLOR_HIGHLIGHT));
  1496. }
  1497. if (m_nEditIconId > 0)
  1498. {
  1499. CXTPImageManagerIcon* pIcon = m_pParent->GetImageManager()->GetImage(m_nEditIconId, 0);
  1500. if (pIcon)
  1501. {
  1502. pIcon->Draw(pDC, CPoint(rcText.left, rcText.CenterPoint().y - pIcon->GetHeight() / 2), GetEnabled() ? pIcon->GetIcon() : pIcon->GetDisabledIcon());
  1503. rcText.left += pIcon->GetWidth() + 2;
  1504. }
  1505. }
  1506. if (GetEditCtrl())
  1507. return;
  1508. CString strListBoxText = GetListBoxText();
  1509. if (!strListBoxText.IsEmpty())
  1510. {
  1511. pDC->SetTextColor(GetXtremeColor(!GetEnabled() ? COLOR_GRAYTEXT: IsFocused() ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT));
  1512. pDC->DrawText(strListBoxText, rcText, DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX);
  1513. }
  1514. else if (!GetEditHint().IsEmpty() && GetEnabled() && !IsFocused())
  1515. {
  1516. pDC->SetTextColor(GetXtremeColor(COLOR_GRAYTEXT));
  1517. pDC->DrawText(GetEditHint(), rcText, DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX);
  1518. }
  1519. }
  1520. void CXTPControlComboBox::MeasureItem(LPMEASUREITEMSTRUCT /*lpMeasureItemStruct*/)
  1521. {
  1522. }
  1523. void CXTPControlComboBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
  1524. {
  1525. CString strText;
  1526. GetLBText(lpDrawItemStruct->itemID, strText);
  1527. CRect rc(&lpDrawItemStruct->rcItem);
  1528. ASSERT(lpDrawItemStruct->CtlType == ODT_LISTBOX);
  1529. CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
  1530. BOOL bSelected = lpDrawItemStruct->itemState & ODS_SELECTED;
  1531. CXTPPaintManager* pPaintManager = GetPaintManager();
  1532. COLORREF crOldTextColor = pDC->SetTextColor(pPaintManager->GetRectangleTextColor(bSelected, FALSE, TRUE, FALSE, FALSE, xtpBarTypePopup, xtpBarPopup));
  1533. if (bSelected)
  1534. pPaintManager->DrawRectangle(pDC, rc, TRUE, FALSE, TRUE, FALSE, FALSE, xtpBarTypePopup, xtpBarPopup);
  1535. else
  1536. pDC->FillSolidRect(rc, pPaintManager->GetXtremeColor(COLOR_WINDOW));
  1537. int nListIconId = GetListIconId();
  1538. if (nListIconId != -1)
  1539. {
  1540. CXTPImageManager* pImageManager = GetCommandBar()->GetImageManager();
  1541. CXTPImageManagerIcon* pImage = pImageManager->GetImage(nListIconId + lpDrawItemStruct->itemID, 0);
  1542. if (pImage)
  1543. {
  1544. pImage->Draw(pDC, CPoint(rc.left + 2, (rc.top + rc.bottom - pImage->GetHeight()) / 2),
  1545. pImage->GetIcon(bSelected ? xtpImageHot : xtpImageNormal));
  1546. rc.left += pImage->GetWidth() + 2;
  1547. }
  1548. }
  1549. CXTPFontDC font(pDC, pPaintManager->GetIconFont());
  1550. pDC->SetBkMode(TRANSPARENT);
  1551. rc.left += 3;
  1552. pDC->DrawText(strText, rc, DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX);
  1553. pDC->SetTextColor(crOldTextColor);
  1554. }