SymbolEdit.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970
  1. // AeroEdit.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "SymbolEdit.h"
  5. #include "cp_main.h"
  6. #include "QListCtrl.h"
  7. #include "Shared\TextConvert.h"
  8. // CSymbolEdit
  9. #define RANGE_START 3000
  10. #define CLEAR_LIST 3050
  11. #define LIST_MAX_COUNT 50
  12. IMPLEMENT_DYNAMIC(CSymbolEdit, CEdit)
  13. CSymbolEdit::CSymbolEdit() :
  14. m_hSymbolIcon(NULL),
  15. m_bInternalIcon(false),
  16. m_colorPromptText(RGB(127, 127, 127)),
  17. m_centerTextDiff(0)
  18. {
  19. m_fontPrompt.CreateFont(
  20. 16, // nHeight
  21. 0, // nWidth
  22. 0, // nEscapement
  23. 0, // nOrientation
  24. FW_NORMAL, // nWeight
  25. TRUE, // bItalic
  26. FALSE, // bUnderline
  27. 0, // cStrikeOut
  28. DEFAULT_CHARSET, // nCharSet
  29. OUT_DEFAULT_PRECIS, // nOutPrecision
  30. CLIP_DEFAULT_PRECIS, // nClipPrecision
  31. DEFAULT_QUALITY, // nQuality
  32. DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily
  33. _T("Calibri"));
  34. m_mouseDownOnSearches = false;
  35. m_mouseHoveringOverSearches = false;
  36. m_mouseDownOnClose = false;
  37. m_mouseHoveringOverClose = false;
  38. m_windowDpi = NULL;
  39. //m_searchButton.LoadStdImageDPI(Search_16, Search_20, Search_24, Search_32, _T("PNG"));
  40. }
  41. CSymbolEdit::~CSymbolEdit()
  42. {
  43. DestroyIcon();
  44. }
  45. BEGIN_MESSAGE_MAP(CSymbolEdit, CEdit)
  46. ON_WM_PAINT()
  47. ON_MESSAGE(WM_SETFONT, OnSetFont)
  48. //ON_MESSAGE(WM_EXITMENULOOP, OnMenuExit)
  49. ON_WM_CTLCOLOR_REFLECT()
  50. ON_WM_SETFOCUS()
  51. ON_WM_KILLFOCUS()
  52. ON_WM_SETCURSOR()
  53. ON_WM_LBUTTONUP()
  54. ON_WM_LBUTTONDOWN()
  55. ON_WM_MOUSEMOVE()
  56. ON_COMMAND_RANGE(RANGE_START, (RANGE_START+ LIST_MAX_COUNT), OnSelectSearchString)
  57. ON_WM_EXITSIZEMOVE()
  58. //ON_WM_ERASEBKGND()
  59. ON_WM_NCCALCSIZE()
  60. ON_WM_NCPAINT()
  61. ON_WM_TIMER()
  62. END_MESSAGE_MAP()
  63. BOOL CSymbolEdit::PreTranslateMessage(MSG* pMsg)
  64. {
  65. // TODO: Add your specialized code here and/or call the base class
  66. // Intercept Ctrl + Z (Undo), Ctrl + X (Cut), Ctrl + C (Copy), Ctrl + V (Paste) and Ctrl + A (Select All)
  67. // before CEdit base class gets a hold of them.
  68. if (pMsg->message == WM_KEYDOWN &&
  69. CONTROL_PRESSED)
  70. {
  71. switch (pMsg->wParam)
  72. {
  73. case 'Z':
  74. Undo();
  75. return TRUE;
  76. case 'X':
  77. Cut();
  78. return TRUE;
  79. case 'C':
  80. {
  81. int startChar;
  82. int endChar;
  83. this->GetSel(startChar, endChar);
  84. if (startChar == endChar)
  85. {
  86. CWnd *pWnd = GetParent();
  87. if (pWnd)
  88. {
  89. pWnd->SendMessage(NM_COPY_CLIP, pMsg->wParam, pMsg->lParam);
  90. }
  91. }
  92. else
  93. {
  94. Copy();
  95. }
  96. }
  97. return TRUE;
  98. case 'V':
  99. Paste();
  100. return TRUE;
  101. case 'A':
  102. SetSel(0, -1);
  103. return TRUE;
  104. }
  105. }
  106. switch (pMsg->message)
  107. {
  108. case WM_KEYDOWN:
  109. {
  110. if (pMsg->wParam == VK_RETURN)
  111. {
  112. CWnd *pWnd = GetParent();
  113. if (pWnd)
  114. {
  115. if (g_Opt.m_bFindAsYouType)
  116. {
  117. pWnd->SendMessage(NM_SEARCH_ENTER_PRESSED, 0, 0);
  118. }
  119. else
  120. {
  121. //Send a message to the parent to refill the lb from the search
  122. pWnd->PostMessage(CB_SEARCH, 0, 0);
  123. }
  124. AddToSearchHistory();
  125. }
  126. return TRUE;
  127. }
  128. else if (pMsg->wParam == VK_DOWN &&
  129. ((GetKeyState(VK_CONTROL) & 0x8000) || ((GetKeyState(VK_CONTROL) & 0x8000) && (GetKeyState(VK_SHIFT) & 0x8000))))
  130. {
  131. if (ShowSearchHistoryMenu())
  132. {
  133. return TRUE;
  134. }
  135. }
  136. else if (pMsg->wParam == VK_DOWN ||
  137. pMsg->wParam == VK_UP ||
  138. pMsg->wParam == VK_PRIOR ||
  139. pMsg->wParam == VK_NEXT)
  140. {
  141. CWnd *pWnd = GetParent();
  142. if (pWnd)
  143. {
  144. pWnd->SendMessage(CB_UPDOWN, pMsg->wParam, pMsg->lParam);
  145. return TRUE;
  146. }
  147. }
  148. else if (pMsg->wParam == VK_DELETE)
  149. {
  150. int startChar;
  151. int endChar;
  152. this->GetSel(startChar, endChar);
  153. CString cs;
  154. this->GetWindowText(cs);
  155. //if selection is at the end then forward this on to the parent to delete the selected clip
  156. if(startChar == cs.GetLength() &&
  157. endChar == cs.GetLength())
  158. {
  159. CWnd *pWnd = GetParent();
  160. if (pWnd)
  161. {
  162. pWnd->SendMessage(NM_DELETE, pMsg->wParam, pMsg->lParam);
  163. return TRUE;
  164. }
  165. }
  166. }
  167. break;
  168. }
  169. }
  170. return CEdit::PreTranslateMessage(pMsg);
  171. }
  172. CString CSymbolEdit::SavePastSearches()
  173. {
  174. TiXmlDocument doc;
  175. TiXmlElement* outer = new TiXmlElement("PastSearches");
  176. doc.LinkEndChild(outer);
  177. int count = (int)m_searches.GetCount();
  178. for (int i = 0; i < count; i++)
  179. {
  180. TiXmlElement* searchElement = new TiXmlElement("Search");
  181. CStringA t;
  182. CTextConvert::ConvertToUTF8(m_searches[i], t);
  183. searchElement->SetAttribute("text", t);
  184. outer->LinkEndChild(searchElement);
  185. }
  186. TiXmlPrinter printer;
  187. printer.SetLineBreak("");
  188. doc.Accept(&printer);
  189. CString cs = printer.CStr();
  190. return cs;
  191. }
  192. void CSymbolEdit::LoadPastSearches(CString values)
  193. {
  194. m_searches.RemoveAll();
  195. TiXmlDocument doc;
  196. CStringA xmlA;
  197. CTextConvert::ConvertToUTF8(values, xmlA);
  198. doc.Parse(xmlA);
  199. TiXmlElement *ItemHeader = doc.FirstChildElement("PastSearches");
  200. if (ItemHeader != NULL)
  201. {
  202. TiXmlElement *ItemElement = ItemHeader->FirstChildElement();
  203. while (ItemElement)
  204. {
  205. CString item = ItemElement->Attribute("text");
  206. m_searches.Add(item);
  207. ItemElement = ItemElement->NextSiblingElement();
  208. }
  209. }
  210. }
  211. void CSymbolEdit::AddToSearchHistory()
  212. {
  213. CString cs;
  214. this->GetWindowText(cs);
  215. if (cs != _T(""))
  216. {
  217. if (m_searches.GetCount() >= LIST_MAX_COUNT)
  218. {
  219. m_searches.RemoveAt(0);
  220. }
  221. bool existing = false;
  222. int count = (int)m_searches.GetCount();
  223. for (int i = 0; i < count; i++)
  224. {
  225. if (m_searches[i] == cs)
  226. {
  227. m_searches.RemoveAt(i);
  228. m_searches.Add(cs);
  229. existing = true;
  230. break;
  231. }
  232. }
  233. if (existing == false)
  234. {
  235. m_searches.Add(cs);
  236. }
  237. }
  238. }
  239. bool CSymbolEdit::ShowSearchHistoryMenu()
  240. {
  241. if (m_searches.GetCount() == 0)
  242. {
  243. return false;
  244. }
  245. CMenu cmPopUp;
  246. cmPopUp.CreatePopupMenu();
  247. int count = min((int)m_searches.GetCount(), LIST_MAX_COUNT);
  248. for (int i = count-1; i >= 0; i--)
  249. {
  250. CString text = m_searches[i];
  251. if (i == count - 1 &&
  252. m_lastSearchShortCut.Key > 0)
  253. {
  254. CString cmdShortcutText = CHotKey::GetHotKeyDisplayStatic(m_lastSearchShortCut.Key);
  255. if (m_lastSearchShortCut.Key2 != 0)
  256. {
  257. CString cmdShortcutText2 = CHotKey::GetHotKeyDisplayStatic(m_lastSearchShortCut.Key2);
  258. if (cmdShortcutText2.GetLength() > 0)
  259. {
  260. cmdShortcutText += _T(" - ");
  261. cmdShortcutText += cmdShortcutText2;
  262. }
  263. }
  264. text += "\t";
  265. text += cmdShortcutText;
  266. }
  267. cmPopUp.AppendMenuW(MF_STRING, (RANGE_START + i), text);
  268. }
  269. cmPopUp.AppendMenu(MF_SEPARATOR);
  270. cmPopUp.AppendMenuW(MF_STRING, CLEAR_LIST, _T("Clear List"));
  271. CRect windowRect;
  272. this->GetWindowRect(&windowRect);
  273. POINT pp;
  274. GetCursorPos(&pp);
  275. POINT x = this->GetCaretPos();
  276. ClientToScreen(&x);
  277. x.y += windowRect.Height();
  278. cmPopUp.TrackPopupMenu(TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON, x.x, x.y, this, NULL);
  279. Invalidate();
  280. return true;
  281. }
  282. void CSymbolEdit::DestroyIcon()
  283. {
  284. // if icon was loaded internally, destroy it
  285. if (m_bInternalIcon || m_hSymbolIcon != NULL)
  286. ::DestroyIcon(m_hSymbolIcon);
  287. }
  288. void CSymbolEdit::PreSubclassWindow()
  289. {
  290. RecalcLayout();
  291. }
  292. void CSymbolEdit::SetSymbolIcon(HICON hIcon, BOOL redraw)
  293. {
  294. DestroyIcon();
  295. m_hSymbolIcon = hIcon;
  296. // icon was not loaded internally
  297. m_bInternalIcon = false;
  298. RecalcLayout();
  299. if (redraw)
  300. Invalidate(TRUE);
  301. }
  302. void CSymbolEdit::SetSymbolIcon(UINT id, BOOL redraw)
  303. {
  304. DestroyIcon();
  305. m_hSymbolIcon = (HICON)::LoadImage(
  306. AfxGetResourceHandle(),
  307. MAKEINTRESOURCE(id),
  308. IMAGE_ICON,
  309. 16,
  310. 16,
  311. LR_DEFAULTCOLOR | LR_LOADTRANSPARENT);
  312. ASSERT(m_hSymbolIcon != NULL);
  313. // icon was loaded internally
  314. m_bInternalIcon = true;
  315. RecalcLayout();
  316. if (redraw)
  317. Invalidate(TRUE);
  318. }
  319. void CSymbolEdit::SetPromptText(CString text, BOOL redraw)
  320. {
  321. m_strPromptText = text;
  322. if (redraw)
  323. Invalidate(TRUE);
  324. }
  325. void CSymbolEdit::SetPromptText(LPCTSTR szText, BOOL redraw)
  326. {
  327. m_strPromptText = szText;
  328. if (redraw)
  329. Invalidate(TRUE);
  330. }
  331. void CSymbolEdit::SetPromptTextColor(COLORREF color, BOOL redraw)
  332. {
  333. m_colorPromptText = color;
  334. if (redraw)
  335. Invalidate(TRUE);
  336. }
  337. void CSymbolEdit::SetPromptFont(CFont& font, BOOL redraw)
  338. {
  339. LOGFONT lf;
  340. memset(&lf, 0, sizeof(LOGFONT));
  341. font.GetLogFont(&lf);
  342. SetPromptFont(&lf);
  343. if (redraw)
  344. Invalidate(TRUE);
  345. }
  346. void CSymbolEdit::SetPromptFont(const LOGFONT* lpLogFont, BOOL redraw)
  347. {
  348. m_fontPrompt.DeleteObject();
  349. m_fontPrompt.CreateFontIndirect(lpLogFont);
  350. if (redraw)
  351. Invalidate(TRUE);
  352. }
  353. void CSymbolEdit::RecalcLayout()
  354. {
  355. int width = GetSystemMetrics(SM_CXSMICON);
  356. if (m_hSymbolIcon)
  357. {
  358. DWORD dwMargins = GetMargins();
  359. SetMargins(LOWORD(dwMargins), width + 6);
  360. }
  361. else
  362. {
  363. if (m_windowDpi != NULL)
  364. {
  365. SetMargins(m_windowDpi->Scale(4), m_windowDpi->Scale(34));
  366. }
  367. }
  368. }
  369. void CSymbolEdit::OnPaint()
  370. {
  371. CPaintDC dc(this);
  372. CRect rect;
  373. GetClientRect(&rect);
  374. DWORD margins = GetMargins();
  375. CRect textRect(rect);
  376. textRect.left += LOWORD(margins);
  377. textRect.right -= HIWORD(margins);
  378. // Clearing the background
  379. dc.FillSolidRect(rect, GetSysColor(COLOR_WINDOW));
  380. if (m_hSymbolIcon)
  381. {
  382. // Drawing the icon
  383. int width = GetSystemMetrics(SM_CXSMICON);
  384. int height = GetSystemMetrics(SM_CYSMICON);
  385. ::DrawIconEx(
  386. dc.m_hDC,
  387. rect.right - width - 1,
  388. 1,
  389. m_hSymbolIcon,
  390. width,
  391. height,
  392. 0,
  393. NULL,
  394. DI_NORMAL);
  395. rect.left += LOWORD(margins) + 1;
  396. rect.right -= (width + 7);
  397. }
  398. else
  399. {
  400. //rect.left += (LOWORD(dwMargins) + 1);
  401. //rect.right -= (HIWORD(dwMargins) + 1);
  402. }
  403. CString text;
  404. GetWindowText(text);
  405. CFont* oldFont = NULL;
  406. //rect.top += 1;
  407. if(this == GetFocus() || text.GetLength() > 0)
  408. {
  409. dc.FillSolidRect(rect, g_Opt.m_Theme.SearchTextBoxFocusBG());
  410. //CBrush borderBrush(g_Opt.m_Theme.SearchTextBoxFocusBorder());
  411. //dc.FrameRect(rect, &borderBrush);
  412. //rect.DeflateRect(1, 1, 1, 1);
  413. //textRect.DeflateRect(0, 1, 1, 1);
  414. oldFont = dc.SelectObject(GetFont());
  415. COLORREF oldColor = dc.GetTextColor();
  416. dc.SetTextColor(g_Opt.m_Theme.SearchTextBoxFocusText());
  417. dc.DrawText(text, textRect, DT_SINGLELINE | DT_INTERNAL | DT_EDITCONTROL | DT_NOPREFIX);
  418. dc.SelectObject(oldFont);
  419. dc.SetTextColor(oldColor);
  420. }
  421. else
  422. {
  423. dc.FillSolidRect(rect, g_Opt.m_Theme.MainWindowBG());
  424. }
  425. if (text.GetLength() == 0 && m_strPromptText.GetLength() > 0)
  426. {
  427. //if we aren't showing the close icon, then use the full space
  428. textRect.right += m_windowDpi->Scale(16);
  429. //textRect.right -= LOWORD(margins);
  430. oldFont = dc.SelectObject(&m_fontPrompt);
  431. COLORREF color = dc.GetTextColor();
  432. dc.SetTextColor(m_colorPromptText);
  433. dc.DrawText(m_strPromptText, textRect, DT_LEFT | DT_SINGLELINE | DT_EDITCONTROL | DT_VCENTER | DT_NOPREFIX);
  434. dc.SetTextColor(color);
  435. dc.SelectObject(oldFont);
  436. }
  437. int right = rect.right;
  438. if ((text.GetLength() > 0 || this == GetFocus()))
  439. {
  440. m_searchesButtonRect.SetRect(rect.right - m_windowDpi->Scale(18), 0, rect.right, rect.bottom);
  441. right = rect.right - m_windowDpi->Scale(18);
  442. m_searchesButton.Draw(&dc, *m_windowDpi, this, m_searchesButtonRect.left, 4, m_mouseHoveringOverSearches, m_mouseDownOnSearches);
  443. }
  444. else
  445. {
  446. m_searchesButtonRect.SetRect(0, 0, 0, 0);
  447. //m_searchButton.Draw(&dc, this, rect.right - 22, 4, false, false);
  448. }
  449. if (text.GetLength() > 0)
  450. {
  451. OutputDebugString(_T("showing close button\n"));
  452. m_closeButtonRect.SetRect(right - m_windowDpi->Scale(16), 0, right, rect.bottom);
  453. m_closeButton.Draw(&dc, *m_windowDpi, this, m_closeButtonRect.left, 4, m_mouseHoveringOverClose, m_mouseDownOnClose);
  454. }
  455. else
  456. {
  457. OutputDebugString(_T("not showing close button\n"));
  458. m_closeButtonRect.SetRect(0, 0, 0, 0);
  459. //m_searchButton.Draw(&dc, this, rect.right - 22, 4, false, false);
  460. }
  461. //OutputDebugString(_T("OnPaint"));
  462. if (text != m_lastTextOnPaint &&
  463. text == _T(""))
  464. {
  465. ::SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0, SWP_DRAWFRAME | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
  466. }
  467. m_lastTextOnPaint = text;
  468. OutputDebugString(_T("OnPaint \r\n"));
  469. }
  470. void CSymbolEdit::OnSize(UINT nType, int cx, int cy)
  471. {
  472. CEdit::OnSize(nType, cx, cy);
  473. RecalcLayout();
  474. }
  475. LRESULT CSymbolEdit::OnSetFont(WPARAM wParam, LPARAM lParam)
  476. {
  477. DefWindowProc(WM_SETFONT, wParam, lParam);
  478. RecalcLayout();
  479. return 0;
  480. }
  481. HBRUSH CSymbolEdit::CtlColor(CDC* pDC, UINT n)
  482. {
  483. OutputDebugString(_T("CtlColor \r\n"));
  484. if (::GetFocus() == m_hWnd)
  485. {
  486. pDC->SetTextColor(g_Opt.m_Theme.SearchTextBoxFocusText());
  487. pDC->SetBkColor(g_Opt.m_Theme.SearchTextBoxFocusBG());
  488. return CreateSolidBrush(g_Opt.m_Theme.SearchTextBoxFocusBG());
  489. }
  490. else
  491. {
  492. pDC->SetBkColor(g_Opt.m_Theme.MainWindowBG());
  493. return CreateSolidBrush(g_Opt.m_Theme.MainWindowBG());
  494. }
  495. }
  496. void CSymbolEdit::OnSetFocus(CWnd* pOldWnd)
  497. {
  498. OutputDebugString(_T("OnSetFocus \r\n"));
  499. //was seeing issues when refreshing non client area inline, do it delayed
  500. SetTimer(1, 500, NULL);
  501. CWnd *pWnd = GetParent();
  502. if (pWnd)
  503. {
  504. if (g_Opt.m_bFindAsYouType)
  505. {
  506. pWnd->SendMessage(NM_FOCUS_ON_SEARCH, 0, 0);
  507. }
  508. }
  509. CEdit::OnSetFocus(pOldWnd);
  510. }
  511. void CSymbolEdit::OnKillFocus(CWnd* pNewWnd)
  512. {
  513. OutputDebugString(_T("OnKillFocus \r\n"));
  514. AddToSearchHistory();
  515. //was seeing issues when refreshing non client area inline, do it delayed
  516. SetTimer(1, 500, NULL);
  517. CEdit::OnKillFocus(pNewWnd);
  518. }
  519. BOOL CSymbolEdit::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
  520. {
  521. CPoint pntCursor;
  522. GetCursorPos(&pntCursor);
  523. ScreenToClient(&pntCursor);
  524. if(m_closeButtonRect.PtInRect(pntCursor))
  525. {
  526. HCURSOR h = ::LoadCursor(NULL, IDC_ARROW);
  527. ::SetCursor(h);
  528. return TRUE;
  529. }
  530. if (m_searchesButtonRect.PtInRect(pntCursor))
  531. {
  532. HCURSOR h = ::LoadCursor(NULL, IDC_ARROW);
  533. ::SetCursor(h);
  534. return TRUE;
  535. }
  536. return CEdit::OnSetCursor(pWnd, nHitTest, message);
  537. }
  538. void CSymbolEdit::OnLButtonUp(UINT nFlags, CPoint point)
  539. {
  540. if (m_mouseDownOnClose)
  541. {
  542. ReleaseCapture();
  543. InvalidateRect(m_closeButtonRect);
  544. }
  545. if (m_mouseDownOnSearches)
  546. {
  547. ReleaseCapture();
  548. InvalidateRect(m_searchesButtonRect);
  549. }
  550. m_mouseDownOnClose = false;
  551. m_mouseDownOnSearches = false;
  552. if (m_closeButtonRect.PtInRect(point))
  553. {
  554. if ((GetWindowTextLength() > 0))
  555. {
  556. CWnd *pOwner = GetOwner();
  557. if (pOwner)
  558. {
  559. pOwner->SendMessage(NM_CANCEL_SEARCH, 0, 0);
  560. }
  561. }
  562. }
  563. if (m_searchesButtonRect.PtInRect(point))
  564. {
  565. this->ShowSearchHistoryMenu();
  566. }
  567. CEdit::OnLButtonUp(nFlags, point);
  568. }
  569. void CSymbolEdit::OnLButtonDown(UINT nFlags, CPoint point)
  570. {
  571. if (m_closeButtonRect.PtInRect(point))
  572. {
  573. m_mouseDownOnClose = true;
  574. SetCapture();
  575. InvalidateRect(m_closeButtonRect);
  576. }
  577. else
  578. {
  579. m_mouseDownOnClose = false;
  580. }
  581. if (m_searchesButtonRect.PtInRect(point))
  582. {
  583. m_mouseDownOnSearches = true;
  584. SetCapture();
  585. InvalidateRect(m_searchesButtonRect);
  586. }
  587. else
  588. {
  589. m_mouseDownOnSearches = false;
  590. }
  591. CEdit::OnLButtonDown(nFlags, point);
  592. Invalidate();
  593. }
  594. void CSymbolEdit::OnMouseMove(UINT nFlags, CPoint point)
  595. {
  596. if (m_closeButtonRect.PtInRect(point))
  597. {
  598. if (m_mouseHoveringOverClose == false)
  599. {
  600. m_mouseHoveringOverClose = true;
  601. InvalidateRect(m_closeButtonRect);
  602. }
  603. }
  604. else if(m_mouseHoveringOverClose)
  605. {
  606. m_mouseHoveringOverClose = false;
  607. InvalidateRect(m_closeButtonRect);
  608. }
  609. if (m_searchesButtonRect.PtInRect(point))
  610. {
  611. if (m_mouseHoveringOverSearches == false)
  612. {
  613. m_mouseHoveringOverSearches = true;
  614. InvalidateRect(m_searchesButtonRect);
  615. }
  616. }
  617. else if (m_mouseHoveringOverSearches)
  618. {
  619. m_mouseHoveringOverSearches = false;
  620. InvalidateRect(m_searchesButtonRect);
  621. }
  622. CEdit::OnMouseMove(nFlags, point);
  623. }
  624. void CSymbolEdit::OnSelectSearchString(UINT idIn)
  625. {
  626. int index = idIn - RANGE_START;
  627. if (idIn == CLEAR_LIST)
  628. {
  629. m_searches.RemoveAll();
  630. }
  631. else if (index >= 0 &&
  632. index < m_searches.GetCount())
  633. {
  634. CString cs = m_searches[index];
  635. this->SetWindowTextW(cs);
  636. this->SetFocus();
  637. this->SetSel(-1);
  638. this->Invalidate();
  639. m_searches.RemoveAt(index);
  640. m_searches.Add(cs);
  641. }
  642. }
  643. bool CSymbolEdit::ApplyLastSearch()
  644. {
  645. bool ret = false;
  646. if (m_searches.GetCount() > 0)
  647. {
  648. CString cs = m_searches[m_searches.GetCount()-1];
  649. this->SetWindowTextW(cs);
  650. this->SetFocus();
  651. this->SetSel(-1);
  652. this->Invalidate();
  653. ret = true;
  654. }
  655. return ret;
  656. }
  657. void CSymbolEdit::OnDpiChanged()
  658. {
  659. SetDpiInfo(m_windowDpi);
  660. }
  661. void CSymbolEdit::SetDpiInfo(CDPI *dpi)
  662. {
  663. m_windowDpi = dpi;
  664. m_closeButton.Reset();
  665. m_closeButton.LoadStdImageDPI(m_windowDpi->GetDPI(), search_close_16, search_close_20, search_close_24, search_close_28, search_close_32, _T("PNG"));
  666. m_searchesButton.Reset();
  667. m_searchesButton.LoadStdImageDPI(m_windowDpi->GetDPI(), down_16, down_20, down_24, down_28, down_32, _T("PNG"));
  668. RecalcLayout();
  669. Invalidate();
  670. }
  671. BOOL CSymbolEdit::OnEraseBkgnd(CDC* pDC)
  672. {
  673. // TODO: Add your message handler code here and/or call default
  674. //return CEdit::OnEraseBkgnd(pDC);
  675. return FALSE;
  676. }
  677. void CSymbolEdit::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
  678. {
  679. CString text;
  680. GetWindowText(text);
  681. //if (text.GetLength() > 0 || this == GetFocus())
  682. if (m_windowDpi != NULL)
  683. {
  684. lpncsp->rgrc[0].left += m_windowDpi->Scale(1);
  685. lpncsp->rgrc[0].top += m_windowDpi->Scale(1);
  686. lpncsp->rgrc[0].right -= m_windowDpi->Scale(1);
  687. lpncsp->rgrc[0].bottom -= m_windowDpi->Scale(1);
  688. CRect rectWnd, rectClient;
  689. ////calculate client area height needed for a font
  690. CFont *pFont = GetFont();
  691. CRect rectText;
  692. CDC *pDC = GetDC();
  693. CFont *pOld = pDC->SelectObject(pFont);
  694. pDC->DrawText("Ky", rectText, DT_CALCRECT | DT_LEFT);
  695. UINT uiVClientHeight = rectText.Height();
  696. pDC->SelectObject(pOld);
  697. ReleaseDC(pDC);
  698. ////calculate NC area to center text.
  699. //GetClientRect(rectClient);
  700. GetWindowRect(rectWnd);
  701. rectWnd.DeflateRect(m_windowDpi->Scale(1), m_windowDpi->Scale(1));
  702. m_centerTextDiff = (rectWnd.Height() - uiVClientHeight) / 2;
  703. if (m_centerTextDiff < 0 || m_centerTextDiff > uiVClientHeight)
  704. {
  705. m_centerTextDiff = 0;
  706. }
  707. lpncsp->rgrc[0].top += m_centerTextDiff;
  708. lpncsp->rgrc[0].bottom -= m_centerTextDiff;
  709. }
  710. //ClientToScreen(rectClient);
  711. //UINT uiCenterOffset = (rectWnd.Height() - uiVClientHeight) / 2;
  712. //UINT uiCY = (rectWnd.Heig%ht() - rectClient.Height()) / 2;
  713. //UINT uiCX = (rectWnd.Width() - rectClient.Width()) / 2;
  714. //rectWnd.OffsetRect(-rectWnd.left, -rectWnd.top);
  715. //m_rectNCTop = rectWnd;
  716. //m_rectNCTop.DeflateRect(uiCX, uiCY, uiCX, uiCenterOffset + uiVClientHeight + uiCY);
  717. //m_rectNCBottom = rectWnd;
  718. //m_rectNCBottom.DeflateRect(uiCX, uiCenterOffset + uiVClientHeight + uiCY, uiCX, uiCY);
  719. //lpncsp->rgrc[0].top += uiCenterOffset;
  720. //lpncsp->rgrc[0].bottom -= uiCenterOffset;
  721. //lpncsp->rgrc[0].left += uiCX;
  722. //lpncsp->rgrc[0].right -= uiCY;
  723. //CEdit::OnNcCalcSize(bCalcValidRects, lpncsp);
  724. }
  725. void CSymbolEdit::OnNcPaint()
  726. {
  727. CString text;
  728. GetWindowText(text);
  729. CWindowDC dc(this);
  730. CRect r;
  731. this->GetWindowRect(r);
  732. this->ScreenToClient(r);
  733. CRect t(0, 0, r.Width(), m_centerTextDiff+ m_windowDpi->Scale(1));
  734. CRect b(0, r.Height() - m_centerTextDiff- m_windowDpi->Scale(1), r.Width(), r.Height());
  735. COLORREF c = g_Opt.m_Theme.MainWindowBG();
  736. if (this == GetFocus() || text.GetLength() > 0)
  737. {
  738. dc.FillSolidRect(t, g_Opt.m_Theme.SearchTextBoxFocusBG());
  739. dc.FillSolidRect(b, g_Opt.m_Theme.SearchTextBoxFocusBG());
  740. c = g_Opt.m_Theme.SearchTextBoxFocusBorder();
  741. }
  742. else
  743. {
  744. dc.FillSolidRect(t, g_Opt.m_Theme.MainWindowBG());
  745. dc.FillSolidRect(b, g_Opt.m_Theme.MainWindowBG());
  746. }
  747. //if ((text.GetLength() > 0 || this == GetFocus()) && m_windowDpi)
  748. {
  749. CWindowDC dc(this);
  750. CRect rcFrame;
  751. this->GetWindowRect(rcFrame);
  752. this->ScreenToClient(rcFrame);
  753. CRect rcBorder(0, 0, rcFrame.Width(), rcFrame.Height());
  754. int border = m_windowDpi->Scale(1);
  755. CBrush borderBrush(c);
  756. for (int x = 0; x < border; x++)
  757. {
  758. dc.FrameRect(rcBorder, &borderBrush);
  759. rcBorder.DeflateRect(1, 1, 1, 1);
  760. }
  761. }
  762. OutputDebugString(_T("OnNCPaint \r\n"));
  763. }
  764. void CSymbolEdit::OnTimer(UINT_PTR nIDEvent)
  765. {
  766. switch (nIDEvent)
  767. {
  768. case 1:
  769. KillTimer(1);
  770. //Invalidate();
  771. ::SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0, SWP_DRAWFRAME | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
  772. break;
  773. }
  774. CEdit::OnTimer(nIDEvent);
  775. }