ToolTipEx.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719
  1. #include "stdafx.h"
  2. #include "cp_main.h"
  3. #include "ToolTipEx.h"
  4. #include "BitmapHelper.h"
  5. #include "Options.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. #define DELETE_BITMAP if(m_pBitmap) \
  12. { \
  13. m_pBitmap->DeleteObject(); \
  14. delete m_pBitmap; \
  15. m_pBitmap = NULL; \
  16. }
  17. /////////////////////////////////////////////////////////////////////////////
  18. // CToolTipEx
  19. CToolTipEx::CToolTipEx(): m_dwTextStyle(DT_EXPANDTABS | DT_EXTERNALLEADING |
  20. DT_NOPREFIX | DT_WORDBREAK), m_rectMargin(2, 2, 3, 3),
  21. m_pBitmap(NULL), m_pNotifyWnd(NULL){}
  22. CToolTipEx::~CToolTipEx()
  23. {
  24. DELETE_BITMAP
  25. m_Font.DeleteObject();
  26. }
  27. BEGIN_MESSAGE_MAP(CToolTipEx, CWnd)
  28. //{{AFX_MSG_MAP(CToolTipEx)
  29. ON_WM_PAINT()
  30. ON_WM_SIZE()
  31. ON_WM_NCHITTEST()
  32. ON_WM_ACTIVATE()
  33. ON_WM_TIMER()
  34. ON_WM_NCPAINT()
  35. ON_WM_NCCALCSIZE()
  36. ON_WM_NCLBUTTONDOWN()
  37. ON_WM_NCMOUSEMOVE()
  38. ON_WM_NCLBUTTONUP()
  39. ON_WM_ERASEBKGND()
  40. ON_COMMAND(ID_FIRST_REMEMBERWINDOWPOSITION, &CToolTipEx::OnRememberwindowposition)
  41. ON_COMMAND(ID_FIRST_SIZEWINDOWTOCONTENT, &CToolTipEx::OnSizewindowtocontent)
  42. ON_COMMAND(ID_FIRST_SCALEIMAGESTOFITWINDOW, &CToolTipEx::OnScaleimagestofitwindow)
  43. ON_COMMAND(2, OnOptions)
  44. END_MESSAGE_MAP()
  45. /////////////////////////////////////////////////////////////////////////////
  46. // CToolTipEx message handlers
  47. BOOL CToolTipEx::Create(CWnd *pParentWnd)
  48. {
  49. // Get the class name and create the window
  50. CString szClassName = AfxRegisterWndClass(CS_CLASSDC | CS_SAVEBITS,
  51. LoadCursor(NULL, IDC_ARROW));
  52. // Create the window - just don't show it yet.
  53. if( !CWnd::CreateEx(WS_EX_TOPMOST, szClassName, _T(""), WS_POPUP | WS_BORDER,
  54. 0, 0, 10, 10, // size & position updated when needed
  55. pParentWnd->GetSafeHwnd(), 0, NULL))
  56. {
  57. return FALSE;
  58. }
  59. m_DittoWindow.DoCreate(this);
  60. m_DittoWindow.SetCaptionColors(g_Opt.m_Theme.CaptionLeft(), g_Opt.m_Theme.CaptionRight());
  61. m_DittoWindow.SetCaptionOn(this, CAPTION_LEFT, true);
  62. m_DittoWindow.m_bDrawMinimize = false;
  63. m_DittoWindow.m_bDrawMinimize = false;
  64. m_DittoWindow.m_bDrawChevron = false;
  65. m_DittoWindow.m_sendWMClose = false;
  66. m_RichEdit.Create(_T(""), _T(""), WS_CHILD | WS_VISIBLE | WS_VSCROLL |
  67. WS_HSCROLL | ES_MULTILINE | ES_AUTOVSCROLL |
  68. ES_AUTOHSCROLL, CRect(10, 10, 100, 200), this, 1);
  69. m_RichEdit.SetReadOnly();
  70. m_RichEdit.SetBackgroundColor(FALSE, GetSysColor(COLOR_INFOBK));
  71. SetLogFont(GetSystemToolTipFont(), FALSE);
  72. m_optionsButton.Create(NULL, WS_CHILD | BS_OWNERDRAW | WS_TABSTOP, CRect(0, 0, 0, 0), this, 2);
  73. m_optionsButton.LoadStdImageDPI(IDB_COG_16_16, IDB_COG_20_20, IDB_COG_24_24, IDB_COG_32_32, _T("PNG"));
  74. m_optionsButton.SetToolTipText(theApp.m_Language.GetString(_T("DescriptionOptionsTooltip"), _T("Description Options")));
  75. m_optionsButton.ShowWindow(SW_SHOW);
  76. return TRUE;
  77. }
  78. BOOL CToolTipEx::Show(CPoint point)
  79. {
  80. m_reducedWindowSize = false;
  81. if(m_pBitmap)
  82. {
  83. m_RichEdit.ShowWindow(SW_HIDE);
  84. }
  85. else
  86. {
  87. m_RichEdit.ShowWindow(SW_SHOW);
  88. }
  89. CRect rect;
  90. if(CGetSetOptions::GetSizeDescWindowToContent() == FALSE)
  91. {
  92. rect.left = point.x;
  93. rect.top = point.y;
  94. CSize size;
  95. CGetSetOptions::GetDescWndSize(size);
  96. rect.right = rect.left + size.cx;
  97. rect.bottom = rect.top + size.cy;
  98. EnsureWindowVisible(&rect);
  99. }
  100. else
  101. {
  102. rect = GetBoundsRect();
  103. //account for the scroll bars
  104. rect.right += 20;
  105. rect.bottom += 20;
  106. if (m_pBitmap)
  107. {
  108. int nWidth = CBitmapHelper::GetCBitmapWidth(*m_pBitmap);
  109. int nHeight = CBitmapHelper::GetCBitmapHeight(*m_pBitmap);
  110. rect.right = rect.left + nWidth;
  111. rect.bottom = rect.top + nHeight;
  112. }
  113. else if(m_csRTF != "")
  114. {
  115. //if showing rtf then increase the size because
  116. //rtf will probably draw bigger
  117. long lNewWidth = (long)rect.Width() + (long)(rect.Width() *.3);
  118. rect.right = rect.left + lNewWidth;
  119. long lNewHeight = rect.Height() + (rect.Height() *1);
  120. rect.bottom = rect.top + lNewHeight;
  121. }
  122. rect.right += CAPTION_BORDER * 2;
  123. rect.bottom += CAPTION_BORDER * 2;
  124. CRect rcScreen;
  125. ClientToScreen(rect);
  126. CRect cr(point, point);
  127. int nMonitor = GetMonitorFromRect(&cr);
  128. GetMonitorRect(nMonitor, &rcScreen);
  129. //ensure that we don't go outside the screen
  130. if(point.x < 0)
  131. {
  132. point.x = 5;
  133. m_reducedWindowSize = true;
  134. }
  135. if(point.y < 0)
  136. {
  137. point.y = 5;
  138. m_reducedWindowSize = true;
  139. }
  140. rcScreen.DeflateRect(0, 0, 5, 5);
  141. long lWidth = rect.Width();
  142. long lHeight = rect.Height();
  143. rect.left = point.x;
  144. rect.top = point.y;
  145. rect.right = rect.left + lWidth;
  146. rect.bottom = rect.top + lHeight;
  147. if(rect.right > rcScreen.right)
  148. {
  149. int diff = rect.right - rcScreen.right;
  150. int newLeft = rect.left - diff;
  151. if(newLeft > 0)
  152. {
  153. rect.left = newLeft;
  154. }
  155. rect.right = rcScreen.right;
  156. m_reducedWindowSize = true;
  157. }
  158. if(rect.bottom > rcScreen.bottom)
  159. {
  160. int diff = rect.bottom - rcScreen.bottom;
  161. int newTop = rect.top - diff;
  162. if(newTop > 0)
  163. {
  164. rect.top = newTop;
  165. }
  166. rect.bottom = rcScreen.bottom;
  167. m_reducedWindowSize = true;
  168. }
  169. }
  170. SetWindowPos(&CWnd::wndTopMost, rect.left, rect.top, rect.Width(), rect.Height
  171. (), SWP_SHOWWINDOW | SWP_NOCOPYBITS | SWP_NOACTIVATE |
  172. SWP_NOZORDER);
  173. return TRUE;
  174. }
  175. BOOL CToolTipEx::Hide()
  176. {
  177. DELETE_BITMAP
  178. ShowWindow(SW_HIDE);
  179. m_csRTF = "";
  180. m_csText = "";
  181. CRect rect;
  182. this->GetWindowRect(&rect);
  183. CGetSetOptions::SetDescWndSize(rect.Size());
  184. CGetSetOptions::SetDescWndPoint(rect.TopLeft());
  185. return TRUE;
  186. }
  187. void CToolTipEx::OnPaint()
  188. {
  189. CPaintDC dc(this); // device context for painting
  190. CRect rect;
  191. GetClientRect(rect);
  192. // Draw Text
  193. // dc.SetBkMode(TRANSPARENT);
  194. // rect.DeflateRect(m_rectMargin);
  195. CBrush Brush, *pOldBrush;
  196. Brush.CreateSolidBrush(GetSysColor(COLOR_INFOBK));
  197. pOldBrush = dc.SelectObject(&Brush);
  198. CFont *pOldFont = dc.SelectObject(&m_Font);
  199. dc.FillRect(&rect, &Brush);
  200. if(m_pBitmap)
  201. {
  202. CDC MemDc;
  203. MemDc.CreateCompatibleDC(&dc);
  204. CBitmap *oldBitmap = MemDc.SelectObject(m_pBitmap);
  205. int nWidth = CBitmapHelper::GetCBitmapWidth(*m_pBitmap);
  206. int nHeight = CBitmapHelper::GetCBitmapHeight(*m_pBitmap);
  207. if(CGetSetOptions::GetScaleImagesToDescWindow())
  208. {
  209. dc.StretchBlt(rect.left, rect.top, rect.Width(), rect.Height(), &MemDc, 0, 0, nWidth, nWidth, SRCCOPY);
  210. }
  211. else
  212. {
  213. dc.BitBlt(rect.left, rect.top, nWidth, nHeight, &MemDc, 0, 0, SRCCOPY);
  214. }
  215. //dc.StretchBlt(rect.left, rect.top, rect.Width(), rect.Height(), &MemDc, 0, 0, nWidth, nHeight, SRCCOPY);
  216. MemDc.SelectObject(oldBitmap);
  217. rect.top += nHeight;
  218. }
  219. //dc.DrawText(m_csText, rect, m_dwTextStyle);
  220. // Cleanup
  221. // dc.SelectObject(pOldBrush);
  222. // dc.SelectObject(pOldFont);
  223. }
  224. void CToolTipEx::PostNcDestroy()
  225. {
  226. CWnd::PostNcDestroy();
  227. delete this;
  228. }
  229. BOOL CToolTipEx::PreTranslateMessage(MSG *pMsg)
  230. {
  231. m_DittoWindow.DoPreTranslateMessage(pMsg);
  232. switch(pMsg->message)
  233. {
  234. case WM_KEYDOWN:
  235. switch(pMsg->wParam)
  236. {
  237. case VK_ESCAPE:
  238. Hide();
  239. return TRUE;
  240. case 'C':
  241. if(GetKeyState(VK_CONTROL) &0x8000)
  242. {
  243. m_RichEdit.Copy();
  244. }
  245. break;
  246. }
  247. }
  248. return CWnd::PreTranslateMessage(pMsg);
  249. }
  250. BOOL CToolTipEx::OnMsg(MSG *pMsg)
  251. {
  252. if(FALSE == IsWindowVisible())
  253. {
  254. return FALSE;
  255. }
  256. switch(pMsg->message)
  257. {
  258. case WM_WINDOWPOSCHANGING:
  259. case WM_LBUTTONDOWN:
  260. {
  261. if(!IsCursorInToolTip())
  262. {
  263. Hide();
  264. }
  265. break;
  266. }
  267. case WM_KEYDOWN:
  268. {
  269. WPARAM vk = pMsg->wParam;
  270. if(vk == VK_ESCAPE)
  271. {
  272. Hide();
  273. return TRUE;
  274. }
  275. else if(vk == VK_TAB)
  276. {
  277. m_RichEdit.SetFocus();
  278. return TRUE;
  279. }
  280. else if(vk == 'N')
  281. {
  282. return FALSE;
  283. }
  284. else if (vk == 'P')
  285. {
  286. return FALSE;
  287. }
  288. Hide();
  289. break;
  290. }
  291. case WM_LBUTTONDBLCLK:
  292. case WM_RBUTTONDOWN:
  293. case WM_RBUTTONDBLCLK:
  294. case WM_MBUTTONDOWN:
  295. case WM_MBUTTONDBLCLK:
  296. case WM_NCLBUTTONDOWN:
  297. case WM_NCLBUTTONDBLCLK:
  298. case WM_NCRBUTTONDOWN:
  299. case WM_NCRBUTTONDBLCLK:
  300. case WM_NCMBUTTONDOWN:
  301. case WM_NCMBUTTONDBLCLK:
  302. {
  303. Hide();
  304. break;
  305. }
  306. }
  307. return FALSE;
  308. }
  309. CRect CToolTipEx::GetBoundsRect()
  310. {
  311. CWindowDC dc(NULL);
  312. CFont *pOldFont = (CFont*)dc.SelectObject((CFont*) &m_Font);
  313. int nLineWidth = 0;
  314. if(nLineWidth == 0)
  315. {
  316. // Count the number of lines of text
  317. int nStart = 0, nNumLines = 0;
  318. CString strTextCopy = m_csText;
  319. do
  320. {
  321. nStart = strTextCopy.Find(_T("\n"));
  322. // skip found character
  323. if(nStart >= 0)
  324. {
  325. strTextCopy = strTextCopy.Mid(nStart + 1);
  326. }
  327. nNumLines++;
  328. }
  329. while(nStart >= 0);
  330. // Find the widest line
  331. for(int i = 0; i < nNumLines; i++)
  332. {
  333. CString strLine = GetFieldFromString(m_csText, i, _T('\n')) + _T(
  334. " ");
  335. nLineWidth = max(nLineWidth, dc.GetTextExtent(strLine).cx);
  336. }
  337. }
  338. CRect rect(0, 0, max(0, nLineWidth), 0);
  339. dc.DrawText(m_csText, rect, DT_CALCRECT | m_dwTextStyle);
  340. dc.SelectObject(pOldFont);
  341. rect.bottom += m_rectMargin.top + m_rectMargin.bottom;
  342. rect.right += m_rectMargin.left + m_rectMargin.right + 2;
  343. if(m_pBitmap)
  344. {
  345. int nWidth = CBitmapHelper::GetCBitmapWidth(*m_pBitmap);
  346. int nHeight = CBitmapHelper::GetCBitmapHeight(*m_pBitmap);
  347. rect.bottom += nHeight;
  348. if((rect.left + nWidth) > rect.right)
  349. {
  350. rect.right = rect.left + nWidth;
  351. }
  352. }
  353. return rect;
  354. }
  355. CString CToolTipEx::GetFieldFromString(CString ref, int nIndex, TCHAR ch)
  356. {
  357. CString strReturn;
  358. LPCTSTR pstrStart = ref.LockBuffer();
  359. LPCTSTR pstrBuffer = pstrStart;
  360. int nCurrent = 0;
  361. int nStart = 0;
  362. int nEnd = 0;
  363. int nOldStart = 0;
  364. while(nCurrent <= nIndex && *pstrBuffer != _T('\0'))
  365. {
  366. if(*pstrBuffer == ch)
  367. {
  368. nOldStart = nStart;
  369. nStart = nEnd + 1;
  370. nCurrent++;
  371. }
  372. nEnd++;
  373. pstrBuffer++;
  374. }
  375. // May have reached the end of the string
  376. if(*pstrBuffer == _T('\0'))
  377. {
  378. nOldStart = nStart;
  379. nEnd++;
  380. }
  381. ref.UnlockBuffer();
  382. if(nCurrent < nIndex)
  383. {
  384. //TRACE1("Warning: GetStringField - Couldn't find field %d.\n", nIndex);
  385. return strReturn;
  386. }
  387. return ref.Mid(nOldStart, nEnd - nOldStart - 1);
  388. }
  389. LPLOGFONT CToolTipEx::GetSystemToolTipFont()
  390. {
  391. static LOGFONT LogFont;
  392. NONCLIENTMETRICS ncm;
  393. ncm.cbSize = sizeof(NONCLIENTMETRICS);
  394. if(!SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS),
  395. &ncm, 0))
  396. {
  397. return FALSE;
  398. }
  399. memcpy(&LogFont, &(ncm.lfStatusFont), sizeof(LOGFONT));
  400. return &LogFont;
  401. }
  402. BOOL CToolTipEx::SetLogFont(LPLOGFONT lpLogFont, BOOL bRedraw /*=TRUE*/)
  403. {
  404. ASSERT(lpLogFont);
  405. if(!lpLogFont)
  406. {
  407. return FALSE;
  408. }
  409. LOGFONT LogFont;
  410. // Store font as the global default
  411. memcpy(&LogFont, lpLogFont, sizeof(LOGFONT));
  412. // Create the actual font object
  413. m_Font.DeleteObject();
  414. m_Font.CreateFontIndirect(&LogFont);
  415. if(bRedraw && ::IsWindow(GetSafeHwnd()))
  416. {
  417. Invalidate();
  418. }
  419. return TRUE;
  420. }
  421. void CToolTipEx::SetBitmap(CBitmap *pBitmap)
  422. {
  423. DELETE_BITMAP
  424. m_pBitmap = pBitmap;
  425. }
  426. void CToolTipEx::OnSize(UINT nType, int cx, int cy)
  427. {
  428. CWnd::OnSize(nType, cx, cy);
  429. if(::IsWindow(m_RichEdit.GetSafeHwnd()) == FALSE)
  430. {
  431. return ;
  432. }
  433. m_DittoWindow.DoSetRegion(this);
  434. CRect cr;
  435. GetClientRect(cr);
  436. cr.DeflateRect(0, 0, 0, theApp.m_metrics.ScaleY(21));
  437. m_RichEdit.MoveWindow(cr);
  438. m_optionsButton.MoveWindow(cr.left, cr.bottom + theApp.m_metrics.ScaleY(2), theApp.m_metrics.ScaleX(17), theApp.m_metrics.ScaleY(17));
  439. this->Invalidate();
  440. }
  441. BOOL CToolTipEx::IsCursorInToolTip()
  442. {
  443. CRect cr;
  444. GetWindowRect(cr);
  445. CPoint cursorPos;
  446. GetCursorPos(&cursorPos);
  447. return cr.PtInRect(cursorPos);
  448. }
  449. void CToolTipEx::SetRTFText(const char *pRTF)
  450. {
  451. m_RichEdit.SetRTF(pRTF);
  452. m_csRTF = pRTF;
  453. }
  454. //void CToolTipEx::SetRTFText(const CString &csRTF)
  455. //{
  456. // m_RichEdit.SetRTF(csRTF);
  457. // m_csRTF = csRTF;
  458. //}
  459. void CToolTipEx::SetToolTipText(const CString &csText)
  460. {
  461. m_csText = csText;
  462. m_RichEdit.SetFont(&m_Font);
  463. m_RichEdit.SetText(csText);
  464. }
  465. void CToolTipEx::OnActivate(UINT nState, CWnd *pWndOther, BOOL bMinimized)
  466. {
  467. CWnd::OnActivate(nState, pWndOther, bMinimized);
  468. if(nState == WA_INACTIVE)
  469. {
  470. Hide();
  471. if(m_pNotifyWnd)
  472. {
  473. m_pNotifyWnd->PostMessage(NM_INACTIVE_TOOLTIPWND, 0, 0);
  474. }
  475. }
  476. }
  477. void CToolTipEx::OnTimer(UINT_PTR nIDEvent)
  478. {
  479. switch(nIDEvent)
  480. {
  481. case HIDE_WINDOW_TIMER:
  482. Hide();
  483. PostMessage(WM_DESTROY, 0, 0);
  484. break;
  485. }
  486. CWnd::OnTimer(nIDEvent);
  487. }
  488. void CToolTipEx::OnNcPaint()
  489. {
  490. m_DittoWindow.DoNcPaint(this);
  491. }
  492. void CToolTipEx::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp)
  493. {
  494. CWnd::OnNcCalcSize(bCalcValidRects, lpncsp);
  495. m_DittoWindow.DoNcCalcSize(bCalcValidRects, lpncsp);
  496. }
  497. HITTEST_RET CToolTipEx::OnNcHitTest(CPoint point)
  498. {
  499. UINT Ret = m_DittoWindow.DoNcHitTest(this, point);
  500. if(Ret == -1)
  501. return CWnd::OnNcHitTest(point);
  502. return Ret;
  503. }
  504. void CToolTipEx::OnNcLButtonDown(UINT nHitTest, CPoint point)
  505. {
  506. m_DittoWindow.DoNcLButtonDown(this, nHitTest, point);
  507. CWnd::OnNcLButtonDown(nHitTest, point);
  508. }
  509. void CToolTipEx::OnNcLButtonUp(UINT nHitTest, CPoint point)
  510. {
  511. long lRet = m_DittoWindow.DoNcLButtonUp(this, nHitTest, point);
  512. switch(lRet)
  513. {
  514. case BUTTON_CLOSE:
  515. Hide();
  516. break;
  517. }
  518. CWnd::OnNcLButtonUp(nHitTest, point);
  519. }
  520. void CToolTipEx::OnNcMouseMove(UINT nHitTest, CPoint point)
  521. {
  522. m_DittoWindow.DoNcMouseMove(this, nHitTest, point);
  523. CWnd::OnNcMouseMove(nHitTest, point);
  524. }
  525. void CToolTipEx::OnOptions()
  526. {
  527. POINT pp;
  528. CMenu cmPopUp;
  529. CMenu *cmSubMenu = NULL;
  530. GetCursorPos(&pp);
  531. if(cmPopUp.LoadMenu(IDR_DESC_OPTIONS_MENU) != 0)
  532. {
  533. cmSubMenu = cmPopUp.GetSubMenu(0);
  534. if(!cmSubMenu)
  535. {
  536. return ;
  537. }
  538. GetCursorPos(&pp);
  539. if(CGetSetOptions::GetRememberDescPos())
  540. cmSubMenu->CheckMenuItem(ID_FIRST_REMEMBERWINDOWPOSITION, MF_CHECKED);
  541. if(CGetSetOptions::GetSizeDescWindowToContent())
  542. cmSubMenu->CheckMenuItem(ID_FIRST_SIZEWINDOWTOCONTENT, MF_CHECKED);
  543. if(CGetSetOptions::GetScaleImagesToDescWindow())
  544. cmSubMenu->CheckMenuItem(ID_FIRST_SCALEIMAGESTOFITWINDOW, MF_CHECKED);
  545. //theApp.m_Language.UpdateRightClickMenu(cmSubMenu);
  546. cmSubMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON, pp.x, pp.y, this, NULL);
  547. }
  548. }
  549. void CToolTipEx::OnRememberwindowposition()
  550. {
  551. CGetSetOptions::SetRememberDescPos(!CGetSetOptions::GetRememberDescPos());
  552. }
  553. void CToolTipEx::OnSizewindowtocontent()
  554. {
  555. CGetSetOptions::SetSizeDescWindowToContent(!CGetSetOptions::GetSizeDescWindowToContent());
  556. CRect rect;
  557. this->GetWindowRect(&rect);
  558. Show(rect.TopLeft());
  559. }
  560. void CToolTipEx::OnScaleimagestofitwindow()
  561. {
  562. CGetSetOptions::SetScaleImagesToDescWindow(!CGetSetOptions::GetScaleImagesToDescWindow());
  563. Invalidate();
  564. }