BalloonTip.cpp
上传用户:tianjwyx
上传日期:2007-01-13
资源大小:813k
文件大小:18k
源码类别:

操作系统开发

开发平台:

Visual C++

  1. /*******************************************************************************
  2. File:        BalloonTip.cpp
  3. Description: This file contains the module for creating a a balloon tip which can
  4.              be shown anywhere on a parent window
  5.              
  6. Created: Nov 1, 2001
  7. Author:  Prateek Kaul
  8. e-mail:  kaulpr@yahoo.com
  9. Compiler with version number : Visual C++ 6.0
  10. Copyright (c) 2001, Prateek Kaul
  11. All rights Reserved.
  12. The copyright to the computer program(s) herein is the property of Prateek Kaul
  13. The program(s) may be used and/or copied only with the written permission of 
  14. Prateek Kaul or in accordance with the terms and conditions stipulated
  15. in the agreement/contract under which the program(s) have been supplied.
  16. ********************************************************************************/
  17. #include "stdafx.h"
  18. #include "BalloonTip.h"
  19. #ifdef _DEBUG
  20. #define new DEBUG_NEW
  21. #undef THIS_FILE
  22. static char THIS_FILE[] = __FILE__;
  23. #endif
  24. /*----------------------------------------------------------------------------
  25.    Message map
  26. ----------------------------------------------------------------------------*/
  27. BEGIN_MESSAGE_MAP(CBalloonTip, CFrameWnd)
  28. //{{AFX_MSG_MAP(CBalloonTip)
  29. ON_WM_TIMER()
  30. ON_WM_LBUTTONDOWN()
  31. ON_WM_RBUTTONDOWN()
  32. ON_WM_CREATE()
  33. ON_WM_PAINT()
  34. //}}AFX_MSG_MAP
  35. END_MESSAGE_MAP()
  36. /*-----------------------------------------------------------------------------
  37.  Function : CBalloonTip::CBalloonTip()
  38.  Created: Nov 1, 2001
  39.  Author:  Prateek Kaul
  40.  e-mail:  kaulpr@yahoo.com
  41.  Abstract : Constructor
  42.  Parameters : 
  43.     1. strMessage -> Message to be shown in the balloon
  44.     2. lf         -> LOGFONT structure from which the the message font
  45.                      will be created.
  46.     3. bBalloonUp -> Is the balloon up or upside down?
  47.     
  48.  Return Value : none
  49.  Exceptions : none
  50.  Revisions : none
  51. ----------------------------------------------------------------------------*/
  52. CBalloonTip::CBalloonTip(CString strMessage, LOGFONT lf, BOOL bBalloonUp)
  53. {
  54.     m_strMessage       = strMessage;
  55.     m_bBalloonUp       = bBalloonUp;
  56.     
  57.     VERIFY(m_fontBalloonText.CreateFontIndirect(&lf));
  58. }
  59. /*-----------------------------------------------------------------------------
  60.  Function : CBalloonTip::~CBalloonTip()
  61.  Created: Nov 1, 2001
  62.  Author:  Prateek Kaul
  63.  e-mail:  kaulpr@yahoo.com
  64.  Abstract : Destructor
  65.  Parameters : none
  66.     
  67.  Return Value : none
  68.  Exceptions : none
  69.  Revisions : none
  70. ----------------------------------------------------------------------------*/
  71. CBalloonTip::~CBalloonTip()
  72. {
  73. }
  74. /*-----------------------------------------------------------------------------
  75.  Function : CBalloonTip::Show()
  76.  Created: Nov 1, 2001
  77.  Author:  Prateek Kaul
  78.  e-mail:  kaulpr@yahoo.com
  79.  Abstract : Creates the CBalloonTip on the heap, forces heap creation
  80.  Parameters : 
  81.     1. pt -> Point of the balloon tip
  82.     2. size -> Size of the window(width and height)
  83.     3. strMessage -> Message to be shown in the balloon
  84.     4. nSecs -> Seconds for which the balloon will be shown
  85.     5. lf -> LOGFONT structure from which the the message font
  86.              will be created.
  87.     6. bBalloonUp -> Is balloon up or upside down?
  88.  Return Value : void
  89.  Exceptions : none
  90.  Revisions : none
  91. ----------------------------------------------------------------------------*/
  92. CBalloonTip* CBalloonTip::Show(CPoint pt, CSize size, CString strMessage, LOGFONT lf, UINT nSecs, BOOL bBalloonUp)
  93. {
  94.     if( CBalloonTip::nBalloonInstances != 0) // No window creation if already one instance of the class
  95.     {
  96.         return NULL;
  97.     }
  98.     CBalloonTip* pBalloonTip = new CBalloonTip(strMessage, lf, bBalloonUp);
  99.     
  100.     CBalloonTip::nBalloonInstances = 1; // Only one instance of window possible.
  101.         
  102.     UINT nRectLeft;
  103. UINT nRectRight;
  104. UINT nRectTop;  
  105. UINT nRectBottom;
  106.     // Rectangle co-ordinates w.r.t balloon tip point
  107. // Balloon tip at CPoint pt shold remain there without change in window size
  108.     if (bBalloonUp)
  109.     {
  110.         nRectLeft   = pt.x - (size.cx * 0.65);
  111.     nRectRight  = pt.x + (size.cx * 0.35);
  112.     nRectTop    = pt.y - size.cy;
  113.     nRectBottom = pt.y;
  114.     }
  115.     else
  116.     {
  117.         nRectLeft   = pt.x - (size.cx * 0.35);
  118.     nRectRight  = pt.x + (size.cx * 0.65);
  119.     nRectTop    = pt.y;
  120.     nRectBottom = pt.y + (size.cy);
  121.     }
  122.         
  123. pBalloonTip->Create(CRect(nRectLeft, nRectTop, nRectRight, nRectBottom));    
  124.     pBalloonTip->MakeVisisble(nSecs);
  125.     return pBalloonTip;
  126. }
  127. /*-----------------------------------------------------------------------------
  128.  Function : CBalloonTip::MakeVisible()
  129.  Created: Nov 1, 2001
  130.  Author:  Prateek Kaul
  131.  e-mail:  kaulpr@yahoo.com
  132.  Abstract : Shows the balloon and sets the timer for it's eventual destruction.
  133.  Parameters : 
  134.     1. nSecs -> Seconds for the balloon to be shown
  135.     
  136.  Return Value : none
  137.  Exceptions : none
  138.  Revisions : none
  139. ----------------------------------------------------------------------------*/
  140. void CBalloonTip::MakeVisisble(UINT nSecs)
  141. {
  142.     ASSERT(nSecs > 0);
  143.     SetTimer(ID_TIMER, (nSecs * 1000), NULL);
  144.         
  145.     CRect rect;
  146.     GetWindowRect(&rect);
  147.     // Caption bar height to offeset when the balloon is shown
  148.     int nCaptionBarSize = ::GetSystemMetrics(SM_CYCAPTION);
  149.     int nVerticalBorderSize = ::GetSystemMetrics(SM_CYSIZEFRAME);
  150.     if(m_bBalloonUp)
  151.     {
  152.         // Account for the missing title bar and border thickness in the 3rd parameter
  153.         // as the balloon shifts up by the height of title bar and window tickness
  154.         SetWindowPos(
  155.             &wndTopMost,
  156.             m_rectWindow.left, 
  157.             (m_rectWindow.top + nCaptionBarSize + (2 * nVerticalBorderSize)),
  158.             m_rectWindow.right,
  159.             m_rectWindow.bottom, 
  160.             SWP_SHOWWINDOW | SWP_NOACTIVATE
  161.         );
  162.     }
  163.     else
  164.     {
  165.         // Account for the missing title bar and border thickness in the 3rd parameter
  166.         // as the balloon shifts up by the height of window tickness.
  167.         SetWindowPos(
  168.             &wndTopMost, 
  169.             m_rectWindow.left,
  170.             m_rectWindow.top - nVerticalBorderSize,
  171.             m_rectWindow.right, 
  172.             m_rectWindow.bottom,
  173.             SWP_SHOWWINDOW | SWP_NOACTIVATE
  174.         );
  175.     }
  176. }
  177. /*-----------------------------------------------------------------------------
  178.  Function : CBalloonTip::OnTimer()
  179.  Created: Nov 1, 2001
  180.  Author:  Prateek Kaul
  181.  e-mail:  kaulpr@yahoo.com
  182.  Abstract : Gets called by MFC for an WM_TIMER message
  183.  Parameters : 
  184.         1. nIDEvent -> Timer ID    
  185.  Return Value : void
  186.  Exceptions : none
  187.  Revisions : none
  188. ----------------------------------------------------------------------------*/
  189. void CBalloonTip::OnTimer(UINT nIDEvent) 
  190. {
  191.     KillTimer(ID_TIMER);
  192.     DestroyWindow();
  193. }
  194. /*-----------------------------------------------------------------------------
  195.  Function : CBalloonTip::OnLButtonDown()
  196.  Created: Nov 1, 2001
  197.  Author:  Prateek Kaul
  198.  e-mail:  kaulpr@yahoo.com
  199.  Abstract : Gets called by MFC for an WM_LBUTTONDOWN message
  200.  Parameters : 
  201.         See MFC documentation
  202.  Return Value : void
  203.  Exceptions : none
  204.  Revisions : none
  205. ----------------------------------------------------------------------------*/
  206. void CBalloonTip::OnLButtonDown(UINT nFlags, CPoint point) 
  207. {
  208.     KillTimer(ID_TIMER);
  209.     DestroyWindow();
  210. }
  211. /*-----------------------------------------------------------------------------
  212.  Function : CBalloonTip::OnRButtonDown()
  213.  Created: Nov 1, 2001
  214.  Author:  Prateek Kaul
  215.  e-mail:  kaulpr@yahoo.com
  216.  Abstract : Gets called by MFC for an WM_RBUTTONDOWN message
  217.  Parameters : 
  218.         See MFC documentation
  219.  Return Value : void
  220.  Exceptions : none
  221.  Revisions : none
  222. ----------------------------------------------------------------------------*/
  223. void CBalloonTip::OnRButtonDown(UINT nFlags, CPoint point) 
  224. {
  225.     KillTimer(ID_TIMER);
  226.     DestroyWindow();
  227. }
  228. /*-----------------------------------------------------------------------------
  229.  Function : CBalloonTip::OnCreate()
  230.  Created: Nov 1, 2001
  231.  Author:  Prateek Kaul
  232.  e-mail:  kaulpr@yahoo.com
  233.  Abstract : Gets called by MFC for an WM_CREATE message
  234.  Parameters : 
  235.         See MFC documentation
  236.  Return Value : int
  237.  Exceptions : none
  238.  Revisions : none
  239. ----------------------------------------------------------------------------*/
  240. int CBalloonTip::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  241. {
  242. if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
  243.     {
  244.         return -1;
  245.     }
  246.     // Remove caption and thick frame for proper shading
  247.     ModifyStyle(WS_CAPTION | WS_THICKFRAME, 0); 
  248.     CRect t_Rect;
  249. GetClientRect(&t_Rect);  // Get the client rectangle to set the balloon region
  250.     if (m_bBalloonUp)
  251.     {
  252.         // Calculation of Text window, where to write text in the balloon
  253.         m_rectText.left   = t_Rect.Width() * 0.10; 
  254.         m_rectText.right  = t_Rect.Width() * 0.90;
  255.         m_rectText.top    = t_Rect.Height() * 0.10; 
  256.         m_rectText.bottom = t_Rect.Height()* 0.70; 
  257.             
  258.         // Create an elliptical region out of the client rectangle
  259.     m_rgnRoundRect.CreateRoundRectRgn(
  260.             t_Rect.left, 
  261.             t_Rect.top, 
  262.             t_Rect.right,
  263.             t_Rect.bottom - (t_Rect.Height() * 0.25), 
  264.             abs(t_Rect.left - t_Rect.right) * 0.18,
  265.             t_Rect.Height() * 0.25
  266.         );
  267.    
  268.         // Start the process of creating the balloon tip
  269.     CPoint ptTri[4];
  270.     ptTri[0].x = (t_Rect.left) + (t_Rect.Width() * 0.93);
  271.     ptTri[0].y = (t_Rect.bottom) - (t_Rect.Height() * 0.40);
  272.     
  273.     ptTri[1].x = (t_Rect.left) + (t_Rect.Width() * 0.65);
  274.     ptTri[1].y = t_Rect.bottom;
  275.     ptTri[2].x = (t_Rect.left) + (t_Rect.Width() * 0.70);
  276.     ptTri[2].y = (t_Rect.bottom) - (t_Rect.Height() * 0.40);
  277.    
  278.     ptTri[3].x = (t_Rect.left) + (t_Rect.Width() * 0.93);
  279.     ptTri[3].y = (t_Rect.bottom) - (t_Rect.Height() * 0.40);
  280.    
  281.     m_rgnTip.CreatePolygonRgn(ptTri, 3, ALTERNATE);
  282.     }
  283.     else
  284.     {
  285.         // Calculation of Text window, where to write text in the balloon
  286.         m_rectText.left   = t_Rect.Width() * 0.10;
  287.         m_rectText.right  = t_Rect.Width() * 0.90;
  288.         m_rectText.top    = t_Rect.Height() * 0.30;
  289.         m_rectText.bottom = t_Rect.Height() * 0.90;
  290.         
  291.         // Create an elliptical region out of the client rectangle
  292.     m_rgnRoundRect.CreateRoundRectRgn(
  293.             t_Rect.left,
  294.             t_Rect.bottom - (t_Rect.Height() * 0.75), 
  295.             t_Rect.right, 
  296.             t_Rect.bottom, 
  297.             abs(t_Rect.left - t_Rect.right) * 0.18,
  298.             t_Rect.Height() * 0.25
  299.         );
  300.         // Start the process of creating the balloon tip
  301.     CPoint ptTri[4];
  302.     ptTri[0].x = (t_Rect.left) + (t_Rect.Width() * 0.07);
  303.     ptTri[0].y = (t_Rect.Height() * 0.40);
  304.             
  305.     ptTri[1].x = (t_Rect.left) + (t_Rect.Width() * 0.35);
  306.     ptTri[1].y = t_Rect.bottom - t_Rect.Height();
  307.     ptTri[2].x = (t_Rect.left) + (t_Rect.Width() * 0.30);
  308.     ptTri[2].y = t_Rect.Height() * 0.40;
  309.            
  310.     ptTri[3].x = (t_Rect.left) + (t_Rect.Width() * 0.07);
  311.     ptTri[3].y = t_Rect.Height() * 0.40;
  312.            
  313.     m_rgnTip.CreatePolygonRgn(ptTri, 3, ALTERNATE);
  314.     }
  315.     
  316.     // Create the combined region with ellipse and tip
  317. CRgn rgnComb;
  318.     
  319.     rgnComb.CreateRectRgn(t_Rect.left, t_Rect.top, t_Rect.right, t_Rect.bottom);
  320. int iRetComb = rgnComb.CombineRgn(&m_rgnTip, &m_rgnRoundRect, RGN_OR);
  321.     if (iRetComb == ERROR)
  322. {
  323.         ::AfxMessageBox( "ERROR in Combining Region" );
  324. return -1;
  325. }
  326.    
  327.     SetWindowRgn(rgnComb.operator HRGN(), TRUE);
  328. return 0;
  329. }
  330. /*-----------------------------------------------------------------------------
  331.  Function : CBalloonTip::OnPaint()
  332.  Created: Nov 1, 2001
  333.  Author:  Prateek Kaul
  334.  e-mail:  kaulpr@yahoo.com
  335.  Abstract : Gets called by MFC for a WM_PAINT message
  336.  Parameters : 
  337.         See MFC documentation
  338.  Return Value : void
  339.  Exceptions : none
  340.  Revisions : none
  341. ----------------------------------------------------------------------------*/
  342. void CBalloonTip::OnPaint() 
  343. {
  344. CPaintDC dc(this); // device context for painting
  345.     CRect t_Rect;
  346.     GetClientRect(&t_Rect);
  347.     // Get the total balloon, inclding all cut out regions
  348. CRgn rgnComb;
  349.     rgnComb.CreateRectRgn(t_Rect.left, t_Rect.top, t_Rect.right, t_Rect.bottom);
  350.    
  351.     // Create a balloon tip from this total region
  352.     int iRetComb = rgnComb.CombineRgn(&m_rgnTip, &m_rgnRoundRect, RGN_OR );
  353.     if (iRetComb == ERROR)
  354. {
  355.         ::AfxMessageBox( "ERROR in Combining Region" );
  356.         return;
  357. }
  358. CBrush brOutlineBrush;
  359.     brOutlineBrush.CreateSolidBrush(RGB(0, 0, 0)); // blue
  360.    
  361.     CBrush brFillBrush;
  362.     brFillBrush.CreateSolidBrush(RGB(249, 254, 188)); // light yellow
  363.    
  364.    
  365.     dc.FillRgn(&rgnComb, &brFillBrush);  // Fill the balloon
  366.     dc.FrameRgn(&rgnComb, &brOutlineBrush, 2, 1); // Outline the balloon
  367.     int nBkMode          = dc.SetBkMode(TRANSPARENT);
  368.     COLORREF clrPrevious =  dc.SetTextColor(RGB(255, 0, 0));
  369.     CFont *pFont = dc.SelectObject(&m_fontBalloonText);
  370.    
  371.     CSize czTextWidth = dc.GetTextExtent(m_strMessage);
  372.    
  373.     if (czTextWidth.cx < m_rectText.Width())
  374.     {
  375.        dc.DrawText(m_strMessage, m_rectText, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  376.     }
  377.      
  378.     else
  379.     {
  380.         dc.DrawText(m_strMessage, m_rectText, DT_CENTER | DT_WORDBREAK);
  381.     }
  382.     
  383.     // Restore the DC to its oroginal state
  384.     dc.SelectObject(pFont);
  385.     dc.SetBkColor(nBkMode);
  386.     dc.SetTextColor(clrPrevious);
  387. }
  388. /*-----------------------------------------------------------------------------
  389.  Function : CBalloonTip::PreCreateWindow(CREATESTRUCT& cs)
  390.  Created: Dec 07, 2001
  391.  Author:  Prateek Kaul
  392.  e-mail:  kaulpr@yahoo.com
  393.  Abstract : Called by MFC when a before WM_CREATE message is received by the
  394.             window.
  395.             We override this function so that the window so created is not
  396.             visible in the Taskbar. We make this window the child of an
  397.             invisible parent m_wndInvisibleParent.
  398.  Parameters : Look in MFC documentation
  399.  Return Value : BOOL
  400.  Exceptions : none
  401.  Revisions : none
  402. ----------------------------------------------------------------------------*/
  403. BOOL CBalloonTip::PreCreateWindow(CREATESTRUCT& cs)
  404. {
  405. if (!CWnd::PreCreateWindow(cs))
  406.     {
  407. return FALSE;
  408.     }
  409.   // Create invisible parent window
  410.   if (!::IsWindow(m_wndInvisibleParent.m_hWnd))
  411.   {
  412.         // Try creating the invisible parent window
  413.         PCSTR pstrOwnerClass = ::AfxRegisterWndClass(0);
  414.        
  415.         BOOL bError = m_wndInvisibleParent.CreateEx(
  416.                           0,
  417.                           pstrOwnerClass, 
  418.                           _T(""), 
  419.                           WS_POPUP,
  420.           0,
  421.                           0,
  422.                           0,
  423.                           0,
  424.           NULL,
  425.                           0
  426.                       );
  427.         if (bError == FALSE)
  428.         {
  429. return FALSE;
  430.         }
  431.   }
  432.     // Set the invisible window as the parent of "this" window
  433. cs.hwndParent = m_wndInvisibleParent.m_hWnd;
  434. return TRUE;
  435. }
  436. /*-----------------------------------------------------------------------------
  437.  Function : CBalloonTip::Create()
  438.  Created: Dec 07, 2001
  439.  Author:  Prateek Kaul
  440.  e-mail:  kaulpr@yahoo.com
  441.  Abstract : Called by the static CBalloonTip to create a Windows(R) window 
  442.  Parameters : rect-> a rectangle in screen co ordinates where the balloon
  443.               will be displayed.
  444.  Return Value : BOOL
  445.  Exceptions : none
  446.  Revisions : none
  447. ----------------------------------------------------------------------------*/
  448. BOOL CBalloonTip::Create(CRect rect)
  449. {
  450.     m_rectWindow = rect;
  451.     PCSTR pstrOwnerClass = ::AfxRegisterWndClass(0);
  452.     BOOL bResult = CFrameWnd::Create(pstrOwnerClass, NULL, WS_OVERLAPPED, m_rectWindow);
  453.     
  454.     return bResult;
  455. }
  456. /*-----------------------------------------------------------------------------
  457.  Function : CBalloonTip::Hide()
  458.  Created: Dec 08, 2001
  459.  Author:  Prateek Kaul
  460.  e-mail:  kaulpr@yahoo.com
  461.  Abstract : Provided to destroy a balloon before it self destructs. If it is 
  462.             already hidden, it will have no effect.
  463.             
  464.  Parameters : CBalloonTip*
  465.  Return Value : void
  466.  Exceptions : none
  467.  Revisions : none
  468. ----------------------------------------------------------------------------*/
  469. void CBalloonTip::Hide(CBalloonTip* pBalloonTip)
  470. {
  471.     if (CBalloonTip::nBalloonInstances != 0)
  472.     {
  473.         pBalloonTip->ShowWindow(SW_HIDE);
  474.         pBalloonTip->KillTimer(ID_TIMER);
  475.         pBalloonTip->DestroyWindow();
  476.     }
  477. }
  478. /*-----------------------------------------------------------------------------
  479.   int CBalloonTip::nBalloonInstances;
  480.   Abstract: Used for preventing more than one instance of the class CBalloonTip
  481. -----------------------------------------------------------------------------*/
  482. int CBalloonTip::nBalloonInstances = 0;
  483. /*-----------------------------------------------------------------------------
  484.  Function : CBalloonTip::PostNcDestroy()
  485.  Created: Dec 08, 2001
  486.  Author:  Prateek Kaul
  487.  e-mail:  kaulpr@yahoo.com
  488.  Abstract : Last function the window receives when it is destroyed.
  489.             Used for resetting the counter CBalloonTip::nBalloonInstances to 0,
  490.             so that a new instance of this class can be created.
  491.             
  492.  Parameters : void
  493.  Return Value : void
  494.  Exceptions : none
  495.  Revisions : none
  496. ----------------------------------------------------------------------------*/
  497. void CBalloonTip::PostNcDestroy()
  498. {
  499.     CBalloonTip::nBalloonInstances = 0;
  500.     CFrameWnd::PostNcDestroy();
  501. }