Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

731 lines
19 KiB

  1. //
  2. // balloon.cpp
  3. //
  4. #include "private.h"
  5. #include "globals.h"
  6. #include "tipbar.h"
  7. #include "helpers.h"
  8. #include "xstring.h"
  9. #include "immxutil.h"
  10. #include "balloon.h"
  11. #include "fontlink.h"
  12. #include "asynccal.h"
  13. extern CTipbarWnd *g_pTipbarWnd;
  14. #define SHOWTOOLTIP_ONUPDATE
  15. __inline void PrectSet(RECT *prc, int left, int top, int right, int bottom)
  16. {
  17. prc->left = left;
  18. prc->top = top;
  19. prc->right = right;
  20. prc->bottom = bottom;
  21. }
  22. //////////////////////////////////////////////////////////////////////////////
  23. //
  24. // CTipbarBalloonItem
  25. //
  26. //////////////////////////////////////////////////////////////////////////////
  27. //+---------------------------------------------------------------------------
  28. //
  29. // IUnknown
  30. //
  31. //----------------------------------------------------------------------------
  32. STDAPI CTipbarBalloonItem::QueryInterface(REFIID riid, void **ppvObj)
  33. {
  34. *ppvObj = NULL;
  35. if (IsEqualIID(riid, IID_IUnknown) ||
  36. IsEqualIID(riid, IID_ITfLangBarItemSink))
  37. {
  38. *ppvObj = SAFECAST(this, ITfLangBarItemSink *);
  39. }
  40. else if (IsEqualIID(riid, IID_PRIV_BALLOONITEM))
  41. {
  42. *ppvObj = this;
  43. }
  44. if (*ppvObj)
  45. {
  46. AddRef();
  47. return S_OK;
  48. }
  49. return E_NOINTERFACE;
  50. }
  51. STDAPI_(ULONG) CTipbarBalloonItem::AddRef()
  52. {
  53. return ++_cRef;
  54. }
  55. STDAPI_(ULONG) CTipbarBalloonItem::Release()
  56. {
  57. _cRef--;
  58. Assert(_cRef >= 0);
  59. if (_cRef == 0)
  60. {
  61. delete this;
  62. return 0;
  63. }
  64. return _cRef;
  65. }
  66. //+---------------------------------------------------------------------------
  67. //
  68. // ctor
  69. //
  70. //----------------------------------------------------------------------------
  71. CTipbarBalloonItem::CTipbarBalloonItem(CTipbarThread *ptt,
  72. ITfLangBarItem *plbi,
  73. ITfLangBarItemBalloon *plbiBalloon,
  74. DWORD dwId,
  75. RECT *prc,
  76. DWORD dwStyle,
  77. TF_LANGBARITEMINFO *plbiInfo,
  78. DWORD dwStatus)
  79. : CUIFObject(ptt->_ptw,
  80. dwId,
  81. prc,
  82. dwStyle) ,
  83. CTipbarItem(ptt, plbi, plbiInfo, dwStatus)
  84. {
  85. Dbg_MemSetThisName(TEXT("CTipbarBalloonItem"));
  86. _plbiBalloon = plbiBalloon;
  87. _plbiBalloon->AddRef();
  88. if (_dwStatus & TF_LBI_STATUS_DISABLED)
  89. Enable(FALSE);
  90. _cRef = 1;
  91. }
  92. //+---------------------------------------------------------------------------
  93. //
  94. // dtor
  95. //
  96. //----------------------------------------------------------------------------
  97. CTipbarBalloonItem::~CTipbarBalloonItem()
  98. {
  99. if (_bstrText)
  100. SysFreeString(_bstrText);
  101. SafeRelease(_plbiBalloon);
  102. }
  103. //+---------------------------------------------------------------------------
  104. //
  105. // Update
  106. //
  107. //----------------------------------------------------------------------------
  108. HRESULT CTipbarBalloonItem::OnUpdateHandler(DWORD dwFlags, DWORD dwStatus)
  109. {
  110. if (!IsConnected())
  111. return S_OK;
  112. HRESULT hr = S_OK;
  113. BOOL fCallPaint = FALSE;
  114. //
  115. // add ref count to be safe for releasing during marshaling.
  116. //
  117. AddRef();
  118. if (dwFlags & TF_LBI_BALLOON)
  119. {
  120. TF_LBBALLOONINFO info;
  121. if (_bstrText)
  122. {
  123. SysFreeString(_bstrText);
  124. _bstrText = NULL;
  125. }
  126. if (SUCCEEDED(_plbiBalloon->GetBalloonInfo(&info)))
  127. {
  128. _bstrText = info.bstrText;
  129. _style = info.style;
  130. }
  131. if (!IsHiddenStatusControl() && IsVisibleInToolbar())
  132. StartDemotingTimer(FALSE);
  133. EndTimer();
  134. DestroyBalloonTip();
  135. #ifdef SHOWTOOLTIP_ONUPDATE
  136. if (IsTextEllipsis(_bstrText, &GetRectRef()))
  137. {
  138. StartTimer(2000);
  139. }
  140. #endif
  141. fCallPaint = TRUE;
  142. }
  143. CTipbarItem::OnUpdateHandler(dwFlags, dwStatus);
  144. if ((_dwStatus & TF_LBI_STATUS_DISABLED) ||
  145. (_dwStatus & TF_LBI_STATUS_HIDDEN))
  146. {
  147. DestroyBalloonTip();
  148. }
  149. if (fCallPaint)
  150. CallOnPaint();
  151. Release();
  152. return hr;
  153. }
  154. //+---------------------------------------------------------------------------
  155. //
  156. // OnTimer
  157. //
  158. //----------------------------------------------------------------------------
  159. void CTipbarBalloonItem::OnTimer()
  160. {
  161. if (!_pblnTip)
  162. {
  163. EndTimer();
  164. StartTimer(20000);
  165. ShowBalloonTip();
  166. }
  167. else
  168. {
  169. EndTimer();
  170. DestroyBalloonTip();
  171. }
  172. }
  173. //----------------------------------------------------------------------------
  174. //
  175. // OnPosChanged
  176. //
  177. //----------------------------------------------------------------------------
  178. void CTipbarBalloonItem::OnPosChanged()
  179. {
  180. EndTimer();
  181. DestroyBalloonTip();
  182. }
  183. //+---------------------------------------------------------------------------
  184. //
  185. // ShowBalloonTip
  186. //
  187. //----------------------------------------------------------------------------
  188. void CTipbarBalloonItem::ShowBalloonTip()
  189. {
  190. RECT rc;
  191. POINT pt;
  192. DestroyBalloonTip();
  193. if (!_ptt)
  194. return;
  195. if (!_ptt->_ptw)
  196. return;
  197. if (!IsVisibleInToolbar() || !_ptt->IsFocusThread())
  198. return;
  199. _pblnTip = new CUIFBalloonWindow(g_hInst, 0);
  200. if (!_pblnTip)
  201. return;
  202. _pblnTip->Initialize();
  203. GetRect(&rc);
  204. pt.x = (rc.left + rc.right) / 2;
  205. pt.y = rc.top;
  206. MyClientToScreen(&pt, &rc);
  207. _pblnTip->SetTargetPos(pt);
  208. _pblnTip->SetExcludeRect(&rc);
  209. _pblnTip->SetText(_bstrText);
  210. _pblnTip->CreateWnd(_ptt->_ptw->GetWnd());
  211. }
  212. //+---------------------------------------------------------------------------
  213. //
  214. // DestroyBalloonTip
  215. //
  216. //----------------------------------------------------------------------------
  217. void CTipbarBalloonItem::DestroyBalloonTip()
  218. {
  219. if (_pblnTip)
  220. {
  221. if (IsWindow(_pblnTip->GetWnd()))
  222. DestroyWindow(_pblnTip->GetWnd());
  223. delete _pblnTip;
  224. _pblnTip = NULL;
  225. }
  226. }
  227. //+---------------------------------------------------------------------------
  228. //
  229. // OnPaint
  230. //
  231. //----------------------------------------------------------------------------
  232. void CTipbarBalloonItem::OnPaint( HDC hdc )
  233. {
  234. switch (_style)
  235. {
  236. case TF_LB_BALLOON_RECO:
  237. DrawRecoBalloon(hdc, _bstrText, &GetRectRef());
  238. break;
  239. case TF_LB_BALLOON_SHOW:
  240. DrawShowBalloon(hdc, _bstrText, &GetRectRef());
  241. break;
  242. case TF_LB_BALLOON_MISS:
  243. DrawUnrecognizedBalloon(hdc, _bstrText, &GetRectRef());
  244. break;
  245. default:
  246. Assert(0);
  247. }
  248. }
  249. //+---------------------------------------------------------------------------
  250. //
  251. // OnRightClick
  252. //
  253. //----------------------------------------------------------------------------
  254. void CTipbarBalloonItem::OnRightClick()
  255. {
  256. if (_plbiBalloon)
  257. {
  258. HRESULT hr;
  259. POINT pt;
  260. RECT rc;
  261. GetCursorPos(&pt);
  262. GetRect(&rc);
  263. MyClientToScreen(&rc);
  264. CAsyncCall *pac = new CAsyncCall(_plbiBalloon);
  265. if (pac)
  266. {
  267. hr = pac->OnClick(TF_LBI_CLK_RIGHT, pt, &rc);
  268. pac->_Release();
  269. }
  270. else
  271. {
  272. hr = E_OUTOFMEMORY;
  273. }
  274. if (RPC_S_SERVER_UNAVAILABLE == HRESULT_CODE(hr))
  275. {
  276. if (_ptt && _ptt->_ptw)
  277. _ptt->_ptw->OnThreadTerminate(_ptt->_dwThreadId);
  278. return;
  279. }
  280. }
  281. }
  282. //+---------------------------------------------------------------------------
  283. //
  284. // OnLeftClick
  285. //
  286. //----------------------------------------------------------------------------
  287. void CTipbarBalloonItem::OnLeftClick()
  288. {
  289. if (_plbiBalloon)
  290. {
  291. HRESULT hr;
  292. POINT pt;
  293. RECT rc;
  294. GetCursorPos(&pt);
  295. GetRect(&rc);
  296. MyClientToScreen(&rc);
  297. CAsyncCall *pac = new CAsyncCall(_plbiBalloon);
  298. if (pac)
  299. {
  300. hr = pac->OnClick(TF_LBI_CLK_LEFT, pt, &rc);
  301. pac->_Release();
  302. }
  303. else
  304. {
  305. hr = E_OUTOFMEMORY;
  306. }
  307. if (RPC_S_SERVER_UNAVAILABLE == HRESULT_CODE(hr))
  308. {
  309. if (_ptt && _ptt->_ptw)
  310. _ptt->_ptw->OnThreadTerminate(_ptt->_dwThreadId);
  311. return;
  312. }
  313. if (!IsHiddenStatusControl() && IsVisibleInToolbar())
  314. StartDemotingTimer(TRUE);
  315. }
  316. }
  317. //+---------------------------------------------------------------------------
  318. //
  319. // SetRect
  320. //
  321. //----------------------------------------------------------------------------
  322. void CTipbarBalloonItem::SetRect( const RECT *prc )
  323. {
  324. CUIFObject::SetRect(prc);
  325. }
  326. /*---------------------------------------------------------------------------
  327. DrawTransparentText
  328. Draws the text string wtz in the font ft with text color crText.
  329. ------------------------------------------------------------------- TCOON -*/
  330. void CTipbarBalloonItem::DrawTransparentText(HDC hdc, COLORREF crText, WCHAR *psz, const RECT *prc)
  331. {
  332. HFONT hFontOld;
  333. SIZE size;
  334. int cch;
  335. RECT rc;
  336. WORD rgfJustify = DT_END_ELLIPSIS | DT_WORDBREAK | DT_EDITCONTROL | DT_CENTER | DT_VCENTER;
  337. if (!psz || !_ptt || !_ptt->_ptw)
  338. return;
  339. cch = wcslen(psz);
  340. // prepare objects
  341. hFontOld= (HFONT)SelectObject(hdc, GetFont() );
  342. // calc alignment
  343. FLGetTextExtentPoint32( hdc, psz, cch, &size );
  344. COLORREF crSave = SetTextColor(hdc, crText);
  345. SetBkMode(hdc, TRANSPARENT);
  346. if (!_ptt->IsVertical())
  347. {
  348. int yAlign = (prc->bottom - prc->top - size.cy) / 2;
  349. rc = *prc;
  350. rc.left += 1;
  351. rc.right -= 1;
  352. rc.top += yAlign;
  353. FLDrawTextW(hdc, psz, cch, &rc, rgfJustify);
  354. }
  355. else
  356. {
  357. int xAlign = (prc->right - prc->left - size.cy) / 2;
  358. rc = *prc;
  359. rc.top += 1;
  360. rc.bottom -= 1;
  361. rc.right -= xAlign;
  362. FLDrawTextWVert(hdc, psz, cch, &rc, rgfJustify);
  363. }
  364. SetTextColor(hdc, crSave);
  365. SelectObject(hdc, hFontOld);
  366. }
  367. /*---------------------------------------------------------------------------
  368. DrawRect
  369. Draws the text string wtz in the font ft with text color crText.
  370. ------------------------------------------------------------------- TCOON -*/
  371. void CTipbarBalloonItem::DrawRect(HDC hdc, const RECT *prc, COLORREF crBorder, COLORREF crFill)
  372. {
  373. HPEN hpen = NULL;
  374. HPEN hpenOld;
  375. HBRUSH hbr = NULL;
  376. HBRUSH hbrOld;
  377. hpen = CreatePen(PS_SOLID, 0, crBorder);
  378. if (!hpen)
  379. goto Exit;
  380. hbr = CreateSolidBrush(crFill);
  381. if (!hbr)
  382. goto Exit;
  383. hpenOld = (HPEN)SelectObject(hdc, hpen);
  384. hbrOld = (HBRUSH)SelectObject(hdc, hbr);
  385. Rectangle(hdc, prc->left, prc->top, prc->right, prc->bottom);
  386. SelectObject(hdc, hpenOld);
  387. SelectObject(hdc, hbrOld);
  388. Exit:
  389. if (hpen)
  390. DeleteObject(hpen);
  391. if (hbr)
  392. DeleteObject(hbr);
  393. }
  394. /*---------------------------------------------------------------------------
  395. DrawUnrecognizedBalloon
  396. Draws the Unrecognized balloon to show the user that the command was
  397. misunderstood.
  398. ------------------------------------------------------------------- TCOON -*/
  399. void CTipbarBalloonItem::DrawUnrecognizedBalloon(HDC hdc, WCHAR *wtz, const RECT *prc)
  400. {
  401. RECT rc = *prc;
  402. COLORREF crBtnText;
  403. HPEN hpen = NULL;
  404. HPEN hpenOld;
  405. HBRUSH hbrOld;
  406. crBtnText = GetSysColor(COLOR_BTNTEXT);
  407. hpen = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_WINDOWFRAME));
  408. if (!hpen)
  409. goto Exit;
  410. hbrOld = (HBRUSH)SelectObject(hdc, GetSysColorBrush(COLOR_HIGHLIGHT));
  411. InflateRect(&rc, -2, -2);
  412. hpenOld = (HPEN)SelectObject(hdc, hpen);
  413. RoundRect(hdc, rc.left,rc.top, rc.right, rc.bottom, 12, 12);
  414. DrawTransparentText(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT), wtz, &rc);
  415. // Restore DC contents
  416. SelectObject(hdc, hpenOld);
  417. SelectObject(hdc, hbrOld);
  418. Exit:
  419. if (hpen)
  420. DeleteObject(hpen);
  421. }
  422. /*---------------------------------------------------------------------------
  423. DrawShowBalloon
  424. Draws the Show balloon to suggest the user say a given command.
  425. ------------------------------------------------------------------- TCOON -*/
  426. void CTipbarBalloonItem::DrawShowBalloon(HDC hdc, WCHAR *wtz, const RECT *prc)
  427. {
  428. COLORREF crBtnFace;
  429. COLORREF crBtnShad;
  430. COLORREF crBalloonText;
  431. COLORREF crBalloon;
  432. RECT rc = *prc;
  433. crBtnFace = GetSysColor(COLOR_BTNFACE);
  434. crBtnShad = GetSysColor(COLOR_BTNSHADOW);
  435. // crBalloonText = GetSysColor(COLOR_INFOTEXT);
  436. // crBalloon = GetSysColor(COLOR_INFOBK) & 0x0000ff00;
  437. // crBalloon = col(30, RGB(0, 0xFF, 0), 70, GetSysColor(COLOR_INFOBK));
  438. crBalloon = GetSysColor(COLOR_BTNFACE);
  439. crBalloonText = GetSysColor(COLOR_BTNTEXT);
  440. // Draw Black outline
  441. InflateRect(&rc, -2, -2);
  442. // rc.bottom -= 5;
  443. DrawRect(hdc, &rc, GetSysColor(COLOR_WINDOWFRAME), crBalloon);
  444. InflateRect(&rc, -1, -1);
  445. // Knock off the corner
  446. RECT rcDraw;
  447. int bkSav = SetBkColor(hdc, crBalloon);
  448. for (int iPixel = 0; iPixel < 7; iPixel++)
  449. {
  450. PrectSet(&rcDraw, rc.right-(7-iPixel), rc.bottom-iPixel-1,
  451. rc.right-(7-iPixel)+1, rc.bottom-iPixel);
  452. ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rcDraw, NULL, 0, 0);
  453. }
  454. PrectSet(&rcDraw, rc.right-3, rc.bottom-2, rc.right-2, rc.bottom);
  455. ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rcDraw, NULL, 0, 0);
  456. PrectSet(&rcDraw, rc.right-2, rc.bottom-3, rc.right, rc.bottom-2);
  457. ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rcDraw, NULL, 0, 0);
  458. // Shadows
  459. SetBkColor(hdc, crBtnShad);
  460. // Lower Shadow
  461. PrectSet(&rcDraw, rc.left+2, rc.bottom+1, rc.right+1, rc.bottom+2);
  462. ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rcDraw, NULL, 0, 0);
  463. for (iPixel = 0; iPixel < 8; iPixel++)
  464. {
  465. PrectSet(&rcDraw, rc.right-(7-iPixel), rc.bottom-iPixel,
  466. rc.right-(7-iPixel)+1, rc.bottom-iPixel+2);
  467. ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rcDraw, NULL, 0, 0);
  468. }
  469. // Button Face portions
  470. SetBkColor(hdc, crBtnFace);
  471. for (iPixel = 0; iPixel < 3; iPixel++)
  472. {
  473. PrectSet(&rcDraw, rc.right-6+iPixel, rc.bottom+1-iPixel,
  474. rc.right-3, rc.bottom-iPixel+2);
  475. ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rcDraw, NULL, 0, 0);
  476. }
  477. for (iPixel = 0; iPixel < 2; iPixel++)
  478. {
  479. PrectSet(&rcDraw, rc.right+iPixel-1, rc.bottom-4-iPixel,
  480. rc.right+iPixel, rc.bottom+iPixel-3);
  481. ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rcDraw, NULL, 0, 0);
  482. }
  483. PrectSet(&rcDraw, rc.right-3, rc.bottom, rc.right-2, rc.bottom+2);
  484. ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rcDraw, NULL, 0, 0);
  485. // Clean up and draw text
  486. SetBkColor(hdc, bkSav);
  487. DrawTransparentText(hdc, crBalloonText, wtz, &rc);
  488. }
  489. /*---------------------------------------------------------------------------
  490. DrawRecoBalloon
  491. Draws the Recognition Balloon.
  492. ------------------------------------------------------------------- TCOON -*/
  493. void CTipbarBalloonItem::DrawRecoBalloon(HDC hdc, WCHAR *wtz, const RECT *prc)
  494. {
  495. COLORREF crBtnFace;
  496. COLORREF crBtnShad;
  497. COLORREF crBalloonText;
  498. COLORREF crBalloon;
  499. RECT rc = *prc;
  500. crBtnFace = GetSysColor(COLOR_BTNFACE);
  501. crBtnShad = GetSysColor(COLOR_BTNSHADOW);
  502. crBalloonText = GetSysColor(COLOR_INFOTEXT);
  503. crBalloon = GetSysColor(COLOR_INFOBK);
  504. // Draw Black outline
  505. InflateRect(&rc, -2, -2);
  506. // rc.bottom -= 5;
  507. rc.bottom -= 1;
  508. DrawRect(hdc, &rc, GetSysColor(COLOR_WINDOWFRAME), crBalloon);
  509. InflateRect(&rc, -1, -1);
  510. // Knock off the corners
  511. int bkSav = SetBkColor(hdc, crBtnFace);
  512. InflateRect(&rc, +1, +1);
  513. RECT rcDraw;
  514. // UpperLeft
  515. PrectSet(&rcDraw, rc.left, rc.top, rc.left+1, rc.top+1);
  516. ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rcDraw, NULL, 0, 0);
  517. // UpperRight
  518. PrectSet(&rcDraw, rc.right-1, rc.top, rc.right, rc.top+1);
  519. ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rcDraw, NULL, 0, 0);
  520. // LowerLeft
  521. PrectSet(&rcDraw, rc.left, rc.bottom-1, rc.left+1, rc.bottom);
  522. ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rcDraw, NULL, 0, 0);
  523. SetBkColor(hdc, crBtnShad);
  524. // LowerRight (done in shadow color)
  525. PrectSet(&rcDraw, rc.right-1, rc.bottom-1, rc.right, rc.bottom);
  526. ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rcDraw, NULL, 0, 0);
  527. // Lower Shadow
  528. PrectSet(&rcDraw, rc.left+2, rc.bottom, rc.right-1, rc.bottom+1);
  529. ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rcDraw, NULL, 0, 0);
  530. // RightSide Shadow
  531. PrectSet(&rcDraw, rc.right, rc.top+2, rc.right+1, rc.bottom-1);
  532. ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rcDraw, NULL, 0, 0);
  533. // Arrow Shadow
  534. PrectSet(&rcDraw, rc.right-4, rc.bottom+1, rc.right-3, rc.bottom+5);
  535. ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rcDraw, NULL, 0, 0);
  536. // Arrow
  537. SetBkColor(hdc, crBalloonText);
  538. PrectSet(&rcDraw, rc.right-5, rc.bottom, rc.right-4, rc.bottom+4);
  539. ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rcDraw, NULL, 0, 0);
  540. int iPixel;
  541. for (iPixel = 0; iPixel < 3; iPixel++)
  542. {
  543. PrectSet(&rcDraw, rc.right-(6+iPixel), rc.bottom+(2-iPixel),
  544. rc.right-(5+iPixel), rc.bottom+(3-iPixel));
  545. ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rcDraw, NULL, 0, 0);
  546. }
  547. // Fill in Arrow
  548. SetBkColor(hdc, crBalloon);
  549. for (iPixel = 0; iPixel < 3; iPixel++)
  550. {
  551. PrectSet(&rcDraw, rc.right-(8-iPixel), rc.bottom-(1-iPixel),
  552. rc.right-5, rc.bottom+iPixel);
  553. ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rcDraw, NULL, 0, 0);
  554. }
  555. SetBkColor(hdc, bkSav);
  556. DrawTransparentText(hdc, crBalloonText, wtz, &rc);
  557. }
  558. /*---------------------------------------------------------------------------
  559. IsTextEllipsis
  560. Draws the text string wtz in the font ft with text color crText.
  561. ------------------------------------------------------------------- TCOON -*/
  562. BOOL CTipbarBalloonItem::IsTextEllipsis(WCHAR *psz, const RECT *prc)
  563. {
  564. HDC hdc;
  565. HFONT hFontOld;
  566. SIZE size;
  567. int cch;
  568. RECT rc;
  569. BOOL bRet = FALSE;
  570. // detect if the item is hidden and return immediately here
  571. if (IsInHiddenStatus())
  572. return bRet;
  573. if (g_pTipbarWnd && g_pTipbarWnd->IsSFHidden( ))
  574. return bRet;
  575. if (!psz)
  576. return bRet;
  577. hdc = CreateIC("DISPLAY", NULL, NULL, NULL);
  578. if (!hdc)
  579. return bRet;
  580. cch = wcslen(psz);
  581. // prepare objects
  582. hFontOld= (HFONT)SelectObject(hdc, GetFont() );
  583. // calc alignment
  584. FLGetTextExtentPoint32( hdc, psz, cch, &size );
  585. rc = *prc;
  586. rc.left += 3;
  587. rc.right -= 3;
  588. SelectObject(hdc, hFontOld);
  589. DeleteDC(hdc);
  590. return (size.cx > (rc.right - rc.left)) ? TRUE : FALSE;
  591. }