MagneticWnd.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #include "stdafx.h"
  2. #include ".\magneticwnd.h"
  3. bool bDoChange = true;
  4. CMagneticWnd::CMagneticWnd()
  5. {
  6. m_bMovedAttachedWnd = false;
  7. m_crLastMove.SetRectEmpty();
  8. m_bHandleWindowPosChanging = true;
  9. }
  10. CMagneticWnd::~CMagneticWnd()
  11. {
  12. }
  13. BEGIN_MESSAGE_MAP(CMagneticWnd, CWnd)
  14. ON_WM_MOVE()
  15. ON_WM_WINDOWPOSCHANGING()
  16. END_MESSAGE_MAP()
  17. void CMagneticWnd::OnMove(int x, int y)
  18. {
  19. CWnd::OnMove(x, y);
  20. if(m_bMovedAttachedWnd)
  21. {
  22. CRect crThis;
  23. CRect crAttached;
  24. long lDiff = 0;
  25. GetWindowRect(crThis);
  26. for(std::vector<CMagneticWnd*>::iterator Iter = m_AttachedWnd.begin(); Iter != m_AttachedWnd.end(); Iter++)
  27. {
  28. CMagneticWnd *pAttachedWnd = *Iter;
  29. if(pAttachedWnd)
  30. {
  31. if(m_crLastMove.IsRectEmpty() == FALSE)
  32. {
  33. pAttachedWnd->GetWindowRect(crAttached);
  34. long lXDiff = crThis.left - m_crLastMove.left;
  35. long lYDiff = crThis.bottom - m_crLastMove.bottom;
  36. crAttached.left += lXDiff;
  37. crAttached.right += lXDiff;
  38. crAttached.top += lYDiff;
  39. crAttached.bottom += lYDiff;
  40. pAttachedWnd->MoveMagneticWWnd(crAttached);
  41. }
  42. }
  43. }
  44. m_crLastMove = crThis;
  45. }
  46. }
  47. void CMagneticWnd::MoveMagneticWWnd(LPCRECT lpRect, BOOL bRepaint)
  48. {
  49. m_bHandleWindowPosChanging = false;
  50. MoveWindow(lpRect, bRepaint);
  51. m_bHandleWindowPosChanging = true;
  52. }
  53. void CMagneticWnd::OnWindowPosChanging(WINDOWPOS* lpwndpos)
  54. {
  55. CWnd::OnWindowPosChanging(lpwndpos);
  56. if(m_bHandleWindowPosChanging == false)
  57. return;
  58. for(std::vector<CMagneticWnd*>::iterator Iter = m_SnapToWnds.begin(); Iter != m_SnapToWnds.end(); Iter++)
  59. {
  60. CMagneticWnd *pOtherWnd = *Iter;
  61. if(pOtherWnd != NULL &&
  62. this->IsWindowVisible() &&
  63. pOtherWnd->IsWindowVisible() &&
  64. lpwndpos->x != 0 && lpwndpos->y != 0 && lpwndpos->cx != 0 && lpwndpos->cy != 0)
  65. {
  66. if(m_bMovedAttachedWnd && (IsWindowAttached(pOtherWnd)))
  67. continue;
  68. CRect rectParent;
  69. pOtherWnd->GetWindowRect(rectParent);
  70. bool bAttached = false;
  71. // Snap left edge
  72. if(abs(lpwndpos->x - rectParent.right) <= 15)
  73. {
  74. lpwndpos->x = rectParent.right;
  75. bAttached = true;
  76. }
  77. // Snap right edge
  78. if (abs(lpwndpos->x + lpwndpos->cx - rectParent.left) <= 15)
  79. {
  80. lpwndpos->x = rectParent.left - lpwndpos->cx;
  81. bAttached = true;
  82. }
  83. // Snap to the bottom
  84. if (abs(lpwndpos->y + lpwndpos->cy - rectParent.top) <= 15)
  85. {
  86. lpwndpos->y = rectParent.top - lpwndpos->cy;
  87. bAttached = true;
  88. }
  89. // Snap the top
  90. if (abs(lpwndpos->y - rectParent.bottom) <= 15)
  91. {
  92. lpwndpos->y = rectParent.bottom;
  93. bAttached = true;
  94. }
  95. pOtherWnd->SetWindowAttached(this, bAttached);
  96. SetWindowAttached(pOtherWnd, bAttached);
  97. if(m_bMovedAttachedWnd)
  98. {
  99. m_crLastMove.left = lpwndpos->x;
  100. m_crLastMove.top = lpwndpos->y;
  101. m_crLastMove.right = lpwndpos->x + lpwndpos->cx;
  102. m_crLastMove.bottom = lpwndpos->y + lpwndpos->cy;
  103. }
  104. }
  105. }
  106. }
  107. void CMagneticWnd::SetWindowAttached(CMagneticWnd *pOtherWnd, bool bAttach)
  108. {
  109. bool bFound = false;
  110. for(std::vector<CMagneticWnd*>::iterator Iter = m_AttachedWnd.begin(); Iter != m_AttachedWnd.end(); Iter++)
  111. {
  112. CMagneticWnd *pAttachedWnd = *Iter;
  113. if(pAttachedWnd == pOtherWnd)
  114. {
  115. bFound = true;
  116. if(bAttach == false)
  117. {
  118. m_AttachedWnd.erase(Iter);
  119. }
  120. break;
  121. }
  122. }
  123. if(bAttach && bFound == false)
  124. {
  125. m_AttachedWnd.push_back(pOtherWnd);
  126. }
  127. }
  128. bool CMagneticWnd::IsWindowAttached(CMagneticWnd *pWnd)
  129. {
  130. for(std::vector<CMagneticWnd*>::iterator Iter = m_AttachedWnd.begin(); Iter != m_AttachedWnd.end(); Iter++)
  131. {
  132. CMagneticWnd *pAttachedWnd = *Iter;
  133. if(pAttachedWnd == pWnd)
  134. {
  135. return true;
  136. }
  137. }
  138. return false;
  139. }