ToolTipEx.cpp 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665
  1. #include "stdafx.h"
  2. #include "cp_main.h"
  3. #include "ToolTipEx.h"
  4. #include "BitmapHelper.h"
  5. #include "Options.h"
  6. #include "ActionEnums.h"
  7. #include "HyperLink.h"
  8. #include <Richedit.h>
  9. #ifdef _DEBUG
  10. #define new DEBUG_NEW
  11. #undef THIS_FILE
  12. static char THIS_FILE[] = __FILE__;
  13. #endif
  14. #define HIDE_WINDOW_TIMER 1
  15. #define SAVE_SIZE 2
  16. #define TIMER_BUTTON_UP 3
  17. #define TIMER_AUTO_MAX 4
  18. /////////////////////////////////////////////////////////////////////////////
  19. // CToolTipEx
  20. CToolTipEx::CToolTipEx(): m_dwTextStyle(DT_EXPANDTABS | DT_EXTERNALLEADING |
  21. DT_NOPREFIX | DT_WORDBREAK), m_rectMargin(2, 2, 3, 3),
  22. m_pNotifyWnd(NULL), m_clipId(0), m_clipRow(-1)
  23. {
  24. m_showPersistant = false;
  25. m_pToolTipActions = NULL;
  26. m_bMaxSetTimer = false;
  27. m_lDelayMaxSeconds = 2;
  28. m_showingText = false;
  29. m_showingRTF = false;
  30. m_showingHTML = false;
  31. }
  32. CToolTipEx::~CToolTipEx()
  33. {
  34. m_Font.DeleteObject();
  35. m_clipDataFont.DeleteObject();
  36. }
  37. BEGIN_MESSAGE_MAP(CToolTipEx, CWnd)
  38. //{{AFX_MSG_MAP(CToolTipEx)
  39. ON_WM_PAINT()
  40. ON_WM_SIZE()
  41. ON_WM_NCHITTEST()
  42. ON_WM_ACTIVATE()
  43. ON_WM_TIMER()
  44. ON_WM_NCLBUTTONDBLCLK()
  45. ON_WM_NCPAINT()
  46. ON_WM_NCCALCSIZE()
  47. ON_WM_NCLBUTTONDOWN()
  48. ON_WM_NCMOUSEMOVE()
  49. ON_WM_NCLBUTTONUP()
  50. ON_WM_ERASEBKGND()
  51. ON_COMMAND(ID_FIRST_REMEMBERWINDOWPOSITION, &CToolTipEx::OnRememberwindowposition)
  52. ON_COMMAND(ID_FIRST_SIZEWINDOWTOCONTENT, &CToolTipEx::OnSizewindowtocontent)
  53. ON_COMMAND(ID_FIRST_SCALEIMAGESTOFITWINDOW, &CToolTipEx::OnScaleimagestofitwindow)
  54. ON_COMMAND(2, OnOptions)
  55. ON_WM_RBUTTONDOWN()
  56. ON_WM_SETFOCUS()
  57. ON_COMMAND(ID_FIRST_HIDEDESCRIPTIONWINDOWONM, &CToolTipEx::OnFirstHidedescriptionwindowonm)
  58. ON_COMMAND(ID_FIRST_WRAPTEXT, &CToolTipEx::OnFirstWraptext)
  59. ON_WM_WINDOWPOSCHANGING()
  60. ON_COMMAND(ID_FIRST_ALWAYSONTOP, &CToolTipEx::OnFirstAlwaysontop)
  61. ON_NOTIFY(EN_MSGFILTER, 1, &CToolTipEx::OnEnMsgfilterRichedit21)
  62. ON_MESSAGE(WM_DPICHANGED, OnDpiChanged)
  63. ON_WM_MOVING()
  64. ON_WM_ENTERSIZEMOVE()
  65. ON_WM_HSCROLL()
  66. ON_MESSAGE(WM_REFRESH_FOOTER, OnRefreshFooter)
  67. ON_COMMAND(ID_FIRST_VIEWTEXT, &CToolTipEx::OnFirstViewtext)
  68. ON_COMMAND(ID_FIRST_VIEWRTF, &CToolTipEx::OnFirstViewrtf)
  69. ON_COMMAND(ID_FIRST_VIEWHTML, &CToolTipEx::OnFirstViewhtml)
  70. ON_COMMAND(ID_FIRST_VIEWASIMAGE, &CToolTipEx::OnFirstViewImage)
  71. ON_UPDATE_COMMAND_UI(ID_FIRST_VIEWTEXT, &CToolTipEx::OnUpdateFirstViewtext)
  72. ON_UPDATE_COMMAND_UI(ID_FIRST_VIEWRTF, &CToolTipEx::OnUpdateFirstViewrtf)
  73. ON_UPDATE_COMMAND_UI(ID_FIRST_VIEWHTML, &CToolTipEx::OnUpdateFirstViewhtml)
  74. END_MESSAGE_MAP()
  75. /////////////////////////////////////////////////////////////////////////////
  76. // CToolTipEx message handlers
  77. BOOL CToolTipEx::Create(CWnd *pParentWnd)
  78. {
  79. m_saveWindowLockout = true;
  80. // Get the class name and create the window
  81. CString szClassName = AfxRegisterWndClass(CS_CLASSDC | CS_SAVEBITS, LoadCursor(NULL, IDC_ARROW));
  82. // Create the window - just don't show it yet.
  83. if( !CWnd::CreateEx(0, szClassName, _T(""), WS_POPUP,
  84. 0, 0, 0, 0, pParentWnd->GetSafeHwnd(), 0, NULL))
  85. {
  86. return FALSE;
  87. }
  88. HICON b = (HICON)LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME), IMAGE_ICON, 64, 64, LR_SHARED);
  89. SetIcon(b, TRUE);
  90. //CString szClassName2 = AfxRegisterWndClass(CS_CLASSDC | CS_SAVEBITS, LoadCursor(NULL, IDC_ARROW));
  91. //BOOL b = m_imageViewer.Create(_T(""), szClassName2, WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL, CRect(0, 0, 0, 0), this, 3);
  92. m_imageViewer.Create(this);
  93. m_DittoWindow.DoCreate(this);
  94. m_DittoWindow.SetCaptionColors(CGetSetOptions::m_Theme.CaptionLeft(), CGetSetOptions::m_Theme.CaptionRight(), CGetSetOptions::m_Theme.Border());
  95. m_DittoWindow.SetCaptionOn(this, CGetSetOptions::GetCaptionPos(), true, CGetSetOptions::m_Theme.GetCaptionSize(), CGetSetOptions::m_Theme.GetCaptionFontSize());
  96. m_DittoWindow.m_bDrawMaximize = false;
  97. m_DittoWindow.m_bDrawMinimize = false;
  98. m_DittoWindow.m_bDrawChevron = true;
  99. m_DittoWindow.m_sendWMClose = false;
  100. m_RichEdit.Create(_T(""), _T(""), WS_CHILD | WS_VISIBLE | WS_VSCROLL |
  101. WS_HSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | ES_NOHIDESEL |
  102. ES_AUTOHSCROLL, CRect(10, 10, 100, 200), this, 1);
  103. m_RichEdit.SetReadOnly();
  104. m_RichEdit.SetBackgroundColor(FALSE, CGetSetOptions::m_Theme.DescriptionWindowBG());
  105. m_RichEdit.SetEventMask(m_RichEdit.GetEventMask() | ENM_SELCHANGE | ENM_LINK | ENM_MOUSEEVENTS | ENM_SCROLLEVENTS);
  106. m_RichEdit.SetAutoURLDetect(TRUE);
  107. ApplyWordWrap();
  108. m_optionsButton.Create(NULL, WS_CHILD | BS_OWNERDRAW | WS_TABSTOP, CRect(0, 0, 0, 0), this, 2);
  109. m_optionsButton.LoadStdImageDPI(m_DittoWindow.m_dpi.GetDPI(), IDB_COG_16_16, IDB_COG_20_20, IDB_COG_24_24, cog_28, IDB_COG_32_32, _T("PNG"));
  110. m_optionsButton.SetToolTipText(theApp.m_Language.GetString(_T("DescriptionOptionsTooltip"), _T("Description Options")));
  111. m_optionsButton.ShowWindow(SW_SHOW);
  112. m_clipDataStatic.Create(_T("some text"), WS_CHILD | WS_VISIBLE | SS_SIMPLE, CRect(0, 0, 0, 0), this, 3);
  113. m_folderPathStatic.Create(_T("some text"), WS_CHILD | WS_VISIBLE | SS_SIMPLE, CRect(0, 0, 0, 0), this, 4);
  114. m_clipDataFont.CreateFont(-m_DittoWindow.m_dpi.Scale(11), 0, 0, 0, 400, 0, 0, 0, DEFAULT_CHARSET, 3, 2, 1, 34, _T("Segoe UI"));
  115. m_Font.CreateFont(-m_DittoWindow.m_dpi.Scale(13), 0, 0, 0, 400, 0, 0, 0, DEFAULT_CHARSET, 3, 2, 1, 34, _T("Segoe UI"));
  116. m_fontHeight = -13;
  117. m_clipDataStatic.SetFont(&m_clipDataFont);
  118. m_clipDataStatic.SetBkColor(CGetSetOptions::m_Theme.DescriptionWindowBG());
  119. m_clipDataStatic.SetTextColor(RGB(80, 80, 80));
  120. m_folderPathStatic.SetFont(&m_clipDataFont);
  121. m_folderPathStatic.SetBkColor(CGetSetOptions::m_Theme.DescriptionWindowBG());
  122. m_folderPathStatic.SetTextColor(RGB(80, 80, 80));
  123. m_saveWindowLockout = false;
  124. return TRUE;
  125. }
  126. BOOL CToolTipEx::Show(CPoint point)
  127. {
  128. m_showingText = false;
  129. m_showingRTF = false;
  130. m_showingHTML = false;
  131. m_showingImage = false;
  132. CRect rect;
  133. if(CGetSetOptions::GetSizeDescWindowToContent() == FALSE)
  134. {
  135. rect.left = point.x;
  136. rect.top = point.y;
  137. CSize size;
  138. CGetSetOptions::GetDescWndSize(size);
  139. rect.right = rect.left + m_DittoWindow.m_dpi.Scale(size.cx);
  140. rect.bottom = rect.top + m_DittoWindow.m_dpi.Scale(size.cy);
  141. EnsureWindowVisible(&rect);
  142. }
  143. else
  144. {
  145. rect = GetBoundsRect();
  146. //account for the scroll bars
  147. rect.right += 20;
  148. rect.bottom += 20;
  149. if (m_imageViewer.m_pGdiplusBitmap)
  150. {
  151. int nWidth = m_imageViewer.m_pGdiplusBitmap->GetWidth() + ::GetSystemMetrics(SM_CXVSCROLL);
  152. int nHeight = m_imageViewer.m_pGdiplusBitmap->GetHeight() + ::GetSystemMetrics(SM_CYHSCROLL);
  153. rect.right = rect.left + nWidth;
  154. rect.bottom = rect.top + nHeight;
  155. }
  156. long lNewWidth = (long)rect.Width() + (long)(rect.Width() *1.25);
  157. rect.right = rect.left + lNewWidth;
  158. long lNewHeight = (long)rect.Height() + (long)(rect.Height() *1.25);
  159. rect.bottom = rect.top + lNewHeight;
  160. ClientToScreen(rect);
  161. CRect cr(point, point);
  162. CRect rcScreen = MonitorRectFromRect(cr);
  163. //ensure that we don't go outside the screen
  164. if(point.x < rcScreen.left)
  165. {
  166. point.x = rcScreen.left + 5;
  167. }
  168. if(point.y < rcScreen.top)
  169. {
  170. point.y = rcScreen.top + 5;
  171. }
  172. rcScreen.DeflateRect(0, 0, 5, 5);
  173. long width = rect.Width();
  174. long height = rect.Height();
  175. if (width < 500)
  176. {
  177. width = 500;
  178. }
  179. rect.left = point.x;
  180. rect.top = point.y;
  181. rect.right = rect.left + width;
  182. rect.bottom = rect.top + height;
  183. if (rect.right > rcScreen.right)
  184. {
  185. rect.right = rcScreen.right;
  186. }
  187. if (rect.bottom > rcScreen.bottom)
  188. {
  189. rect.bottom = rcScreen.bottom;
  190. }
  191. }
  192. if (m_csText.GetLength())
  193. {
  194. int wordCount = WordCount(m_csText);
  195. m_clipData = StrF(_T("%s | Length: %d | Words: %d"), m_originalClipData, m_csText.GetLength(), wordCount);
  196. }
  197. m_clipDataStatic.SetWindowText(m_clipData);
  198. m_folderPathStatic.SetWindowText(m_folderPath);
  199. if (m_DittoWindow.m_bMinimized)
  200. {
  201. //m_DittoWindow.MinMaxWindow(this, FORCE_MAX);
  202. m_DittoWindow.m_bMinimized = false;
  203. }
  204. m_saveWindowLockout = true;
  205. MoveWindow(rect);
  206. MoveControls();
  207. if (m_imageViewer.m_pGdiplusBitmap)
  208. {
  209. m_imageViewer.UpdateBitmapSize(true);
  210. }
  211. if (m_imageViewer.m_pGdiplusBitmap)
  212. {
  213. int percent = (m_imageViewer.m_scale - 1.0) * 100.0;
  214. m_clipData = m_originalClipData + _T(" | ") + StrF(_T("%d x %d, %d%%"), m_imageViewer.m_pGdiplusBitmap->GetWidth(), m_imageViewer.m_pGdiplusBitmap->GetHeight(), percent);
  215. //OutputDebugString(_T("Showing image editor\r\n"));
  216. m_RichEdit.ShowWindow(SW_HIDE);
  217. if (::IsWindow(m_browser.m_hWnd))
  218. {
  219. m_browser.ShowWindow(SW_HIDE);
  220. }
  221. m_imageViewer.ShowWindow(SW_SHOW);
  222. m_showingImage = true;
  223. }
  224. else if (m_html.GetLength() > 0 && m_csRTF.GetLength() <= 0)
  225. {
  226. m_imageViewer.ShowWindow(SW_HIDE);
  227. m_RichEdit.ShowWindow(SW_HIDE);
  228. if (::IsWindow(m_browser.m_hWnd))
  229. {
  230. m_browser.ShowWindow(SW_SHOW);
  231. m_browser.Invalidate();
  232. }
  233. m_showingHTML = true;
  234. //OutputDebugString(_T("Showing html\r\n"));
  235. }
  236. else
  237. {
  238. m_imageViewer.ShowWindow(SW_HIDE);
  239. if (::IsWindow(m_browser.m_hWnd))
  240. {
  241. m_browser.ShowWindow(SW_HIDE);
  242. }
  243. m_RichEdit.ShowWindow(SW_SHOW);
  244. //OutputDebugString(_T("Showing rich text\r\n"));
  245. if (m_csRTF.GetLength() > 0)
  246. {
  247. m_showingRTF = true;
  248. }
  249. else
  250. {
  251. m_showingText = true;
  252. }
  253. }
  254. ShowWindow(SW_SHOWNA);
  255. //this->Invalidate();
  256. //this->UpdateWindow();
  257. m_saveWindowLockout = false;
  258. return TRUE;
  259. }
  260. void CToolTipEx::GetWindowRectEx(LPRECT lpRect)
  261. {
  262. if (m_DittoWindow.m_bMinimized)
  263. {
  264. *lpRect = m_DittoWindow.m_crFullSizeWindow;
  265. return;
  266. }
  267. CWnd::GetWindowRect(lpRect);
  268. }
  269. BOOL CToolTipEx::Hide()
  270. {
  271. delete m_imageViewer.m_pGdiplusBitmap;
  272. m_imageViewer.m_pGdiplusBitmap = NULL;
  273. SaveWindowSize();
  274. ShowWindow(SW_HIDE);
  275. if (m_browser.m_hWnd != NULL &&
  276. ::IsWindow(m_browser.m_hWnd))
  277. {
  278. m_browser.DestroyWindow();
  279. }
  280. m_csRTF = "";
  281. m_csText = "";
  282. m_html = "";
  283. m_clipId = 0;
  284. m_clipRow = -1;
  285. m_searchText = _T("");
  286. m_showPersistant = false;
  287. return TRUE;
  288. }
  289. void CToolTipEx::OnNcLButtonDblClk(UINT nHitTest, CPoint point)
  290. {
  291. // toggle ShowPersistent when we double click the caption
  292. if (nHitTest == HTCAPTION)
  293. {
  294. OnFirstAlwaysontop();
  295. }
  296. CWnd::OnNcLButtonDblClk(nHitTest, point);
  297. }
  298. void CToolTipEx::SaveWindowSize()
  299. {
  300. if (::IsWindowVisible(m_hWnd))
  301. {
  302. CRect rect;
  303. if (m_DittoWindow.m_bMinimized)
  304. {
  305. rect = m_DittoWindow.m_crFullSizeWindow;
  306. }
  307. else
  308. {
  309. this->GetWindowRect(&rect);
  310. }
  311. CSize s = rect.Size();
  312. CGetSetOptions::SetDescWndSize(CSize(m_DittoWindow.m_dpi.UnScale(s.cx), m_DittoWindow.m_dpi.UnScale(s.cy)));
  313. CGetSetOptions::SetDescWndPoint(rect.TopLeft());
  314. OutputDebugString(_T("Saving tooltip size"));
  315. }
  316. }
  317. void CToolTipEx::PostNcDestroy()
  318. {
  319. CWnd::PostNcDestroy();
  320. delete this;
  321. }
  322. BOOL CToolTipEx::PreTranslateMessage(MSG *pMsg)
  323. {
  324. m_DittoWindow.DoPreTranslateMessage(pMsg);
  325. switch (pMsg->message)
  326. {
  327. case WM_KEYDOWN:
  328. switch(pMsg->wParam)
  329. {
  330. case 'C':
  331. if(GetKeyState(VK_CONTROL) &0x8000)
  332. {
  333. m_RichEdit.Copy();
  334. theApp.SetCopyReason(CopyReasonEnum::COPY_FROM_TOOLTIP);
  335. return TRUE;
  336. }
  337. break;
  338. }
  339. break;
  340. case WM_RBUTTONDOWN:
  341. {
  342. auto f = GetFocus();
  343. if (f != NULL &&
  344. (m_RichEdit.m_hWnd == f->m_hWnd ||
  345. m_imageViewer.m_hWnd == f->m_hWnd))
  346. {
  347. OnOptions();
  348. return TRUE;
  349. }
  350. }
  351. break;
  352. case WM_LBUTTONUP:
  353. auto f = GetFocus();
  354. if (f != NULL &&
  355. m_RichEdit.m_hWnd != f->m_hWnd &&
  356. m_optionsButton.m_hWnd != f->m_hWnd)
  357. {
  358. auto p = GetParent();
  359. if (p != NULL)
  360. {
  361. p->SetFocus();
  362. }
  363. }
  364. break;
  365. }
  366. if (m_pToolTipActions != NULL)
  367. {
  368. CAccel a;
  369. if (m_pToolTipActions->OnMsg(pMsg, a))
  370. {
  371. switch (a.Cmd)
  372. {
  373. case ActionEnums::CLOSEWINDOW:
  374. /*if (this->m_showPersistant &&
  375. m_DittoWindow.m_bMinimized == false)
  376. {
  377. m_DittoWindow.MinMaxWindow(this, FORCE_MIN);
  378. theApp.m_activeWnd.ReleaseFocus();
  379. return TRUE;
  380. }*/
  381. break;
  382. }
  383. }
  384. }
  385. return CWnd::PreTranslateMessage(pMsg);
  386. }
  387. BOOL CToolTipEx::OnMsg(MSG *pMsg)
  388. {
  389. if(FALSE == IsWindowVisible())
  390. {
  391. return FALSE;
  392. }
  393. switch(pMsg->message)
  394. {
  395. case WM_WINDOWPOSCHANGING:
  396. case WM_LBUTTONDOWN:
  397. {
  398. if (m_showPersistant == false)
  399. {
  400. if (CGetSetOptions::GetMouseClickHidesDescription())
  401. {
  402. if (!IsCursorInToolTip())
  403. {
  404. Hide();
  405. }
  406. }
  407. }
  408. }
  409. break;
  410. case WM_KEYDOWN:
  411. {
  412. WPARAM vk = pMsg->wParam;
  413. if(vk == 'C')
  414. {
  415. if (GetKeyState(VK_CONTROL) & 0x8000)
  416. {
  417. if (::IsWindow(m_browser.m_hWnd))
  418. {
  419. m_browser.Copy();
  420. theApp.SetCopyReason(CopyReasonEnum::COPY_FROM_TOOLTIP);
  421. return TRUE;
  422. }
  423. }
  424. }
  425. if(vk == VK_TAB)
  426. {
  427. m_RichEdit.SetFocus();
  428. return TRUE;
  429. }
  430. else if (vk == VK_CONTROL || vk == VK_SHIFT)
  431. {
  432. return FALSE;
  433. }
  434. else if (vk == VK_UP)
  435. {
  436. return FALSE;
  437. }
  438. else if (vk == VK_DOWN)
  439. {
  440. return FALSE;
  441. }
  442. else if (vk == VK_NEXT)
  443. {
  444. return FALSE;
  445. }
  446. else if (vk == VK_PRIOR)
  447. {
  448. return FALSE;
  449. }
  450. else if (vk == VK_DELETE)
  451. {
  452. return FALSE;
  453. }
  454. if (m_pToolTipActions != NULL)
  455. {
  456. if (m_pToolTipActions->ContainsKey((int)vk))
  457. {
  458. return FALSE;
  459. }
  460. }
  461. if (m_showPersistant == false)
  462. {
  463. Hide();
  464. }
  465. break;
  466. }
  467. case WM_LBUTTONDBLCLK:
  468. case WM_RBUTTONDBLCLK:
  469. case WM_MBUTTONDOWN:
  470. case WM_MBUTTONDBLCLK:
  471. case WM_NCLBUTTONDOWN:
  472. case WM_NCLBUTTONDBLCLK:
  473. case WM_NCRBUTTONDOWN:
  474. case WM_NCRBUTTONDBLCLK:
  475. case WM_NCMBUTTONDOWN:
  476. case WM_NCMBUTTONDBLCLK:
  477. {
  478. if (m_showPersistant == false)
  479. {
  480. Hide();
  481. }
  482. break;
  483. }
  484. case WM_MOUSEWHEEL:
  485. case WM_MOUSEHWHEEL:
  486. {
  487. if (m_imageViewer.m_pGdiplusBitmap)
  488. {
  489. m_imageViewer.PostMessageW(pMsg->message, pMsg->wParam, pMsg->lParam);
  490. return TRUE;
  491. }
  492. else
  493. {
  494. m_RichEdit.PostMessageW(pMsg->message, pMsg->wParam, pMsg->lParam);
  495. return TRUE;
  496. }
  497. }
  498. break;
  499. }
  500. return FALSE;
  501. }
  502. CRect CToolTipEx::GetBoundsRect()
  503. {
  504. DWORD d = GetTickCount();
  505. CWindowDC dc(NULL);
  506. int nLineWidth = 0;
  507. CRect rect(0, 0, 0, 0);
  508. if(nLineWidth == 0)
  509. {
  510. // Count the number of lines of text
  511. int nStart = 0;
  512. INT nNumLines = 0;
  513. int longestLength = 0;
  514. CString longestString;
  515. do
  516. {
  517. nNumLines++;
  518. int newStart = m_csText.Find(_T("\n"), nStart);
  519. if (newStart < 0)
  520. {
  521. int length = m_csText.GetLength() - nStart;
  522. if (length > longestLength)
  523. {
  524. longestString = m_csText.Mid(nStart, length);
  525. longestLength = length;
  526. }
  527. break;
  528. }
  529. int length = newStart - nStart;
  530. if(length > longestLength)
  531. {
  532. longestString = m_csText.Mid(nStart, length);
  533. longestLength = length;
  534. }
  535. nStart = newStart + 1;
  536. }
  537. while(nStart >= 0 && nNumLines < 100);
  538. CFont *pOldFont = (CFont*)dc.SelectObject((CFont*)&m_Font);
  539. CSize size = dc.GetTextExtent(longestString);
  540. dc.SelectObject(pOldFont);
  541. rect.right = size.cx;
  542. rect.bottom = size.cy * nNumLines;
  543. }
  544. rect.bottom += m_rectMargin.top + m_rectMargin.bottom + GetSystemMetrics(SM_CYVSCROLL);
  545. rect.right += m_rectMargin.left + m_rectMargin.right + GetSystemMetrics(SM_CXVSCROLL);
  546. if(m_imageViewer.m_pGdiplusBitmap)
  547. {
  548. int nWidth = m_imageViewer.m_pGdiplusBitmap->GetWidth();
  549. int nHeight = m_imageViewer.m_pGdiplusBitmap->GetHeight();
  550. rect.bottom += nHeight;
  551. if((rect.left + nWidth) > rect.right)
  552. {
  553. rect.right = rect.left + nWidth;
  554. }
  555. }
  556. DWORD diff = GetTickCount() - d;
  557. if (diff > 10)
  558. {
  559. Log(StrF(_T("Size To Content: %d\n"), diff));
  560. }
  561. return rect;
  562. }
  563. CString CToolTipEx::GetFieldFromString(CString ref, int nIndex, TCHAR ch)
  564. {
  565. CString strReturn;
  566. LPCTSTR pstrStart = ref.LockBuffer();
  567. LPCTSTR pstrBuffer = pstrStart;
  568. int nCurrent = 0;
  569. int nStart = 0;
  570. int nEnd = 0;
  571. int nOldStart = 0;
  572. while(nCurrent <= nIndex && *pstrBuffer != _T('\0'))
  573. {
  574. if(*pstrBuffer == ch)
  575. {
  576. nOldStart = nStart;
  577. nStart = nEnd + 1;
  578. nCurrent++;
  579. }
  580. nEnd++;
  581. pstrBuffer++;
  582. }
  583. // May have reached the end of the string
  584. if(*pstrBuffer == _T('\0'))
  585. {
  586. nOldStart = nStart;
  587. nEnd++;
  588. }
  589. ref.UnlockBuffer();
  590. if(nCurrent < nIndex)
  591. {
  592. //TRACE1("Warning: GetStringField - Couldn't find field %d.\n", nIndex);
  593. return strReturn;
  594. }
  595. return ref.Mid(nOldStart, nEnd - nOldStart - 1);
  596. }
  597. BOOL CToolTipEx::SetLogFont(LPLOGFONT lpLogFont, BOOL bRedraw /*=TRUE*/)
  598. {
  599. ASSERT(lpLogFont);
  600. if(!lpLogFont)
  601. {
  602. return FALSE;
  603. }
  604. LOGFONT LogFont;
  605. // Store font as the global default
  606. memcpy(&LogFont, lpLogFont, sizeof(LOGFONT));
  607. m_fontHeight = lpLogFont->lfHeight;
  608. LogFont.lfHeight = m_DittoWindow.m_dpi.Scale(LogFont.lfHeight);
  609. // Create the actual font object
  610. m_Font.DeleteObject();
  611. m_Font.CreateFontIndirect(&LogFont);
  612. if(bRedraw && ::IsWindow(GetSafeHwnd()))
  613. {
  614. Invalidate();
  615. }
  616. return TRUE;
  617. }
  618. void CToolTipEx::SetGdiplusBitmap(Gdiplus::Bitmap *gdiplusBitmap)
  619. {
  620. delete m_imageViewer.m_pGdiplusBitmap;
  621. m_imageViewer.m_pGdiplusBitmap = NULL;
  622. m_imageViewer.m_pGdiplusBitmap = gdiplusBitmap;
  623. m_imageViewer.UpdateBitmapSize(true);
  624. Invalidate();
  625. }
  626. void CToolTipEx::OnSize(UINT nType, int cx, int cy)
  627. {
  628. CWnd::OnSize(nType, cx, cy);
  629. if(::IsWindow(m_RichEdit.GetSafeHwnd()) == FALSE)
  630. {
  631. return ;
  632. }
  633. MoveControls();
  634. }
  635. void CToolTipEx::MoveControls()
  636. {
  637. CRect cr;
  638. GetClientRect(cr);
  639. int bottom = m_DittoWindow.m_dpi.Scale(22);
  640. int optionsExtra = 0;
  641. if (m_folderPath != _T(""))
  642. {
  643. bottom += m_DittoWindow.m_dpi.Scale(17);
  644. optionsExtra += m_DittoWindow.m_dpi.Scale(10);
  645. m_folderPathStatic.ShowWindow(SW_SHOW);
  646. }
  647. else
  648. {
  649. m_folderPathStatic.ShowWindow(SW_HIDE);
  650. }
  651. cr.DeflateRect(0, 0, 0, bottom);
  652. m_RichEdit.MoveWindow(cr);
  653. m_imageViewer.MoveWindow(cr);
  654. if (::IsWindow(m_browser.m_hWnd))
  655. {
  656. m_browser.MoveWindow(cr);
  657. }
  658. m_optionsButton.MoveWindow(cr.left, cr.bottom + m_DittoWindow.m_dpi.Scale(3) + optionsExtra, m_DittoWindow.m_dpi.Scale(17), m_DittoWindow.m_dpi.Scale(17));
  659. m_clipDataStatic.MoveWindow(cr.left + m_DittoWindow.m_dpi.Scale(19), cr.bottom + m_DittoWindow.m_dpi.Scale(4), cr.Width() - cr.left + m_DittoWindow.m_dpi.Scale(19), m_DittoWindow.m_dpi.Scale(20));
  660. m_folderPathStatic.MoveWindow(cr.left + m_DittoWindow.m_dpi.Scale(19), cr.bottom + m_DittoWindow.m_dpi.Scale(20), cr.Width() - cr.left + m_DittoWindow.m_dpi.Scale(19), m_DittoWindow.m_dpi.Scale(20));
  661. this->Invalidate();
  662. if (m_saveWindowLockout == false)
  663. {
  664. SetTimer(SAVE_SIZE, 250, NULL);
  665. }
  666. }
  667. BOOL CToolTipEx::IsCursorInToolTip()
  668. {
  669. CRect cr;
  670. GetWindowRect(cr);
  671. CPoint cursorPos;
  672. GetCursorPos(&cursorPos);
  673. return cr.PtInRect(cursorPos);
  674. }
  675. void CToolTipEx::SetHtmlText(const CString &html)
  676. {
  677. //OutputDebugString(_T("SetHtmlText-") + html.Left(20) + "\r\n");
  678. if (html.GetLength() > 0 &&
  679. ::IsWindow(m_browser.m_hWnd) == FALSE)
  680. {
  681. m_browser.Create(WS_CHILD | WS_VISIBLE, CRect(10, 10, 100, 200), this, 2);
  682. }
  683. if (::IsWindow(m_browser.m_hWnd))
  684. {
  685. int pos = html.Find(_T("<html"));
  686. if (pos >= 0)
  687. {
  688. m_html = html.Mid(pos);
  689. }
  690. else
  691. {
  692. int pos = html.Find(_T("<HTML"));
  693. if (pos >= 0)
  694. {
  695. m_html = html.Mid(pos);
  696. }
  697. else
  698. {
  699. m_html = html;
  700. }
  701. }
  702. COLORREF c = CGetSetOptions::m_Theme.DescriptionWindowBG();
  703. DWORD dwR = GetRValue(c);
  704. DWORD dwG = GetGValue(c);
  705. DWORD dwB = GetBValue(c);
  706. CString colorHex;
  707. colorHex.Format(_T("#%02X%02X%02X"), dwR, dwG, dwB);
  708. m_html.Replace(_T("<body>"), StrF(_T("<body bgcolor=\"%s\">"), colorHex));
  709. m_browser.PutSilent(true);
  710. m_browser.Clear();
  711. m_browser.Write(m_html);
  712. }
  713. }
  714. void CToolTipEx::SetRTFText(const CStringA &rtf)
  715. {
  716. //OutputDebugStringA("SetRTF-" + rtf.Left(20) + "\r\n");
  717. m_RichEdit.SetRTF(rtf);
  718. m_csRTF = rtf;
  719. m_RichEdit.SetSel(0, 0);
  720. HighlightSearchText();
  721. }
  722. //void CToolTipEx::SetRTFText(const CString &csRTF)
  723. //{
  724. // m_RichEdit.SetRTF(csRTF);
  725. // m_csRTF = csRTF;
  726. //}
  727. void CToolTipEx::SetToolTipText(const CString &csText)
  728. {
  729. //OutputDebugString(_T("SetRTF-") + csText.Left(20) + "\r\n");
  730. m_csText = csText;
  731. m_RichEdit.SetFont(&m_Font);
  732. m_RichEdit.SetText(csText);
  733. m_RichEdit.SetSel(0, 0);
  734. CHARFORMAT cfNew;
  735. cfNew.cbSize = sizeof(CHARFORMAT);
  736. cfNew.dwMask = CFM_COLOR;
  737. cfNew.dwEffects = CFM_COLOR;
  738. cfNew.dwEffects &= ~CFE_AUTOCOLOR;
  739. cfNew.crTextColor = CGetSetOptions::m_Theme.DescriptionWindowText();
  740. m_RichEdit.SetDefaultCharFormat(cfNew);
  741. HighlightSearchText();
  742. }
  743. void CToolTipEx::HighlightSearchText()
  744. {
  745. if (m_searchText.GetLength() <= 0)
  746. return;
  747. FINDTEXTEX ft;
  748. long n = -1;
  749. ft.lpstrText = m_searchText;
  750. ft.chrg.cpMin = 0;
  751. ft.chrg.cpMax = -1;
  752. CHARFORMAT cf;
  753. cf.cbSize = sizeof(cf);
  754. cf.dwMask = CFM_COLOR;
  755. cf.dwEffects = CFE_BOLD | ~CFE_AUTOCOLOR;
  756. cf.crTextColor = RGB(255, 0, 0);
  757. m_RichEdit.SetRedraw(0);
  758. auto mask = m_RichEdit.GetEventMask();
  759. m_RichEdit.SetEventMask(0);
  760. int matches = 0;
  761. do
  762. {
  763. ft.chrg.cpMin = n+1;
  764. n = m_RichEdit.FindText(FR_DOWN, &ft);
  765. if (n != -1)
  766. {
  767. m_RichEdit.SetSel(ft.chrgText);
  768. m_RichEdit.SetSelectionCharFormat(cf);
  769. }
  770. matches++;
  771. } while (n != -1 && matches < 100);
  772. m_RichEdit.SetSel(0, 0);
  773. m_RichEdit.SetEventMask(mask);
  774. m_RichEdit.SetRedraw(1);
  775. m_RichEdit.UpdateWindow();
  776. }
  777. void CToolTipEx::DoSearch()
  778. {
  779. if (m_searchText.GetLength() <= 0)
  780. return;
  781. FINDTEXTEX ft;
  782. long n = -1;
  783. ft.lpstrText = m_searchText;
  784. long start;
  785. long end;
  786. m_RichEdit.GetSel(start, end);
  787. ft.chrg.cpMin = end;
  788. ft.chrg.cpMax = -1;
  789. int searchDirection = FR_DOWN;
  790. if (GetKeyState(VK_SHIFT) & 0x8000)
  791. {
  792. searchDirection = 0;
  793. ft.chrg.cpMin = start;
  794. }
  795. n = m_RichEdit.FindText(searchDirection, &ft);
  796. if (n != -1)
  797. {
  798. //if needing to scroll back to the left make sure the full text is visible
  799. //setSel scrolls to the end of the selection
  800. int start = ft.chrgText.cpMin;
  801. if (start < 0)
  802. {
  803. start = 0;
  804. }
  805. m_RichEdit.SetSel(start, start);
  806. m_RichEdit.SetSel(ft.chrgText);
  807. }
  808. else
  809. {
  810. if (searchDirection == 0)
  811. {
  812. ft.chrg.cpMin = m_RichEdit.GetTextLength();
  813. }
  814. else
  815. {
  816. ft.chrg.cpMin = 0;
  817. }
  818. ft.chrg.cpMax = -1;
  819. n = m_RichEdit.FindText(searchDirection, &ft);
  820. if (n != -1)
  821. {
  822. //if needing to scroll back to the left make sure the full text is visible
  823. //setSel scrolls to the end of the selection
  824. int start = ft.chrgText.cpMin;
  825. if (start < 0)
  826. {
  827. start = 0;
  828. }
  829. m_RichEdit.SetSel(start, start);
  830. m_RichEdit.SetSel(ft.chrgText);
  831. }
  832. }
  833. }
  834. void CToolTipEx::OnActivate(UINT nState, CWnd *pWndOther, BOOL bMinimized)
  835. {
  836. CWnd::OnActivate(nState, pWndOther, bMinimized);
  837. if (nState == WA_INACTIVE)
  838. {
  839. if(m_pNotifyWnd)
  840. {
  841. m_pNotifyWnd->PostMessage(NM_INACTIVE_TOOLTIPWND, 0, 0);
  842. }
  843. }
  844. }
  845. void CToolTipEx::OnTimer(UINT_PTR nIDEvent)
  846. {
  847. switch(nIDEvent)
  848. {
  849. case HIDE_WINDOW_TIMER:
  850. Hide();
  851. PostMessage(WM_DESTROY, 0, 0);
  852. break;
  853. case SAVE_SIZE:
  854. SaveWindowSize();
  855. KillTimer(SAVE_SIZE);
  856. break;
  857. case TIMER_BUTTON_UP:
  858. {
  859. if ((GetKeyState(VK_LBUTTON) & 0x100) == 0)
  860. {
  861. m_DittoWindow.DoNcLButtonUp(this, 0, CPoint(0, 0));
  862. KillTimer(TIMER_BUTTON_UP);
  863. auto f = GetFocus();
  864. if (f != NULL &&
  865. m_RichEdit.m_hWnd != f->m_hWnd)
  866. {
  867. auto p = GetParent();
  868. if (p != NULL)
  869. {
  870. p->SetFocus();
  871. }
  872. }
  873. }
  874. break;
  875. }
  876. case TIMER_AUTO_MAX:
  877. {
  878. if (m_DittoWindow.m_bMinimized)
  879. {
  880. CPoint cp;
  881. GetCursorPos(&cp);
  882. UINT nHitTest = (UINT)OnNcHitTest(cp);
  883. ScreenToClient(&cp);
  884. if (nHitTest == HTCAPTION)
  885. {
  886. if (m_DittoWindow.m_crCloseBT.PtInRect(cp) == false)
  887. {
  888. if (m_DittoWindow.m_crMinimizeBT.PtInRect(cp) == false)
  889. {
  890. m_DittoWindow.MinMaxWindow(this, FORCE_MAX);
  891. }
  892. }
  893. }
  894. }
  895. KillTimer(TIMER_AUTO_MAX);
  896. m_bMaxSetTimer = false;
  897. }
  898. }
  899. CWnd::OnTimer(nIDEvent);
  900. }
  901. void CToolTipEx::OnNcPaint()
  902. {
  903. m_DittoWindow.DoNcPaint(this);
  904. }
  905. void CToolTipEx::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp)
  906. {
  907. CWnd::OnNcCalcSize(bCalcValidRects, lpncsp);
  908. m_DittoWindow.DoNcCalcSize(bCalcValidRects, lpncsp);
  909. }
  910. HITTEST_RET CToolTipEx::OnNcHitTest(CPoint point)
  911. {
  912. UINT Ret = m_DittoWindow.DoNcHitTest(this, point);
  913. if(Ret == -1)
  914. return CWnd::OnNcHitTest(point);
  915. return Ret;
  916. }
  917. void CToolTipEx::OnNcLButtonDown(UINT nHitTest, CPoint point)
  918. {
  919. int buttonPressed = m_DittoWindow.DoNcLButtonDown(this, nHitTest, point);
  920. SetTimer(TIMER_BUTTON_UP, 100, NULL);
  921. CWnd::OnNcLButtonDown(nHitTest, point);
  922. }
  923. void CToolTipEx::OnNcLButtonUp(UINT nHitTest, CPoint point)
  924. {
  925. long lRet = m_DittoWindow.DoNcLButtonUp(this, nHitTest, point);
  926. switch(lRet)
  927. {
  928. case BUTTON_CLOSE:
  929. Hide();
  930. break;
  931. case BUTTON_CHEVRON:
  932. m_DittoWindow.MinMaxWindow(this, SWAP_MIN_MAX);
  933. OnNcPaint();
  934. break;
  935. }
  936. KillTimer(TIMER_BUTTON_UP);
  937. auto f = GetFocus();
  938. if (f != NULL &&
  939. m_RichEdit.m_hWnd != f->m_hWnd)
  940. {
  941. auto p = GetParent();
  942. if (p != NULL)
  943. {
  944. p->SetFocus();
  945. }
  946. }
  947. CWnd::OnNcLButtonUp(nHitTest, point);
  948. }
  949. void CToolTipEx::OnNcMouseMove(UINT nHitTest, CPoint point)
  950. {
  951. m_DittoWindow.DoNcMouseMove(this, nHitTest, point);
  952. if ((m_bMaxSetTimer == false) && m_DittoWindow.m_bMinimized)
  953. {
  954. COleDateTimeSpan sp = COleDateTime::GetCurrentTime() - m_DittoWindow.m_TimeMinimized;
  955. if (sp.GetTotalSeconds() >= m_lDelayMaxSeconds)
  956. {
  957. SetTimer(TIMER_AUTO_MAX, CGetSetOptions::GetTimeBeforeExpandWindow(), NULL);
  958. m_bMaxSetTimer = true;
  959. }
  960. }
  961. CWnd::OnNcMouseMove(nHitTest, point);
  962. }
  963. void CToolTipEx::OnOptions()
  964. {
  965. POINT pp;
  966. CMenu cmPopUp;
  967. CMenu *cmSubMenu = NULL;
  968. GetCursorPos(&pp);
  969. if(cmPopUp.LoadMenu(IDR_DESC_OPTIONS_MENU) != 0)
  970. {
  971. cmSubMenu = cmPopUp.GetSubMenu(0);
  972. if(!cmSubMenu)
  973. {
  974. return ;
  975. }
  976. GetCursorPos(&pp);
  977. //theApp.m_Language.UpdateRightClickMenu(cmSubMenu);
  978. if(CGetSetOptions::GetRememberDescPos())
  979. cmSubMenu->CheckMenuItem(ID_FIRST_REMEMBERWINDOWPOSITION, MF_CHECKED);
  980. if(CGetSetOptions::GetSizeDescWindowToContent())
  981. cmSubMenu->CheckMenuItem(ID_FIRST_SIZEWINDOWTOCONTENT, MF_CHECKED);
  982. if(CGetSetOptions::GetScaleImagesToDescWindow())
  983. cmSubMenu->CheckMenuItem(ID_FIRST_SCALEIMAGESTOFITWINDOW, MF_CHECKED);
  984. if (CGetSetOptions::GetMouseClickHidesDescription())
  985. cmSubMenu->CheckMenuItem(ID_FIRST_HIDEDESCRIPTIONWINDOWONM, MF_CHECKED);
  986. if (m_showPersistant)
  987. cmSubMenu->CheckMenuItem(ID_FIRST_ALWAYSONTOP, MF_CHECKED);
  988. if (m_showingText)
  989. {
  990. cmSubMenu->CheckMenuItem(ID_FIRST_VIEWTEXT, MF_CHECKED);
  991. }
  992. if (m_csText.GetLength() <= 0)
  993. {
  994. cmSubMenu->EnableMenuItem(ID_FIRST_VIEWTEXT, MF_DISABLED);
  995. }
  996. if (m_showingRTF)
  997. {
  998. cmSubMenu->CheckMenuItem(ID_FIRST_VIEWRTF, MF_CHECKED);
  999. }
  1000. if (m_csRTF.GetLength() <= 0)
  1001. {
  1002. cmSubMenu->EnableMenuItem(ID_FIRST_VIEWRTF, MF_DISABLED);
  1003. }
  1004. if (m_showingHTML)
  1005. {
  1006. cmSubMenu->CheckMenuItem(ID_FIRST_VIEWHTML, MF_CHECKED);
  1007. }
  1008. if (m_html.GetLength() <= 0)
  1009. {
  1010. cmSubMenu->EnableMenuItem(ID_FIRST_VIEWHTML, MF_DISABLED);
  1011. }
  1012. if (m_showingImage)
  1013. {
  1014. cmSubMenu->CheckMenuItem(ID_FIRST_VIEWASIMAGE, MF_CHECKED);
  1015. }
  1016. if (m_imageViewer.m_pGdiplusBitmap == NULL)
  1017. {
  1018. cmSubMenu->EnableMenuItem(ID_FIRST_VIEWASIMAGE, MF_DISABLED);
  1019. }
  1020. UpdateMenuShortCut(cmSubMenu, ID_FIRST_WRAPTEXT, ActionEnums::TOGGLE_DESCRIPTION_WORD_WRAP);
  1021. UpdateMenuShortCut(cmSubMenu, ID_FIRST_ALWAYSONTOP, ActionEnums::TOGGLESHOWPERSISTANT);
  1022. if (CGetSetOptions::GetWrapDescriptionText())
  1023. cmSubMenu->CheckMenuItem(ID_FIRST_WRAPTEXT, MF_CHECKED);
  1024. cmSubMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON, pp.x, pp.y, this, NULL);
  1025. }
  1026. }
  1027. void CToolTipEx::UpdateMenuShortCut(CMenu *subMenu, int id, DWORD action)
  1028. {
  1029. if (m_pToolTipActions != NULL)
  1030. {
  1031. CString cs;
  1032. subMenu->GetMenuString(id, cs, MF_BYCOMMAND);
  1033. CString shortcutText = m_pToolTipActions->GetCmdKeyText(action);
  1034. if (shortcutText != _T("") &&
  1035. cs.Find("\t" + shortcutText) < 0)
  1036. {
  1037. cs += "\t";
  1038. cs += shortcutText;
  1039. subMenu->ModifyMenu(id, MF_BYCOMMAND, id, cs);
  1040. }
  1041. }
  1042. }
  1043. void CToolTipEx::OnRememberwindowposition()
  1044. {
  1045. CGetSetOptions::SetRememberDescPos(!CGetSetOptions::GetRememberDescPos());
  1046. }
  1047. void CToolTipEx::OnSizewindowtocontent()
  1048. {
  1049. CGetSetOptions::SetSizeDescWindowToContent(!CGetSetOptions::GetSizeDescWindowToContent());
  1050. CRect rect;
  1051. this->GetWindowRect(&rect);
  1052. Show(rect.TopLeft());
  1053. }
  1054. void CToolTipEx::OnScaleimagestofitwindow()
  1055. {
  1056. CGetSetOptions::SetScaleImagesToDescWindow(!CGetSetOptions::GetScaleImagesToDescWindow());
  1057. m_imageViewer.UpdateBitmapSize(true);
  1058. Invalidate();
  1059. }
  1060. void CToolTipEx::OnRButtonDown(UINT nFlags, CPoint point)
  1061. {
  1062. OnOptions();
  1063. CWnd::OnRButtonDown(nFlags, point);
  1064. }
  1065. void CToolTipEx::OnSetFocus(CWnd* pOldWnd)
  1066. {
  1067. CWnd::OnSetFocus(pOldWnd);
  1068. if (m_RichEdit.IsWindowVisible())
  1069. {
  1070. m_RichEdit.SetFocus();
  1071. }
  1072. }
  1073. void CToolTipEx::OnPaint()
  1074. {
  1075. CPaintDC dc(this); // device context for painting
  1076. CRect rect;
  1077. GetClientRect(rect);
  1078. CBrush Brush, *pOldBrush;
  1079. Brush.CreateSolidBrush(CGetSetOptions::m_Theme.DescriptionWindowBG());
  1080. pOldBrush = dc.SelectObject(&Brush);
  1081. dc.FillRect(&rect, &Brush);
  1082. // Cleanup
  1083. dc.SelectObject(pOldBrush);
  1084. }
  1085. void CToolTipEx::OnFirstHidedescriptionwindowonm()
  1086. {
  1087. CGetSetOptions::SetMouseClickHidesDescription(!CGetSetOptions::GetMouseClickHidesDescription());
  1088. }
  1089. bool CToolTipEx::ToggleWordWrap()
  1090. {
  1091. bool didWordWrap = false;
  1092. if (m_RichEdit.IsWindowVisible())
  1093. {
  1094. OnFirstWraptext();
  1095. didWordWrap = true;
  1096. }
  1097. return didWordWrap;
  1098. }
  1099. void CToolTipEx::OnFirstWraptext()
  1100. {
  1101. CGetSetOptions::SetWrapDescriptionText(!CGetSetOptions::GetWrapDescriptionText());
  1102. ApplyWordWrap();
  1103. }
  1104. void CToolTipEx::ApplyWordWrap()
  1105. {
  1106. if (CGetSetOptions::GetWrapDescriptionText())
  1107. {
  1108. m_RichEdit.SetTargetDevice(NULL, 0);
  1109. }
  1110. else
  1111. {
  1112. m_RichEdit.SetTargetDevice(NULL, 1);
  1113. }
  1114. }
  1115. void CToolTipEx::HideWindowInXMilliSeconds(long lms)
  1116. {
  1117. SetTimer(HIDE_WINDOW_TIMER, lms, NULL);
  1118. }
  1119. void CToolTipEx::OnWindowPosChanging(WINDOWPOS* lpwndpos)
  1120. {
  1121. CWnd::OnWindowPosChanging(lpwndpos);
  1122. //m_DittoWindow.SnapToEdge(this, lpwndpos);
  1123. }
  1124. void CToolTipEx::OnFirstAlwaysontop()
  1125. {
  1126. m_showPersistant = !m_showPersistant;
  1127. if (m_showPersistant)
  1128. {
  1129. m_DittoWindow.m_customWindowTitle = _T("[Always on top]");
  1130. m_DittoWindow.m_useCustomWindowTitle = true;
  1131. ::SetWindowPos(m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW | SWP_NOACTIVATE);
  1132. }
  1133. else
  1134. {
  1135. m_DittoWindow.m_customWindowTitle = _T("");
  1136. m_DittoWindow.m_useCustomWindowTitle = true;
  1137. }
  1138. ::SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0, SWP_DRAWFRAME | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
  1139. }
  1140. BOOL CToolTipEx::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
  1141. {
  1142. //CString cs;
  1143. //cs.Format(_T("On Notify: %d\r\n"), ((LPNMHDR)lParam)->code);
  1144. //OutputDebugString(cs);
  1145. switch (((LPNMHDR)lParam)->code)
  1146. {
  1147. case EN_LINK:
  1148. {
  1149. ENLINK *enLinkInfo = (ENLINK *)lParam; // pointer to a ENLINK structure
  1150. if (enLinkInfo->msg == WM_LBUTTONUP)
  1151. {
  1152. CString s;
  1153. m_RichEdit.GetTextRange(enLinkInfo->chrg.cpMin, enLinkInfo->chrg.cpMax, s);
  1154. if (s == m_mouseDownOnLink)
  1155. {
  1156. CHyperLink::GotoURL(s, SW_SHOW);
  1157. }
  1158. m_mouseDownOnLink = _T("");
  1159. }
  1160. if (enLinkInfo->msg == WM_LBUTTONDOWN)
  1161. {
  1162. m_RichEdit.GetTextRange(enLinkInfo->chrg.cpMin, enLinkInfo->chrg.cpMax, m_mouseDownOnLink);
  1163. }
  1164. }
  1165. break;
  1166. case SimpleBrowser::NotificationType::BeforeNavigate2:
  1167. {
  1168. SimpleBrowser::Notification * not = (SimpleBrowser::Notification *)lParam;
  1169. if (not != NULL)
  1170. {
  1171. if (not->URL.Find(_T("http")) >= 0)
  1172. {
  1173. CHyperLink::GotoURL(not->URL, SW_SHOW);
  1174. *pResult = TRUE;
  1175. //return TRUE;
  1176. }
  1177. }
  1178. }
  1179. break;
  1180. case 5:
  1181. int x = 0;
  1182. break;
  1183. }
  1184. return CWnd::OnNotify(wParam, lParam, pResult);
  1185. }
  1186. void CToolTipEx::OnEnMsgfilterRichedit21(NMHDR *pNMHDR, LRESULT *pResult)
  1187. {
  1188. MSGFILTER *pMsgFilter = reinterpret_cast<MSGFILTER *>(pNMHDR);
  1189. if (pMsgFilter != NULL)
  1190. {
  1191. switch (pMsgFilter->msg)
  1192. {
  1193. //handle click on the rich text control when it doesn't have focus
  1194. //set focus so the first click is handled by the rich text control
  1195. case WM_MOUSEACTIVATE:
  1196. m_RichEdit.SetFocus();
  1197. break;
  1198. case WM_MOUSEHWHEEL:
  1199. int delta = GET_WHEEL_DELTA_WPARAM(pMsgFilter->wParam);
  1200. if (delta < 0)
  1201. {
  1202. m_RichEdit.SendMessage(WM_HSCROLL, SB_LINERIGHT, NULL);
  1203. }
  1204. else
  1205. {
  1206. m_RichEdit.SendMessage(WM_HSCROLL, SB_LINELEFT, NULL);
  1207. }
  1208. break;
  1209. }
  1210. }
  1211. *pResult = 0;
  1212. }
  1213. LRESULT CToolTipEx::OnDpiChanged(WPARAM wParam, LPARAM lParam)
  1214. {
  1215. int dpi = HIWORD(wParam);
  1216. m_DittoWindow.OnDpiChanged(this, dpi);
  1217. RECT* const prcNewWindow = (RECT*)lParam;
  1218. SetWindowPos(NULL,
  1219. prcNewWindow->left,
  1220. prcNewWindow->top,
  1221. prcNewWindow->right - prcNewWindow->left,
  1222. prcNewWindow->bottom - prcNewWindow->top,
  1223. SWP_NOZORDER | SWP_NOACTIVATE);
  1224. log(StrF(_T("CQPasteWnd::OnDpiChanged dpi: %d width: %d, height: %d"), dpi, (prcNewWindow->right - prcNewWindow->left), (prcNewWindow->bottom - prcNewWindow->top)));
  1225. m_optionsButton.Reset();
  1226. m_optionsButton.LoadStdImageDPI(m_DittoWindow.m_dpi.GetDPI(), IDB_COG_16_16, IDB_COG_20_20, IDB_COG_24_24, cog_28, IDB_COG_32_32, _T("PNG"));
  1227. m_clipDataFont.DeleteObject();
  1228. m_clipDataFont.CreateFont(-m_DittoWindow.m_dpi.Scale(8), 0, 0, 0, 400, 0, 0, 0, DEFAULT_CHARSET, 3, 2, 1, 34, _T("Segoe UI"));
  1229. m_clipDataStatic.SetFont(&m_clipDataFont);
  1230. m_clipDataStatic.SetBkColor(CGetSetOptions::m_Theme.DescriptionWindowBG());
  1231. m_clipDataStatic.SetTextColor(RGB(80, 80, 80));
  1232. m_folderPathStatic.SetFont(&m_clipDataFont);
  1233. m_folderPathStatic.SetBkColor(CGetSetOptions::m_Theme.DescriptionWindowBG());
  1234. m_folderPathStatic.SetTextColor(RGB(80, 80, 80));
  1235. LOGFONT lf;
  1236. m_Font.GetLogFont(&lf);
  1237. lf.lfHeight = m_DittoWindow.m_dpi.Scale(m_fontHeight);
  1238. // Create the actual font object
  1239. m_Font.DeleteObject();
  1240. m_Font.CreateFontIndirect(&lf);
  1241. m_RichEdit.SetFont(&m_Font);
  1242. this->MoveControls();
  1243. this->Invalidate();
  1244. this->UpdateWindow();
  1245. return TRUE;
  1246. }
  1247. void CToolTipEx::OnMoving(UINT fwSide, LPRECT pRect)
  1248. {
  1249. CWnd::OnMoving(fwSide, pRect);
  1250. m_snap.OnSnapMoving(m_hWnd, pRect);
  1251. // TODO: Add your message handler code here
  1252. }
  1253. void CToolTipEx::OnEnterSizeMove()
  1254. {
  1255. m_snap.OnSnapEnterSizeMove(m_hWnd);
  1256. CWnd::OnEnterSizeMove();
  1257. }
  1258. void CToolTipEx::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
  1259. {
  1260. int x = 9;
  1261. //m_scrollHelper.OnHScroll(nSBCode, nPos, pScrollBar);
  1262. }
  1263. LRESULT CToolTipEx::OnRefreshFooter(WPARAM wParam, LPARAM lParam)
  1264. {
  1265. m_clipData = m_originalClipData;
  1266. if (m_imageViewer.m_pGdiplusBitmap)
  1267. {
  1268. int percent = ((m_imageViewer.m_scale) * 100.0) + .5;
  1269. m_clipData = m_originalClipData + _T(" | ") + StrF(_T("%d x %d, %d%%"), m_imageViewer.m_pGdiplusBitmap->GetWidth(), m_imageViewer.m_pGdiplusBitmap->GetHeight(), percent);
  1270. }
  1271. m_clipDataStatic.SetWindowText(m_clipData);
  1272. m_clipDataStatic.Invalidate();
  1273. this->Invalidate();
  1274. return TRUE;
  1275. }
  1276. void CToolTipEx::OnFirstViewtext()
  1277. {
  1278. if (::IsWindow(m_browser.m_hWnd))
  1279. {
  1280. m_browser.ShowWindow(SW_HIDE);
  1281. }
  1282. m_imageViewer.ShowWindow(SW_HIDE);
  1283. m_RichEdit.SetText(m_csText);
  1284. m_RichEdit.SetSel(0, 0);
  1285. HighlightSearchText();
  1286. m_RichEdit.ShowWindow(SW_SHOW);
  1287. this->Invalidate();
  1288. this->UpdateWindow();
  1289. m_showingText = true;
  1290. m_showingRTF = false;
  1291. m_showingHTML = false;
  1292. m_showingImage = false;
  1293. }
  1294. void CToolTipEx::OnFirstViewrtf()
  1295. {
  1296. if (::IsWindow(m_browser.m_hWnd))
  1297. {
  1298. m_browser.ShowWindow(SW_HIDE);
  1299. }
  1300. m_imageViewer.ShowWindow(SW_HIDE);
  1301. m_RichEdit.SetRTF(m_csRTF);
  1302. m_RichEdit.SetSel(0, 0);
  1303. HighlightSearchText();
  1304. m_RichEdit.ShowWindow(SW_SHOW);
  1305. this->Invalidate();
  1306. this->UpdateWindow();
  1307. m_showingText = false;
  1308. m_showingRTF = true;
  1309. m_showingHTML = false;
  1310. m_showingImage = false;
  1311. }
  1312. void CToolTipEx::OnFirstViewhtml()
  1313. {
  1314. m_imageViewer.ShowWindow(SW_HIDE);
  1315. m_RichEdit.ShowWindow(SW_HIDE);
  1316. if (::IsWindow(m_browser.m_hWnd))
  1317. {
  1318. m_browser.ShowWindow(SW_SHOW);
  1319. }
  1320. m_showingText = false;
  1321. m_showingRTF = false;
  1322. m_showingHTML = true;
  1323. m_showingImage = false;
  1324. }
  1325. void CToolTipEx::OnFirstViewImage()
  1326. {
  1327. m_RichEdit.ShowWindow(SW_HIDE);
  1328. if (::IsWindow(m_browser.m_hWnd))
  1329. {
  1330. m_browser.ShowWindow(SW_HIDE);
  1331. }
  1332. if (m_imageViewer.m_pGdiplusBitmap)
  1333. {
  1334. m_imageViewer.UpdateBitmapSize(true);
  1335. m_imageViewer.ShowWindow(SW_SHOW);
  1336. }
  1337. m_showingText = false;
  1338. m_showingRTF = false;
  1339. m_showingHTML = false;
  1340. m_showingImage = true;
  1341. }
  1342. void CToolTipEx::OnUpdateFirstViewtext(CCmdUI* pCmdUI)
  1343. {
  1344. if (m_csText.IsEmpty())
  1345. {
  1346. pCmdUI->Enable(0);
  1347. }
  1348. }
  1349. void CToolTipEx::OnUpdateFirstViewrtf(CCmdUI* pCmdUI)
  1350. {
  1351. if (m_csRTF.IsEmpty())
  1352. {
  1353. pCmdUI->Enable(0);
  1354. }
  1355. }
  1356. void CToolTipEx::OnUpdateFirstViewhtml(CCmdUI* pCmdUI)
  1357. {
  1358. if (m_html.IsEmpty())
  1359. {
  1360. pCmdUI->Enable(0);
  1361. }
  1362. }