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

对话框与窗口

开发平台:

Visual C++

  1. // XTPReportInplaceControls.cpp
  2. //
  3. // This file is a part of the XTREME REPORTCONTROL 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/XTPSystemHelpers.h"
  23. #include "XTPReportControl.h"
  24. #include "XTPReportDefines.h"
  25. #include "XTPReportInplaceControls.h"
  26. #include "XTPReportColumn.h"
  27. #include "XTPReportRecordItemText.h"
  28. #ifdef _DEBUG
  29. #define new DEBUG_NEW
  30. #undef THIS_FILE
  31. static char THIS_FILE[] = __FILE__;
  32. #endif
  33. CXTPReportInplaceControl::CXTPReportInplaceControl()
  34. {
  35. }
  36. CXTPReportInplaceControl::~CXTPReportInplaceControl()
  37. {
  38. SetItemArgs(0);
  39. }
  40. void CXTPReportInplaceControl::SetItemArgs(XTP_REPORTRECORDITEM_ARGS* pItemArgs)
  41. {
  42. if (pItemArgs)
  43. {
  44. pItemArgs->AddRef();
  45. Release();
  46. pItem = pItemArgs->pItem;
  47. pControl = pItemArgs->pControl;
  48. pRow = pItemArgs->pRow;
  49. pColumn = pItemArgs->pColumn;
  50. rcItem = pItemArgs->rcItem;
  51. }
  52. else
  53. {
  54. Release();
  55. pItem = 0;
  56. pControl = 0;
  57. pRow = 0;
  58. pColumn = 0;
  59. }
  60. }
  61. IMPLEMENT_DYNAMIC(CXTPReportInplaceEdit, CEdit)
  62. CXTPReportInplaceEdit::CXTPReportInplaceEdit()
  63. {
  64. m_pSelectedConstraint = NULL;
  65. m_clrText = 0;
  66. m_bSetWindowText = FALSE;
  67. }
  68. CXTPReportInplaceEdit::~CXTPReportInplaceEdit()
  69. {
  70. }
  71. BEGIN_MESSAGE_MAP(CXTPReportInplaceEdit, CEdit)
  72. //{{AFX_MSG_MAP(CXTPReportInplaceEdit)
  73. ON_WM_MOUSEACTIVATE()
  74. ON_WM_CTLCOLOR_REFLECT()
  75. ON_CONTROL_REFLECT(EN_KILLFOCUS, OnEnKillfocus)
  76. ON_CONTROL_REFLECT(EN_CHANGE, OnEnChange)
  77. ON_WM_LBUTTONDBLCLK()
  78. ON_WM_KEYDOWN()
  79. ON_WM_SYSKEYDOWN()
  80. ON_WM_GETDLGCODE()
  81. ON_WM_CHAR()
  82. //}}AFX_MSG_MAP
  83. END_MESSAGE_MAP()
  84. void CXTPReportInplaceEdit::HideWindow()
  85. {
  86. if (m_hWnd)
  87. {
  88. ShowWindow(SW_HIDE);
  89. SetItemArgs(0);
  90. }
  91. }
  92. void CXTPReportInplaceEdit::Create(XTP_REPORTRECORDITEM_ARGS* pItemArgs)
  93. {
  94. SetItemArgs(pItemArgs);
  95. m_pSelectedConstraint = NULL;
  96. XTP_REPORTRECORDITEM_METRICS* pMetrics = new XTP_REPORTRECORDITEM_METRICS;
  97. //pMetrics->strText = pItem->GetCaption(pColumn);
  98. CXTPReportRecordItemText* pTextItem = DYNAMIC_DOWNCAST(CXTPReportRecordItemText, pItem);
  99. if(pTextItem != NULL)
  100. pMetrics->strText = pTextItem->GetValue();
  101. else
  102. pMetrics->strText = pItem->GetCaption(pColumn);
  103. pItemArgs->pRow->FillMetrics(pColumn, pItem, pMetrics);
  104. CRect rect = pItemArgs->rcItem;
  105. pItem->GetCaptionRect(pItemArgs, rect);
  106. rect.DeflateRect(2, 1, 2, 2);
  107. CXTPReportRecordItemEditOptions* pEditOptions = pItem->GetEditOptions(pColumn);
  108. ASSERT(pEditOptions);
  109. if (!pEditOptions)
  110. return;
  111. m_clrText = pMetrics->clrForeground;
  112. m_strValue = pMetrics->strText;
  113. m_strText_prev = pMetrics->strText;
  114. DWORD dwEditStyle = WS_CHILD | pEditOptions->m_dwEditStyle;
  115. dwEditStyle &= ~(ES_LEFT | ES_RIGHT | ES_CENTER);
  116. if (pControl->GetPaintManager()->m_bUseEditTextAlignment)
  117. {
  118. if (pMetrics->nColumnAlignment & DT_RIGHT)
  119. {
  120. dwEditStyle |= ES_RIGHT;
  121. }
  122. else if (pMetrics->nColumnAlignment & DT_CENTER)
  123. {
  124. dwEditStyle |= ES_CENTER;
  125. }
  126. }
  127. if (m_hWnd)
  128. {
  129. DWORD dwStyle = WS_CHILD | WS_VISIBLE | ES_READONLY;
  130. if ((GetStyle() & dwStyle) != (dwEditStyle & dwStyle))
  131. DestroyWindow();
  132. }
  133. if (!m_hWnd)
  134. {
  135. CEdit::Create(dwEditStyle, rect, pControl, 0);
  136. }
  137. if (pControl->GetExStyle() & WS_EX_RTLREADING)
  138. {
  139. ModifyStyleEx(0, WS_EX_RTLREADING);
  140. }
  141. SetLimitText(pEditOptions->m_nMaxLength);
  142. SetFocus();
  143. SetFont(pMetrics->pFont);
  144. SetWindowText(m_strValue);
  145. pMetrics->InternalRelease();
  146. if (rect.right > rect.left)
  147. {
  148. SetWindowPos(0, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOZORDER | SWP_SHOWWINDOW);
  149. }
  150. else
  151. {
  152. HideWindow();
  153. }
  154. SetMargins(0, 0);
  155. }
  156. void CXTPReportInplaceEdit::SetWindowText(LPCTSTR lpszString)
  157. {
  158. m_bSetWindowText = TRUE;
  159. CWnd::SetWindowText(lpszString);
  160. m_strText_prev = lpszString;
  161. m_bSetWindowText = FALSE;
  162. }
  163. void CXTPReportInplaceEdit::SetFont(CFont* pFont)
  164. {
  165. m_fntEdit.DeleteObject();
  166. LOGFONT lf;
  167. pFont->GetLogFont(&lf);
  168. m_fntEdit.CreateFontIndirect(&lf);
  169. CEdit::SetFont(&m_fntEdit);
  170. }
  171. void CXTPReportInplaceEdit::OnEnKillfocus()
  172. {
  173. if (pControl && pItem)
  174. {
  175. pItem->OnValidateEdit((XTP_REPORTRECORDITEM_ARGS*)this);
  176. HideWindow();
  177. }
  178. }
  179. void CXTPReportInplaceEdit::OnEnChange()
  180. {
  181. if(m_bSetWindowText || !pControl || !pItem)
  182. return;
  183. CString strValue, strValNew;
  184. GetWindowText(strValue);
  185. strValNew = strValue;
  186. BOOL bCommit = pItem->OnEditChanging((XTP_REPORTRECORDITEM_ARGS*)this, strValNew);
  187. if (!bCommit || strValNew != strValue)
  188. {
  189. int nSelStart = 0, nSelEnd = 0;
  190. GetSel(nSelStart, nSelEnd);
  191. SetWindowText(bCommit ? strValNew : m_strText_prev);
  192. SetSel(nSelStart, nSelEnd);
  193. }
  194. else
  195. {
  196. m_strText_prev = strValue;
  197. }
  198. }
  199. int CXTPReportInplaceEdit::OnMouseActivate(CWnd* , UINT , UINT ) //(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
  200. {
  201. return MA_NOACTIVATE;
  202. }
  203. UINT CXTPReportInplaceEdit::OnGetDlgCode()
  204. {
  205. return DLGC_WANTALLKEYS;
  206. }
  207. void CXTPReportInplaceEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
  208. {
  209. //  TRACE(_T("ReportControl, OnChar('%d') n"), nChar);
  210. if (!pControl)
  211. return;
  212. // Moved to PreTranslateMessage
  213. //  if (!pControl->OnPreviewKeyDown(nChar, nRepCnt, nFlags))
  214. //  {
  215. //      return;
  216. //  }
  217. if (nChar == VK_TAB) return;
  218. if (nChar == VK_ESCAPE || nChar == VK_RETURN)
  219. {
  220. pControl->EditItem(NULL);
  221. return;
  222. }
  223. if (pItem && pColumn && pItem->GetEditOptions(pColumn)->m_bConstraintEdit)
  224. {
  225. CXTPReportRecordItemEditOptions* pEditOptions = pItem->GetEditOptions(pColumn);
  226. CXTPReportRecordItemConstraints* pConstraints = pEditOptions->GetConstraints();
  227. int nCount = pConstraints->GetCount();
  228. if (nCount > 0)
  229. {
  230. CString str, strActual;
  231. GetWindowText(str);
  232. strActual = str;
  233. CXTPReportRecordItemConstraint* pConstraint = (m_pSelectedConstraint == NULL) ?
  234. pEditOptions->FindConstraint(str): m_pSelectedConstraint;
  235. int nIndexStart, nIndex;
  236. nIndexStart = nIndex = (pConstraint == NULL ? nCount - 1 : pConstraint->GetIndex());
  237. CString strSeach ((TCHAR)nChar);
  238. do
  239. {
  240. nIndex = nIndex < nCount - 1 ? nIndex + 1 : 0;
  241. pConstraint = pConstraints->GetAt(nIndex);
  242. str = pConstraint->m_strConstraint;
  243. if (strSeach.CompareNoCase(str.Left(1)) == 0)
  244. {
  245. m_pSelectedConstraint = pConstraint;
  246. SetWindowText(str);
  247. SetSel(0, -1);
  248. if(strActual.CompareNoCase(str) != 0)
  249. ((CXTPReportControl*)pControl)->OnConstraintSelecting(pRow, pItem, pColumn, pConstraint);
  250. return;
  251. }
  252. } while (nIndex != nIndexStart);
  253. return;
  254. }
  255. }
  256. CEdit::OnChar(nChar, nRepCnt, nFlags);
  257. }
  258. void CXTPReportInplaceEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  259. {
  260. CXTPReportControl* _pControl = pControl;
  261. ASSERT(_pControl);
  262. if (!_pControl)
  263. {
  264. return;
  265. }
  266. //-----------------------------------------------------------------------
  267. if (nChar == VK_TAB && _pControl)
  268. {
  269. _pControl->SetFocus();
  270. _pControl->SendMessage(WM_CHAR, nChar);
  271. return;
  272. }
  273. if (nChar == VK_ESCAPE)
  274. {
  275. SetWindowText(m_strValue);
  276. return;
  277. }
  278. else if (nChar == VK_RETURN)
  279. {
  280. return;
  281. }
  282. else if (nChar == VK_UP || nChar == VK_DOWN || nChar == VK_PRIOR || nChar == VK_NEXT)
  283. {
  284. if (pItem && pColumn && pItem->GetEditOptions(pColumn)->m_bConstraintEdit)
  285. {
  286. CXTPReportRecordItemConstraint* pConstraint;
  287. CXTPReportRecordItemEditOptions* pEditOptions = pItem->GetEditOptions(pColumn);
  288. CXTPReportRecordItemConstraints* pConstraints = pEditOptions->GetConstraints();
  289. int nCount = pConstraints->GetCount();
  290. if (nCount > 1)
  291. {
  292. CString strActual, str;
  293. GetWindowText(strActual);
  294. int nIndex = 0;          // the first item
  295. if(nChar == VK_NEXT)
  296. {
  297. nIndex = nCount - 1; // the last item
  298. }
  299. else if (nChar != VK_PRIOR)
  300. {
  301. // look for the actually selected item
  302. for(int i = 0; i < nCount; i++)
  303. {
  304. pConstraint = pConstraints->GetAt(i);
  305. if (strActual.CompareNoCase(pConstraint->m_strConstraint) == 0)
  306. {
  307. if(nChar == VK_UP)
  308. nIndex = max(0, i - 1);
  309. else if(nChar == VK_DOWN)
  310. nIndex = min(nCount-1, i + 1);
  311. break;
  312. }
  313. }
  314. }
  315. pConstraint = pConstraints->GetAt(max(0, min(nIndex, nCount-1)));
  316. str = pConstraint->m_strConstraint;
  317. m_pSelectedConstraint = pConstraint;
  318. // set the default font, because user could change the font (for ex. to striked one)
  319. SetFont(pControl->GetPaintManager()->GetTextFont());
  320. SetWindowText(str);
  321. SetSel(0, -1);
  322. if(strActual.CompareNoCase(str) != 0)
  323. ((CXTPReportControl*)pControl)->OnConstraintSelecting(pRow, pItem, pColumn, pConstraint);
  324. return;
  325. }
  326. }
  327. }
  328. CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
  329. }
  330. void CXTPReportInplaceEdit::OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  331. {
  332. if ((nChar == VK_UP || nChar == VK_DOWN) && pControl)
  333. {
  334. if (pControl->GetInplaceButtons()->GetSize() > 0)
  335. {
  336. CXTPReportInplaceButton* pButton = pControl->GetInplaceButtons()->GetAt(0);
  337. if (pButton->GetItem() == pItem)
  338. {
  339. pItem->OnInplaceButtonDown(pButton);
  340. }
  341. }
  342. }
  343. CEdit::OnSysKeyDown(nChar, nRepCnt, nFlags);
  344. }
  345. BOOL CXTPReportInplaceEdit::PreTranslateMessage(MSG* pMsg)
  346. {
  347. if (pMsg->message == WM_KEYDOWN && pControl)
  348. {
  349. if (!pControl->OnPreviewKeyDown((UINT&)pMsg->wParam, LOWORD(pMsg->lParam), HIWORD(pMsg->lParam)) )
  350. {
  351. // TRACE(_T("InplaceEdit, PreTranslateMessagem-OnPreviewKeyDown('%d') = CANCEL  n"), pMsg->wParam);
  352. return TRUE;
  353. }
  354. }
  355. if (pMsg->message == WM_KEYDOWN && IsDialogMessage(pMsg))
  356. return TRUE;
  357. return CEdit::PreTranslateMessage(pMsg);
  358. }
  359. void CXTPReportInplaceEdit::OnLButtonDblClk(UINT nFlags, CPoint point)
  360. {
  361. if (pRow && pItem)
  362. {
  363. MapWindowPoints(pControl, &point, 1);
  364. pRow->OnDblClick(point);
  365. }
  366. if (pItem)
  367. {
  368. CEdit::OnLButtonDblClk(nFlags, point);
  369. }
  370. }
  371. HBRUSH CXTPReportInplaceEdit::CtlColor(CDC* pDC, UINT /*nCtlColor*/)
  372. {
  373. pDC->SetTextColor(m_clrText);
  374. return GetSysColorBrush(COLOR_WINDOW);
  375. }
  376. //////////////////////////////////////////////////////////////////////////
  377. // CXTPReportInplaceButton
  378. CXTPReportInplaceButton::CXTPReportInplaceButton(UINT nID)
  379. {
  380. m_nID = nID;
  381. m_nWidth = 17;
  382. m_nFixedHeight = 19;
  383. m_bInsideCell = FALSE;
  384. m_nIconIndex = XTP_REPORT_NOICON;
  385. m_bPressed = m_bOver = FALSE;
  386. m_nState = 0;
  387. m_nSpinIncrement = 0;
  388. m_unSpinTimerCnt = 0;
  389. m_unSpinTimerId = 0;
  390. }
  391. void CXTPReportInplaceButton::Create(XTP_REPORTRECORDITEM_ARGS* pItemArgs, CRect& rcButtons)
  392. {
  393. m_bPressed = m_bOver = FALSE;
  394. m_nState = 0;
  395. m_nSpinIncrement = 0;
  396. m_unSpinTimerCnt = 0;
  397. m_unSpinTimerId = 0;
  398. SetItemArgs(pItemArgs);
  399. CRect rect(rcButtons);
  400. if (pControl->GetPaintManager()->IsFixedInplaceButtonHeight())
  401. rect.bottom = rect.top + m_nFixedHeight;
  402. if (m_bInsideCell)
  403. {
  404. rect.right = rcButtons.left;
  405. rect.left = rect.right - m_nWidth;
  406. rcButtons.left = rect.left;
  407. }
  408. else
  409. {
  410. rect.left = rcButtons.right;
  411. rect.right = rect.left + m_nWidth;
  412. rcButtons.right = rect.right;
  413. }
  414. if (!m_hWnd)
  415. {
  416. CStatic::Create(NULL, SS_NOTIFY | WS_CHILD, rect, pItemArgs->pControl);
  417. }
  418. SetWindowPos(0, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOZORDER | SWP_SHOWWINDOW);
  419. }
  420. BEGIN_MESSAGE_MAP(CXTPReportInplaceButton, CStatic)
  421. //{{AFX_MSG_MAP(CXTPReportInplaceButton)
  422. ON_WM_PAINT()
  423. ON_WM_LBUTTONDOWN()
  424. ON_WM_LBUTTONUP()
  425. ON_WM_LBUTTONDBLCLK()
  426. ON_WM_MOUSEMOVE()
  427. ON_WM_CAPTURECHANGED()
  428. ON_WM_TIMER()
  429. //}}AFX_MSG_MAP
  430. END_MESSAGE_MAP()
  431. void CXTPReportInplaceButton::OnPaint()
  432. {
  433. CPaintDC dc(this);
  434. if (pControl)
  435. {
  436. pControl->GetPaintManager()->DrawInplaceButton(&dc, this);
  437. }
  438. }
  439. void CXTPReportInplaceButton::OnFinalRelease()
  440. {
  441. if (m_hWnd != NULL)
  442. DestroyWindow();
  443. CCmdTarget::OnFinalRelease();
  444. }
  445. void CXTPReportInplaceButton::OnLButtonDown(UINT, CPoint point)
  446. {
  447. switch(m_nID)
  448. {
  449. case XTP_ID_REPORT_COMBOBUTTON :
  450. case XTP_ID_REPORT_EXPANDBUTTON :
  451. m_bOver = m_bPressed = TRUE;
  452. break;
  453. case XTP_ID_REPORT_SPINBUTTON :
  454. {
  455. CXTPClientRect rect(this);
  456. m_bOver = TRUE;
  457. rect.bottom -= rect.Height() / 2;
  458. m_nState = rect.PtInRect(point) ? SPNP_UP : SPNP_DOWN;
  459. m_nSpinIncrement = m_nState == SPNP_UP ? 1 : -1;
  460. pItem->OnInplaceButtonDown(this);
  461. // start timer
  462. m_unSpinTimerCnt = 0;
  463. m_unSpinTimerId = SetTimer(1, 500, NULL);
  464. break;
  465. }
  466. }
  467. Invalidate(FALSE);
  468. SetCapture();
  469. }
  470. void CXTPReportInplaceButton::OnLButtonUp(UINT nFlags, CPoint point)
  471. {
  472. if ((m_bPressed || m_nState) && pItem)
  473. {
  474. if(m_unSpinTimerId)
  475. {
  476. KillTimer(1);
  477. m_unSpinTimerId = 0;
  478. }
  479. m_nSpinIncrement = 0;
  480. m_unSpinTimerCnt = 0;
  481. m_bPressed = FALSE;
  482. m_nState = 0;
  483. Invalidate(FALSE);
  484. ReleaseCapture();
  485. if (m_bOver && m_nID != XTP_ID_REPORT_SPINBUTTON)
  486. {
  487. pItem->OnInplaceButtonDown(this);
  488. }
  489. }
  490. CStatic::OnLButtonUp(nFlags, point);
  491. }
  492. void CXTPReportInplaceButton::OnLButtonDblClk(UINT nFlags, CPoint point)
  493. {
  494. UNREFERENCED_PARAMETER(nFlags);
  495. if(m_nID == XTP_ID_REPORT_SPINBUTTON)
  496. {
  497. CXTPClientRect rect(this);
  498. if (rect.PtInRect(point))
  499. {
  500. rect.bottom -= rect.Height() / 2;
  501. m_nState = rect.PtInRect(point) ? SPNP_UP : SPNP_DOWN;
  502. m_nSpinIncrement = m_nState == SPNP_UP ? 1 : -1;
  503. pItem->OnInplaceButtonDown(this);
  504. // start timer
  505. m_unSpinTimerCnt = 0;
  506. m_unSpinTimerId = SetTimer(1, 500, NULL);
  507. }
  508. Invalidate(FALSE);
  509. SetCapture();
  510. }
  511. }
  512. void CXTPReportInplaceButton::OnMouseMove(UINT nFlags, CPoint point)
  513. {
  514. if (m_bPressed || m_nState)
  515. {
  516. CXTPClientRect rect(this);
  517. BOOL bOver;
  518. if(m_nID != XTP_ID_REPORT_SPINBUTTON)
  519. bOver = rect.PtInRect(point);
  520. else
  521. {
  522. bOver = rect.PtInRect(point) &&
  523. (point.y < (rect.bottom - rect.Height() / 2) && m_nState == SPNP_UP ||
  524. point.y >= (rect.bottom - rect.Height() / 2) && m_nState == SPNP_DOWN);
  525. }
  526. if ((bOver && !m_bOver) || (!bOver && m_bOver))
  527. {
  528. m_bOver = bOver;
  529. if(m_nID == XTP_ID_REPORT_SPINBUTTON)
  530. {
  531. if(m_bOver)
  532. {
  533. m_nSpinIncrement = m_nState == SPNP_UP ? 1 : -1;
  534. m_unSpinTimerCnt = 0;
  535. m_unSpinTimerId = SetTimer(1, 500, NULL); // start timer
  536. }
  537. else if(m_unSpinTimerId)
  538. {
  539. // stop timer
  540. KillTimer(1);
  541. m_nSpinIncrement = 0;
  542. m_unSpinTimerCnt = 0;
  543. m_unSpinTimerId = 0;
  544. }
  545. }
  546. Invalidate(FALSE);
  547. }
  548. }
  549. CStatic::OnMouseMove(nFlags, point);
  550. }
  551. void CXTPReportInplaceButton::OnCaptureChanged(CWnd* pWnd)
  552. {
  553. m_bPressed = FALSE;
  554. m_nState = 0;
  555. Invalidate(FALSE);
  556. CStatic::OnCaptureChanged(pWnd);
  557. }
  558. void CXTPReportInplaceButton::OnTimer(UINT_PTR nIDEvent)
  559. {
  560. if(m_unSpinTimerCnt == 0 && abs(m_nSpinIncrement) < 10)
  561. {
  562. // first timer event, reset timer
  563. KillTimer(1);
  564. m_unSpinTimerId = SetTimer(1, 100, NULL);
  565. }
  566. m_unSpinTimerCnt++;
  567. if(m_unSpinTimerCnt >= 20 && abs(m_nSpinIncrement < 100000))
  568. {
  569. m_nSpinIncrement *= 10;
  570. m_unSpinTimerCnt = 0;
  571. }
  572. pItem->OnInplaceButtonDown(this);
  573. CStatic::OnTimer(nIDEvent);
  574. }
  575. //////////////////////////////////////////////////////////////////////////
  576. // CXTPReportInplaceList
  577. CXTPReportInplaceList::CXTPReportInplaceList()
  578. {
  579. m_bApply = FALSE;
  580. m_dwLastKeyDownTime = 0;
  581. }
  582. void CXTPReportInplaceList::Create(XTP_REPORTRECORDITEM_ARGS* pItemArgs, CXTPReportRecordItemConstraints* pConstaints)
  583. {
  584. SetItemArgs(pItemArgs);
  585. CRect rect(pItemArgs->rcItem);
  586. if (!m_hWnd)
  587. {
  588. CListBox::CreateEx(WS_EX_TOOLWINDOW | (pControl->GetExStyle() & WS_EX_LAYOUTRTL), _T("LISTBOX"), _T(""), LBS_NOTIFY | WS_CHILD | WS_BORDER | WS_VSCROLL, CRect(0, 0, 0, 0), pControl, 0);
  589. SetOwner(pControl);
  590. }
  591. SetFont(pControl->GetPaintManager()->GetTextFont());
  592. ResetContent();
  593. int dx = rect.right - rect.left + 1;
  594. CWindowDC dc(pControl);
  595. CXTPFontDC font(&dc, GetFont());
  596. int nThumbLength = GetSystemMetrics(SM_CXHTHUMB);
  597. CString strCaption = pItem->GetCaption(pColumn);
  598. DWORD dwData = pItem->GetSelectedConstraintData(pItemArgs);
  599. for (int i = 0; i < pConstaints->GetCount(); i++)
  600. {
  601. CXTPReportRecordItemConstraint* pConstaint = pConstaints->GetAt(i);
  602. CString str = pConstaint->m_strConstraint;
  603. int nIndex = AddString(str);
  604. SetItemDataPtr(nIndex, pConstaint);
  605. dx = max(dx, dc.GetTextExtent(str).cx + nThumbLength);
  606. if ((dwData == (DWORD)-1 && strCaption == str) || (dwData == pConstaint->m_dwData))
  607. SetCurSel(nIndex);
  608. }
  609. int nHeight = GetItemHeight(0);
  610. rect.top = rect.bottom;
  611. rect.bottom += nHeight * min(10, GetCount()) + 2;
  612. rect.left = rect.right - dx;
  613. pControl->ClientToScreen(&rect);
  614. CRect rcWork = XTPMultiMonitor()->GetWorkArea(rect);
  615. if (rect.bottom > rcWork.bottom && rect.top > rcWork.CenterPoint().y)
  616. {
  617. rect.OffsetRect(0, - rect.Height() - pItemArgs->rcItem.Height());
  618. }
  619. if (rect.left < rcWork.left) rect.OffsetRect(rcWork.left - rect.left, 0);
  620. if (rect.right > rcWork.right) rect.OffsetRect(rcWork.right - rect.right, 0);
  621. SetFocus();
  622. if (!m_hWnd) // Can be destroyed after focus set
  623. return;
  624. SetWindowLongPtr(m_hWnd, GWLP_HWNDPARENT, 0);
  625. ModifyStyle(WS_CHILD, WS_POPUP);
  626. SetWindowLongPtr(m_hWnd, GWLP_HWNDPARENT, (LONG_PTR)pControl->m_hWnd);
  627. SetWindowPos(&CWnd::wndTopMost, rect.left, rect.top, rect.Width(), rect.Height(), SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
  628. CXTPMouseMonitor::SetupHook(this);
  629. }
  630. BEGIN_MESSAGE_MAP(CXTPReportInplaceList, CListBox)
  631. //{{AFX_MSG_MAP(CXTPReportInplaceList)
  632. ON_WM_MOUSEACTIVATE()
  633. ON_WM_KILLFOCUS()
  634. ON_WM_LBUTTONUP()
  635. ON_WM_CHAR()
  636. ON_WM_KEYDOWN()
  637. ON_WM_SYSKEYDOWN()
  638. //}}AFX_MSG_MAP
  639. END_MESSAGE_MAP()
  640. int CXTPReportInplaceList::OnMouseActivate(CWnd* /*pDesktopWnd*/, UINT /*nHitTest*/, UINT /*message*/)
  641. {
  642. return MA_NOACTIVATE;
  643. }
  644. void CXTPReportInplaceList::SetItemArgs(XTP_REPORTRECORDITEM_ARGS* pItemArgs)
  645. {
  646. m_bApply = FALSE;
  647. CXTPReportInplaceControl::SetItemArgs(pItemArgs);
  648. m_dwLastKeyDownTime = 0;
  649. m_strHotSearchContext.Empty();
  650. }
  651. void CXTPReportInplaceList::PostNcDestroy()
  652. {
  653. CXTPMouseMonitor::SetupHook(NULL);
  654. SetItemArgs(NULL);
  655. CListBox::PostNcDestroy();
  656. }
  657. void CXTPReportInplaceList::OnKillFocus(CWnd* pNewWnd)
  658. {
  659. //ASSERT(pItem || m_bApply);
  660. if (pItem && !m_bApply)
  661. pItem->OnEditCanceled(this);
  662. CListBox::OnKillFocus(pNewWnd);
  663. DestroyWindow();
  664. }
  665. void CXTPReportInplaceList::OnLButtonUp(UINT, CPoint point)
  666. {
  667. CXTPClientRect rc(this);
  668. if (rc.PtInRect(point))
  669. Apply();
  670. else
  671. Cancel();
  672. }
  673. void CXTPReportInplaceList::Cancel()
  674. {
  675. m_bApply = FALSE;
  676. GetOwner()->SetFocus();
  677. }
  678. void CXTPReportInplaceList::Apply()
  679. {
  680. if (!pControl)
  681. return;
  682. CXTPReportControl* pReportControl = pControl;
  683. int nIndex = GetCurSel();
  684. if (nIndex != LB_ERR)
  685. {
  686. m_bApply = TRUE;
  687. CXTPReportRecordItemConstraint* pConstraint = (CXTPReportRecordItemConstraint*)GetItemDataPtr(nIndex);
  688. XTP_REPORTRECORDITEM_ARGS itemArgs = *((XTP_REPORTRECORDITEM_ARGS*)this);
  689. itemArgs.AddRef();
  690. pItem->OnConstraintChanged(&itemArgs, pConstraint);
  691. pReportControl->RedrawControl();
  692. pReportControl->SendMessageToParent(itemArgs.pRow, itemArgs.pItem, itemArgs.pColumn, XTP_NM_REPORT_VALUECHANGED, 0);
  693. itemArgs.Release();
  694. }
  695. pReportControl->SetFocus();
  696. }
  697. void CXTPReportInplaceList::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
  698. {
  699. UNREFERENCED_PARAMETER(nRepCnt); UNREFERENCED_PARAMETER(nFlags);
  700. const DWORD cwdHotSearchTomeOut_ms = 1300;
  701. DWORD dwTime = GetTickCount();
  702. if (dwTime - m_dwLastKeyDownTime > cwdHotSearchTomeOut_ms)
  703. m_strHotSearchContext.Empty();
  704. m_dwLastKeyDownTime = dwTime;
  705. //----------------------------------------------
  706. m_strHotSearchContext += (TCHAR)nChar;
  707. int nIndex = GetCurSel();
  708. if (nIndex == LB_ERR)
  709. nIndex = 0;
  710. int nFindIdx = FindString(nIndex, m_strHotSearchContext);
  711. if(nFindIdx == LB_ERR && nIndex > 0)
  712. nFindIdx = FindString(0, m_strHotSearchContext);
  713. if(nFindIdx != LB_ERR)
  714. {
  715. SetCurSel(nFindIdx);
  716. if(nIndex != nFindIdx)
  717. OnSelectionChanged(nFindIdx);
  718. }
  719. }
  720. void CXTPReportInplaceList::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  721. {
  722. switch(nChar)
  723. {
  724. case VK_UP:
  725. case VK_DOWN:
  726. case VK_PRIOR:
  727. case VK_NEXT:
  728. case VK_HOME:
  729. case VK_END:
  730. m_strHotSearchContext.Empty();
  731. }
  732. //----------------------------------------------
  733. if (nChar == VK_ESCAPE)
  734. {
  735. Cancel();
  736. }
  737. else if (nChar == VK_RETURN || nChar == VK_F4)
  738. {
  739.  Apply();
  740. }
  741. else
  742. {
  743. int nPrevSel = CListBox::GetCurSel();
  744. CListBox::OnKeyDown(nChar, nRepCnt, nFlags);
  745. int nActualSel = CListBox::GetCurSel();
  746. if(nPrevSel != nActualSel)
  747. OnSelectionChanged(nActualSel);
  748. }
  749. }
  750. void CXTPReportInplaceList::OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  751. {
  752. if (nChar == VK_DOWN || nChar == VK_UP)
  753. {
  754. Apply();
  755. return;
  756. }
  757. CListBox::OnSysKeyDown(nChar, nRepCnt, nFlags);
  758. }
  759. void CXTPReportInplaceList::OnSelectionChanged(int nLBIndex)
  760. {
  761. CString strActual, str;
  762. CListBox::GetText(nLBIndex,strActual);
  763. CXTPReportRecordItemEditOptions* pEditOptions = pItem->GetEditOptions(pColumn);
  764. CXTPReportRecordItemConstraints* pConstraints = pEditOptions->GetConstraints();
  765. int nCount = pConstraints->GetCount();
  766. for(int nIndex = 0; nIndex < nCount; nIndex++)
  767. {
  768. CXTPReportRecordItemConstraint* pConstraint = pConstraints->GetAt(nIndex);
  769. str = pConstraint->m_strConstraint;
  770. if(strActual.CompareNoCase(str) == 0)
  771. {
  772. ((CXTPReportControl*)pControl)->OnConstraintSelecting(pRow, pItem, pColumn, pConstraint);
  773. break;
  774. }
  775. }
  776. }