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

对话框与窗口

开发平台:

Visual C++

  1. // XTPToolTipContext.cpp: implementation of the CXTPToolTipContext class.
  2. //
  3. // This file is a part of the XTREME TOOLKIT PRO MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #if _MSC_VER < 1200
  22. #define _XTP_EXCLUDE_HTML
  23. #else
  24. #include <mshtml.h>
  25. #include <mshtmhst.h>
  26. #endif // !_MSC_VER < 1200
  27. #include "XTPToolTipContext.h"
  28. #include "XTPVC80Helpers.h"
  29. #include "XTPDrawHelpers.h"
  30. #include "XTPColorManager.h"
  31. #include "XTPImageManager.h"
  32. #include "XTPOffice2007Image.h"
  33. #include "XTPSystemHelpers.h"
  34. #include "XTPRichRender.h"
  35. #include "XTPResourceManager.h"
  36. #include "XTPMarkupRender.h"
  37. #ifdef _INC_COMDEF
  38. // Warning "ComDef.h" was included
  39. #endif
  40. #ifdef _DEBUG
  41. #undef THIS_FILE
  42. static char THIS_FILE[] = __FILE__;
  43. #define new DEBUG_NEW
  44. #endif
  45. #pragma warning (disable : 4097) // typedef-name 'CXTPToolTipContextTipOfficeCtrl' used as synonym for class-name 'CRichEditToolTip'
  46. #define WM_SYSKEYFIRST WM_SYSKEYDOWN
  47. #define WM_SYSKEYLAST WM_SYSDEADCHAR
  48. #define VERSION_IE5             MAKELONG(80, 5)
  49. #define TTS_NOANIMATE           0x10
  50. #define TTS_NOFADE              0x20
  51. #define TTS_BALLOON             0x40
  52. #define CS_DROPSHADOW       0x00020000
  53. #ifndef TTM_SETTITLE
  54. #define TTM_SETTITLEA           (WM_USER + 32)  // wParam = TTI_*, lParam = char* szTitle
  55. #define TTM_SETTITLEW           (WM_USER + 33)  // wParam = TTI_*, lParam = wchar* szTitle
  56. #ifdef UNICODE
  57. #define TTM_SETTITLE            TTM_SETTITLEW
  58. #else
  59. #define TTM_SETTITLE            TTM_SETTITLEA
  60. #endif
  61. #endif
  62. #ifndef WF_TRACKINGTOOLTIPS
  63. #define WF_TRACKINGTOOLTIPS 0x0400
  64. #endif
  65. #define SAFE_DELETEWINDOW(ptr) 
  66. if (ptr) { ptr->DestroyWindow(); delete ptr; ptr = NULL; }
  67. CXTPToolTipContext* CXTPToolTipContext::m_pModuleContext = 0;
  68. IMPLEMENT_DYNAMIC(CXTPToolTipContextToolTip, CWnd)
  69. //////////////////////////////////////////////////////////////////////////
  70. // CXTPToolTipContextToolTip
  71. CXTPToolTipContextToolTip::CXTPToolTipContextToolTip(CXTPToolTipContext* pContext)
  72. : m_pContext(pContext)
  73. {
  74. m_bActive = FALSE;
  75. m_toolVisible.Reset();
  76. m_toolDisabled.Reset();
  77. m_toolDelay.Reset();
  78. m_pIcon = NULL;
  79. m_nDelayTimer = 0;
  80. m_dwLastTip = 0;
  81. m_nDelayInitial = 500;
  82. m_nDelayReshow = 200;
  83. }
  84. void CXTPToolTipContext::SetFont(CFont* pFont)
  85. {
  86. LOGFONT lf;
  87. pFont->GetLogFont(&lf);
  88. SetFontIndirect(&lf);
  89. }
  90. void CXTPToolTipContext::SetFontIndirect(LOGFONT* lpLogFont)
  91. {
  92. if (!lpLogFont)
  93. return;
  94. lpLogFont->lfWeight = FW_NORMAL;
  95. m_fnt.DeleteObject();
  96. m_fnt.CreateFontIndirect(lpLogFont);
  97. lpLogFont->lfWeight = FW_BOLD;
  98. m_fntTitle.DeleteObject();
  99. m_fntTitle.CreateFontIndirect(lpLogFont);
  100. if (m_pToolTip) m_pToolTip->DestroyWindow();
  101. }
  102. CXTPToolTipContextToolTip::~CXTPToolTipContextToolTip()
  103. {
  104. for (int i = 0; i < (int)m_arrTools.GetSize(); i++)
  105. {
  106. delete m_arrTools[i];
  107. }
  108. m_arrTools.RemoveAll();
  109. HookMouseMove(FALSE);
  110. }
  111. BEGIN_MESSAGE_MAP(CXTPToolTipContextToolTip, CWnd)
  112. //{{AFX_MSG_MAP(CXTPToolTipContextToolTip)
  113. ON_MESSAGE(TTM_ADDTOOL, OnAddTool)
  114. ON_MESSAGE(TTM_ACTIVATE, OnActivate)
  115. ON_MESSAGE(TTM_DELTOOL, OnDelTool)
  116. ON_MESSAGE(TTM_RELAYEVENT, OnRelayEvent)
  117. ON_MESSAGE(TTM_SETTITLE, OnSetTitle)
  118. ON_MESSAGE(TTM_UPDATETIPTEXT, OnUpdateTipText)
  119. ON_MESSAGE(TTM_SETDELAYTIME, OnSetDelayTime)
  120. ON_MESSAGE(XTP_TTM_SETIMAGE, OnSetImage)
  121. ON_WM_PAINT()
  122. ON_WM_ERASEBKGND()
  123. ON_WM_NCHITTEST_EX()
  124. ON_WM_MOUSEACTIVATE()
  125. ON_WM_MOUSEMOVE()
  126. ON_WM_TIMER()
  127. ON_WM_DESTROY()
  128. ON_MESSAGE(TTM_WINDOWFROMPOINT, OnWindowFromPoint)
  129. //}}AFX_MSG_MAP
  130. END_MESSAGE_MAP()
  131. /////////////////////////////////////////////////////////////////////////////
  132. // CXTPToolTipContextToolTip message handlers
  133. BOOL CXTPToolTipContextToolTip::Create(CWnd* pParentWnd, DWORD dwStyle)
  134. {
  135. UINT nClassStyle = (dwStyle & XTP_TTS_NOSHADOW ? 0 : CS_DROPSHADOW) | CS_SAVEBITS | CS_OWNDC;
  136. if ((nClassStyle & CS_DROPSHADOW) && !XTPSystemVersion()->IsWinXPOrGreater()) // Windows XP only
  137. {
  138. nClassStyle &= ~CS_DROPSHADOW;
  139. }
  140. BOOL bResult = CWnd::CreateEx(WS_EX_TOOLWINDOW, AfxRegisterWndClass(nClassStyle, AfxGetApp()->LoadStandardCursor(IDC_ARROW)), NULL,
  141. WS_POPUP | dwStyle, // force WS_POPUP
  142. CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  143. pParentWnd->GetSafeHwnd(), NULL, NULL);
  144. if (bResult)
  145. SetOwner(pParentWnd);
  146. return bResult;
  147. }
  148. void CXTPToolTipContextToolTip::OnDestroy()
  149. {
  150. m_toolVisible.Reset();
  151. m_toolDisabled.Reset();
  152. m_toolDelay.Reset();
  153. for (int i = 0; i < (int)m_arrTools.GetSize(); i++)
  154. {
  155. delete m_arrTools[i];
  156. }
  157. m_arrTools.RemoveAll();
  158. m_strTitle.Empty();
  159. m_pIcon = NULL;
  160. Activate(FALSE);
  161. HookMouseMove(FALSE);
  162. CWnd::OnDestroy();
  163. }
  164. LRESULT CXTPToolTipContextToolTip::OnSetImage(WPARAM, LPARAM lParam)
  165. {
  166. m_pIcon = (CXTPImageManagerIcon*)lParam;
  167. return 0;
  168. }
  169. LRESULT CXTPToolTipContextToolTip::OnSetTitle(WPARAM, LPARAM lParam)
  170. {
  171. m_strTitle = (LPCTSTR)lParam;
  172. return 0;
  173. }
  174. LRESULT CXTPToolTipContextToolTip::OnSetDelayTime(WPARAM dwDuration, LPARAM lParam)
  175. {
  176. UINT iTime = LOWORD(lParam);
  177. switch (dwDuration)
  178. {
  179. case TTDT_RESHOW:
  180. m_nDelayReshow = iTime;
  181. break;
  182. case TTDT_INITIAL:
  183. m_nDelayInitial = iTime;
  184. break;
  185. }
  186. return 0;
  187. }
  188. LRESULT CXTPToolTipContextToolTip::OnUpdateTipText(WPARAM, LPARAM lParam)
  189. {
  190. LPTOOLINFO lpToolInfo = LPTOOLINFO(lParam);
  191. for (int i = 0; i < (int)m_arrTools.GetSize(); i++)
  192. {
  193. TOOLITEM* pItem = m_arrTools[i];
  194. if ((pItem->uId == lpToolInfo->uId) && (pItem->hwnd == lpToolInfo->hwnd))
  195. {
  196. pItem->bAutoCaption = (lpToolInfo->lpszText == LPSTR_TEXTCALLBACK);
  197. pItem->strCaption = pItem->bAutoCaption ? _T("") : lpToolInfo->lpszText;
  198. break;
  199. }
  200. }
  201. return 0;
  202. }
  203. LRESULT CXTPToolTipContextToolTip::OnAddTool(WPARAM, LPARAM lParam)
  204. {
  205. return AddTool((LPTOOLINFO)lParam);
  206. }
  207. LRESULT CXTPToolTipContextToolTip::OnActivate(WPARAM wParam, LPARAM)
  208. {
  209. Activate((BOOL)wParam);
  210. return 0;
  211. }
  212. LRESULT CXTPToolTipContextToolTip::OnDelTool(WPARAM, LPARAM lParam)
  213. {
  214. DelTool((LPTOOLINFO)lParam);
  215. return 0;
  216. }
  217. LRESULT CXTPToolTipContextToolTip::OnRelayEvent(WPARAM, LPARAM lParam)
  218. {
  219. RelayEvent((LPMSG)lParam);
  220. return 0;
  221. }
  222. LRESULT CXTPToolTipContextToolTip::OnWindowFromPoint(WPARAM, LPARAM lParam)
  223. {
  224. LPPOINT lpPoint = (LPPOINT)lParam;
  225. HWND hWnd = lpPoint ? ::WindowFromPoint(*lpPoint) : 0;
  226. if ((hWnd != NULL) && (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD) && (::SendMessage(hWnd, XTP_TTM_WINDOWFROMPOINT, 0, 0) == 1))
  227. {
  228. return (LRESULT)::GetParent(hWnd);
  229. }
  230. return (LRESULT)hWnd;
  231. }
  232. BOOL CXTPToolTipContextToolTip::AddTool(LPTOOLINFO lpToolInfo)
  233. {
  234. ASSERT(lpToolInfo);
  235. if (!lpToolInfo)
  236. return FALSE;
  237. TOOLITEM* pti = new TOOLITEM;
  238. pti->hwnd = lpToolInfo->hwnd;
  239. pti->uFlags = lpToolInfo->uFlags;
  240. pti->uId = lpToolInfo->uId;
  241. pti->rect = lpToolInfo->rect;
  242. pti->bAutoCaption = (lpToolInfo->lpszText == LPSTR_TEXTCALLBACK);
  243. pti->strCaption = pti->bAutoCaption ? _T("") : lpToolInfo->lpszText;
  244. pti->hinst = lpToolInfo->hinst;
  245. pti->rectExclude.SetRectEmpty();
  246. if (lpToolInfo->cbSize == sizeof(XTP_TOOLTIP_TOOLINFO_EX))
  247. {
  248. pti->rectExclude = ((XTP_TOOLTIP_TOOLINFO_EX*)lpToolInfo)->pToolInfo->rcExclude;
  249. }
  250. m_arrTools.Add(pti);
  251. return TRUE;
  252. }
  253. void CXTPToolTipContextToolTip::Activate(BOOL bActivate)
  254. {
  255. m_bActive = bActivate;
  256. if (!bActivate && GetSafeHwnd() && m_nDelayTimer)
  257. {
  258. KillTimer(m_nDelayTimer);
  259. m_nDelayTimer = 0;
  260. m_toolDelay.Reset();
  261. }
  262. if (!bActivate && GetSafeHwnd() && IsWindowVisible())
  263. {
  264. SetVisibleTool(NULL);
  265. }
  266. }
  267. void CXTPToolTipContextToolTip::DelTool(LPTOOLINFO lpToolInfo)
  268. {
  269. ASSERT(lpToolInfo);
  270. if (!lpToolInfo)
  271. return;
  272. for (int i = 0; i < (int)m_arrTools.GetSize(); i++)
  273. {
  274. TOOLITEM* pItem = m_arrTools[i];
  275. if ((pItem->uId == lpToolInfo->uId) && (pItem->hwnd == lpToolInfo->hwnd))
  276. {
  277. if (m_toolVisible.IsEqual(pItem))
  278. SetVisibleTool(0);
  279. if (m_toolDisabled.IsEqual(pItem)) m_toolDisabled.Reset();
  280. if (m_toolDelay.IsEqual(pItem)) m_toolDelay.Reset();
  281. m_arrTools.RemoveAt(i);
  282. delete pItem;
  283. break;
  284. }
  285. }
  286. }
  287. CXTPToolTipContextToolTip::TOOLITEM* CXTPToolTipContextToolTip::FindTool()
  288. {
  289. if (!(GetKeyState(VK_LBUTTON) >= 0 && GetKeyState(VK_RBUTTON) >= 0 &&
  290. GetKeyState(VK_MBUTTON) >= 0))
  291. {
  292. return NULL;
  293. }
  294. CPoint pt;
  295. GetCursorPos(&pt);
  296. for (int i = 0; i < m_arrTools.GetSize(); i++)
  297. {
  298. TOOLITEM* pItem = m_arrTools[i];
  299. if (!::IsWindow(pItem->hwnd))
  300. continue;
  301. CWnd* pWnd = CWnd::FromHandle(pItem->hwnd);
  302. CRect rcTool = pItem->rect;
  303. if (pItem->uFlags & TTF_IDISHWND)
  304. {
  305. pWnd->GetWindowRect(rcTool);
  306. }
  307. else
  308. {
  309. pWnd->ClientToScreen(rcTool);
  310. }
  311. if (rcTool.PtInRect(pt) && ((pItem->uFlags & TTF_IDISHWND) || ((HWND)OnWindowFromPoint(0, (LRESULT)(LPPOINT)&pt) == pItem->hwnd)))
  312. return pItem;
  313. }
  314. return NULL;
  315. }
  316. #ifndef IS_INTRESOURCE
  317. #define IS_INTRESOURCE(x) (((size_t)(x) >> 16) == 0)
  318. #endif
  319. CString CXTPToolTipContextToolTip::GetToolText(TOOLITEM* lpToolInfo)
  320. {
  321. if (lpToolInfo->bAutoCaption)
  322. {
  323. UINT_PTR id = lpToolInfo->uId;
  324. TOOLTIPTEXT tt = {0};
  325. tt.hdr.hwndFrom = m_hWnd;
  326. tt.hdr.idFrom = lpToolInfo->uId;
  327. tt.hdr.code = TTN_NEEDTEXT;
  328. tt.uFlags = lpToolInfo->uFlags;
  329. tt.hinst = NULL;
  330. tt.szText[0] = _T('');
  331. tt.lpszText = tt.szText;
  332. ::SendMessage(lpToolInfo->hwnd, WM_NOTIFY, id, (LPARAM)&tt);
  333. if (IS_INTRESOURCE(tt.lpszText))
  334. {
  335. XTPResourceManager()->LoadLocaleString(tt.hinst, (UINT)(UINT_PTR)tt.lpszText, lpToolInfo->strCaption);
  336. }
  337. else
  338. {
  339. lpToolInfo->strCaption = tt.lpszText;
  340. }
  341. if ((m_pContext->GetControlStyle() & TTS_NOPREFIX) == 0)
  342. {
  343. CXTPDrawHelpers::StripMnemonics(lpToolInfo->strCaption);
  344. }
  345. lpToolInfo->bAutoCaption = FALSE;
  346. }
  347. return lpToolInfo->strCaption;
  348. }
  349. int CXTPToolTipContextToolTip::GetMaxTipWidth() const
  350. {
  351. const int nWidth = m_pContext->GetMaxTipWidth();
  352. if (nWidth == -1)
  353. {
  354. return ::GetSystemMetrics(SM_CXSCREEN);
  355. }
  356. return nWidth;
  357. }
  358. CSize CXTPToolTipContextToolTip::GetToolSize(TOOLITEM* lpToolInfo)
  359. {
  360. CClientDC dc(this);
  361. CFont* pOldFont = dc.SelectObject(&m_pContext->m_fnt);
  362. CString str = GetToolText(lpToolInfo);
  363. if (str.IsEmpty())
  364. return CSize(0);
  365. int nMaxTipWidth = GetMaxTipWidth();
  366. CRect rcMargin = m_pContext->GetMargin();
  367. CSize szMargin(3 + rcMargin.left + rcMargin.right + 3, 3 + rcMargin.top + rcMargin.bottom + 3);
  368. DWORD dwFlags = DT_NOPREFIX | DT_EXPANDTABS;
  369. CRect rc(0, 0, nMaxTipWidth - szMargin.cx, 0);
  370. dc.DrawText(str, rc, dwFlags | DT_CALCRECT | DT_WORDBREAK);
  371. CSize sz = rc.Size();
  372. BOOL bDrawImage = m_pIcon != NULL;
  373. BOOL bDrawTitle = !m_strTitle.IsEmpty();
  374. BOOL bDrawImageTop = TRUE;
  375. CSize szImage(0, 0);
  376. if (bDrawImage)
  377. {
  378. szImage = CSize(m_pIcon->GetWidth(), m_pIcon->GetHeight());
  379. bDrawImageTop = (szImage.cy <= 16);
  380. if (bDrawImageTop)
  381. {
  382. if (!bDrawTitle)
  383. {
  384. sz.cx += szImage.cx + 3;
  385. }
  386. }
  387. else
  388. {
  389. sz.cx += szImage.cx + 5;
  390. }
  391. sz.cy = max(sz.cy, szImage.cy);
  392. }
  393. if (bDrawTitle)
  394. {
  395. CXTPFontDC fntTitle(&dc, &m_pContext->m_fntTitle);
  396. CRect rcTitle(0, 0, nMaxTipWidth - szMargin.cx - 25, 0);
  397. dc.DrawText(m_strTitle, rcTitle, dwFlags | DT_CALCRECT | DT_SINGLELINE);
  398. sz.cy += rcTitle.Height() + 10 + 10;
  399. sz.cx = max(sz.cx + 10 + 15, min(nMaxTipWidth - szMargin.cx, rcTitle.Width() + 4) + (bDrawImage && bDrawImageTop ? szImage.cx + 1: 0));
  400. }
  401. dc.SelectObject(pOldFont);
  402. sz += szMargin;
  403. return sz;
  404. }
  405. HHOOK CXTPToolTipContextToolTip::m_hHookMouse = 0;
  406. CXTPToolTipContextToolTip* CXTPToolTipContextToolTip::m_pWndMonitor = 0;
  407. LRESULT CALLBACK CXTPToolTipContextToolTip::MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
  408. {
  409. if (nCode != HC_ACTION || !m_pWndMonitor || m_pWndMonitor->m_toolVisible.IsEmpty())
  410. return CallNextHookEx(m_hHookMouse, nCode, wParam, lParam);
  411. POINT pt = ((PMOUSEHOOKSTRUCT)lParam)->pt;
  412. HWND hWnd = (HWND)m_pWndMonitor->OnWindowFromPoint(0, (LPARAM)&pt);
  413. if (hWnd != m_pWndMonitor->m_toolVisible.hwnd)
  414. {
  415. MSG msg;
  416. msg.pt = pt;
  417. msg.message = WM_MOUSEMOVE;
  418. m_pWndMonitor->RelayEvent(&msg);
  419. }
  420. return CallNextHookEx(m_hHookMouse, nCode, wParam, lParam);
  421. }
  422. void CXTPToolTipContextToolTip::HookMouseMove(BOOL bSetupHook)
  423. {
  424. if (bSetupHook && m_hHookMouse == 0 && (m_pWndMonitor == NULL))
  425. {
  426. m_hHookMouse = SetWindowsHookEx(WH_MOUSE, MouseProc, 0, GetCurrentThreadId ());
  427. m_pWndMonitor = this;
  428. }
  429. else if (!bSetupHook && m_hHookMouse && (m_pWndMonitor == this))
  430. {
  431. UnhookWindowsHookEx(m_hHookMouse);
  432. m_hHookMouse = 0;
  433. m_pWndMonitor = NULL;
  434. }
  435. }
  436. void CXTPToolTipContextToolTip::EnsureVisible(CRect& rcToolTip)
  437. {
  438. CRect rcWork = XTPMultiMonitor()->GetWorkArea();
  439. int nGap = 4;
  440. if (rcWork.right - nGap < rcToolTip.right)
  441. {
  442. rcToolTip.OffsetRect(- rcToolTip.right + rcWork.right - nGap, 0);
  443. }
  444. if (rcWork.left > rcToolTip.left)
  445. {
  446. rcToolTip.OffsetRect(rcWork.left - rcToolTip.left, 0);
  447. }
  448. if (rcWork.bottom - nGap < rcToolTip.bottom)
  449. {
  450. CPoint pt;
  451. GetCursorPos(&pt);
  452. rcToolTip.OffsetRect(0, pt.y - rcToolTip.bottom - 3);
  453. }
  454. }
  455. int CXTPToolTipContextToolTip::GetCursorHeight() const
  456. {
  457. HCURSOR hCursor = GetCursor();
  458. ICONINFO iconInfo;
  459. if (!GetIconInfo(hCursor, &iconInfo))
  460. return 21;
  461. BITMAP bm;
  462. if (!GetObject(iconInfo.hbmMask, sizeof(BITMAP), &bm))
  463. return 21;
  464. WORD curBits[16 * 8];
  465. memset(&curBits, -1, sizeof(curBits));
  466. if (!GetBitmapBits(iconInfo.hbmMask, sizeof(curBits), curBits))
  467. return 21;
  468. int nBitSize = sizeof(WORD) * 8;
  469. int nCount = MulDiv(bm.bmWidth, bm.bmHeight, nBitSize);
  470. int nXor = 0;
  471. if (!iconInfo.hbmColor)
  472. {
  473. nXor = nCount - 1;
  474. nCount = nCount / 2;
  475. }
  476. if (nCount >= sizeof(curBits)/sizeof(WORD)) nCount = sizeof(curBits)/sizeof(WORD) - 1;
  477. if (nXor >= sizeof(curBits)/sizeof(WORD)) nXor = 0;
  478. int i = nCount - 1;
  479. for (; i >= 0; i--)
  480. {
  481. if (curBits[i] != 0xFFFF || (nXor && (curBits[nXor--] != 0)))
  482. break;
  483. }
  484. if (iconInfo.hbmColor) DeleteObject(iconInfo.hbmColor);
  485. if (iconInfo.hbmMask) DeleteObject(iconInfo.hbmMask);
  486. return MulDiv(i + 1, nBitSize, (int)bm.bmWidth) - (int)iconInfo.yHotspot;
  487. }
  488. void CXTPToolTipContextToolTip::SetRoundRectRegion(CWnd* pWnd)
  489. {
  490. CXTPWindowRect rc(pWnd);
  491. rc.OffsetRect(-rc.TopLeft());
  492. int cx = rc.Width(), cy = rc.Height();
  493. RECT rgn[] =
  494. {
  495. {1, 0, cx - 1, 1}, {0, 1, cx, cy - 1}, {1, cy - 1, cx - 1, cy}
  496. };
  497. int nSizeData = sizeof(RGNDATAHEADER) + sizeof(rgn);
  498. RGNDATA* pRgnData = (RGNDATA*)malloc(nSizeData);
  499. if (!pRgnData)
  500. return;
  501. MEMCPY_S(&pRgnData->Buffer, (void*)&rgn, sizeof(rgn));
  502. pRgnData->rdh.dwSize = sizeof(RGNDATAHEADER);
  503. pRgnData->rdh.iType = RDH_RECTANGLES;
  504. pRgnData->rdh.nCount = sizeof(rgn) / sizeof(RECT);
  505. pRgnData->rdh.nRgnSize = 0;
  506. pRgnData->rdh.rcBound = CRect(0, 0, cx, cy);
  507. CRgn rgnResult;
  508. VERIFY(rgnResult.CreateFromData(NULL, nSizeData, pRgnData));
  509. free(pRgnData);
  510. pWnd->SetWindowRgn((HRGN)rgnResult.Detach(), FALSE);
  511. }
  512. void CXTPToolTipContextToolTip::SetVisibleTool(TOOLITEM* pVisibleTool)
  513. {
  514. if (!m_toolVisible.IsEqual(pVisibleTool))
  515. {
  516. CSize sz(0);
  517. if (pVisibleTool)
  518. {
  519. sz = GetToolSize(pVisibleTool);
  520. if (sz == CSize(0)) pVisibleTool = 0;
  521. }
  522. if (m_hWnd)
  523. {
  524. SetWindowPos(0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
  525. SetWindowRgn(NULL, FALSE);
  526. }
  527. if (pVisibleTool)
  528. {
  529. CRect rcToolTip(0, 0, 0, 0);
  530. if (!pVisibleTool->rectExclude.IsRectEmpty())
  531. {
  532. CWnd* pWnd = CWnd::FromHandle(pVisibleTool->hwnd);
  533. //CRect rcExclude = pVisibleTool->rectExclude;
  534. //rcToolTip = pVisibleTool->rect;
  535. rcToolTip.SetRect(pVisibleTool->rect.left, pVisibleTool->rectExclude.bottom,
  536. pVisibleTool->rect.left + sz.cx, pVisibleTool->rectExclude.bottom + sz.cy);
  537. pWnd->ClientToScreen(rcToolTip);
  538. }
  539. else
  540. {
  541. CPoint pt;
  542. GetCursorPos(&pt);
  543. int nCursorHeight = GetCursorHeight();
  544. rcToolTip.SetRect(pt.x, pt.y + nCursorHeight, pt.x + sz.cx, pt.y + nCursorHeight + sz.cy);
  545. if (GetWindowLong(pVisibleTool->hwnd, GWL_EXSTYLE) & WS_EX_LAYOUTRTL)
  546. {
  547. rcToolTip.OffsetRect(-sz.cx, 0);
  548. }
  549. }
  550. EnsureVisible(rcToolTip);
  551. SetWindowPos(&CWnd::wndTop, rcToolTip.left, rcToolTip.top,
  552. rcToolTip.Width(), rcToolTip.Height(), SWP_NOACTIVATE | SWP_NOOWNERZORDER);
  553. UINT_PTR id = pVisibleTool->uId;
  554. NMHDR hdr = {0};
  555. hdr.hwndFrom = m_hWnd;
  556. hdr.idFrom = pVisibleTool->uId;
  557. hdr.code = TTN_SHOW;
  558. ::SendMessage(pVisibleTool->hwnd, WM_NOTIFY, id, (LPARAM)&hdr);
  559. if (GetStyle() & XTP_TTS_OFFICE2007FRAME)
  560. {
  561. SetRoundRectRegion(this);
  562. }
  563. SetWindowPos(0, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
  564. Invalidate(FALSE);
  565. HookMouseMove(TRUE);
  566. m_toolDisabled.Reset();
  567. }
  568. else
  569. {
  570. HookMouseMove(FALSE);
  571. m_toolDelay.Reset();
  572. }
  573. m_toolVisible.Assign(pVisibleTool);
  574. m_dwLastTip = GetTickCount();
  575. OnVisibleChanged(pVisibleTool != NULL);
  576. }
  577. }
  578. void CXTPToolTipContextToolTip::RelayEvent(LPMSG lpMsg)
  579. {
  580. if (!m_bActive)
  581. return;
  582. if (!((lpMsg->message >= WM_MOUSEFIRST && lpMsg->message <= WM_MOUSELAST) ||
  583. (lpMsg->message >= WM_NCMOUSEMOVE && lpMsg->message <= WM_NCMBUTTONDBLCLK)))
  584. return;
  585. TOOLITEM* pVisibleTool = FindTool();
  586. if (lpMsg->message == WM_LBUTTONDOWN)
  587. {
  588. if (pVisibleTool)
  589. {
  590. m_toolDisabled = *pVisibleTool;
  591. pVisibleTool = 0;
  592. }
  593. }
  594. if (pVisibleTool && (m_toolDisabled.IsEqual(pVisibleTool)))
  595. {
  596. pVisibleTool = 0;
  597. }
  598. if (m_nDelayTimer && !m_toolDelay.IsEqual(pVisibleTool))
  599. {
  600. KillTimer(m_nDelayTimer);
  601. m_nDelayTimer = 0;
  602. m_toolDelay.Reset();
  603. }
  604. if (pVisibleTool)
  605. {
  606. if (!m_toolVisible.IsEqual(pVisibleTool))
  607. {
  608. if (GetTickCount() - m_dwLastTip < m_nDelayReshow)
  609. {
  610. SetVisibleTool(pVisibleTool);
  611. }
  612. else if (!m_toolDelay.IsEqual(pVisibleTool))
  613. {
  614. m_toolDelay = *pVisibleTool;
  615. m_nDelayTimer = SetTimer(1, m_nDelayInitial, NULL);
  616. }
  617. }
  618. }
  619. else
  620. {
  621. SetVisibleTool(0);
  622. }
  623. }
  624. void CXTPToolTipContextToolTip::DrawEntry(CDC* pDC, TOOLITEM* lpToolInfo, CRect rc)
  625. {
  626. CString str = lpToolInfo->strCaption;
  627. rc.DeflateRect(m_pContext->GetMargin());
  628. rc.DeflateRect(3, 3, 3, 3);
  629. DWORD dwFlags = DT_NOPREFIX | DT_EXPANDTABS;
  630. BOOL bLayoutRTL = lpToolInfo->hwnd && GetWindowLong(lpToolInfo->hwnd, GWL_EXSTYLE) & WS_EX_LAYOUTRTL;
  631. if (bLayoutRTL)
  632. {
  633. dwFlags |= DT_RTLREADING | DT_RIGHT;
  634. }
  635. CRect rcTitle(rc.left + 2, rc.top + 2, rc.right - 2, rc.bottom);
  636. BOOL bDrawImage = m_pIcon != NULL;
  637. BOOL bDrawTitle = !m_strTitle.IsEmpty();
  638. BOOL bDrawImageTop = TRUE;
  639. CSize szImage(0, 0);
  640. if (bDrawImage)
  641. {
  642. szImage = CSize(m_pIcon->GetWidth(), m_pIcon->GetHeight());
  643. bDrawImageTop = (szImage.cy <= 16);
  644. if (bDrawImageTop)
  645. {
  646. CPoint ptIcon = bLayoutRTL ? CPoint(rc.right - szImage.cx, rc.top) : rc.TopLeft();
  647. m_pIcon->Draw(pDC, ptIcon);
  648. if (bLayoutRTL)
  649. {
  650. if (bDrawTitle) rcTitle.right -= szImage.cx + 1; else rc.right -= szImage.cx + 3;
  651. }
  652. else
  653. {
  654. if (bDrawTitle) rcTitle.left += szImage.cx + 1; else rc.left += szImage.cx + 3;
  655. }
  656. }
  657. }
  658. if (bDrawTitle)
  659. {
  660. CXTPFontDC fnt(pDC, &m_pContext->m_fntTitle);
  661. pDC->DrawText(m_strTitle, rcTitle, dwFlags | DT_SINGLELINE);
  662. rc.top += pDC->GetTextExtent(m_strTitle).cy;
  663. if (bLayoutRTL)
  664. {
  665. rc.DeflateRect(15, 12, 10, 0);
  666. }
  667. else
  668. {
  669. rc.DeflateRect(10, 12, 15, 0);
  670. }
  671. }
  672. if (bDrawImage && !bDrawImageTop)
  673. {
  674. CPoint ptIcon = bLayoutRTL ? CPoint(rc.right - szImage.cx, rc.top) : rc.TopLeft();
  675. m_pIcon->Draw(pDC, ptIcon);
  676. if (bLayoutRTL) rc.right -= szImage.cx + 5; else rc.left += szImage.cx + 5;
  677. }
  678. pDC->DrawText(str, rc, dwFlags | DT_WORDBREAK);
  679. }
  680. void CXTPToolTipContextToolTip::DrawBackground(CDC* pDC, TOOLITEM* /*lpToolInfo*/, CRect rc)
  681. {
  682. if (GetStyle() & XTP_TTS_OFFICE2007FRAME)
  683. {
  684. COLORREF clrLight = XTPOffice2007Images()->GetImageColor(_T("Window"), _T("TooltipLight"));
  685. COLORREF clrDark = XTPOffice2007Images()->GetImageColor(_T("Window"), _T("TooltipDark"));
  686. if (clrLight == COLORREF_NULL) clrLight = RGB(255, 255, 255);
  687. if (clrDark == COLORREF_NULL) clrDark = RGB(201, 217, 239);
  688. XTPDrawHelpers()->GradientFill(pDC, rc, clrLight, clrDark, FALSE);
  689. CXTPOffice2007Image* pImage = XTPOffice2007Images()->LoadFile(_T("TOOLTIPFRAME"));
  690. if (pImage)
  691. {
  692. pImage->DrawImage(pDC, rc, pImage->GetSource(0, 1), CRect(3, 3, 3, 3), 0xFF00FF);
  693. }
  694. else
  695. {
  696. COLORREF clrBorder = XTPOffice2007Images()->GetImageColor(_T("Window"), _T("TooltipBorder"));
  697. if (clrBorder == COLORREF_NULL) clrBorder = RGB(118, 118, 118);
  698. pDC->Draw3dRect(rc, clrBorder, clrBorder);
  699. }
  700. }
  701. else
  702. {
  703. pDC->FillSolidRect(rc, m_pContext->GetTipBkColor());
  704. if (GetStyle() & XTP_TTS_OFFICEFRAME)
  705. pDC->Draw3dRect(rc, GetSysColor(COLOR_3DFACE), 0);
  706. else
  707. pDC->Draw3dRect(rc, 0, 0);
  708. }
  709. }
  710. void CXTPToolTipContextToolTip::OnPaint()
  711. {
  712. CPaintDC dc(this); // device context for painting
  713. CXTPClientRect rc(this);
  714. DrawBackground(&dc, &m_toolVisible, rc);
  715. COLORREF clrTextColor = m_pContext->GetTipTextColor();
  716. dc.SetBkMode(TRANSPARENT);
  717. dc.SetTextColor(clrTextColor);
  718. CXTPFontDC font(&dc, &m_pContext->m_fnt);
  719. DrawEntry(&dc, &m_toolVisible, rc);
  720. }
  721. BOOL CXTPToolTipContextToolTip::OnEraseBkgnd(CDC* /*pDC*/)
  722. {
  723. return TRUE;
  724. }
  725. LRESULT CXTPToolTipContextToolTip::OnNcHitTest(CPoint /*point*/)
  726. {
  727. return (LRESULT)HTTRANSPARENT;
  728. }
  729. int CXTPToolTipContextToolTip::OnMouseActivate(CWnd* /*pDesktopWnd*/, UINT /*nHitTest*/, UINT /*message*/)
  730. {
  731. return MA_NOACTIVATE;
  732. }
  733. void CXTPToolTipContextToolTip::OnMouseMove(UINT /*nFlags*/, CPoint /*point*/)
  734. {
  735. SetVisibleTool(NULL);
  736. }
  737. void CXTPToolTipContextToolTip::OnTimer(UINT_PTR nIDEvent)
  738. {
  739. if (nIDEvent == m_nDelayTimer)
  740. {
  741. if (!m_toolDelay.IsEmpty())
  742. {
  743. TOOLITEM* pVisibleTool = FindTool();
  744. if (m_toolDelay.IsEqual(pVisibleTool))
  745. {
  746. SetVisibleTool(pVisibleTool);
  747. }
  748. }
  749. KillTimer(m_nDelayTimer);
  750. m_nDelayTimer = 0;
  751. m_toolDelay.Reset();
  752. }
  753. CWnd::OnTimer(nIDEvent);
  754. }
  755. //////////////////////////////////////////////////////////////////////////
  756. // CXTPToolTipContext::CStandardToolTip
  757. class CXTPToolTipContext::CStandardToolTip : public CToolTipCtrl
  758. {
  759. DECLARE_MESSAGE_MAP()
  760. LRESULT OnWindowFromPoint(WPARAM, LPARAM);
  761. };
  762. typedef CXTPToolTipContext::CStandardToolTip CXTPToolTipContextStandardTip;
  763. BEGIN_MESSAGE_MAP(CXTPToolTipContextStandardTip, CToolTipCtrl)
  764. ON_MESSAGE(TTM_WINDOWFROMPOINT, OnWindowFromPoint)
  765. END_MESSAGE_MAP()
  766. LRESULT CXTPToolTipContext::CStandardToolTip::OnWindowFromPoint(WPARAM, LPARAM)
  767. {
  768. HWND hWnd = (HWND)Default();
  769. if ((hWnd != NULL) && (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD) && (::SendMessage(hWnd, XTP_TTM_WINDOWFROMPOINT, 0, 0) == 1))
  770. {
  771. return (LRESULT)::GetParent(hWnd);
  772. }
  773. return (LRESULT)hWnd;
  774. }
  775. //////////////////////////////////////////////////////////////////////////
  776. // CXTPToolTipContext::CLunaToolTip
  777. class CXTPToolTipContext::CLunaToolTip : public CXTPToolTipContextToolTip
  778. {
  779. public:
  780. CLunaToolTip(CXTPToolTipContext* pContext)
  781. : CXTPToolTipContextToolTip(pContext)
  782. {
  783. }
  784. void DrawBackground(CDC* pDC, TOOLITEM* /*lpToolInfo*/, CRect rc)
  785. {
  786. switch (XTPColorManager()->GetCurrentSystemTheme())
  787. {
  788. case xtpSystemThemeBlue:
  789. case xtpSystemThemeRoyale:
  790. case xtpSystemThemeAero:
  791. XTPDrawHelpers()->GradientFill(pDC, rc, RGB(255, 212, 151), RGB(255, 242, 200), FALSE);
  792. pDC->Draw3dRect(rc, RGB(0, 0, 128), RGB(0, 0, 128));
  793. break;
  794. case xtpSystemThemeOlive:
  795. XTPDrawHelpers()->GradientFill(pDC, rc, RGB(255, 212, 151), RGB(255, 242, 200), FALSE);
  796. pDC->Draw3dRect(rc, RGB(63, 93, 56), RGB(63, 93, 56));
  797. break;
  798. case xtpSystemThemeSilver:
  799. XTPDrawHelpers()->GradientFill(pDC, rc, RGB(255, 212, 151), RGB(255, 242, 200), FALSE);
  800. pDC->Draw3dRect(rc, RGB(75, 75, 111), RGB(75, 75, 111));
  801. break;
  802. default:
  803. XTPDrawHelpers()->GradientFill(pDC, rc, m_pContext->GetTipBkColor(), RGB(255, 255, 255), FALSE);
  804. pDC->Draw3dRect(rc, 0, 0);
  805. }
  806. }
  807. };
  808. //////////////////////////////////////////////////////////////////////////
  809. // CXTPToolTipContext::CRichEditToolTip
  810. class CXTPToolTipContext::CRichEditToolTip : public CXTPToolTipContextToolTip
  811. {
  812. public:
  813. CRichEditToolTip(CXTPToolTipContext* pContext)
  814. : CXTPToolTipContextToolTip(pContext)
  815. {
  816. }
  817. protected:
  818. virtual void DrawEntry(CDC* pDC, TOOLITEM* lpToolInfo, CRect rc);
  819. virtual CSize GetToolSize(TOOLITEM* lpToolInfo);
  820. protected:
  821. CXTPRichRender m_render;
  822. };
  823. CSize CXTPToolTipContext::CRichEditToolTip::GetToolSize(TOOLITEM* lpToolInfo)
  824. {
  825. if (!m_render.GetTextService())
  826. return CSize(0);
  827. CString sText = GetToolText(lpToolInfo);
  828. if (sText.IsEmpty())
  829. return CSize(0);
  830. CClientDC dc(this);
  831. CXTPFontDC font(&dc, &m_pContext->m_fnt);
  832. CHARFORMATW cf;
  833. ZeroMemory(&cf, sizeof(CHARFORMATW));
  834. cf.cbSize = sizeof(CHARFORMATW);
  835. cf.dwMask = CFM_BOLD | CFM_COLOR | CFM_ITALIC | CFM_PROTECTED | CFM_STRIKEOUT | CFM_UNDERLINE;
  836. cf.crTextColor = m_pContext->GetTipTextColor();
  837. LOGFONT lf;
  838. if (m_pContext->GetFont()->GetLogFont(&lf))
  839. {
  840. cf.yHeight = -MulDiv(lf.lfHeight, 1440, ::GetDeviceCaps(dc, LOGPIXELSY));
  841. WCSNCPY_S(cf.szFaceName, XTP_CT2CW(lf.lfFaceName), LF_FACESIZE);
  842. cf.dwMask |= CFM_FACE | CFM_SIZE;
  843. }
  844. m_render.SetText(NULL);
  845. m_render.SetDefaultCharFormat(&cf);
  846. m_render.SetText(sText);
  847. CRect rcMargin = m_pContext->GetMargin();
  848. CSize szMargin(3 + rcMargin.left + rcMargin.right + 3, 3 + rcMargin.top + rcMargin.bottom + 3);
  849. CSize size = m_render.GetTextExtent(&dc, GetMaxTipWidth() - szMargin.cx);
  850. size += szMargin;
  851. return size;
  852. }
  853. void CXTPToolTipContext::CRichEditToolTip::DrawEntry(CDC* pDC, TOOLITEM* /*lpToolInfo*/, CRect rc)
  854. {
  855. rc.DeflateRect(m_pContext->GetMargin());
  856. rc.DeflateRect(3, 3, 3, 3);
  857. m_render.DrawText(pDC, rc);
  858. }
  859. class CXTPToolTipContext::CMarkupToolTip : public CXTPToolTipContextToolTip
  860. {
  861. public:
  862. CMarkupToolTip(CXTPToolTipContext* pContext)
  863. : CXTPToolTipContextToolTip(pContext)
  864. {
  865. m_pUIElement = NULL;
  866. m_pMarkupContext = XTPMarkupCreateContext();
  867. }
  868. ~CMarkupToolTip()
  869. {
  870. XTPMarkupReleaseElement(m_pUIElement);
  871. XTPMarkupReleaseContext(m_pMarkupContext);
  872. }
  873. protected:
  874. virtual void DrawEntry(CDC* pDC, TOOLITEM* lpToolInfo, CRect rc);
  875. virtual CSize GetToolSize(TOOLITEM* lpToolInfo);
  876. protected:
  877. CXTPMarkupUIElement* m_pUIElement;
  878. CXTPMarkupContext* m_pMarkupContext;
  879. };
  880. CSize CXTPToolTipContext::CMarkupToolTip::GetToolSize(TOOLITEM* lpToolInfo)
  881. {
  882. XTPMarkupReleaseElement(m_pUIElement);
  883. CString sText = GetToolText(lpToolInfo);
  884. if (sText.IsEmpty())
  885. return CSize(0);
  886. XTPMarkupSetDefaultFont(m_pMarkupContext, (HFONT)m_pContext->GetFont()->GetSafeHandle(), m_pContext->GetTipTextColor());
  887. m_pUIElement = XTPMarkupParseText(m_pMarkupContext, sText);
  888. if (!m_pUIElement)
  889. {
  890. return CXTPToolTipContextToolTip::GetToolSize(lpToolInfo);
  891. }
  892. CRect rcMargin = m_pContext->GetMargin();
  893. CSize szMargin(3 + rcMargin.left + rcMargin.right + 3, 3 + rcMargin.top + rcMargin.bottom + 3);
  894. CSize size = XTPMarkupMeasureElement(m_pUIElement, GetMaxTipWidth() - szMargin.cx);
  895. size += szMargin;
  896. return size;
  897. }
  898. void CXTPToolTipContext::CMarkupToolTip::DrawEntry(CDC* pDC, TOOLITEM* lpToolInfo, CRect rc)
  899. {
  900. if (m_pUIElement)
  901. {
  902. CRect rcMargin = m_pContext->GetMargin();
  903. CRect rcText(rc);
  904. rcText.DeflateRect(3 + rcMargin.left, 3 + rcMargin.top, rcMargin.right + 3, rcMargin.bottom + 3);
  905. XTPMarkupRenderElement(m_pUIElement, pDC->GetSafeHdc(), rcText);
  906. }
  907. else
  908. {
  909. CXTPToolTipContextToolTip::DrawEntry(pDC, lpToolInfo, rc);
  910. }
  911. }
  912. #ifndef _XTP_EXCLUDE_HTML
  913. //////////////////////////////////////////////////////////////////////////
  914. // CXTPToolTipContext::CHTMLToolTip
  915. class CXTPToolTipContext::CHTMLToolTip : public CXTPToolTipContextToolTip
  916. {
  917. public:
  918. CHTMLToolTip(CXTPToolTipContext* pContext);
  919. ~CHTMLToolTip();
  920. protected:
  921. virtual void DrawEntry(CDC* pDC, TOOLITEM* lpToolInfo, CRect rc);
  922. virtual CSize GetToolSize(TOOLITEM* lpToolInfo);
  923. virtual void OnVisibleChanged(BOOL bVisble);
  924. protected:
  925. DECLARE_INTERFACE_MAP()
  926. BEGIN_INTERFACE_PART(OleClientSite, IOleClientSite)
  927. STDMETHOD(SaveObject)( void) { return E_NOTIMPL;}
  928. STDMETHOD (GetMoniker)(
  929. /* [in] */ DWORD /*dwAssign*/,
  930. /* [in] */ DWORD /*dwWhichMoniker*/,
  931. /* [out] */ IMoniker ** /*ppmk*/) { return E_NOTIMPL;}
  932. STDMETHOD(GetContainer)(
  933. /* [out] */ IOleContainer ** /*ppContainer*/) { return E_NOTIMPL;}
  934. STDMETHOD(ShowObject)( void) { return E_NOTIMPL;}
  935. STDMETHOD(OnShowWindow)(
  936. /* [in] */ BOOL /*fShow*/) { return E_NOTIMPL;}
  937. STDMETHOD(RequestNewObjectLayout)( void) { return E_NOTIMPL;}
  938. END_INTERFACE_PART(OleClientSite)
  939. BEGIN_INTERFACE_PART(DocHostUIHandler, IDocHostUIHandler)
  940. STDMETHOD(ShowContextMenu)(/* [in] */ DWORD dwID,
  941. /* [in] */ POINT __RPC_FAR *ppt,
  942. /* [in] */ IUnknown __RPC_FAR *pcmdtReserved,
  943. /* [in] */ IDispatch __RPC_FAR *pdispReserved);
  944. STDMETHOD(GetHostInfo)(
  945. /* [out][in] */ DOCHOSTUIINFO __RPC_FAR *pInfo);
  946. STDMETHOD(ShowUI)(
  947. /* [in] */ DWORD dwID,
  948. /* [in] */ IOleInPlaceActiveObject __RPC_FAR *pActiveObject,
  949. /* [in] */ IOleCommandTarget __RPC_FAR *pCommandTarget,
  950. /* [in] */ IOleInPlaceFrame __RPC_FAR *pFrame,
  951. /* [in] */ IOleInPlaceUIWindow __RPC_FAR *pDoc);
  952. STDMETHOD(HideUI)(void);
  953. STDMETHOD(UpdateUI)(void);
  954. STDMETHOD(EnableModeless)(/* [in] */ BOOL fEnable);
  955. STDMETHOD(OnDocWindowActivate)(/* [in] */ BOOL fEnable);
  956. STDMETHOD(OnFrameWindowActivate)(/* [in] */ BOOL fEnable);
  957. STDMETHOD(ResizeBorder)(
  958. /* [in] */ LPCRECT prcBorder,
  959. /* [in] */ IOleInPlaceUIWindow __RPC_FAR *pUIWindow,
  960. /* [in] */ BOOL fRameWindow);
  961. STDMETHOD(TranslateAccelerator)(
  962. /* [in] */ LPMSG lpMsg,
  963. /* [in] */ const GUID __RPC_FAR *pguidCmdGroup,
  964. /* [in] */ DWORD nCmdID);
  965. STDMETHOD(GetOptionKeyPath)(
  966. /* [out] */ LPOLESTR __RPC_FAR *pchKey,
  967. /* [in] */ DWORD dw);
  968. STDMETHOD(GetDropTarget)(
  969. /* [in] */ IDropTarget __RPC_FAR *pDropTarget,
  970. /* [out] */ IDropTarget __RPC_FAR *__RPC_FAR *ppDropTarget);
  971. STDMETHOD(GetExternal)(
  972. /* [out] */ IDispatch __RPC_FAR *__RPC_FAR *ppDispatch);
  973. STDMETHOD(TranslateUrl)(
  974. /* [in] */ DWORD dwTranslate,
  975. /* [in] */ OLECHAR __RPC_FAR *pchURLIn,
  976. /* [out] */ OLECHAR __RPC_FAR *__RPC_FAR *ppchURLOut);
  977. STDMETHOD(FilterDataObject)(
  978. /* [in] */ IDataObject __RPC_FAR *pDO,
  979. /* [out] */ IDataObject __RPC_FAR *__RPC_FAR *ppDORet);
  980. END_INTERFACE_PART(DocHostUIHandler)
  981. protected:
  982. CBitmap m_bmpScreen;
  983. CWnd m_wndBrowser;
  984. IWebBrowser2* m_pBrowserApp;
  985. };
  986. //////////////////////////////////////////////////////////////////////////
  987. // CWebBrowserSite
  988. BEGIN_INTERFACE_MAP(CXTPToolTipContext::CHTMLToolTip, CWnd)
  989. INTERFACE_PART(CXTPToolTipContext::CHTMLToolTip, IID_IOleClientSite, OleClientSite)
  990. INTERFACE_PART(CXTPToolTipContext::CHTMLToolTip, IID_IDocHostUIHandler, DocHostUIHandler)
  991. END_INTERFACE_MAP()
  992. #define IMPLEMENT_INTERFACE_PART(theClass, localClass)
  993. STDMETHODIMP_(ULONG) theClass::X##localClass::AddRef()
  994. {
  995. METHOD_PROLOGUE(theClass, localClass)
  996. return pThis->ExternalAddRef();
  997. }
  998. STDMETHODIMP_(ULONG) theClass::X##localClass::Release()
  999. {
  1000. METHOD_PROLOGUE(theClass, localClass)
  1001. return pThis->ExternalRelease();
  1002. }
  1003. STDMETHODIMP theClass::X##localClass::QueryInterface(REFIID riid, void **ppvObj)
  1004. {
  1005. METHOD_PROLOGUE(theClass, localClass)
  1006. HRESULT hr = (HRESULT)pThis->ExternalQueryInterface(&riid, ppvObj);
  1007. return hr;
  1008. }
  1009. IMPLEMENT_INTERFACE_PART(CXTPToolTipContext::CHTMLToolTip, OleClientSite)
  1010. IMPLEMENT_INTERFACE_PART(CXTPToolTipContext::CHTMLToolTip, DocHostUIHandler)
  1011. STDMETHODIMP CXTPToolTipContext::CHTMLToolTip::XDocHostUIHandler::GetHostInfo( DOCHOSTUIINFO* pInfo )
  1012. {
  1013. pInfo->dwFlags = 0x40000 | DOCHOSTUIFLAG_NO3DBORDER;
  1014. pInfo->dwFlags |= DOCHOSTUIFLAG_DIALOG;
  1015. pInfo->dwFlags |= DOCHOSTUIFLAG_SCROLL_NO;
  1016. pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT;
  1017. return S_OK;
  1018. }
  1019. STDMETHODIMP  CXTPToolTipContext::CHTMLToolTip::XDocHostUIHandler::ShowUI(
  1020. DWORD /*dwID*/,
  1021. IOleInPlaceActiveObject * /*pActiveObject*/,
  1022. IOleCommandTarget * /*pCommandTarget*/,
  1023. IOleInPlaceFrame * /*pFrame*/,
  1024. IOleInPlaceUIWindow * /*pDoc*/)
  1025. {
  1026. return S_OK;
  1027. }
  1028. STDMETHODIMP  CXTPToolTipContext::CHTMLToolTip::XDocHostUIHandler::HideUI(void)
  1029. {
  1030. return S_OK;
  1031. }
  1032. STDMETHODIMP  CXTPToolTipContext::CHTMLToolTip::XDocHostUIHandler::UpdateUI(void)
  1033. {
  1034. return S_OK;
  1035. }
  1036. STDMETHODIMP  CXTPToolTipContext::CHTMLToolTip::XDocHostUIHandler::EnableModeless(BOOL /*fEnable*/)
  1037. {
  1038. return E_NOTIMPL;
  1039. }
  1040. STDMETHODIMP  CXTPToolTipContext::CHTMLToolTip::XDocHostUIHandler::OnDocWindowActivate(BOOL /*fActivate*/)
  1041. {
  1042. return E_NOTIMPL;
  1043. }
  1044. STDMETHODIMP  CXTPToolTipContext::CHTMLToolTip::XDocHostUIHandler::OnFrameWindowActivate(BOOL /*fActivate*/)
  1045. {
  1046. return E_NOTIMPL;
  1047. }
  1048. STDMETHODIMP CXTPToolTipContext::CHTMLToolTip::XDocHostUIHandler::ResizeBorder(
  1049. LPCRECT /*prcBorder*/,
  1050. IOleInPlaceUIWindow* /*pUIWindow*/,
  1051. BOOL /*fRameWindow*/)
  1052. {
  1053. return E_NOTIMPL;
  1054. }
  1055. STDMETHODIMP  CXTPToolTipContext::CHTMLToolTip::XDocHostUIHandler::ShowContextMenu(
  1056. DWORD /*dwID*/,
  1057. POINT* /*pptPosition*/,
  1058. IUnknown* /*pCommandTarget*/,
  1059. IDispatch* /*pDispatchObjectHit*/)
  1060. {
  1061. return S_OK;
  1062. }
  1063. STDMETHODIMP  CXTPToolTipContext::CHTMLToolTip::XDocHostUIHandler::TranslateAccelerator(LPMSG /*lpMsg*/,
  1064. /* [in] */ const GUID __RPC_FAR* /*pguidCmdGroup*/,
  1065. /* [in] */ DWORD /*nCmdID*/)
  1066. {
  1067. return S_FALSE;
  1068. }
  1069. STDMETHODIMP  CXTPToolTipContext::CHTMLToolTip::XDocHostUIHandler::GetOptionKeyPath(BSTR* /*pbstrKey*/, DWORD)
  1070. {
  1071. return E_NOTIMPL;
  1072. }
  1073. STDMETHODIMP CXTPToolTipContext::CHTMLToolTip::XDocHostUIHandler::GetDropTarget(
  1074. /* [in] */ IDropTarget __RPC_FAR* /*pDropTarget*/,
  1075. /* [out] */ IDropTarget __RPC_FAR *__RPC_FAR* /*ppDropTarget*/)
  1076. {
  1077. return E_NOTIMPL;
  1078. }
  1079. STDMETHODIMP CXTPToolTipContext::CHTMLToolTip::XDocHostUIHandler::GetExternal(
  1080. /* [out] */ IDispatch __RPC_FAR *__RPC_FAR* /*ppDispatch*/)
  1081. {
  1082. return E_NOTIMPL;
  1083. }
  1084. STDMETHODIMP CXTPToolTipContext::CHTMLToolTip::XDocHostUIHandler::TranslateUrl(
  1085. /* [in] */ DWORD /*dwTranslate*/,
  1086. /* [in] */ OLECHAR __RPC_FAR* /*pchURLIn*/,
  1087. /* [out] */ OLECHAR __RPC_FAR *__RPC_FAR* /*ppchURLOut*/)
  1088. {
  1089. return E_NOTIMPL;
  1090. }
  1091. STDMETHODIMP CXTPToolTipContext::CHTMLToolTip::XDocHostUIHandler::FilterDataObject(
  1092. /* [in] */ IDataObject __RPC_FAR* /*pDO*/,
  1093. /* [out] */ IDataObject __RPC_FAR *__RPC_FAR* /*ppDORet*/)
  1094. {
  1095. return E_NOTIMPL;
  1096. }
  1097. CXTPToolTipContext::CHTMLToolTip::CHTMLToolTip(CXTPToolTipContext* pContext)
  1098. : CXTPToolTipContextToolTip(pContext)
  1099. {
  1100. AfxEnableControlContainer();
  1101. m_pBrowserApp = 0;
  1102. }
  1103. CXTPToolTipContext::CHTMLToolTip::~CHTMLToolTip()
  1104. {
  1105. SAFE_RELEASE(m_pBrowserApp);
  1106. }
  1107. CSize CXTPToolTipContext::CHTMLToolTip::GetToolSize(TOOLITEM* lpToolInfo)
  1108. {
  1109. m_bmpScreen.DeleteObject();
  1110. if (m_wndBrowser.GetSafeHwnd() == 0)
  1111. {
  1112. // create the control window
  1113. // AFX_IDW_PANE_FIRST is a safe but arbitrary ID
  1114. if (!m_wndBrowser.CreateControl(CLSID_WebBrowser, 0,
  1115. WS_VISIBLE | WS_CHILD, CRect(0, 0, 200, 200), this, AFX_IDW_PANE_FIRST))
  1116. {
  1117. return 0;
  1118. }
  1119. LPUNKNOWN lpUnk = m_wndBrowser.GetControlUnknown();
  1120. HRESULT hr = lpUnk->QueryInterface(IID_IWebBrowser2, (void**) &m_pBrowserApp);
  1121. if (!SUCCEEDED(hr) || !m_pBrowserApp)
  1122. {
  1123. m_pBrowserApp = NULL;
  1124. m_wndBrowser.DestroyWindow();
  1125. return 0;
  1126. }
  1127. IOleObject* spOleObj = NULL;
  1128. m_pBrowserApp->QueryInterface(IID_IOleObject, (void**)&spOleObj);
  1129. if (spOleObj)
  1130. {
  1131. spOleObj->SetClientSite((IOleClientSite*)GetInterface(&IID_IOleClientSite));
  1132. spOleObj->Release();
  1133. }
  1134. CString strFaceName = _T("Arial");
  1135. int nFontSize = 11;
  1136. LOGFONT lf;
  1137. if (m_pContext->GetFont()->GetLogFont(&lf))
  1138. {
  1139. strFaceName = lf.lfFaceName;
  1140. nFontSize = lf.lfHeight < 0 ? -lf.lfHeight : lf.lfHeight;
  1141. }
  1142. CString strBackColor; COLORREF clrBack = m_pContext->GetTipBkColor();
  1143. strBackColor.Format(_T("#%0.2x%0.2x%0.2x"), GetRValue(clrBack), GetGValue(clrBack), GetBValue(clrBack));
  1144. CString strBody;
  1145. strBody.Format(
  1146. _T("about:<head><style> body {font-family:%s; font-size:%i;}")
  1147. _T("table {font-family:%s; font-size:%i;}</style></head>")
  1148. _T("<body topmargin=0 leftmargin=0 bottommargin=0 rightmargin=0 bgColor=%s></body>"),
  1149. (LPCTSTR)strFaceName, nFontSize, (LPCTSTR)strFaceName, nFontSize, (LPCTSTR)strBackColor);
  1150. COleVariant varEmpty;
  1151. BSTR bstrBody = strBody.AllocSysString();
  1152. m_pBrowserApp->Navigate(bstrBody,
  1153. (VARIANT*)&varEmpty,
  1154. (VARIANT*)&varEmpty,
  1155. (VARIANT*)&varEmpty,
  1156. (VARIANT*)&varEmpty);
  1157. SysFreeString(bstrBody);
  1158. READYSTATE rs;
  1159. do
  1160. {
  1161. AfxGetApp()->PumpMessage();
  1162. m_pBrowserApp->get_ReadyState (&rs);
  1163. }
  1164. while (rs != READYSTATE_COMPLETE);
  1165. }
  1166. CString strText = GetToolText(lpToolInfo);
  1167. if (strText.IsEmpty())
  1168. return CSize(0);
  1169. IDispatch* lpDocument = NULL;
  1170. m_pBrowserApp->get_Document(&lpDocument);
  1171. if (lpDocument == 0)
  1172. return 0;
  1173. // Verify that what we get is a pointer to a IHTMLDocument2
  1174. // interface. To be sure, let's query for
  1175. // the IHTMLDocument2 interface (through smart pointers)
  1176. IHTMLDocument2* lpHTML = NULL;
  1177. lpDocument->QueryInterface(IID_IHTMLDocument2, (void**)&lpHTML);
  1178. if (lpHTML == 0)
  1179. {
  1180. lpDocument->Release();
  1181. return 0;
  1182. }
  1183. // The previous step is sufficient to keep Explorer aside
  1184. // without an explicit check against the loader module
  1185. // Extract the source code of the document
  1186. IHTMLElement* lpBody = NULL;
  1187. // Get the BODY object
  1188. HRESULT hr = lpHTML->get_body(&lpBody);
  1189. if (FAILED(hr) || (lpBody == 0))
  1190. {
  1191. lpHTML->Release();
  1192. lpDocument->Release();
  1193. return 0;
  1194. }
  1195. BSTR bstrText = strText.AllocSysString();
  1196. lpBody->put_innerHTML(bstrText);
  1197. SysFreeString(bstrText);
  1198. m_wndBrowser.MoveWindow(0, 0, 650, 200);
  1199. IHTMLTextContainer* lpHTMLContainer = NULL;
  1200. lpBody->QueryInterface(IID_IHTMLTextContainer, (void**)&lpHTMLContainer);
  1201. if (lpHTMLContainer == 0)
  1202. {
  1203. lpBody->Release();
  1204. lpHTML->Release();
  1205. lpDocument->Release();
  1206. return 0;
  1207. }
  1208. long nScrollHeight, nScrollWidth;
  1209. lpHTMLContainer->get_scrollHeight(&nScrollHeight);
  1210. int nBestWidth = m_pContext->GetMaxTipWidth();
  1211. int nBestHeight = nScrollHeight;
  1212. int cxFirst = 0;
  1213. int cxLast = nBestWidth * 2;
  1214. do
  1215. {
  1216. // Taking a guess
  1217. int cx = (cxFirst + cxLast) / 2;
  1218. m_wndBrowser.MoveWindow(0, 0, cx, nScrollHeight);
  1219. lpHTMLContainer->get_scrollHeight(&nScrollHeight);
  1220. lpHTMLContainer->get_scrollWidth(&nScrollWidth);
  1221. if (nScrollWidth > cx && nScrollHeight <= nBestHeight)
  1222. {
  1223. nBestWidth = nScrollWidth;
  1224. break;
  1225. }
  1226. if (nScrollHeight > nBestHeight)
  1227. {
  1228. // If the control required a larger height, then
  1229. // it's too narrow.
  1230. cxFirst = cx + 1;
  1231. }
  1232. else
  1233. {
  1234. // If the control didn't required a larger height,
  1235. // then it's too wide.
  1236. cxLast = cx - 1;
  1237. nBestWidth = cx;
  1238. }
  1239. }
  1240. while (cxFirst <= cxLast);
  1241. m_wndBrowser.MoveWindow(0, 0, nBestWidth, nBestHeight);
  1242. CSize sz(nBestWidth, nBestHeight);
  1243. CRect rcMargin = m_pContext->GetMargin();
  1244. #if 0
  1245. if (sz.cx > 0 && sz.cy > 0)
  1246. {
  1247. CWindowDC dcPaint(this);
  1248. CDC dc;
  1249. dc.CreateCompatibleDC(&dcPaint);
  1250. m_bmpScreen.CreateCompatibleBitmap(&dcPaint, sz.cx, sz.cy);
  1251. CBitmap* pOldBitmap = dc.SelectObject(&m_bmpScreen);
  1252. dc.FillSolidRect(0, 0, sz.cx, sz.cy, m_pContext->GetTipBkColor());
  1253. m_wndBrowser.SendMessage(WM_PRINT, (WPARAM)dc.GetSafeHdc(), PRF_CLIENT | PRF_CHILDREN);
  1254. dc.SelectObject(pOldBitmap);
  1255. }
  1256. m_wndBrowser.MoveWindow(0, 0, 0, 0);
  1257. #else
  1258. m_wndBrowser.MoveWindow(3 + rcMargin.left, 3 + rcMargin.top, nBestWidth, nBestHeight);
  1259. #endif
  1260. CSize szMargin(3 + rcMargin.left + rcMargin.right + 3, 3 + rcMargin.top + rcMargin.bottom + 3);
  1261. sz += szMargin;
  1262. lpHTMLContainer->Release();
  1263. lpBody->Release();
  1264. lpHTML->Release();
  1265. lpDocument->Release();
  1266. return sz;
  1267. }
  1268. void CXTPToolTipContext::CHTMLToolTip::DrawEntry(CDC* pDC, TOOLITEM* /*lpToolInfo*/, CRect rc)
  1269. {
  1270. rc.DeflateRect(m_pContext->GetMargin());
  1271. rc.DeflateRect(3, 3, 3, 3);
  1272. if (m_bmpScreen.GetSafeHandle())
  1273. {
  1274. pDC->DrawState(rc.TopLeft(), CSize(0, 0), &m_bmpScreen, DSS_NORMAL, 0);
  1275. }
  1276. }
  1277. void CXTPToolTipContext::CHTMLToolTip::OnVisibleChanged(BOOL bVisble)
  1278. {
  1279. if (!bVisble)
  1280. {
  1281. m_bmpScreen.DeleteObject();
  1282. }
  1283. }
  1284. #endif // _XTP_EXCLUDE_HTML
  1285. //////////////////////////////////////////////////////////////////////
  1286. // Construction/Destruction
  1287. //////////////////////////////////////////////////////////////////////
  1288. CXTPToolTipContext::CXTPToolTipContext()
  1289. {
  1290. m_pToolTip = 0;
  1291. m_bShowTitleAndDescription = FALSE;
  1292. m_bShowImage = FALSE;
  1293. m_nImageSize = ICON_BIG;
  1294. m_nImageBase = 0;
  1295. m_toolStyle = xtpToolTipStandard;
  1296. m_nMaxTipWidth = ::GetSystemMetrics(SM_CXSCREEN) / 2;
  1297. ZeroMemory(&m_lastInfo, sizeof(m_lastInfo));
  1298. m_dwComCtlVersion = XTPSystemVersion()->GetComCtlVersion();
  1299. m_clrTipTextColor = m_clrTipBkColor = COLORREF_NULL;
  1300. m_nIconTitle = TTI_INFO;
  1301. m_dwStyle = TTS_NOPREFIX;
  1302. m_rcMargin.SetRect(0, 0, 0, 0);
  1303. m_nDelayAutoPop = m_nDelayInitial = m_nDelayReshow = -1;
  1304. NONCLIENTMETRICS ncm;
  1305. ::ZeroMemory(&ncm, sizeof(NONCLIENTMETRICS));
  1306. ncm.cbSize = sizeof(NONCLIENTMETRICS);
  1307. VERIFY(::SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
  1308. sizeof(NONCLIENTMETRICS), &ncm, 0));
  1309. ncm.lfStatusFont.lfWeight = FW_NORMAL;
  1310. m_fnt.CreateFontIndirect(&ncm.lfStatusFont);
  1311. ncm.lfStatusFont.lfWeight = FW_BOLD;
  1312. m_fntTitle.CreateFontIndirect(&ncm.lfStatusFont);
  1313. }
  1314. CXTPToolTipContext::~CXTPToolTipContext()
  1315. {
  1316. SAFE_DELETEWINDOW(m_pToolTip);
  1317. if (m_pModuleContext == this)
  1318. {
  1319. m_pModuleContext = 0;
  1320. }
  1321. }
  1322. BOOL CXTPToolTipContext::IsBalloonStyleSupported() const
  1323. {
  1324. return m_dwComCtlVersion >= VERSION_IE5;
  1325. }
  1326. void CXTPToolTipContext::ShowTitleAndDescription(BOOL bShowTitleAndDescription, int nIconTitle)
  1327. {
  1328. m_bShowTitleAndDescription = bShowTitleAndDescription;
  1329. m_nIconTitle = nIconTitle;
  1330. }
  1331. void CXTPToolTipContext::ShowImage(BOOL bShowImage, int nImageBase, int nImageSize)
  1332. {
  1333. m_bShowImage = bShowImage;
  1334. m_nImageBase = nImageBase;
  1335. m_nImageSize = nImageSize;
  1336. SAFE_DELETEWINDOW(m_pToolTip);
  1337. }
  1338. void CXTPToolTipContext::FillInToolInfo(TOOLINFO* pTI, HWND hWnd, CRect rect, INT_PTR nHit, const CString& strToolTip)
  1339. {
  1340. #if _MSC_VER < 1200 // MFC 5.0
  1341. if (pTI != NULL && pTI->cbSize >= sizeof(TOOLINFO))
  1342. #else
  1343. if (pTI != NULL && pTI->cbSize >= sizeof(XTP_TOOLTIP_TOOLINFO))
  1344. #endif
  1345. {
  1346. pTI->hwnd = hWnd;
  1347. pTI->rect = rect;
  1348. pTI->uId = nHit;
  1349. pTI->lpszText = (LPTSTR) ::calloc(strToolTip.GetLength() + 1, sizeof(TCHAR));
  1350. if (pTI->lpszText != NULL) STRCPY_S(pTI->lpszText, strToolTip.GetLength() + 1, (LPCTSTR)strToolTip);
  1351. }
  1352. }
  1353. void CXTPToolTipContext::FillInToolInfo(TOOLINFO* pTI, HWND hWnd, CRect rect, INT_PTR nHit,
  1354. const CString& strToolTip, const CString& strTitle, const CString& strDescription, CXTPImageManager* pImageManager)
  1355. {
  1356. FillInToolInfo(pTI, hWnd, rect, nHit, strToolTip);
  1357. if (pTI != NULL && pTI->cbSize == sizeof(XTP_TOOLTIP_TOOLINFO_EX))
  1358. {
  1359. XTP_TOOLTIP_CONTEXT* ptc = ((XTP_TOOLTIP_TOOLINFO_EX*)pTI)->pToolInfo;
  1360. if (!ptc)
  1361. return;
  1362. if (!strDescription.IsEmpty() && !strTitle.IsEmpty())
  1363. {
  1364. ptc->lpszDescription = (LPTSTR)::calloc(strDescription.GetLength() + 1, sizeof(TCHAR));
  1365. if (ptc->lpszDescription != NULL) STRCPY_S(ptc->lpszDescription, strDescription.GetLength() + 1, (LPCTSTR)strDescription);
  1366. ptc->lpszTitle = (LPTSTR)::calloc(strTitle.GetLength() + 1, sizeof(TCHAR));
  1367. if (ptc->lpszTitle != NULL) STRCPY_S(ptc->lpszTitle, strTitle.GetLength() + 1, (LPCTSTR)strTitle);
  1368. }
  1369. ptc->pImageManager = pImageManager;
  1370. }
  1371. }
  1372. void CXTPToolTipContext::SetMargin(LPCRECT lprc)
  1373. {
  1374. if (lprc)
  1375. {
  1376. m_rcMargin = *lprc;
  1377. if (m_pToolTip) m_pToolTip->DestroyWindow();
  1378. }
  1379. }
  1380. void CXTPToolTipContext::SetStyle(XTPToolTipStyle toolStyle)
  1381. {
  1382. if (m_toolStyle != toolStyle && (toolStyle != xtpToolTipBalloon || IsBalloonStyleSupported()))
  1383. {
  1384. m_toolStyle = toolStyle;
  1385. SAFE_DELETEWINDOW(m_pToolTip);
  1386. ModifyToolTipStyle(XTP_TTS_OFFICEFRAME | XTP_TTS_NOSHADOW, m_toolStyle == xtpToolTipOffice ? XTP_TTS_OFFICEFRAME | XTP_TTS_NOSHADOW : 0);
  1387. ModifyToolTipStyle(XTP_TTS_OFFICE2007FRAME, m_toolStyle == xtpToolTipOffice2007 ? XTP_TTS_OFFICE2007FRAME : 0);
  1388. }
  1389. }
  1390. XTPToolTipStyle CXTPToolTipContext::GetStyle() const
  1391. {
  1392. return m_toolStyle;
  1393. }
  1394. void CXTPToolTipContext::SetMaxTipWidth(int iWidth)
  1395. {
  1396. m_nMaxTipWidth = iWidth;
  1397. if (m_pToolTip) m_pToolTip->DestroyWindow();
  1398. }
  1399. int CXTPToolTipContext::GetMaxTipWidth() const
  1400. {
  1401. return m_nMaxTipWidth;
  1402. }
  1403. COLORREF CXTPToolTipContext::GetTipBkColor() const
  1404. {
  1405. return m_clrTipBkColor != COLORREF_NULL ? m_clrTipBkColor :GetXtremeColor(COLOR_INFOBK);
  1406. }
  1407. void CXTPToolTipContext::SetTipBkColor(COLORREF clr)
  1408. {
  1409. m_clrTipBkColor = clr;
  1410. if (m_pToolTip) m_pToolTip->DestroyWindow();
  1411. }
  1412. void CXTPToolTipContext::ModifyToolTipStyle(DWORD dwRemove, DWORD dwAdd)
  1413. {
  1414. DWORD dwStyle = (m_dwStyle & ~dwRemove) | dwAdd;
  1415. if (m_dwStyle != dwStyle)
  1416. {
  1417. m_dwStyle = dwStyle;
  1418. SAFE_DELETEWINDOW(m_pToolTip);
  1419. }
  1420. }
  1421. COLORREF CXTPToolTipContext::GetTipTextColor() const
  1422. {
  1423. return m_clrTipTextColor != COLORREF_NULL ? m_clrTipTextColor :
  1424. m_dwStyle & XTP_TTS_OFFICE2007FRAME ?  RGB(76, 76, 76) : GetXtremeColor(COLOR_INFOTEXT);
  1425. }
  1426. void CXTPToolTipContext::SetTipTextColor(COLORREF clr)
  1427. {
  1428. m_clrTipTextColor = clr;
  1429. if (m_pToolTip) m_pToolTip->DestroyWindow();
  1430. }
  1431. void CXTPToolTipContext::SetDelayTime(DWORD dwDuration, int iTime)
  1432. {
  1433. switch (dwDuration)
  1434. {
  1435. case TTDT_RESHOW:
  1436. m_nDelayReshow = iTime;
  1437. break;
  1438. case TTDT_INITIAL:
  1439. m_nDelayInitial = iTime;
  1440. break;
  1441. case TTDT_AUTOPOP:
  1442. m_nDelayAutoPop = iTime;
  1443. break;
  1444. default:
  1445. ASSERT(FALSE);
  1446. }
  1447. if (m_pToolTip) m_pToolTip->DestroyWindow();
  1448. }
  1449. void CXTPToolTipContext::RelayToolTipMessage(CWnd* pToolTip, MSG* pMsg)
  1450. {
  1451. // transate the message based on TTM_WINDOWFROMPOINT
  1452. MSG msg = *pMsg;
  1453. msg.hwnd = (HWND)pToolTip->SendMessage(TTM_WINDOWFROMPOINT, 0, (LPARAM)&msg.pt);
  1454. CPoint pt = pMsg->pt;
  1455. if (msg.message >= WM_MOUSEFIRST && msg.message <= WM_MOUSELAST)
  1456. ::ScreenToClient(msg.hwnd, &pt);
  1457. msg.lParam = MAKELONG(pt.x, pt.y);
  1458. // relay mouse event before deleting old tool
  1459. pToolTip->SendMessage(TTM_RELAYEVENT, 0, (LPARAM)&msg);
  1460. }
  1461. void CXTPToolTipContext::FilterToolTipMessage(CWnd* pWndHost, UINT message, WPARAM wParam, LPARAM lParam)
  1462. {
  1463. MSG msg;
  1464. msg.wParam = wParam;
  1465. msg.lParam = lParam;
  1466. msg.message = message;
  1467. msg.hwnd = pWndHost->m_hWnd;
  1468. GetCursorPos(&msg.pt);
  1469. FilterToolTipMessage(pWndHost, &msg);
  1470. }
  1471. void CXTPToolTipContext::FilterToolTipMessage(CWnd* pWndHost, MSG* pMsg)
  1472. {
  1473. FilterToolTipMessageHelper(pWndHost, pMsg, TRUE);
  1474. }
  1475. void PASCAL CXTPToolTipContext::FilterToolTipMessageStatic(MSG* pMsg, CWnd* pWnd)
  1476. {
  1477. if (m_pModuleContext)
  1478. {
  1479. m_pModuleContext->FilterToolTipMessageHelper(pWnd, pMsg, FALSE);
  1480. }
  1481. else
  1482. {
  1483. pWnd->FilterToolTipMessage(pMsg);
  1484. }
  1485. }
  1486. void CXTPToolTipContext::SetModuleToolTipContext()
  1487. {
  1488. AFX_MODULE_STATE* pModuleState = _AFX_CMDTARGET_GETSTATE();
  1489. pModuleState->m_pfnFilterToolTipMessage = &CXTPToolTipContext::FilterToolTipMessageStatic;
  1490. m_pModuleContext = this;
  1491. }
  1492. CWnd* CXTPToolTipContext::CreateToolTip(CWnd* /*pOwner*/)
  1493. {
  1494. switch (m_toolStyle)
  1495. {
  1496. case xtpToolTipOffice:
  1497. return new CXTPToolTipContextToolTip(this);
  1498. case xtpToolTipRTF:
  1499. return new CRichEditToolTip(this);
  1500. case xtpToolTipLuna:
  1501. return new CLunaToolTip(this);
  1502. case xtpToolTipOffice2007:
  1503. return new CXTPToolTipContextToolTip(this);
  1504. #ifndef _XTP_EXCLUDE_HTML
  1505. case xtpToolTipHTML:
  1506. return new CHTMLToolTip(this);
  1507. #endif
  1508. case xtpToolTipMarkup:
  1509. return new CMarkupToolTip(this);
  1510. }
  1511. return new CStandardToolTip();
  1512. }
  1513. void CXTPToolTipContext::SetToolTipCtrl(CXTPToolTipContextToolTip* pToolTipCtrl)
  1514. {
  1515. SAFE_DELETEWINDOW(m_pToolTip);
  1516. m_pToolTip = pToolTipCtrl;
  1517. }
  1518. void CXTPToolTipContext::CancelToolTips()
  1519. {
  1520. if (m_pToolTip->GetSafeHwnd() != NULL)
  1521. m_pToolTip->SendMessage(TTM_ACTIVATE, FALSE);
  1522. }
  1523. INT_PTR CXTPToolTipContext::OnToolHitTest(CWnd* pWnd, CPoint point, TOOLINFO* pToolInfo)
  1524. {
  1525. return pWnd->OnToolHitTest(point, pToolInfo);
  1526. }
  1527. void CXTPToolTipContext::FilterToolTipMessageHelper(CWnd* pWndHost, MSG* pMsg, BOOL bIgnoreFlags)
  1528. {
  1529. // this CWnd has tooltips enabled
  1530. UINT message = pMsg->message;
  1531. if ((message == WM_MOUSEMOVE || message == WM_NCMOUSEMOVE || message == WM_MOUSELEAVE ||
  1532. message == WM_LBUTTONUP || message == WM_RBUTTONUP ||
  1533. message == WM_MBUTTONUP) &&
  1534. (GetKeyState(VK_LBUTTON) >= 0 && GetKeyState(VK_RBUTTON) >= 0 &&
  1535. GetKeyState(VK_MBUTTON) >= 0))
  1536. {
  1537. if (!bIgnoreFlags)
  1538. {
  1539. // make sure that tooltips are not already being handled
  1540. CWnd* pWnd = CWnd::FromHandle(pMsg->hwnd);
  1541. while (pWnd != NULL && !(pWnd->m_nFlags & (WF_TOOLTIPS | WF_TRACKINGTOOLTIPS)))
  1542. {
  1543. pWnd = pWnd->GetParent();
  1544. }
  1545. if (pWnd != pWndHost)
  1546. {
  1547. return;
  1548. }
  1549. }
  1550. BOOL bTopParentActive = CXTPDrawHelpers::IsTopParentActive(pWndHost->GetSafeHwnd());
  1551. if (m_pToolTip->GetSafeHwnd() && m_pToolTip->IsWindowVisible() && !bTopParentActive)
  1552. {
  1553. m_pToolTip->SendMessage(TTM_ACTIVATE, FALSE);
  1554. return;
  1555. }
  1556. CWnd* pOwner = pWndHost->GetParentOwner();
  1557. if (m_pToolTip != NULL && m_pToolTip->GetOwner() != pOwner)
  1558. {
  1559. m_pToolTip->DestroyWindow();
  1560. }
  1561. if (m_pToolTip == NULL || m_pToolTip->GetSafeHwnd() == NULL)
  1562. {
  1563. if (m_pToolTip == NULL)
  1564. {
  1565. m_pToolTip = CreateToolTip(pOwner);
  1566. }
  1567. if (!m_pToolTip)
  1568. return;
  1569. if (!m_pToolTip->GetSafeHwnd())
  1570. {
  1571. if (DYNAMIC_DOWNCAST(CXTPToolTipContextToolTip, m_pToolTip))
  1572. {
  1573. ((CXTPToolTipContextToolTip*)m_pToolTip)->Create(pOwner, m_dwStyle | TTS_ALWAYSTIP | TTS_NOPREFIX);
  1574. }
  1575. else if (DYNAMIC_DOWNCAST(CToolTipCtrl, m_pToolTip))
  1576. {
  1577. ((CToolTipCtrl*)m_pToolTip)->Create(pOwner, m_dwStyle | TTS_ALWAYSTIP | TTS_NOPREFIX | (m_toolStyle == xtpToolTipBalloon ? TTS_BALLOON : 0));
  1578. }
  1579. else
  1580. {
  1581. ASSERT(FALSE);
  1582. return;
  1583. }
  1584. }
  1585. if (!m_pToolTip->GetSafeHwnd())
  1586. return;
  1587. m_pToolTip->SetFont(&m_fnt);
  1588. m_pToolTip->SendMessage(TTM_SETMAXTIPWIDTH, 0, m_nMaxTipWidth);
  1589. m_pToolTip->SendMessage(TTM_SETMARGIN, 0, (LPARAM)(LPRECT)&m_rcMargin);
  1590. if (m_clrTipBkColor != COLORREF_NULL)
  1591. m_pToolTip->SendMessage(TTM_SETTIPBKCOLOR, m_clrTipBkColor);
  1592. if (m_clrTipTextColor != COLORREF_NULL)
  1593. m_pToolTip->SendMessage(TTM_SETTIPTEXTCOLOR, m_clrTipTextColor);
  1594. if (m_nDelayReshow != -1)
  1595. m_pToolTip->SendMessage(TTM_SETDELAYTIME, TTDT_RESHOW, MAKELPARAM(m_nDelayReshow, 0));
  1596. if (m_nDelayInitial != -1)
  1597. m_pToolTip->SendMessage(TTM_SETDELAYTIME, TTDT_INITIAL, MAKELPARAM(m_nDelayInitial, 0));
  1598. if (m_nDelayAutoPop != -1)
  1599. m_pToolTip->SendMessage(TTM_SETDELAYTIME, TTDT_AUTOPOP, MAKELPARAM(m_nDelayAutoPop, 0));
  1600. m_pToolTip->SendMessage(TTM_ACTIVATE, FALSE);
  1601. }
  1602. CWnd* pToolTip = m_pToolTip;
  1603. ASSERT_VALID(pToolTip);
  1604. ASSERT(::IsWindow(pToolTip->m_hWnd));
  1605. XTP_TOOLTIP_CONTEXT tc;
  1606. ZeroMemory(&tc, sizeof(tc));
  1607. // determine which tool was hit
  1608. CPoint point = pMsg->pt;
  1609. ::ScreenToClient(pWndHost->m_hWnd, &point);
  1610. XTP_TOOLTIP_TOOLINFO_EX tiHit;
  1611. memset(&tiHit, 0, sizeof(XTP_TOOLTIP_TOOLINFO_EX));
  1612. tiHit.cbSize = m_bShowTitleAndDescription || m_bShowImage ? sizeof(XTP_TOOLTIP_TOOLINFO_EX) : sizeof(XTP_TOOLTIP_TOOLINFO);
  1613. tiHit.pToolInfo = &tc;
  1614. INT_PTR nHit = OnToolHitTest(pWndHost, point, (TOOLINFO*)&tiHit);
  1615. if (m_bShowTitleAndDescription && tc.lpszDescription &&
  1616. tc.lpszTitle && (_tcscmp(tc.lpszDescription, tc.lpszTitle) == 0))
  1617. {
  1618. free(tc.lpszDescription);
  1619. tc.lpszDescription = 0;
  1620. }
  1621. if ((m_dwStyle & TTS_NOPREFIX) == 0)
  1622. {
  1623. CXTPDrawHelpers::StripMnemonics(tiHit.lpszText);
  1624. CXTPDrawHelpers::StripMnemonics(tiHit.pToolInfo->lpszTitle);
  1625. }
  1626. // build new toolinfo and if different than current, register it
  1627. BOOL bTipInfoChanged = m_lastInfo.uId != tiHit.uId || m_lastInfo.hwnd != tiHit.hwnd;
  1628. if (bTipInfoChanged || CRect(m_lastInfo.rect) != CRect(tiHit.rect))
  1629. {
  1630. if (m_lastInfo.cbSize >= sizeof(XTP_TOOLTIP_TOOLINFO) && !bTipInfoChanged)
  1631. pToolTip->SendMessage(TTM_DELTOOL, 0, (LPARAM)&m_lastInfo);
  1632. if (nHit != -1)
  1633. {
  1634. // add new tool and activate the tip
  1635. XTP_TOOLTIP_TOOLINFO_EX ti = tiHit;
  1636. ti.uFlags &= ~(TTF_NOTBUTTON | TTF_ALWAYSTIP);
  1637. VERIFY(pToolTip->SendMessage(TTM_ADDTOOL, 0, (LPARAM)&ti));
  1638. if ((m_toolStyle != xtpToolTipRTF && m_toolStyle != xtpToolTipHTML && m_toolStyle != xtpToolTipMarkup) && ((m_dwComCtlVersion >= VERSION_IE5) || (m_toolStyle != xtpToolTipStandard)))
  1639. {
  1640. if (m_bShowTitleAndDescription && tc.lpszDescription && tc.lpszTitle)
  1641. {
  1642. pToolTip->SendMessage(TTM_SETTITLE, m_nIconTitle, (LPARAM)(LPCTSTR)tc.lpszTitle);
  1643. ti.lpszText = tc.lpszDescription;
  1644. pToolTip->SendMessage(TTM_UPDATETIPTEXT, 0, (LPARAM)&ti);
  1645. }
  1646. else
  1647. {
  1648. pToolTip->SendMessage(TTM_SETTITLE, 0, 0);
  1649. }
  1650. }
  1651. if (m_bShowImage)
  1652. {
  1653. CXTPImageManagerIcon* pIcon = NULL;
  1654. pIcon =  tc.pImageManager ? tc.pImageManager->GetImage(UINT(m_nImageBase + nHit), m_nImageSize) : 0;
  1655. if (pIcon)
  1656. {
  1657. pToolTip->SendMessage(XTP_TTM_SETIMAGE, 0, (LPARAM)pIcon);
  1658. }
  1659. else
  1660. {
  1661. pToolTip->SendMessage(XTP_TTM_SETIMAGE, 0, NULL);
  1662. }
  1663. }
  1664. if ((tiHit.uFlags & TTF_ALWAYSTIP) || bTopParentActive)
  1665. {
  1666. // allow the tooltip to popup when it should
  1667. pToolTip->SendMessage(TTM_ACTIVATE, TRUE);
  1668. // bring the tooltip window above other popup windows
  1669. ::SetWindowPos(pToolTip->m_hWnd, HWND_TOP, 0, 0, 0, 0,
  1670. SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_NOOWNERZORDER);
  1671. }
  1672. }
  1673. else
  1674. {
  1675. pToolTip->SendMessage(TTM_ACTIVATE, FALSE);
  1676. }
  1677. // relay mouse event before deleting old tool
  1678. RelayToolTipMessage(pToolTip, pMsg);
  1679. //// now safe to delete the old tool
  1680. if (m_lastInfo.cbSize >= sizeof(XTP_TOOLTIP_TOOLINFO) && bTipInfoChanged)
  1681. pToolTip->SendMessage(TTM_DELTOOL, 0, (LPARAM)&m_lastInfo);
  1682. m_lastInfo = tiHit;
  1683. }
  1684. else
  1685. {
  1686. // relay mouse events through the tooltip
  1687. if (nHit != -1)
  1688. RelayToolTipMessage(pToolTip, pMsg);
  1689. }
  1690. if ((tiHit.lpszText != LPSTR_TEXTCALLBACK) && (tiHit.hinst == 0))
  1691. free(tiHit.lpszText);
  1692. if (tc.lpszDescription  != 0)
  1693. free(tc.lpszDescription);
  1694. if (tc.lpszTitle != 0)
  1695. free(tc.lpszTitle);
  1696. }
  1697. else
  1698. {
  1699. if (!bIgnoreFlags)
  1700. {
  1701. // make sure that tooltips are not already being handled
  1702. CWnd* pWnd = CWnd::FromHandle(pMsg->hwnd);
  1703. while (pWnd != NULL && pWnd != pWndHost && !(pWnd->m_nFlags & (WF_TOOLTIPS | WF_TRACKINGTOOLTIPS)))
  1704. {
  1705. pWnd = pWnd->GetParent();
  1706. }
  1707. if (pWnd != pWndHost)
  1708. return;
  1709. }
  1710. BOOL bKeys = (message >= WM_KEYFIRST && message <= WM_KEYLAST) ||
  1711. (message >= WM_SYSKEYFIRST && message <= WM_SYSKEYLAST);
  1712. if ((bKeys ||
  1713. (message == WM_LBUTTONDOWN || message == WM_LBUTTONDBLCLK) ||
  1714. (message == WM_RBUTTONDOWN || message == WM_RBUTTONDBLCLK) ||
  1715. (message == WM_MBUTTONDOWN || message == WM_MBUTTONDBLCLK) ||
  1716. (message == WM_NCLBUTTONDOWN || message == WM_NCLBUTTONDBLCLK) ||
  1717. (message == WM_NCRBUTTONDOWN || message == WM_NCRBUTTONDBLCLK) ||
  1718. (message == WM_NCMBUTTONDOWN || message == WM_NCMBUTTONDBLCLK)))
  1719. {
  1720. CancelToolTips();
  1721. }
  1722. }
  1723. }