ToolTipWnd.cpp
上传用户:lydc80129
上传日期:2013-01-15
资源大小:979k
文件大小:15k
源码类别:

界面编程

开发平台:

Visual C++

  1. // ToolTipWnd.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "ToolTipWnd.h"
  5. #ifdef _DEBUG
  6. #define new DEBUG_NEW
  7. #undef THIS_FILE
  8. static char THIS_FILE[] = __FILE__;
  9. #endif
  10. /////////////////////////////////////////////////////////////////////////////
  11. // CToolTipWnd
  12. DWORD CToolTipWnd::nCurntTTWStyle=TTWS_HEART;
  13. CToolTipWnd::CToolTipWnd()
  14. {
  15. lpWndCls = AfxRegisterWndClass(0);
  16. //Defaults
  17. m_bMouseIn = false;
  18. m_bStuck = false;
  19. m_iWidth = 120;
  20. m_iHeight = 100;
  21.     m_hWndAlpha=175;//缺省透明度
  22. m_clrBkColor =RGB(213,253,224);//RGB(249,254,188); //light yellow
  23. m_clrFrameColor =RGB(0,0,0);  //blue
  24. m_clrTextColor = RGB(0,0,255);  //black
  25. m_iFontHeight = 14;
  26. m_strFontName = "Arial";
  27. //    nCurntTTWStyle=TTWS_NACELLE;//缺省样式为吊篮样式 
  28. pCurrwnd = NULL;
  29. }
  30. CToolTipWnd::~CToolTipWnd()
  31. {
  32. BTOOLINFO *stToolInfo;
  33. CWnd *pWnd;
  34. for(POSITION pos = m_ToolPtr.GetStartPosition(); pos != NULL;)
  35. {
  36. m_ToolPtr.GetNextAssoc(pos, (void *&)pWnd, (void*&) stToolInfo);
  37. delete stToolInfo;
  38. }
  39. m_ToolPtr.RemoveAll();
  40. }
  41. BEGIN_MESSAGE_MAP(CToolTipWnd, CWnd)
  42. //{{AFX_MSG_MAP(CToolTipWnd)
  43. ON_WM_PAINT()
  44. ON_WM_CREATE()
  45. //}}AFX_MSG_MAP
  46. END_MESSAGE_MAP()
  47. /////////////////////////////////////////////////////////////////////////////
  48. // CToolTipWnd message handlers
  49. BOOL CToolTipWnd::Create(CWnd* pParentWnd,DWORD dwStyle) 
  50. {//主要目的是创建一个ToolTip窗口
  51. BOOL bRet = CWnd::CreateEx(NULL, lpWndCls, NULL,
  52. WS_POPUP, 0, 0, m_iWidth, m_iHeight,
  53. pParentWnd->GetSafeHwnd(), NULL, NULL);
  54. m_hParentWnd = pParentWnd->GetSafeHwnd();
  55. if(bRet)
  56. SetOwner(pParentWnd);
  57. //设置当前样式
  58. this->SetCurrentTTWStyle(dwStyle);
  59. /*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/
  60. //设置窗口的透明度
  61. SetWindowLong(this->GetSafeHwnd(),GWL_EXSTYLE,
  62. GetWindowLong(this->GetSafeHwnd(),GWL_EXSTYLE)^0x80000);
  63. HINSTANCE hInst=LoadLibrary("user32.dll");
  64. if(hInst)
  65. {//加载成功
  66. typedef BOOL(WINAPI* LPSETLAYWND)(HWND,COLORREF,BYTE,DWORD);
  67.         LPSETLAYWND MyProc=(LPSETLAYWND)GetProcAddress(hInst,"SetLayeredWindowAttributes");
  68.         MyProc(this->GetSafeHwnd(),0,m_hWndAlpha,2);
  69. FreeLibrary(hInst);
  70. }
  71. /*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/
  72. return bRet;
  73. }
  74. void CToolTipWnd::OnPaint() 
  75. {
  76. CPaintDC dc(this); // device context for painting
  77. CRect rectCl;
  78. GetClientRect(&rectCl);
  79. CRgn rgnComb;
  80.     rgnComb.CreateRectRgn(rectCl.left,rectCl.top,rectCl.right,rectCl.bottom);
  81. int iRetComb = rgnComb.CombineRgn(&rgnTri, &rgn, RGN_OR);
  82. if(iRetComb==ERROR)
  83. {
  84. AfxMessageBox("ERROR in Combining Region");
  85. return;
  86. }
  87. CBrush pBrush;
  88. pBrush.CreateSolidBrush(m_clrFrameColor);
  89. CBrush pBrush1;
  90. pBrush1.CreateSolidBrush(m_clrBkColor);
  91. dc.FillRgn( &rgnComb, &pBrush1);
  92. dc.FrameRgn(&rgnComb, &pBrush, 2, 1);
  93. dc.SetBkMode(TRANSPARENT);
  94. dc.SetTextColor(m_clrTextColor);
  95. CFont *pFont = dc.SelectObject(&m_fontText);
  96.     CSize czTextWidth = dc.GetTextExtent(m_strText);
  97. if( czTextWidth.cx < m_RectText.Width())
  98. dc.DrawText(m_strText, m_RectText, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  99. else
  100. dc.DrawText(m_strText, m_RectText, DT_CENTER | DT_WORDBREAK);
  101.     dc.SelectObject(pFont);
  102. }
  103. int CToolTipWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  104. {//合并区域
  105. if (CWnd::OnCreate(lpCreateStruct) == -1)
  106. return -1;
  107. SetTTWStyle(nCurntTTWStyle);//创建一个当前指定的窗口样式
  108. m_fontText.CreateFont(m_iFontHeight, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,m_strFontName);
  109. return 0;
  110. }
  111. void CToolTipWnd::RelayEvent(LPMSG lpMsg)
  112. {
  113. switch(lpMsg->message) 
  114. {
  115. case WM_KEYDOWN:
  116. if(IsWindowVisible())
  117. {
  118. ShowWindow(SW_HIDE);
  119. }
  120. break;
  121. case WM_LBUTTONDOWN:
  122. case WM_RBUTTONDOWN:
  123. if(IsWindowVisible())
  124. {
  125. ShowWindow(SW_HIDE);
  126. }
  127. break;
  128. case WM_MOUSEMOVE:
  129. {
  130. CWnd *pFocusWnd = AfxGetApp()->m_pMainWnd->GetFocus();
  131. if(pFocusWnd==NULL)
  132. break;
  133. CWnd* pWnd = CWnd::FromHandle(lpMsg->hwnd);
  134. HWND hWndTemp = ::GetParent(lpMsg->hwnd);
  135. CPoint pt;
  136. pt.x = lpMsg->pt.x;
  137. pt.y = lpMsg->pt.y;
  138. BTOOLINFO *stToolInfo;
  139. CWnd *pBToolWnd;
  140. for(POSITION pos = m_ToolPtr.GetStartPosition(); pos != NULL;)
  141. {
  142. m_ToolPtr.GetNextAssoc(pos, (void *&)pBToolWnd, (void*&) stToolInfo);
  143. if(!m_bMouseIn)
  144. {
  145. if(lpMsg->hwnd == stToolInfo->hwndTool)
  146. {
  147. if(m_bStuck && IsWindowVisible())
  148. {
  149. SetWindowPos(&wndTop,pt.x,pt.y,m_iWidth,m_iHeight,SWP_NOACTIVATE);
  150. ShowWindow(SW_SHOWNOACTIVATE);
  151. }
  152. m_bMouseIn = true;
  153. m_clrTextColor = stToolInfo->clrToolTextClr; 
  154. m_strText = stToolInfo->strToolText; 
  155. SetWindowPos(&wndTop,pt.x,pt.y,m_iWidth,m_iHeight,SWP_NOACTIVATE);
  156. ShowWindow(SW_SHOWNOACTIVATE);
  157. pCurrwnd = stToolInfo->hwndTool;
  158. break;
  159. }
  160. }
  161. else
  162. {
  163. CRect rect;
  164. ::GetWindowRect(pCurrwnd, &rect);
  165. if(m_bStuck && IsWindowVisible())
  166. {
  167. SetWindowPos(&wndTop,pt.x,pt.y,m_iWidth,m_iHeight,SWP_NOACTIVATE);
  168. ShowWindow(SW_SHOWNOACTIVATE);
  169. }
  170. CWnd* pWnd = CWnd::FromHandle(lpMsg->hwnd);
  171. CWnd *WndPt = pWnd->WindowFromPoint(lpMsg->pt);
  172. if(WndPt->GetSafeHwnd() != pCurrwnd)
  173. {
  174. m_bMouseIn = false;
  175. ShowWindow(SW_HIDE);
  176. }
  177. break;
  178. }
  179. }
  180. }
  181. break; //WM_MOUSEMOVE
  182. }
  183.  
  184. }
  185. void CToolTipWnd::AddTool(CWnd *pWnd, CString strText, COLORREF clrTextColor)
  186. {
  187. BTOOLINFO *stToolInfo;
  188. if(!m_ToolPtr.Lookup( pWnd, ( void*& )  stToolInfo))
  189. {
  190. stToolInfo = new BTOOLINFO;
  191. stToolInfo->hwndTool = pWnd->GetSafeHwnd();
  192. stToolInfo->strToolText = strText;
  193. if(clrTextColor==NULL)
  194. stToolInfo->clrToolTextClr = m_clrTextColor;
  195. else
  196. stToolInfo->clrToolTextClr = clrTextColor;
  197. m_ToolPtr.SetAt(pWnd, stToolInfo);
  198. }
  199. }
  200. BOOL CToolTipWnd::SetTTWStyle(DWORD nStyle)
  201. {//设置指定样式窗口
  202. CRect rectCl;
  203. GetClientRect(&rectCl);
  204. //区域初始化
  205. rgn.m_hObject = NULL;
  206. rgnTri.m_hObject = NULL;
  207. rgnComb.m_hObject = NULL;
  208. this->RedrawWindow(NULL,NULL,RDW_INVALIDATE|RDW_UPDATENOW|RDW_ERASE);
  209. /////////////////////////////////////////////////////////////////////
  210. //////////////////       设置气球样式
  211. /////////////////////////////////////////////////////////////////////
  212.    if(nStyle==TTWS_BALLOON)
  213.    {//气球样式
  214. /*=======================创建气球提示框=========================*/
  215. int x=0, y=0;
  216. CRect rectTemp;
  217. rectTemp = rectCl;
  218. rectTemp.left = rectTemp.left + 10;//影响m_RectText
  219. x = (int)( (float)((float)rectTemp.Width() / 2.0) / 1.41421);
  220. y = (int)( (float)((float)rectTemp.Height() / 2.0) / 1.41421);
  221. m_RectText.top = ( (rectTemp.Height() / 2) - y);
  222. m_RectText.left = ( (rectTemp.Width() / 2) - x) + 10;
  223. m_RectText.right = ( (rectTemp.Width() / 2) + x) + 10;
  224. m_RectText.bottom = ( (rectTemp.Height() / 2) + y);
  225.     BOOL bRegRet = rgn.CreateEllipticRgn(rectCl.left+10,rectCl.top,rectCl.right,rectCl.bottom);
  226. CPoint ptTri[3];
  227. ptTri[0].x = rectCl.left;
  228. ptTri[0].y = (rectCl.bottom / 2) - 10;
  229. ptTri[1].x = rectCl.left + 15;
  230. ptTri[1].y = (rectCl.bottom / 2) - 5;
  231. ptTri[2].x = rectCl.left + 15;
  232. ptTri[2].y = (rectCl.bottom / 2) + 5;
  233. ptTri[3].x = rectCl.left;
  234. ptTri[3].y = (rectCl.bottom / 2) - 10;
  235. BOOL bRegTriRet = rgnTri.CreatePolygonRgn(ptTri, 3, ALTERNATE);
  236. rgnComb.CreateRectRgn(rectCl.left+10,rectCl.top,rectCl.right,rectCl.bottom);
  237. int iRetComb = rgnComb.CombineRgn(&rgnTri, &rgn, RGN_OR);
  238. if(iRetComb == ERROR)
  239. {
  240. AfxMessageBox("ERROR in Combining Region");
  241. return -1;
  242. }
  243. int bRgnWnd = SetWindowRgn(rgnComb.operator HRGN( ), TRUE);
  244. /*=========================创建完成============================*/
  245. // nCurntTTWStyle=TTWS_BALLOON;
  246.    }
  247. //////////////////////////////////////////////////////////////////////
  248. ///////////////           设置吊篮样式 
  249. //////////////////////////////////////////////////////////////////////
  250.     if(nStyle==TTWS_NACELLE)
  251. {//吊篮样式
  252. /*====================创建一个箭头提示框=======================*/
  253.     rgn.m_hObject = NULL;
  254.     rgnTri.m_hObject = NULL;
  255.     rgnComb.m_hObject = NULL;
  256.         /*##################创建上面的小的三角形##################*/
  257.     CPoint pnt[3];
  258. pnt[0].x=rectCl.left;
  259. pnt[0].y=rectCl.top;//第一点
  260. pnt[1].x=rectCl.left+15;
  261. pnt[1].y=(rectCl.top+rectCl.bottom)/2;
  262. pnt[2].x=pnt[1].x+20;
  263. pnt[2].y=pnt[1].y;
  264.         BOOL bRegTriRet=rgnTri.CreatePolygonRgn(pnt,3,ALTERNATE);
  265.     /*#######################END##############################*/
  266.         
  267. /*######################创建圆角矩形######################*/
  268. CRect rect;
  269. rect=rectCl;
  270. rect.top=(rectCl.top+rectCl.bottom)/2;
  271. rgn.CreateRoundRectRgn(rect.left,rect.top,rect.right,rect.bottom,15,15);
  272.         /*##########################END###########################*/
  273. ///////设置文本框
  274.   m_RectText.left=rectCl.left+15;
  275.   m_RectText.top=(rectCl.top+rectCl.bottom)/2;
  276.   m_RectText.right=rectCl.right-15;
  277.   m_RectText.bottom=rectCl.bottom;
  278. ///////over//////////
  279. rgnComb.CreateRectRgn(rectCl.left,rectCl.top,rectCl.right,rectCl.bottom);
  280. int iRetComb = rgnComb.CombineRgn(&rgnTri, &rgn, RGN_OR);
  281.  if(iRetComb == ERROR)
  282.  {
  283. AfxMessageBox("ERROR in Combining Region");
  284. return -1;
  285.  }
  286.  /*=========================创建完成============================*/
  287. int bRgnWnd = SetWindowRgn(rgnComb.operator HRGN( ), TRUE);
  288. // nCurntTTWStyle=TTWS_NACELLE;
  289. }
  290. //////////////////////////////////////////////////////////////////////
  291. ////                  设置心脏样式
  292. //////////////////////////////////////////////////////////////////////
  293. if(nStyle==TTWS_HEART)
  294. {
  295. //########################设定文本框#######################*/
  296.         m_RectText.left=rectCl.left+rectCl.Width()/4;
  297. m_RectText.top=rectCl.top+rectCl.Height()/4;
  298. m_RectText.right=rectCl.right-rectCl.Width()/4;
  299. m_RectText.bottom=rectCl.top+3*rectCl.Height()/4;
  300. //#########################################################*/
  301. /*======================设置左右椭圆=======================*/
  302. CRect rectLeft,rectRight;
  303. rectLeft=rectCl;
  304. rectRight=rectCl;
  305. //设置窗口
  306. rectLeft.right=rectCl.Width()/2;
  307. rectLeft.bottom=rectCl.Height()/2;
  308. rectRight.left=rectCl.Width()/2;
  309. rectRight.bottom=rectCl.Height()/2;
  310. CRgn rgnLeft,rgnRight;
  311. rgnLeft.CreateEllipticRgn(rectLeft.left,rectLeft.top,rectLeft.right,rectLeft.bottom);
  312. rgnRight.CreateEllipticRgn(rectRight.left,rectRight.top,rectRight.right,rectRight.bottom);
  313. rgnTri.CreateRectRgn(rectCl.left,rectCl.top,rectCl.right,rectCl.bottom/2);
  314. int nBet=rgnTri.CombineRgn(&rgnLeft,&rgnRight,RGN_OR);
  315. if(nBet==ERROR )
  316. {
  317. AfxMessageBox("合并区域失败!");
  318. return -1;
  319. }
  320. /*===============================================================*/
  321. //设置抛物线部分
  322. CRect rectTemp;
  323. rectTemp=rectCl;
  324. rectTemp.top=rectCl.Height()/4;
  325. int nWidth,nHeight;
  326. nWidth=rectTemp.Width();
  327. nHeight=rectTemp.Height();
  328. CPoint points[1000];
  329. for(int i=0;i<1000;i++)
  330. {
  331. points[i].x=rectTemp.left;
  332. points[i].y=rectTemp.top;
  333. }
  334. for(i=0;i<nWidth;i++)
  335. {
  336. points[i].x=rectTemp.left+i;
  337. points[i].y=rectTemp.top+nHeight-4*nHeight*(points[i].x-nWidth/2)*(points[i].x-nWidth/2)/(nWidth*nWidth);
  338. }
  339. rgn.CreatePolygonRgn(points,1000,ALTERNATE);
  340. //合并区域
  341. rgnComb.CreateRectRgn(rectCl.left,rectCl.top,rectCl.right,rectCl.bottom);
  342.    int iRetComb = rgnComb.CombineRgn(&rgnTri, &rgn, RGN_OR);
  343.  if(iRetComb == ERROR)
  344.  {
  345. AfxMessageBox("ERROR in Combining Region");
  346. return -1;
  347.  }
  348.  /*=========================创建完成============================*/
  349. int bRgnWnd = SetWindowRgn(rgnComb.operator HRGN( ), TRUE);
  350. }
  351. /////////////////////////////////////////////////////////////////////
  352. ////////////////      设置普通矩形样式
  353. /////////////////////////////////////////////////////////////////////
  354. if(nStyle==TTWS_RECT)
  355. {
  356. rgnTri.CreateRectRgn(rectCl.left,rectCl.top,rectCl.right,rectCl.bottom);
  357. rgn.CreateRectRgn(rectCl.left,rectCl.top,rectCl.right,rectCl.bottom);
  358. rgnComb.CreateRectRgn(rectCl.left,rectCl.top,rectCl.right,rectCl.bottom);
  359.        m_RectText=rectCl;//设置文本框
  360.        int iRetComb = rgnComb.CombineRgn(&rgnTri, &rgn, RGN_AND);
  361.  if(iRetComb == ERROR)
  362.  {
  363. AfxMessageBox("ERROR in Combining Region");
  364. return -1;
  365.  }
  366.  /*=========================创建完成============================*/
  367. int bRgnWnd = SetWindowRgn(rgnComb.operator HRGN( ), TRUE);
  368. }
  369. //////////////////////////////////////////////////////////////////////
  370. /////////////////////////设置圆角矩形
  371. //////////////////////////////////////////////////////////////////////
  372. if(nStyle==TTWS_ROUNDRECT)
  373. {
  374. rgnTri.CreateRoundRectRgn(rectCl.left,rectCl.top,rectCl.right,rectCl.bottom,15,15);
  375. rgn.CreateRoundRectRgn(rectCl.left,rectCl.top,rectCl.right,rectCl.bottom,15,15);
  376. rgnComb.CreateRectRgn(rectCl.left,rectCl.top,rectCl.right,rectCl.bottom);
  377. //设置文本框
  378.        m_RectText.left=rectCl.left+15;
  379.    m_RectText.top=rectCl.top+15; 
  380.    m_RectText.right=rectCl.right-15;
  381.    m_RectText.bottom=rectCl.bottom-15;
  382.    //区域合并
  383.        int iRetComb = rgnComb.CombineRgn(&rgnTri, &rgn, RGN_AND);
  384.  if(iRetComb == ERROR)
  385.  {
  386. AfxMessageBox("ERROR in Combining Region");
  387. return -1;
  388.  }
  389.  /*=========================创建完成============================*/
  390. int bRgnWnd = SetWindowRgn(rgnComb.operator HRGN( ), TRUE);
  391. }
  392. //////////////////////////////////////////////////////////////////////
  393. ////////////////////////椭圆区域设置
  394. //////////////////////////////////////////////////////////////////////
  395.     if(nStyle==TTWS_ELLIPSE)
  396. {
  397.         rgnTri.CreateEllipticRgn(rectCl.left,rectCl.top,rectCl.right,rectCl.bottom);
  398. rgn.CreateEllipticRgn(rectCl.left,rectCl.top,rectCl.right,rectCl.bottom);
  399. rgnComb.CreateRectRgn(rectCl.left,rectCl.top,rectCl.right,rectCl.bottom);
  400. //设置文本框
  401. CRect rectTemp=rectCl;
  402. int x,y;
  403.        x = (int)( (float)((float)rectTemp.Width() / 2.0) / 1.41421);
  404.    y = (int)( (float)((float)rectTemp.Height() / 2.0) / 1.41421);
  405.    m_RectText.left=rectCl.left+rectCl.Width()/2-x;
  406.    m_RectText.top=rectCl.top+rectCl.Height()/2-y;
  407.    m_RectText.right=rectCl.right+x-rectCl.Width()/2;
  408.    m_RectText.bottom=rectCl.bottom+y-rectCl.Height()/2;
  409.    //区域合并
  410.        int iRetComb = rgnComb.CombineRgn(&rgnTri, &rgn, RGN_AND);
  411.  if(iRetComb == ERROR)
  412.  {
  413. AfxMessageBox("ERROR in Combining Region");
  414. return -1;
  415.  }
  416.  /*=========================创建完成============================*/
  417.    int bRgnWnd = SetWindowRgn(rgnComb.operator HRGN( ), TRUE);
  418. }
  419. //////////////////////////////////////////////////////////////////////
  420.   return false;
  421. }