CoolTipCtrl.cpp
上传用户:sunh8215
上传日期:2010-02-13
资源大小:1616k
文件大小:15k
源码类别:

酒店行业

开发平台:

Visual C++

  1. /*########################################################################
  2. Filename:  cooltipctrl.cpp
  3. ----------------------------------------------------
  4. Remarks: ...
  5. ----------------------------------------------------
  6. Author: 成真
  7. Email: anyou@sina.com
  8. anyou@msn.com
  9. Created: 23/3/2003 19:20
  10.   ########################################################################*/
  11. #include "stdafx.h"
  12. #include "CoolTipCtrl.h"
  13. #ifdef _DEBUG
  14. #define new DEBUG_NEW
  15. #undef THIS_FILE
  16. static char THIS_FILE[] = __FILE__;
  17. #endif
  18. #define TIMER_DELAY  1
  19. #define TIMER_FADE   2
  20. #define TIMER_PTTEST 3
  21. /*########################################################################
  22. -------------------------
  23.     Construction
  24. -------------------------
  25.   ########################################################################*/
  26. CCoolTipCtrl::CCoolTipCtrl()
  27. {
  28. m_nSize  = CSize(10, 10);
  29. m_nFade  = 0;
  30. m_nDelayTime = 10;
  31. m_rcRect  = CRect(0, 0, 8888, 6666);
  32. m_crBk  = RGB(250, 255, 225);
  33. m_crText  = RGB(0, 0, 0);
  34. m_crTitle  = RGB(0, 0, 0);
  35. m_hIcon  = NULL;
  36. m_szIcon  = CSize(0, 0);
  37. m_dwState  = 0;
  38. }
  39. BOOL CCoolTipCtrl::Create(CSize size, CWnd *pParentWnd, UINT dwStyle, UINT uID)
  40. {
  41. m_nSize = size;
  42. m_dwStyle = dwStyle;
  43. return CreateEx(WS_EX_TOOLWINDOW,
  44. ::AfxRegisterWndClass(0),
  45. "COOL_TIP_CTRL_WINDOW",
  46. WS_POPUP,
  47. CRect(0, 0, size.cx, size.cy),
  48. pParentWnd,
  49. uID);
  50. }
  51. CCoolTipCtrl::~CCoolTipCtrl()
  52. {
  53. }
  54. /*################################################################
  55. --------------------------------------
  56. CoolTip control message handlers
  57. --------------------------------------
  58.   ################################################################*/
  59. BEGIN_MESSAGE_MAP(CCoolTipCtrl, CWnd)
  60. //{{AFX_MSG_MAP(CCoolTipCtrl)
  61. ON_WM_CREATE()
  62. ON_WM_DESTROY()
  63. ON_WM_LBUTTONUP()
  64. ON_WM_TIMER()
  65. ON_WM_PAINT()
  66. ON_WM_NCPAINT()
  67. ON_WM_NCCALCSIZE()
  68. ON_WM_NCHITTEST()
  69. //}}AFX_MSG_MAP
  70. END_MESSAGE_MAP()
  71. int CCoolTipCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  72. {
  73. if (CWnd::OnCreate(lpCreateStruct) == -1)
  74. {
  75. return -1;
  76. }
  77. CRect rect;
  78. GetClientRect(&rect);
  79. CDC *pdc = GetDC();
  80. m_MemDC.CreateCompatibleDC(pdc);
  81. bitmap.CreateCompatibleBitmap(pdc, m_nSize.cx, m_nSize.cy);
  82. oldbitmap = m_MemDC.SelectObject(&bitmap);
  83. ReleaseDC(pdc);
  84. //load dll-------------------------------------------------
  85. hUserDll = ::LoadLibrary(_T("USER32.dll"));
  86. //Change style to layered window style...
  87. ::SetWindowLong(m_hWnd, GWL_EXSTYLE, ::GetWindowLong(m_hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);
  88. SetTransparent(m_hWnd, 0, 0 , LWA_ALPHA );
  89. return 0;
  90. }
  91. void CCoolTipCtrl::OnDestroy() 
  92. {
  93. CWnd::OnDestroy();
  94. KillTimer(TIMER_FADE);
  95. KillTimer(TIMER_DELAY);
  96. KillTimer(TIMER_PTTEST);
  97. m_MemDC.SelectObject(oldbitmap);
  98. bitmap.DeleteObject();
  99. m_MemDC.DeleteDC();
  100. }
  101. void CCoolTipCtrl::OnLButtonUp(UINT nFlags, CPoint point) 
  102. {
  103. Hide();
  104. CWnd::OnLButtonUp(nFlags, point);
  105. }
  106. void CCoolTipCtrl::OnTimer(UINT nIDEvent) 
  107. {
  108. switch (nIDEvent) 
  109. {
  110. //Delay show=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  111. case TIMER_DELAY:
  112. m_nShowTime--;
  113. //Delay time over-----------------------------=
  114. if (m_nShowTime <= 0)
  115. {
  116. //Kill this timer-----------------------
  117. KillTimer(TIMER_DELAY);
  118. //PtTest--------------------------------
  119. ::GetCursorPos(&m_point);
  120. if (!m_rcRect.PtInRect(m_point))
  121. {
  122. KillTimer(TIMER_PTTEST);
  123. m_dwState = TIPS_HIDE;
  124. return;
  125. }
  126. //Set size------------------------------
  127. m_point.y += 20;
  128. if (m_dwStyle & TIPS_AUTOSIZE)
  129. {
  130. AutoSize();
  131. }
  132. //Captrue Screen for draw shadow--------
  133. CDC dc;
  134. dc.Attach(::GetWindowDC(NULL));
  135. m_MemDC.BitBlt(0, 0, m_nSize.cx, m_nSize.cy, &dc, m_point.x, m_point.y, SRCCOPY);
  136. dc.Detach();
  137. dc.DeleteDC();
  138. //Display tip window---------------------
  139. SetWindowPos(&wndTopMost,
  140.  m_point.x, 
  141.  m_point.y, 
  142.  m_nSize.cx, 
  143.  m_nSize.cy,
  144.  SWP_SHOWWINDOW | SWP_NOACTIVATE);
  145. //Draw window memory dc------------------
  146. OnDraw(&m_MemDC);
  147. //fade out window------------------------
  148. SetTransparent(m_hWnd, 0, 0 , LWA_ALPHA );
  149. m_dwState = TIPS_FADEOUT;
  150. m_nFade = 0;
  151. SetTimer(TIMER_FADE, 30, NULL);
  152. }
  153. break;
  154. //Fade out or in window=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  155. case TIMER_FADE:
  156. if (m_dwState == TIPS_FADEIN)
  157. {
  158. m_nFade -= 28; //Fade in
  159. }
  160. else if (m_dwState == TIPS_FADEOUT)
  161. {
  162. m_nFade += 28; //Fade out
  163. }
  164. if (m_nFade >= 230)
  165. {
  166. m_nFade = (m_dwStyle & 0x00000002) ? 230 : 255;
  167. m_dwState &= TIPS_NORMAL;
  168. KillTimer(TIMER_FADE);
  169. SetTimer (TIMER_PTTEST, 500, NULL);
  170. }
  171. else if (m_nFade < 0)
  172. {
  173. //Hide window-----------------
  174. m_nFade = 0;
  175. m_dwState = TIPS_HIDE;
  176. KillTimer(TIMER_FADE);
  177. KillTimer(TIMER_PTTEST);
  178. ShowWindow(SW_HIDE);
  179. if (GetStyle() & TIPS_SHOWNEXT)
  180. {
  181. m_dwStyle &= ~TIPS_SHOWNEXT;
  182. m_nShowTime = 1;
  183. m_dwState = TIPS_DELAYSHOW;
  184. SetTimer(TIMER_DELAY , 100, NULL);
  185. SetTimer(TIMER_PTTEST, 500, NULL);
  186. }
  187. }
  188. SetTransparent(m_hWnd, 0, m_nFade , LWA_ALPHA );
  189. break;
  190. case TIMER_PTTEST:
  191. ::GetCursorPos(&m_point);
  192. if (!m_rcRect.PtInRect(m_point))
  193. {
  194. KillTimer(TIMER_DELAY);
  195. KillTimer(TIMER_PTTEST);
  196. m_dwState = TIPS_FADEIN;
  197. SetTimer(TIMER_FADE, 30, NULL);
  198. }
  199. break;
  200. default:
  201. break;
  202. }
  203. CWnd::OnTimer(nIDEvent);
  204. }
  205. void CCoolTipCtrl::OnPaint() 
  206. {
  207. CRect rect;
  208. GetClientRect(&rect);
  209. CPaintDC dc(this);
  210. CFont font, *oldfont;
  211. font.CreateFont(-12, 0, 0, 400, 600, 0, 0, 0, 0, 0, 0, 0, 1, "宋体");
  212. oldfont = dc.SelectObject(&font);
  213. dc.SetBkMode(TRANSPARENT);
  214. //Draw background ----------------------------------
  215. dc.FillSolidRect(rect, m_crBk);
  216. dc.Draw3dRect(rect, RGB(140, 140, 140), RGB(99, 99, 99));
  217. rect.InflateRect(-5, -5);
  218. //Draw title----------------------------------------
  219. if (m_hIcon != NULL)
  220. {
  221. ::DrawIconEx(dc.m_hDC, rect.left, rect.top, m_hIcon,
  222. m_szIcon.cx, m_szIcon.cy, NULL, NULL, DI_NORMAL);
  223. rect.left += m_szIcon.cx + 5;
  224. }
  225. if (m_strTitle != "")
  226. {
  227. dc.SetTextColor(m_crTitle);
  228. dc.DrawText(m_strTitle, rect, DT_LEFT | DT_SINGLELINE);
  229. rect.top += 15;
  230. }
  231. font.DeleteObject();
  232. font.CreateFont(-12, 0, 0, 400, 400, 0, 0, 0, 0, 0, 0, 0, 1, "宋体");
  233. dc.SelectObject(&font);
  234. //Draw text------------------------------------
  235. dc.SetTextColor(m_crText);
  236. dc.DrawText(m_strText, rect, DT_LEFT | DT_WORDBREAK);
  237. dc.SelectObject(oldfont);
  238. font.DeleteObject();
  239. }
  240. /*===============================================================
  241. Set Transparent 
  242. =================================================================*/
  243. BOOL CCoolTipCtrl::SetTransparent(HWND hWnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags)
  244. {
  245. BOOL bRet = FALSE;
  246. typedef BOOL (WINAPI* lpfnSetTransparent)(HWND hWnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags);
  247. // Check that "USER32.dll" library has been loaded successfully...
  248. if ( hUserDll )
  249. {
  250. lpfnSetTransparent pFnSetTransparent  = NULL;
  251. pFnSetTransparent  = (lpfnSetTransparent)GetProcAddress(hUserDll, "SetLayeredWindowAttributes");
  252. if (pFnSetTransparent )
  253. {
  254. bRet = pFnSetTransparent(hWnd, crKey, bAlpha, dwFlags);
  255. }
  256. } //if( hUserDll )
  257. return bRet;
  258. } // End of SetTransparent function
  259. /*################################################################
  260. --------------------------------------
  261. CoolTip control display handlers
  262. --------------------------------------
  263.   ################################################################*/
  264. void CCoolTipCtrl::SetRect(const CRect& rect)
  265. {
  266. m_rcRect = rect;
  267. }
  268. void CCoolTipCtrl::SetDelayTime(int nTime)
  269. {
  270. m_nDelayTime = nTime;
  271. }
  272. /*===============================================================
  273. display window
  274. =================================================================*/
  275. BOOL CCoolTipCtrl::Show(CPoint point)
  276. {
  277. if (IsShow() && GetState() != TIPS_DELAYSHOW) 
  278. {
  279. if (m_dwState != TIPS_FADEIN) Hide();
  280. m_nFade = 10;
  281. m_dwStyle |= TIPS_SHOWNEXT;
  282. return FALSE;
  283. }
  284. m_point = point;
  285. m_nShowTime = m_nDelayTime;
  286. m_dwState = TIPS_DELAYSHOW;
  287. SetTimer(TIMER_DELAY , 100, NULL);
  288. SetTimer(TIMER_PTTEST, 500, NULL);
  289. return TRUE;
  290. }
  291. /*===============================================================
  292. hide window
  293. =================================================================*/
  294. BOOL CCoolTipCtrl::Hide()
  295. {
  296. if (m_dwState == TIPS_HIDE)
  297. {
  298. return FALSE;
  299. }
  300. m_dwState = TIPS_FADEIN;
  301. SetTimer(TIMER_FADE, 30, NULL);
  302. return TRUE;
  303. }
  304. BOOL CCoolTipCtrl::IsShow()
  305. {
  306. return (m_dwState != TIPS_HIDE) ;
  307. }
  308. void CCoolTipCtrl::DrawShadow(CDC *pDC, CRect rect, COLORREF color)
  309. {
  310. //Draw shadow----------------------------------------->>
  311. COLORREF oldcolor = RGB(255, 255, 255);
  312. BYTE newPixeValR, newPixeValG, newPixeValB;
  313. BYTE AlphaArray[6] = {140, 170, 212, 240};
  314. BYTE AlphaArray2[] = {170, 205, 220, 240, 240, 250, 255};
  315. BYTE Alpha = 0;
  316. //bottom shadow-----------------------------------------
  317. int i, j;
  318. for (j = 0; j < 4; j++)
  319. {
  320. Alpha = AlphaArray[j];
  321. for (i = 6; i <= rect.right - 5; i++)
  322. {
  323. oldcolor = pDC->GetPixel(i, rect.bottom - (4 - j));
  324. newPixeValR = GetRValue(oldcolor) * Alpha / 255;  
  325. newPixeValG = GetGValue(oldcolor) * Alpha / 255;  
  326. newPixeValB = GetBValue(oldcolor) * Alpha / 255;  
  327. pDC->SetPixel(i, rect.bottom - (4 - j), RGB(newPixeValR, newPixeValG, newPixeValB));
  328. }
  329. }
  330. //right shadow-----------------------------------------
  331. Alpha = 120;
  332. for (i = 0; i < 4; i++)
  333. {
  334. Alpha = AlphaArray[i];
  335. for (j = 6; j <= rect.bottom - 5; j++)
  336. {
  337. oldcolor = pDC->GetPixel(rect.right - (4 - i), j);
  338. newPixeValR = GetRValue(oldcolor) * Alpha / 255;  
  339. newPixeValG = GetGValue(oldcolor) * Alpha / 255;  
  340. newPixeValB = GetBValue(oldcolor) * Alpha / 255;  
  341. pDC->SetPixel(rect.right - (4 - i), j, RGB(newPixeValR, newPixeValG, newPixeValB));
  342. }
  343. }
  344. //other------------------------------------------------
  345. for (i = 0; i < 4; i++)
  346. {
  347. for (j = 0; j < 4; j++)
  348. {
  349. if ((i + j) > 6) break;
  350. Alpha = AlphaArray2[j + i];
  351. oldcolor = pDC->GetPixel(rect.right - 4 + i, rect.bottom - 4 + j);
  352. newPixeValR = GetRValue(oldcolor) * Alpha / 255;  
  353. newPixeValG = GetGValue(oldcolor) * Alpha / 255;  
  354. newPixeValB = GetBValue(oldcolor) * Alpha / 255;  
  355. pDC->SetPixel(rect.right - 4 + i, rect.bottom - 4 + j, RGB(newPixeValR, newPixeValG, newPixeValB));
  356. oldcolor = pDC->GetPixel(rect.right - 4 + i, rect.top + 5 - j);
  357. newPixeValR = GetRValue(oldcolor) * Alpha / 255;  
  358. newPixeValG = GetGValue(oldcolor) * Alpha / 255;  
  359. newPixeValB = GetBValue(oldcolor) * Alpha / 255;  
  360. pDC->SetPixel(rect.right - 4 + i, rect.top + 5 - j, RGB(newPixeValR, newPixeValG, newPixeValB));
  361. oldcolor = pDC->GetPixel(rect.left - i + 5, rect.bottom - 4 + j);
  362. newPixeValR = GetRValue(oldcolor) * Alpha / 255;  
  363. newPixeValG = GetGValue(oldcolor) * Alpha / 255;  
  364. newPixeValB = GetBValue(oldcolor) * Alpha / 255;  
  365. pDC->SetPixel(rect.left - i + 5, rect.bottom - 4 + j, RGB(newPixeValR, newPixeValG, newPixeValB));
  366. }
  367. }
  368. }
  369. void CCoolTipCtrl::OnDraw(CDC *pDC)
  370. {
  371. }
  372. /*################################################################
  373. ------------------------------------
  374. CoolTip control size handlers
  375. ------------------------------------
  376.   ################################################################*/
  377. void CCoolTipCtrl::SetSize(CSize size)
  378. {
  379. m_nSize  = size;
  380. CDC *pdc = GetDC();
  381. bitmap.DeleteObject();
  382. bitmap.CreateCompatibleBitmap(pdc, m_nSize.cx, m_nSize.cy);
  383. m_MemDC.SelectObject(&bitmap);
  384. ReleaseDC(pdc);
  385. }
  386. void CCoolTipCtrl::AutoSize()
  387. {
  388. int nstrLength = m_strTitle.GetLength();
  389. nstrLength = nstrLength > 30 ? nstrLength : 30;
  390.   CSize szText = GetStringSize(m_strText, nstrLength, CSize(6, 12));
  391. m_nSize   = szText;
  392. m_nSize.cx += 14;
  393. m_nSize.cy += 14;
  394. if (m_strTitle != "" )
  395. {
  396. if (szText.cx < 180 && szText.cx < m_strTitle.GetLength() * 7 ) m_nSize.cx += m_strTitle.GetLength() * 7;
  397. if (m_nSize.cx > 194) m_nSize.cx = 194;
  398. m_nSize.cy += 15;
  399. }
  400. m_nSize.cx += m_szIcon.cx + 5;
  401. if (m_nSize.cy < m_szIcon.cy + 14 ) m_nSize.cy = m_szIcon.cy + 14;
  402. SetSize(m_nSize);
  403. }
  404. CSize CCoolTipCtrl::GetStringSize(CString strText, int nlinecount, CSize szFont)
  405. {
  406. int npos = 0;
  407. CSize sz(0,0);
  408. while (true)
  409. {
  410. npos = strText.Find('n');
  411. if (npos >= 0)
  412. {
  413. if  (npos > nlinecount)
  414. {
  415. sz.cx = nlinecount;
  416. sz.cy += npos / nlinecount + 1;
  417. }
  418. else
  419. {
  420. sz.cx = sz.cx > npos ? sz.cx : npos;
  421. sz.cy += 1;
  422. }
  423. if (npos < (strText.GetLength() - 1))
  424. {
  425. strText = strText.Right(strText.GetLength() - npos - 1);
  426. continue;
  427. }
  428. }
  429. else if (npos == -1)
  430. {
  431. if  (strText.GetLength() > nlinecount)
  432. {
  433. sz.cx = nlinecount;
  434. sz.cy += strText.GetLength() / nlinecount + 1;
  435. }
  436. else
  437. {
  438. sz.cx = sz.cx > strText.GetLength() ? sz.cx : strText.GetLength();
  439. sz.cy += 1;
  440. }
  441. }
  442. break;
  443. }
  444. sz.cx = sz.cx * szFont.cx;
  445. sz.cy = sz.cy * szFont.cy;
  446. return sz;
  447. }
  448. /*################################################################
  449. ------------------------------------
  450. CoolTip control text handlers
  451. ------------------------------------
  452.   ################################################################*/
  453. void CCoolTipCtrl::SetText(CString strText)
  454. {
  455. m_strText = strText;
  456. }
  457. void CCoolTipCtrl::SetTitle(CString strTitle)
  458. {
  459. m_strTitle = strTitle;
  460. }
  461. /*################################################################
  462. -------------------------------------
  463. CoolTip control color handlers
  464. -------------------------------------
  465.   ################################################################*/
  466. void CCoolTipCtrl::SetTextColor(COLORREF crText)
  467. {
  468. m_crText = crText;
  469. }
  470. void CCoolTipCtrl::SetBkColor(COLORREF crBk)
  471. {
  472. m_crBk = crBk;
  473. }
  474. void CCoolTipCtrl::SetTitleColor(COLORREF crTitle)
  475. {
  476. m_crTitle = crTitle;
  477. }
  478. /*################################################################
  479. ------------------------------------
  480. CoolTip control icon handlers
  481. ------------------------------------
  482.   ################################################################*/
  483. void CCoolTipCtrl::SetIcon(HICON hIcon, CSize szIcon)
  484. {
  485. m_hIcon = hIcon;
  486. m_szIcon  = szIcon;
  487. }
  488. void CCoolTipCtrl::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS *lpncsp)
  489. {
  490. CRect rect = lpncsp->rgrc[0];
  491. rect.DeflateRect(0, 0, 4, 4);
  492. lpncsp->rgrc[0] = rect;
  493. }
  494. void CCoolTipCtrl::OnNcPaint()
  495. {
  496. CWindowDC dc(this);
  497. CRect rect;
  498. GetWindowRect(&rect);
  499. ScreenToClient(&rect);
  500. dc.ExcludeClipRect(&CRect(0, 0, m_nSize.cx-4, m_nSize.cy-4));
  501. dc.BitBlt(0, 0, m_nSize.cx, m_nSize.cy, &m_MemDC, 0, 0, SRCCOPY);
  502. DrawShadow(&dc, rect);
  503. }
  504. UINT CCoolTipCtrl::OnNcHitTest(CPoint point)
  505. {
  506. return HTCAPTION ;
  507. }