RgnButton.cpp
上传用户:helenlwl
上传日期:2007-01-01
资源大小:14k
文件大小:4k
源码类别:

按钮控件

开发平台:

Visual C++

  1. /********************************************* 
  2.  REVISION LOG ENTRY 
  3.  Revision By: Noam Rathaus
  4.  Revised on 26/5/1999 14:57:00
  5.  Comments: RgnButton.cpp : implementation file 
  6. **********************************************/ 
  7. #include "stdafx.h"
  8. #include "CRgnedButton.h"
  9. #include "RgnButton.h"
  10. #ifdef _DEBUG
  11. #define new DEBUG_NEW
  12. #undef THIS_FILE
  13. static char THIS_FILE[] = __FILE__;
  14. #endif
  15. /////////////////////////////////////////////////////////////////////////////
  16. // CRgnButton
  17. CRgnButton::CRgnButton()
  18. {
  19. }
  20. CRgnButton::~CRgnButton()
  21. {
  22. }
  23. BEGIN_MESSAGE_MAP(CRgnButton, CButton)
  24. //{{AFX_MSG_MAP(CRgnButton)
  25. ON_WM_PAINT()
  26. //}}AFX_MSG_MAP
  27. END_MESSAGE_MAP()
  28. /////////////////////////////////////////////////////////////////////////////
  29. // CRgnButton message handlers
  30. /*==========================================================================================*/
  31. // 
  32. // Function: CRgnButton::OnPaint
  33. // 
  34. // Description: 
  35. //Override for the default OnPaint() event 
  36. // 
  37. // Parameters: 
  38. //    None
  39. // 
  40. // Return: 
  41. //    None
  42. /*==========================================================================================*/
  43. void CRgnButton::OnPaint() 
  44. {
  45.   CButton::OnPaint();
  46.   
  47.   CRect RectParent, RectInner;
  48. // RectParent - Used for storing the Parent Button Rectangle (In their Windows prespective)
  49. // RectInner - Used for storing the Parent's Child Button Rectangle (In their Windows prespective)
  50.   CRect RgnRectParent, RgnRectMini;
  51. // RgnRectParent - Used to store the Button's Client Region (In their Client prespective)
  52. // RgnRectMini - Used to store the Button's Child Client Region (In their Client prespective)
  53.   CRgn m_hRgnParent, m_hRgnMini[256];
  54. // m_hRgnParent - Used to store the new CRgn of the Button.
  55. // m_hRgnMini - Used to store the sub Region of the Button (Caused by the childs)
  56.   int i = 0;
  57. // i - An incremental counter for storing up to 256 Overlapping Buttons.
  58.   
  59.   GetClientRect(&RgnRectParent);
  60.   RgnRectParent.InflateRect(6,6);
  61. // This is needed in order for the Button's Rectangle to include its shadows too.
  62.   m_hRgnParent.CreateRectRgn(RgnRectParent.left, RgnRectParent.top, 
  63.     RgnRectParent.right, RgnRectParent.bottom);
  64.   
  65.   GetWindowRect(&RectParent);
  66.   
  67.   CWnd *pWnd = GetParent()->GetWindow(GW_CHILD);
  68.   
  69.   while (pWnd != NULL)
  70.   {
  71.     pWnd->GetWindowRect(&RectInner);
  72.     if ( (RectParent.PtInRect( RectInner.CenterPoint() )) && (pWnd != this) && (pWnd->IsWindowVisible()))
  73. // If the button's center is inside the Button, than it must be an overlapping button,
  74. // A better could be used, (You can use also UnionRect for this test, but I prefer PtInRect())
  75.     {
  76.       pWnd->GetClientRect(&RgnRectMini);
  77. //      MiniRgnRect.OffsetRect(3,3);
  78. // If the buttons (the parent buttons, not the overlapping ones) include a 
  79. // "larger frame" for example their style was set to Modal Frame you need 
  80. // to offset the childs location acordingly... is there a more generalized way? 
  81. // maybe... let me know if it is possible.
  82.       
  83.       pWnd->ClientToScreen(&RgnRectMini);
  84.       ScreenToClient(&RgnRectMini);
  85.       
  86.       m_hRgnMini[i].CreateRectRgn(RgnRectMini.left, RgnRectMini.top, 
  87.         RgnRectMini.right, RgnRectMini.bottom);
  88.       m_hRgnParent.CombineRgn(&m_hRgnParent, &m_hRgnMini[i++], RGN_DIFF);
  89. // Combine the RGN of the parent button with its overlapping "childern".
  90.     }
  91.     pWnd = pWnd->GetNextWindow(GW_HWNDNEXT);
  92.   }
  93.   
  94.   CRgn compareRgn;
  95.   compareRgn.CreateRectRgn(0,0,0,0);
  96. // Create a dummy CRgn so using GetWindowRgn() won't fail.
  97.   if (IsWindowVisible())
  98. // Is this button Visible? if not, why bother with changing its Region?
  99.   {
  100.     GetWindowRgn(compareRgn);
  101.     if (compareRgn.m_hObject != NULL)
  102.     {
  103.       if (!compareRgn.EqualRgn(&m_hRgnParent))
  104. // If the new Region does not equal the current Region, set the Current Region to
  105. // the new one.
  106.         SetWindowRgn(m_hRgnParent, TRUE);
  107.     }
  108.     else
  109. // If there is no Rgn present, set the Current Region to the new one.
  110.       SetWindowRgn(m_hRgnParent, TRUE);
  111.   }
  112. }
  113. void CRgnButton::PreSubclassWindow() 
  114. {
  115.   ModifyStyle(0,WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
  116. // Prevent this button from drawing on all the button area. (Both are not need in all
  117. // cases, but in a very specail case so both were added.
  118.   
  119. CButton::PreSubclassWindow();
  120. }