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

对话框与窗口

开发平台:

Visual C++

  1. // XTEditListBox.cpp : implementation of the CXTEditListBox class.
  2. //
  3. // This file is a part of the XTREME CONTROLS 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/XTPResourceManager.h"
  22. #include "Common/XTPColorManager.h"
  23. #include "Common/XTPDrawHelpers.h"
  24. #include "Common/XTPWinThemeWrapper.h"
  25. #include "Resource.h"
  26. #include "XTDefines.h"
  27. #include "XTUtil.h"
  28. #include "XTGlobal.h"
  29. #include "XTButton.h"
  30. #include "XTFlatComboBox.h"
  31. #include "XTBrowseEdit.h"
  32. #include "XTListBox.h"
  33. #include "XTEditListBox.h"
  34. #include "XTThemeManager.h"
  35. #include "XTButtonTheme.h"
  36. #ifdef _DEBUG
  37. #define new DEBUG_NEW
  38. #undef THIS_FILE
  39. static char THIS_FILE[] = __FILE__;
  40. #endif
  41. #define XT_IDC_GROUP_EDIT               200
  42. /////////////////////////////////////////////////////////////////////////////
  43. // CXTEditListBox
  44. /////////////////////////////////////////////////////////////////////////////
  45. const int BTN_OFFSET = 22;
  46. CXTEditListBox::CXTEditListBox()
  47. : m_bEnableEdit(true)
  48. , m_pParentWnd(NULL)
  49. {
  50. m_pItemEdit = NULL;
  51. m_nIndex = -1;
  52. m_bNewItem = FALSE;
  53. m_strItemDefaultText.Empty();
  54. SetListEditStyle(XT_IDS_DIRECTORIES, LBS_XT_CHOOSEDIR);
  55. }
  56. CXTEditListBox::~CXTEditListBox()
  57. {
  58. }
  59. IMPLEMENT_DYNAMIC(CXTEditListBox, CXTListBox)
  60. BEGIN_MESSAGE_MAP(CXTEditListBox, CXTListBox)
  61. //{{AFX_MSG_MAP(CXTEditListBox)
  62. ON_LBN_XT_LABELEDITEND(XT_IDC_LBOX_EDIT, OnEndLabelEdit)
  63. ON_LBN_XT_NEWITEM(XT_IDC_GROUP_EDIT, OnNewItem)
  64. ON_LBN_XT_DELETEITEM(XT_IDC_GROUP_EDIT, OnDeleteItem)
  65. ON_LBN_XT_MOVEITEMUP(XT_IDC_GROUP_EDIT, OnMoveItemUp)
  66. ON_LBN_XT_MOVEITEMDOWN(XT_IDC_GROUP_EDIT, OnMoveItemDown)
  67. ON_WM_LBUTTONDBLCLK()
  68. ON_WM_LBUTTONDOWN()
  69. ON_WM_NCLBUTTONDOWN()
  70. ON_WM_NCMBUTTONDOWN()
  71. ON_WM_NCRBUTTONDOWN()
  72. ON_WM_WINDOWPOSCHANGED()
  73. ON_LBN_XT_LABELEDITCANCEL(XT_IDC_LBOX_EDIT, OnEndLabelEdit)
  74. ON_LBN_XT_ONBROWSE(XT_IDC_LBOX_EDIT, OnItemBrowse)
  75. ON_WM_ENABLE()
  76. ON_WM_SHOWWINDOW()
  77. ON_WM_MOUSEWHEEL()
  78. ON_WM_SIZE()
  79. //}}AFX_MSG_MAP
  80. END_MESSAGE_MAP()
  81. COLORREF CXTEditListBox::GetBackColor()
  82. {
  83. return IsWindowEnabled() ?
  84. GetXtremeColor(COLOR_WINDOW) : GetXtremeColor(COLOR_3DFACE);
  85. }
  86. void CXTEditListBox::OnSize(UINT nType, int cx, int cy)
  87. {
  88. if (m_pItemEdit)
  89. {
  90. m_pItemEdit->EndLabelEdit();
  91. Invalidate(FALSE);
  92. }
  93. CXTListBox::OnSize(nType, cx, cy);
  94. }
  95. BOOL CXTEditListBox::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
  96. {
  97. if (m_pItemEdit)
  98. {
  99. m_pItemEdit->EndLabelEdit();
  100. Invalidate(FALSE);
  101. }
  102. return CXTListBox::OnMouseWheel(nFlags, zDelta, pt);
  103. }
  104. void CXTEditListBox::OnEndLabelEdit()
  105. {
  106. // Get a pointer to the owner window.
  107. CWnd* pOwner = GetOwner();
  108. ASSERT(pOwner);
  109. if (!pOwner)
  110. return;
  111. if (m_bNewItem)
  112. {
  113. // Delete the temp string.
  114. DeleteString(m_nIndex);
  115. // If the text string is empty, then send a cancel message.
  116. if (m_strItemText.IsEmpty())
  117. {
  118. pOwner->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(),
  119. LBN_XT_LABELEDITCANCEL), (LPARAM)m_hWnd);
  120. m_nIndex = LB_ERR;
  121. }
  122. // The user has entered text, send the new item message
  123. // and insert the new string.
  124. else
  125. {
  126. m_nIndex = AddString(m_strItemText);
  127. // NB: SetTopIndex below causes some confusion if you have editing session, change content
  128. // and then double click on another item - the result looks like misplaced
  129. // edit control
  130. //SetTopIndex(m_nIndex);
  131. pOwner->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(),
  132. LBN_XT_NEWITEM), (LPARAM)m_hWnd);
  133. }
  134. }
  135. else
  136. {
  137. // set the index to the current selection.
  138. m_nIndex = GetCurSel();
  139. // Get the text for the selected item.
  140. CString strItemText;
  141. GetText(m_nIndex, strItemText);
  142. // If the new string is the same as the old string,
  143. // then send a cancel message.
  144. if (strItemText == m_strItemText)
  145. {
  146. pOwner->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(),
  147. LBN_XT_LABELEDITCANCEL), (LPARAM)m_hWnd);
  148. }
  149. // The user has updated the text string, delete the
  150. // existing string and replace it with the new text.
  151. else
  152. {
  153. DWORD_PTR dwData = GetItemData(m_nIndex);
  154. DeleteString(m_nIndex);
  155. InsertString(m_nIndex, m_strItemText);
  156. SetItemData(m_nIndex, dwData);
  157. // NB: SetTopIndex below causes some confusion if you have editing session, change content
  158. // and then double click on another item - the result looks like misplaced
  159. // edit control
  160. //SetTopIndex(m_nIndex);
  161. pOwner->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(),
  162. LBN_XT_LABELEDITEND), (LPARAM)m_hWnd);
  163. }
  164. }
  165. // Set the focus back to the listbox.
  166. SetCurSel(m_nIndex);
  167. SetFocus();
  168. m_pItemEdit = NULL;
  169. }
  170. // Basically, save any edited state, then pass the browse message to the parent window
  171. void CXTEditListBox::OnItemBrowse()
  172. {
  173. m_nIndex = GetCurSel(); // Current index.
  174. int nNewIndex = m_nIndex + 1; // New index.
  175. // If there is a valid selection made, and the
  176. // selection is not the last item and...
  177. if ((m_nIndex != LB_ERR) && (nNewIndex < GetCount()))
  178. {
  179. // Save the string for the current
  180. // selection.
  181. CString strCurItem;
  182. GetText(m_nIndex, strCurItem);
  183. // Save any item data.
  184. DWORD_PTR dwCurData = GetItemData(m_nIndex);
  185. // Remove both the new and current
  186. // index items...
  187. DeleteString(m_nIndex);
  188. // then swap and re-insert them into
  189. // the list box.
  190. InsertString(nNewIndex, strCurItem);
  191. // Restore any item data.
  192. SetItemData(nNewIndex, dwCurData);
  193. // Select the item at the new index.
  194. SetCurSel(nNewIndex);
  195. }
  196. // Set the focus back to the listbox.
  197. SetFocus();
  198. CWnd* pOwner = GetOwner();
  199. ASSERT(pOwner);
  200. // Send notification to owner.
  201. if (pOwner) pOwner->SendMessage( WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(),
  202. LBN_XT_ONBROWSE), (LPARAM)m_hWnd );
  203. }
  204. // This member function will enable editing for the a list box item.
  205. void CXTEditListBox::EditItem(int iItem)
  206. {
  207. SetFocus();
  208. SetCurSel(iItem);
  209. m_nIndex = iItem;
  210. EditListItem(FALSE);
  211. }
  212. void CXTEditListBox::GetEditItemText()
  213. {
  214. GetText(m_nIndex, m_strItemText);
  215. }
  216. void CXTEditListBox::SetEditText( LPCTSTR pcszText )
  217. {
  218. if (m_pItemEdit == NULL)
  219. {
  220. return;
  221. }
  222. m_pItemEdit->SetWindowText( pcszText );
  223. }
  224. void CXTEditListBox::EditListItem(BOOL bNewItem)
  225. {
  226. if (!m_bEnableEdit)
  227. return;
  228. CWnd* pOwner = GetOwner();
  229. ASSERT(pOwner);
  230. if (!pOwner)
  231. return;
  232. // Turn off redraw until we are ready to
  233. // create the edit field.
  234. SetRedraw(FALSE);
  235. // flush the item text string.
  236. m_strItemText = m_strItemDefaultText;
  237. // if this is a new item, add a temporary string
  238. // to the list box and set the selection to it. This
  239. // is where the in place edit box will appear.
  240. if (bNewItem || GetCurSel() == LB_ERR)
  241. {
  242. pOwner->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(),
  243. LBN_XT_PRENEWITEM), (LPARAM)m_hWnd);
  244. m_nIndex = AddString(m_strItemText);
  245. SetCurSel(m_nIndex);
  246. m_bNewItem = TRUE;
  247. }
  248. // get the text for the currently selected
  249. // item and set the new flag to FALSE.
  250. else
  251. {
  252. m_bNewItem = FALSE;
  253. int iCount = GetCount();
  254. m_nIndex = GetCurSel();
  255. if (m_nIndex >= iCount || iCount <= 0)
  256. {
  257. m_nIndex = LB_ERR;
  258. SetCurSel(LB_ERR);
  259. // turn redraw back.
  260. SetRedraw(TRUE);
  261. Invalidate();
  262. return;
  263. }
  264. GetEditItemText();
  265. }
  266. // turn redraw back.
  267. SetRedraw(TRUE);
  268. Invalidate();
  269. if (m_dwLStyle & LBS_XT_BROWSE_ONLY)
  270. {
  271. // Send notification to owner.
  272. pOwner->SendMessage( WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(),
  273. LBN_XT_ONBROWSE), (LPARAM)m_hWnd );
  274. return;
  275. }
  276. // Get the size of the currently selected item.
  277. CRect rcItem;
  278. GetItemRect(m_nIndex, rcItem);
  279. rcItem.InflateRect(-2, 2);
  280. // create the edit box.
  281. m_pItemEdit = CreateEditControl(rcItem);
  282. // if defined, set the filter for the item edit control.
  283. if (!m_strFilter.IsEmpty())
  284. {
  285. m_pItemEdit->SetDlgFilter(m_strFilter);
  286. }
  287. if (!m_strInitialDir.IsEmpty())
  288. {
  289. m_pItemEdit->SetDlgInitialDir(m_strInitialDir);
  290. }
  291. }
  292. CXTItemEdit* CXTEditListBox::CreateEditControl(CRect rcItem)
  293. {
  294. return new CXTItemEdit(this, rcItem, m_strItemText, m_dwLStyle, true);
  295. }
  296. void CXTEditListBox::OnNewItem()
  297. {
  298. EditListItem(TRUE);
  299. }
  300. void CXTEditListBox::OnLButtonDblClk(UINT nFlags, CPoint point)
  301. {
  302. CWnd::OnLButtonDblClk(nFlags, point);
  303. EditListItem(FALSE);
  304. }
  305. void CXTEditListBox::OnDeleteItem()
  306. {
  307. DeleteItem();
  308. }
  309. void CXTEditListBox::DeleteItem()
  310. {
  311. CWnd* pOwner = GetOwner();
  312. ASSERT(pOwner);
  313. if (!pOwner)
  314. return;
  315. // Send notification to owner that we are about to delete the item
  316. pOwner->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(),
  317. LBN_XT_PREDELETEITEM), (LPARAM)m_hWnd);
  318. int nCurIndex = GetCurSel();    // Current index.
  319. // If there is a valid selection made...
  320. if (nCurIndex != LB_ERR)
  321. {
  322. // Remove the new current item.
  323. int nCount = DeleteString(nCurIndex);
  324. if ((nCount != LB_ERR) && (nCurIndex < nCount))
  325. {
  326. SetCurSel(nCurIndex);
  327. }
  328. else
  329. {
  330. SetCurSel(nCurIndex-1);
  331. }
  332. }
  333. // Set the focus back to the listbox.
  334. SetFocus();
  335. // Send notification to owner.
  336. pOwner->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(),
  337. LBN_XT_DELETEITEM), (LPARAM)m_hWnd);
  338. }
  339. void CXTEditListBox::OnMoveItemUp()
  340. {
  341. int nIndex = GetCurSel();
  342. if (nIndex != LB_ERR)
  343. MoveItemUp(nIndex);
  344. }
  345. void CXTEditListBox::MoveItemUp(int nIndex)
  346. {
  347. m_nIndex = nIndex; // Current index.
  348. int nNewIndex = m_nIndex - 1; // New index.
  349. // If there is a valid selection made, and the
  350. // selection is not the first item and...
  351. if ((m_nIndex != LB_ERR) && (m_nIndex != 0))
  352. {
  353. // Save the string for the item we are
  354. // going to swap position with.
  355. CString strItem;
  356. GetText(nNewIndex, strItem);
  357. // Save any item data.
  358. DWORD_PTR dwNewData = GetItemData(nNewIndex);
  359. // Remove both the new and current
  360. // index items...
  361. DeleteString(nNewIndex);
  362. // then swap and re-insert them into
  363. // the list box.
  364. InsertString(m_nIndex, strItem);
  365. // Restore any item data.
  366. SetItemData(m_nIndex, dwNewData);
  367. // Select the item at the new index.
  368. SetCurSel(nNewIndex);
  369. }
  370. // Set the focus back to the listbox.
  371. SetFocus();
  372. CWnd* pOwner = GetOwner();
  373. ASSERT(pOwner);
  374. if (!pOwner)
  375. return;
  376. // Send notification to owner.
  377. pOwner->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(),
  378. LBN_XT_MOVEITEMUP), (LPARAM)m_hWnd);
  379. }
  380. void CXTEditListBox::OnMoveItemDown()
  381. {
  382. int nIndex = GetCurSel();
  383. if (nIndex != LB_ERR)
  384. MoveItemDown(nIndex);
  385. }
  386. void CXTEditListBox::MoveItemDown(int nIndex)
  387. {
  388. m_nIndex = nIndex; // Current index.
  389. int nNewIndex = m_nIndex + 1; // New index.
  390. // If there is a valid selection made, and the
  391. // selection is not the last item and...
  392. if ((m_nIndex != LB_ERR) && (nNewIndex < GetCount()))
  393. {
  394. // Save the string for the current
  395. // selection.
  396. CString strCurItem;
  397. GetText(m_nIndex, strCurItem);
  398. // Save any item data.
  399. DWORD_PTR dwCurData = GetItemData(m_nIndex);
  400. // Remove both the new and current
  401. // index items...
  402. DeleteString(m_nIndex);
  403. // then swap and re-insert them into
  404. // the list box.
  405. InsertString(nNewIndex, strCurItem);
  406. // Restore any item data.
  407. SetItemData(nNewIndex, dwCurData);
  408. // Select the item at the new index.
  409. SetCurSel(nNewIndex);
  410. }
  411. // Set the focus back to the listbox.
  412. SetFocus();
  413. CWnd* pOwner = GetOwner();
  414. ASSERT(pOwner);
  415. if (!pOwner)
  416. return;
  417. // Send notification to owner.
  418. pOwner->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(),
  419. LBN_XT_MOVEITEMDOWN), (LPARAM)m_hWnd);
  420. }
  421. void CXTEditListBox::SetListEditStyle(UINT nTitle, DWORD dwLStyle/*= LBS_XT_DEFAULT*/)
  422. {
  423. CString string;
  424. VERIFY(string.LoadString(nTitle));
  425. SetListEditStyle(string, dwLStyle);
  426. }
  427. void CXTEditListBox::SetListEditStyle(LPCTSTR lpszTitle, DWORD dwLStyle/*= LBS_XT_DEFAULT*/)
  428. {
  429. m_strTitle = lpszTitle;
  430. m_dwLStyle = dwLStyle;
  431. if (m_editGroup.GetSafeHwnd())
  432. {
  433. m_editGroup.SetWindowText(m_strTitle);
  434. }
  435. }
  436. void CXTEditListBox::Initialize(bool bAutoFont/*= true*/)
  437. {
  438. CXTListBox::Initialize(bAutoFont);
  439. // get a pointer to the parent window.
  440. m_pParentWnd = GetParent();
  441. ASSERT_VALID(m_pParentWnd); // must be valid.
  442. // Create the edit toolbar group.
  443. if (!HasToolbar())
  444. return;
  445. // Create the toolbar.
  446. if (!CreateEditGroup(bAutoFont))
  447. return;
  448. // Resize the edit list which will also cause WM_WINDOWPOSCHANGED
  449. // to be called to position the toolbar.
  450. CXTPWindowRect rcWindow(this);
  451. rcWindow.top += BTN_OFFSET + ::GetSystemMetrics(SM_CXEDGE);
  452. m_pParentWnd->ScreenToClient(&rcWindow);
  453. ::SetWindowPos(GetSafeHwnd(), NULL, rcWindow.left, rcWindow.top,
  454. rcWindow.Width(), rcWindow.Height(), SWP_FRAMECHANGED);
  455. }
  456. BOOL CXTEditListBox::CreateEditGroup(bool bAutoFont)
  457. {
  458. // Create the edit button group that appears at the top of the
  459. // list edit control.
  460. DWORD dwStyle = (GetStyle() & WS_VISIBLE) | WS_CHILD |
  461. SS_CENTERIMAGE | SS_LEFT | SS_NOTIFY;
  462. if (!m_editGroup.CreateEx(WS_EX_STATICEDGE, _T("Static"), m_strTitle,
  463. dwStyle, CRect(0, 0, 0, 0), GetParent(), XT_IDC_GROUP_EDIT))
  464. {
  465. TRACE0("Unable to create caption.n");
  466. return FALSE;
  467. }
  468. m_editGroup.m_bShowUpDownButtons = ( (m_dwLStyle & LBS_XT_HIDE_UP_DOWN) == 0 );
  469. m_editGroup.m_bShowNewDeleteButtons = ( (m_dwLStyle & LBS_XT_ONLY_UP_DOWN) == 0 );
  470. m_editGroup.SetOwner(this);
  471. m_editGroup.Initialize(bAutoFont);
  472. // enable the window depending on the list box enabled state.
  473. m_editGroup.EnableWindow(IsWindowEnabled());
  474. return TRUE;
  475. }
  476. BOOL CXTEditListBox::PreTranslateMessage(MSG* pMsg)
  477. {
  478. // Send message to edit window if active.
  479. if (m_pItemEdit && ::IsWindow(m_pItemEdit->m_hWnd))
  480. {
  481. if (pMsg->wParam == VK_TAB)
  482. {
  483. SetFocus();
  484. return CWnd::PreTranslateMessage(pMsg);
  485. }
  486. return m_pItemEdit->PreTranslateMessage(pMsg);
  487. }
  488. if (pMsg->message == WM_KEYUP)
  489. {
  490. if (pMsg->wParam == VK_DELETE && GetCurSel() != LB_ERR)
  491. {
  492. OnDeleteItem();
  493. }
  494. if (pMsg->wParam == VK_INSERT)
  495. {
  496. OnNewItem();
  497. }
  498. }
  499. if (pMsg->message == WM_SYSKEYUP)
  500. {
  501. if ((pMsg->wParam == VK_UP) &&
  502. (::GetKeyState(VK_MENU) < 0) && GetCurSel() != LB_ERR)
  503. {
  504. OnMoveItemUp();
  505. }
  506. if ((pMsg->wParam == VK_DOWN) &&
  507. (::GetKeyState(VK_MENU) < 0) && GetCurSel() != LB_ERR)
  508. {
  509. OnMoveItemDown();
  510. }
  511. }
  512. return CWnd::PreTranslateMessage(pMsg);
  513. }
  514. void CXTEditListBox::OnLButtonDown(UINT nFlags, CPoint point)
  515. {
  516. CXTListBox::OnLButtonDown(nFlags, point);
  517. m_nIndex = GetCurSel();
  518. if (m_nIndex >= GetCount())
  519. {
  520. SetCurSel(GetCount() - 1);
  521. GetOwner()->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), LBN_SELCHANGE), (LPARAM)m_hWnd);
  522. }
  523. CRect rcItem;
  524. if (GetItemRect(m_nIndex, rcItem) != LB_ERR)
  525. {
  526. if (!rcItem.PtInRect(point))
  527. {
  528. CWnd* pOwner = GetOwner();
  529. ASSERT(pOwner);
  530. if (!pOwner)
  531. return;
  532. SetCurSel(-1);
  533. pOwner->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), LBN_SELCHANGE), (LPARAM)m_hWnd);
  534. }
  535. }
  536. }
  537. void CXTEditListBox::OnNcLButtonDown(UINT nHitTest, CPoint point)
  538. {
  539. if (m_pItemEdit)
  540. {
  541. m_pItemEdit->DestroyWindow();
  542. m_pItemEdit = NULL;
  543. }
  544. CListBox::OnNcLButtonDown(nHitTest, point);
  545. }
  546. void CXTEditListBox::OnNcMButtonDown(UINT nHitTest, CPoint point)
  547. {
  548. if (m_pItemEdit)
  549. {
  550. m_pItemEdit->DestroyWindow();
  551. m_pItemEdit = NULL;
  552. }
  553. CListBox::OnNcMButtonDown(nHitTest, point);
  554. }
  555. void CXTEditListBox::OnNcRButtonDown(UINT nHitTest, CPoint point)
  556. {
  557. if (m_pItemEdit)
  558. {
  559. m_pItemEdit->DestroyWindow();
  560. m_pItemEdit = NULL;
  561. }
  562. CListBox::OnNcRButtonDown(nHitTest, point);
  563. }
  564. void CXTEditListBox::OnWindowPosChanged(WINDOWPOS FAR* lpwndpos)
  565. {
  566. CXTListBox::OnWindowPosChanged(lpwndpos);
  567. // adjust the toolbar size and location.
  568. RecalcLayout();
  569. }
  570. void CXTEditListBox::RecalcLayout()
  571. {
  572. if (HasToolbar() && ::IsWindow(m_editGroup.m_hWnd))
  573. {
  574. ASSERT_VALID(m_pParentWnd); // must be valid.
  575. CXTPWindowRect rcWindow(this);
  576. m_pParentWnd->ScreenToClient(&rcWindow);
  577. // move the group edit control.
  578. rcWindow.top -= BTN_OFFSET;
  579. rcWindow.bottom = rcWindow.top + BTN_OFFSET;
  580. ::SetWindowPos(m_editGroup.m_hWnd, NULL, rcWindow.left, rcWindow.top,
  581. rcWindow.Width(), rcWindow.Height(), SWP_FRAMECHANGED);
  582. }
  583. }
  584. void CXTEditListBox::OnEnable(BOOL bEnable)
  585. {
  586. CXTListBox::OnEnable(bEnable);
  587. if (HasToolbar() && ::IsWindow(m_editGroup.m_hWnd))
  588. m_editGroup.EnableWindow(bEnable);
  589. }
  590. void CXTEditListBox::OnShowWindow(BOOL bShow, UINT nStatus)
  591. {
  592. CXTListBox::OnShowWindow(bShow, nStatus);
  593. if (HasToolbar() && ::IsWindow(m_editGroup.m_hWnd))
  594. m_editGroup.ShowWindow(bShow ? SW_SHOW : SW_HIDE);
  595. }
  596. /////////////////////////////////////////////////////////////////////////////
  597. // CXTEditListBoxToolBar
  598. /////////////////////////////////////////////////////////////////////////////
  599. CXTEditListBoxToolBar::CXTEditListBoxToolBar()
  600. : m_bShowUpDownButtons(true)
  601. , m_bEnableEdit(true)
  602. , m_bShowNewDeleteButtons(true)
  603. {
  604. }
  605. CXTEditListBoxToolBar::~CXTEditListBoxToolBar()
  606. {
  607. }
  608. IMPLEMENT_DYNAMIC(CXTEditListBoxToolBar, CStatic)
  609. BEGIN_MESSAGE_MAP(CXTEditListBoxToolBar, CStatic)
  610. //{{AFX_MSG_MAP(CXTEditListBoxToolBar)
  611. ON_BN_CLICKED(XT_IDC_BTN_NEW, OnButtonNew)
  612. ON_BN_CLICKED(XT_IDC_BTN_DELETE, OnButtonDelete)
  613. ON_BN_CLICKED(XT_IDC_BTN_UP, OnButtonUp)
  614. ON_BN_CLICKED(XT_IDC_BTN_DOWN, OnButtonDown)
  615. ON_WM_WINDOWPOSCHANGED()
  616. ON_WM_ERASEBKGND()
  617. ON_WM_PAINT()
  618. ON_WM_ENABLE()
  619. ON_WM_SHOWWINDOW()
  620. ON_WM_NCPAINT()
  621. //}}AFX_MSG_MAP
  622. END_MESSAGE_MAP()
  623. BOOL CXTEditListBoxToolBar::PreTranslateMessage(MSG* pMsg)
  624. {
  625. // Let the ToolTip process this message.
  626. m_tooltip.RelayEvent(pMsg);
  627. return CStatic::PreTranslateMessage(pMsg);
  628. }
  629. static UINT _arButtonID[] =
  630. {
  631. XT_IDC_BTN_NEW,
  632. XT_IDC_BTN_DELETE,
  633. XT_IDC_BTN_UP,
  634. XT_IDC_BTN_DOWN,
  635. };
  636. void CXTEditListBoxToolBar::MoveButtons()
  637. {
  638. if (!::IsWindow(m_hWnd))
  639. return;
  640. // Set the initial size for the first button.
  641. CXTPClientRect rcClient(this);
  642. rcClient.left = rcClient.right-BTN_OFFSET;
  643. for (int i = _countof(m_arButton)-1; i >= 0 ; --i)
  644. {
  645. if (::IsWindow(m_arButton[i].GetSafeHwnd()))
  646. {
  647. m_arClipRect[i] = rcClient;
  648. ::SetWindowPos(m_arButton[i].GetSafeHwnd(), NULL, rcClient.left, rcClient.top,
  649. rcClient.Width(), rcClient.Height(), SWP_FRAMECHANGED);
  650. rcClient.OffsetRect(-BTN_OFFSET, 0);
  651. }
  652. else
  653. {
  654. m_arClipRect[i] = CRect(0, 0, 0, 0);
  655. }
  656. }
  657. Invalidate();
  658. }
  659. void CXTEditListBoxToolBar::SetXButtonStyle(DWORD dwxStyle, BOOL bRedraw/*= TRUE*/)
  660. {
  661. for (int i = 0; i < _countof(m_arButton); ++i)
  662. {
  663. if (::IsWindow(m_arButton[i].m_hWnd))
  664. {
  665. m_arButton[i].SetXButtonStyle(dwxStyle, bRedraw);
  666. if (dwxStyle == (BS_XT_FLAT | BS_XT_WINXP_COMPAT))
  667. m_arButton[i].SetTheme(new CXTToolbarButtonTheme);
  668. }
  669. }
  670. }
  671. void CXTEditListBoxToolBar::Initialize(bool bAutoFont/*= true*/)
  672. {
  673. // Create the ToolTip control.
  674. m_tooltip.Create(this);
  675. m_tooltip.Activate(TRUE);
  676. CImageList imageList;
  677. imageList.Create(14, 12, ILC_COLOR8 | ILC_MASK, 0, 1);
  678. CBitmap bmp;
  679. VERIFY(XTPResourceManager()->LoadBitmap(&bmp, XT_IDB_LISTEDIT));
  680. imageList.Add(&bmp, RGB(255, 0, 255));
  681. for (int i = 0; i < _countof(m_arButton); ++i)
  682. {
  683. if ((!m_bShowNewDeleteButtons) && ((i==0) || (i==1)))
  684. continue;
  685. if ((!m_bShowUpDownButtons) && ((i==2) || (i==3)))
  686. continue;
  687. if (!m_arButton[i].Create(NULL, WS_CHILD | WS_VISIBLE | BS_ICON | BS_OWNERDRAW | BS_CENTER | BS_VCENTER,
  688. CRect(0, 0, 0, 0), this, _arButtonID[i]))
  689. {
  690. TRACE0("Unable to create edit button.n");
  691. continue;
  692. }
  693. m_arIcon[i] = imageList.ExtractIcon(i);
  694. m_arButton[i].SetIcon(CSize(0), m_arIcon[i]);
  695. CString strToolTip;
  696. VERIFY(XTPResourceManager()->LoadString(&strToolTip, _arButtonID[i]));
  697. // Add tooltips to group buttons.
  698. m_tooltip.AddTool(&m_arButton[i], strToolTip);
  699. // make sure the button is Windows XP theme compatible using
  700. // the toolbar button theme.
  701. m_arButton[i].SetXButtonStyle(BS_XT_FLAT | BS_XT_WINXP_COMPAT);
  702. m_arButton[i].SetTheme(new CXTToolbarButtonTheme);
  703. }
  704. // Move the buttons to their correct location.
  705. MoveButtons();
  706. // Set the font for this window.
  707. if (bAutoFont)
  708. {
  709. SetFont(&XTAuxData().font);
  710. }
  711. }
  712. void CXTEditListBoxToolBar::SendCommand(UINT nCmdID)
  713. {
  714. if (m_bEnableEdit)
  715. {
  716. CWnd* pOwner = GetOwner();
  717. ASSERT(pOwner);
  718. if (pOwner) pOwner->SendMessage(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(),
  719. nCmdID), (LPARAM)m_hWnd);
  720. }
  721. }
  722. void CXTEditListBoxToolBar::OnButtonNew()
  723. {
  724. SendCommand(LBN_XT_NEWITEM);
  725. }
  726. void CXTEditListBoxToolBar::OnButtonDelete()
  727. {
  728. SendCommand(LBN_XT_DELETEITEM);
  729. }
  730. void CXTEditListBoxToolBar::OnButtonUp()
  731. {
  732. SendCommand(LBN_XT_MOVEITEMUP);
  733. }
  734. void CXTEditListBoxToolBar::OnButtonDown()
  735. {
  736. SendCommand(LBN_XT_MOVEITEMDOWN);
  737. }
  738. void CXTEditListBoxToolBar::OnWindowPosChanged(WINDOWPOS FAR* lpwndpos)
  739. {
  740. CStatic::OnWindowPosChanged(lpwndpos);
  741. // Move the buttons to their correct location.
  742. MoveButtons();
  743. }
  744. BOOL CXTEditListBoxToolBar::OnEraseBkgnd(CDC* /*pDC*/)
  745. {
  746. return TRUE;
  747. }
  748. #ifndef WM_QUERYUISTATE
  749. #define WM_QUERYUISTATE     0x0129
  750. #define UISF_HIDEACCEL      0x2
  751. #endif
  752. #ifndef DT_HIDEPREFIX
  753. #define DT_HIDEPREFIX 0x00100000
  754. #endif //!DT_HIDEPREFIX
  755. void CXTEditListBoxToolBar::DrawText(CDC* pDC, CRect& rcClient)
  756. {
  757. // get the text for the control.
  758. CString strWindowText;
  759. GetWindowText(strWindowText);
  760. if (strWindowText.IsEmpty())
  761. return;
  762. // select the font into the device context.
  763. CXTPFontDC font(pDC, GetFont());
  764. CRect rcText(rcClient);
  765. rcText.left += 1;
  766. // determine if the text is drawn disabled.
  767. pDC->SetTextColor(GetXtremeColor(IsWindowEnabled() ? COLOR_BTNTEXT : COLOR_GRAYTEXT));
  768. pDC->SetBkMode(TRANSPARENT);
  769. DWORD dwFlags = DT_LEFT | DT_VCENTER | DT_SINGLELINE;
  770. if (SendMessage(WM_QUERYUISTATE) & UISF_HIDEACCEL)
  771. {
  772. dwFlags |= DT_HIDEPREFIX;
  773. }
  774. pDC->DrawText(strWindowText, rcText, dwFlags);
  775. }
  776. void CXTEditListBoxToolBar::OnNcPaint()
  777. {
  778. CXTPWinThemeWrapper wrpTreeView;
  779. wrpTreeView.OpenTheme(0, L"LISTBOX");
  780. if (wrpTreeView.IsAppThemed() && wrpTreeView.IsAppThemeReady() && (GetOwner()->GetExStyle() & WS_EX_CLIENTEDGE))
  781. {
  782. CXTPWindowRect rc(this);
  783. CXTPClientRect rcClient(this);
  784. COLORREF clr = GetXtremeColor(COLOR_BTNSHADOW);
  785. if (rc.Width() == rcClient.Width() + 2 &&
  786. SUCCEEDED(wrpTreeView.GetThemeColor(0, 0, TMT_BORDERCOLOR, &clr)))
  787. {
  788. CWindowDC dc(this);
  789. dc.FillSolidRect(0, 0, rc.Width(), 1, clr);
  790. dc.FillSolidRect(0, 0, 1, rc.Height(), clr);
  791. dc.FillSolidRect(rc.Width() - 1, 0, 1, rc.Height(), clr);
  792. dc.FillSolidRect(1, rc.Height() - 1, rc.Width() - 2, 1, GetXtremeColor(COLOR_3DFACE));
  793. return;
  794. }
  795. }
  796. Default();
  797. }
  798. void CXTEditListBoxToolBar::OnPaint()
  799. {
  800. CPaintDC dc(this); // device context for painting
  801. // Exclude the buttons from getting repainted.
  802. int i;
  803. for (i = 0; i < _countof(m_arClipRect); ++i)
  804. dc.ExcludeClipRect(&m_arClipRect[i]);
  805. CRect r;
  806. GetClientRect(&r);
  807. CXTPBufferDC memDC(dc, r);
  808. memDC.FillSolidRect(r, GetXtremeColor(COLOR_3DFACE));
  809. DrawText(&memDC, r);
  810. }
  811. void CXTEditListBoxToolBar::OnEnable(BOOL bEnable)
  812. {
  813. CStatic::OnEnable(bEnable);
  814. for (int i = 0; i < _countof(m_arButton); ++i)
  815. {
  816. if (::IsWindow(m_arButton[i].GetSafeHwnd()))
  817. {
  818. m_arButton[i].EnableWindow(bEnable);
  819. m_arButton[i].Invalidate();
  820. }
  821. }
  822. Invalidate();
  823. }
  824. void CXTEditListBoxToolBar::OnShowWindow(BOOL bShow, UINT nStatus)
  825. {
  826. CStatic::OnShowWindow(bShow, nStatus);
  827. for (int i = 0; i < _countof(m_arButton); ++i)
  828. {
  829. if (::IsWindow(m_arButton[i].GetSafeHwnd()))
  830. m_arButton[i].ShowWindow(bShow ? SW_SHOW : SW_HIDE);
  831. }
  832. }