Browse Source

- handle nc button up when mouse isn't over window
- size content to size of window better (less cpu for large texts)

ScottBrogden 8 years ago
parent
commit
98dd761629
10 changed files with 274 additions and 132 deletions
  1. 112 2
      DittoWindow.cpp
  2. 5 1
      DittoWindow.h
  3. 36 1
      EditFrameWnd.cpp
  4. 2 0
      EditFrameWnd.h
  5. 35 1
      QRCodeViewer.cpp
  6. 2 0
      QRCodeViewer.h
  7. 67 26
      ToolTipEx.cpp
  8. 1 0
      ToolTipEx.h
  9. 14 98
      WndEx.cpp
  10. 0 3
      WndEx.h

+ 112 - 2
DittoWindow.cpp

@@ -37,6 +37,8 @@ CDittoWindow::CDittoWindow(void)
 	m_customWindowTitle = _T("");
 	m_useCustomWindowTitle = false;
 
+	m_buttonDownOnCaption = false;
+
 	
 }
 
@@ -547,7 +549,7 @@ void CDittoWindow::DrawMinimizeBtn(CWindowDC &dc, CWnd *pWnd)
 		return;
 	}
 
-	m_minimizeButton.Draw(&dc, pWnd, m_crMinimizeBT, m_bMouseOverClose, m_bMouseDownOnClose);
+	m_minimizeButton.Draw(&dc, pWnd, m_crMinimizeBT, m_bMouseOverMinimize, m_bMouseDownOnMinimize);
 }
 
 void CDittoWindow::DrawMaximizeBtn(CWindowDC &dc, CWnd *pWnd)
@@ -560,8 +562,18 @@ void CDittoWindow::DrawMaximizeBtn(CWindowDC &dc, CWnd *pWnd)
 	m_maximizeButton.Draw(&dc, pWnd, m_crMaximizeBT, m_bMouseOverMaximize, m_bMouseDownOnMaximize);
 }
 
-void CDittoWindow::DoNcLButtonDown(CWnd *pWnd, UINT nHitTest, CPoint point) 
+int CDittoWindow::DoNcLButtonDown(CWnd *pWnd, UINT nHitTest, CPoint point) 
 {
+	switch (nHitTest)
+	{
+	case HTCAPTION:
+		m_buttonDownOnCaption = true;
+		break;
+	default:
+		m_buttonDownOnCaption = false;
+	}
+
+	int buttonPressed = 0;
 	//ReleaseCapture();
 	CPoint clPoint(point);
 	pWnd->ScreenToClient(&clPoint);
@@ -577,30 +589,38 @@ void CDittoWindow::DoNcLButtonDown(CWnd *pWnd, UINT nHitTest, CPoint point)
 		//pWnd->UpdateWindow();
 		//DoNcPaint(pWnd);
 		RedrawWindow(pWnd->m_hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
+		buttonPressed = BUTTON_CLOSE;
 	}
 	else if(m_crChevronBT.PtInRect(clPoint))
 	{
 		m_bMouseDownOnChevron = true;
 		RedrawWindow(pWnd->m_hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
+		buttonPressed = BUTTON_CHEVRON;
 	}
 	else if(m_crMinimizeBT.PtInRect(clPoint))
 	{
 		m_bMouseDownOnMinimize = true;
 		RedrawWindow(pWnd->m_hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
+		buttonPressed = BUTTON_MINIMIZE;
 	}
 	else if(m_crMaximizeBT.PtInRect(clPoint))
 	{
 		m_bMouseDownOnMaximize = true;
 		RedrawWindow(pWnd->m_hWnd, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
+		buttonPressed = BUTTON_MAXIMIZE;
 	}
 	else if(m_bMinimized)
 	{
 		//MinMaxWindow(FORCE_MAX);
 	}
+
+	return buttonPressed;
 }
 
 long CDittoWindow::DoNcLButtonUp(CWnd *pWnd, UINT nHitTest, CPoint point) 
 {
+	m_buttonDownOnCaption = false;
+
 	CRect crWindow;
 	pWnd->GetWindowRect(crWindow);
 
@@ -796,4 +816,94 @@ bool CDittoWindow::SetCaptionColors(COLORREF left, COLORREF right, COLORREF bord
 void CDittoWindow::SetCaptionTextColor(COLORREF color)
 {
 	m_CaptionTextColor = color;
+}
+
+void CDittoWindow::SnapToEdge(CWnd *pWnd, WINDOWPOS* lpwndpos)
+{
+	if (lpwndpos->cx == 0 &&
+		lpwndpos->cy == 0)
+	{
+		return;
+	}
+
+	const char threshold = 12;
+	RECT rect = { 0 };
+	HMONITOR hMonitor;
+	MONITORINFO mi;
+
+	// Grab information about our monitors
+	// For multi-monitor support, we use this instead of SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0);
+	hMonitor = MonitorFromWindow(pWnd->m_hWnd, MONITOR_DEFAULTTONEAREST);
+	mi.cbSize = sizeof(mi);
+	GetMonitorInfo(hMonitor, &mi);
+	rect = mi.rcWork;
+
+	bool edgeMove = true;
+	bool captionMove = false;
+
+	if (m_buttonDownOnCaption)
+	{
+		edgeMove = false;
+		captionMove = true;
+	}
+
+	// Snap to left
+	if (lpwndpos->x >= (rect.left - threshold) &&
+		lpwndpos->x <= (rect.left + threshold))
+	{
+		if (edgeMove)
+		{
+			int diff = lpwndpos->x - rect.left;
+			lpwndpos->cx += diff;
+		}
+		if (edgeMove || captionMove)
+		{
+			lpwndpos->x = rect.left;
+		}
+	}
+
+	// Snap to right
+	if ((lpwndpos->x + lpwndpos->cx) >= (rect.right - threshold) &&
+		(lpwndpos->x + lpwndpos->cx) <= (rect.right + threshold))
+	{
+		if (edgeMove)
+		{
+			int diff = rect.right - (lpwndpos->x + lpwndpos->cx);
+			lpwndpos->cx += diff;
+		}
+		if (captionMove)
+		{
+			lpwndpos->x = (rect.right - lpwndpos->cx);
+		}
+	}
+
+	// Snap to top
+	if (lpwndpos->y >= (rect.top - threshold) &&
+		lpwndpos->y <= (rect.top + threshold))
+	{
+		if (edgeMove)
+		{
+			int diff = lpwndpos->y - rect.top;
+			lpwndpos->cy += diff;
+		}
+		if (edgeMove || captionMove)
+		{
+			lpwndpos->y = rect.top;
+		}
+	}
+
+	// Snap to bottom
+	if ((lpwndpos->y + lpwndpos->cy) >= (rect.bottom - threshold) &&
+		(lpwndpos->y + lpwndpos->cy) <= (rect.bottom + threshold))
+	{
+		if (edgeMove)
+		{
+			int diff = rect.bottom - (lpwndpos->y + lpwndpos->cy);
+			lpwndpos->cy += diff;
+		}
+		if (captionMove)
+		{
+			lpwndpos->y = (rect.bottom - lpwndpos->cy);
+		}
+	}
 }

+ 5 - 1
DittoWindow.h

@@ -27,7 +27,7 @@ public:
 	UINT DoNcHitTest(CWnd *pWnd, CPoint point);
 	void DoSetRegion(CWnd *pWnd);
 	long DoNcLButtonUp(CWnd *pWnd, UINT nHitTest, CPoint point);
-	void DoNcLButtonDown(CWnd *pWnd, UINT nHitTest, CPoint point);
+	int DoNcLButtonDown(CWnd *pWnd, UINT nHitTest, CPoint point);
 	void DoNcMouseMove(CWnd *pWnd, UINT nHitTest, CPoint point) ;
 	bool DoPreTranslateMessage(MSG* pMsg);
 	void SetCaptionOn(CWnd *pWnd, int nPos, bool bOnstartup, int captionSize, int captionFontSize);
@@ -36,6 +36,8 @@ public:
 
 	void SetTitleTextHeight(CWnd *pWnd);
 
+	void SnapToEdge(CWnd *pWnd, WINDOWPOS* lpwndpos);
+
 	long m_lTopBorder;
 	long m_lRightBorder;
 	long m_lBottomBorder;
@@ -85,4 +87,6 @@ public:
 	int m_captionBorderWidth;
 
 	int m_titleTextHeight;
+
+	bool m_buttonDownOnCaption;
 };

+ 36 - 1
EditFrameWnd.cpp

@@ -6,6 +6,7 @@
 #include "EditFrameWnd.h"
 #include ".\editframewnd.h"
 
+#define TIMER_BUTTON_UP 1
 
 // CEditFrameWnd
 
@@ -39,6 +40,8 @@ BEGIN_MESSAGE_MAP(CEditFrameWnd, CFrameWnd)
 	ON_WM_NCLBUTTONUP()
 	ON_WM_NCMOUSEMOVE()
 	ON_WM_NCLBUTTONDBLCLK()
+	ON_WM_WINDOWPOSCHANGING()
+	ON_WM_TIMER()
 END_MESSAGE_MAP()
 
 
@@ -177,7 +180,12 @@ HITTEST_RET CEditFrameWnd::OnNcHitTest(CPoint point)
 }
 void CEditFrameWnd::OnNcLButtonDown(UINT nHitTest, CPoint point)
 {
-	m_DittoWindow.DoNcLButtonDown(this, nHitTest, point);
+	int buttonPressed = m_DittoWindow.DoNcLButtonDown(this, nHitTest, point);
+
+	if (buttonPressed != 0)
+	{
+		SetTimer(TIMER_BUTTON_UP, 100, NULL);
+	}
 
 	CFrameWnd::OnNcLButtonDown(nHitTest, point);
 }
@@ -187,6 +195,8 @@ void CEditFrameWnd::OnNcLButtonUp(UINT nHitTest, CPoint point)
 	if(m_DittoWindow.DoNcLButtonUp(this, nHitTest, point) > 0)
 		return;
 
+	KillTimer(TIMER_BUTTON_UP);
+
 	CFrameWnd::OnNcLButtonUp(nHitTest, point);
 }
 
@@ -221,3 +231,28 @@ void CEditFrameWnd::OnNcLButtonDblClk(UINT nHitTest, CPoint point)
 
 	CFrameWnd::OnNcLButtonDblClk(nHitTest, point);
 }
+
+void CEditFrameWnd::OnWindowPosChanging(WINDOWPOS* lpwndpos)
+{
+	CFrameWnd::OnWindowPosChanging(lpwndpos);
+
+	m_DittoWindow.SnapToEdge(this, lpwndpos);
+}
+
+void CEditFrameWnd::OnTimer(UINT_PTR nIDEvent)
+{
+	switch (nIDEvent)
+	{
+		case TIMER_BUTTON_UP:
+		{
+			if ((GetKeyState(VK_LBUTTON) & 0x100) == 0)
+			{
+				m_DittoWindow.DoNcLButtonUp(this, 0, CPoint(0, 0));
+				KillTimer(TIMER_BUTTON_UP);
+			}
+			break;
+		}
+	}
+
+	CWnd::OnTimer(nIDEvent);
+}

+ 2 - 0
EditFrameWnd.h

@@ -45,6 +45,8 @@ public:
 	afx_msg void OnNcMouseMove(UINT nHitTest, CPoint point);
 	virtual BOOL PreTranslateMessage(MSG* pMsg);
 	afx_msg void OnNcLButtonDblClk(UINT nHitTest, CPoint point);
+	afx_msg void OnWindowPosChanging(WINDOWPOS* lpwndpos);
+	afx_msg void OnTimer(UINT_PTR nIDEvent);
 };
 
 

+ 35 - 1
QRCodeViewer.cpp

@@ -6,6 +6,7 @@
 #include "QRCodeViewer.h"
 #include "MainTableFunctions.h"
 
+#define TIMER_BUTTON_UP 1
 
 // QRCodeViewer
 
@@ -37,6 +38,8 @@ BEGIN_MESSAGE_MAP(QRCodeViewer, CWnd)
 	ON_WM_NCLBUTTONUP()
 	ON_WM_ERASEBKGND()
 	ON_WM_CTLCOLOR()
+	ON_WM_WINDOWPOSCHANGING()
+	ON_WM_TIMER()
 END_MESSAGE_MAP()
 
 
@@ -201,7 +204,12 @@ BOOL QRCodeViewer::OnEraseBkgnd(CDC* pDC)
 
 void QRCodeViewer::OnNcLButtonDown(UINT nHitTest, CPoint point) 
 {
-	m_DittoWindow.DoNcLButtonDown(this, nHitTest, point);
+	int buttonPressed = m_DittoWindow.DoNcLButtonDown(this, nHitTest, point);
+
+	if (buttonPressed != 0)
+	{
+		SetTimer(TIMER_BUTTON_UP, 100, NULL);
+	}
 
 	CWnd::OnNcLButtonDown(nHitTest, point);
 }
@@ -217,6 +225,8 @@ void QRCodeViewer::OnNcLButtonUp(UINT nHitTest, CPoint point)
 		break;
 	}
 
+	KillTimer(TIMER_BUTTON_UP);
+
 	CWnd::OnNcLButtonUp(nHitTest, point);
 }
 
@@ -239,4 +249,28 @@ HBRUSH QRCodeViewer::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
 
 	// TODO:  Return a different brush if the default is not desired
 	return hbr;
+}
+void QRCodeViewer::OnWindowPosChanging(WINDOWPOS* lpwndpos)
+{
+	CWnd::OnWindowPosChanging(lpwndpos);
+
+	m_DittoWindow.SnapToEdge(this, lpwndpos);
+}
+
+void QRCodeViewer::OnTimer(UINT_PTR nIDEvent)
+{
+	switch (nIDEvent)
+	{
+		case TIMER_BUTTON_UP:
+		{
+			if ((GetKeyState(VK_LBUTTON) & 0x100) == 0)
+			{
+				m_DittoWindow.DoNcLButtonUp(this, 0, CPoint(0, 0));
+				KillTimer(TIMER_BUTTON_UP);
+			}
+			break;
+		}
+	}
+
+	CWnd::OnTimer(nIDEvent);
 }

+ 2 - 0
QRCodeViewer.h

@@ -32,6 +32,8 @@ protected:
 	afx_msg BOOL OnEraseBkgnd(CDC* pDC);
 	afx_msg void OnSize(UINT nType, int cx, int cy);
 	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+	afx_msg void OnWindowPosChanging(WINDOWPOS* lpwndpos);
+	afx_msg void OnTimer(UINT_PTR nIDEvent);
 
 	unsigned char* m_bitmapData;
 	int m_imageSize;

+ 67 - 26
ToolTipEx.cpp

@@ -20,6 +20,7 @@ m_imageViewer.m_pBitmap = NULL;		\
 
 #define HIDE_WINDOW_TIMER 1
 #define SAVE_SIZE 2
+#define TIMER_BUTTON_UP 3
 
 /////////////////////////////////////////////////////////////////////////////
 // CToolTipEx
@@ -62,6 +63,7 @@ ON_WM_SETFOCUS()
 
 ON_COMMAND(ID_FIRST_HIDEDESCRIPTIONWINDOWONM, &CToolTipEx::OnFirstHidedescriptionwindowonm)
 ON_COMMAND(ID_FIRST_WRAPTEXT, &CToolTipEx::OnFirstWraptext)
+ON_WM_WINDOWPOSCHANGING()
 END_MESSAGE_MAP()
 
 
@@ -401,45 +403,54 @@ BOOL CToolTipEx::OnMsg(MSG *pMsg)
 
 CRect CToolTipEx::GetBoundsRect()
 {
-    CWindowDC dc(NULL);
+	DWORD d = GetTickCount();
 
-    CFont *pOldFont = (CFont*)dc.SelectObject((CFont*) &m_Font);
+    CWindowDC dc(NULL);
+	int nLineWidth = 0;
 
-    int nLineWidth = 0;
+	CRect rect(0, 0, 0, 0);
 
     if(nLineWidth == 0)
     {
         // Count the number of lines of text
-        int nStart = 0, nNumLines = 0;
-        CString strTextCopy = m_csText;
+		int nStart = 0;
+		INT nNumLines = 0;
+		int longestLength = 0;
+		CString longestString;
         do
         {
-            nStart = strTextCopy.Find(_T("\n"));
-
-            // skip found character 
-            if(nStart >= 0)
-            {
-                strTextCopy = strTextCopy.Mid(nStart + 1);
-            }
+            int newStart = m_csText.Find(_T("\n"), nStart);
+			if (newStart < 0)
+			{
+				int length = m_csText.GetLength() - nStart;
+				if (length > longestLength)
+				{
+					longestString = m_csText.Mid(nStart, length);
+					longestLength = length;
+				}
 
-            nNumLines++;
-        }
+				break;
+			}
 
-        while(nStart >= 0);
+			int length = newStart - nStart;
+			if(length > longestLength)
+			{
+				longestString = m_csText.Mid(nStart, length);
+				longestLength = length;
+			}           
 
-        // Find the widest line
-        for(int i = 0; i < nNumLines; i++)
-        {
-            CString strLine = GetFieldFromString(m_csText, i, _T('\n')) + _T(
-                "  ");
-            nLineWidth = max(nLineWidth, dc.GetTextExtent(strLine).cx);
+            nNumLines++;
+			nStart = newStart + 1;
         }
-    }
+        while(nStart >= 0 && nNumLines < 100);
 
-    CRect rect(0, 0, max(0, nLineWidth), 0);
-    dc.DrawText(m_csText, rect, DT_CALCRECT | m_dwTextStyle);
+		CFont *pOldFont = (CFont*)dc.SelectObject((CFont*)&m_Font);
+		CSize size = dc.GetTextExtent(longestString);  
+		dc.SelectObject(pOldFont);
 
-    dc.SelectObject(pOldFont);
+		rect.right = size.cx;
+		rect.bottom = size.cy * nNumLines;
+    }    
 
     rect.bottom += m_rectMargin.top + m_rectMargin.bottom;
     rect.right += m_rectMargin.left + m_rectMargin.right + 2;
@@ -456,6 +467,12 @@ CRect CToolTipEx::GetBoundsRect()
         }
     }
 
+	DWORD diff = GetTickCount() - d;
+	if (diff > 10)
+	{
+		Log(StrF(_T("Size To Content: %d\n"), diff));
+	}
+
     return rect;
 }
 
@@ -736,6 +753,16 @@ void CToolTipEx::OnTimer(UINT_PTR nIDEvent)
 			SaveWindowSize();
 			KillTimer(SAVE_SIZE);
 			break;
+		case TIMER_BUTTON_UP:
+		{
+			if ((GetKeyState(VK_LBUTTON) & 0x100) == 0)
+			{
+				m_DittoWindow.DoNcLButtonUp(this, 0, CPoint(0, 0));
+				KillTimer(TIMER_BUTTON_UP);
+			}
+			break;
+		}
+
     }
 
     CWnd::OnTimer(nIDEvent);
@@ -765,7 +792,12 @@ HITTEST_RET CToolTipEx::OnNcHitTest(CPoint point)
 
 void CToolTipEx::OnNcLButtonDown(UINT nHitTest, CPoint point) 
 {
-	m_DittoWindow.DoNcLButtonDown(this, nHitTest, point);
+	int buttonPressed = m_DittoWindow.DoNcLButtonDown(this, nHitTest, point);
+
+	if (buttonPressed != 0)
+	{
+		SetTimer(TIMER_BUTTON_UP, 100, NULL);
+	}
 
 	CWnd::OnNcLButtonDown(nHitTest, point);
 }
@@ -781,6 +813,8 @@ void CToolTipEx::OnNcLButtonUp(UINT nHitTest, CPoint point)
 		break;
 	}
 
+	KillTimer(TIMER_BUTTON_UP);
+
 	CWnd::OnNcLButtonUp(nHitTest, point);
 }
 
@@ -910,4 +944,11 @@ void CToolTipEx::ApplyWordWrap()
 void CToolTipEx::HideWindowInXMilliSeconds(long lms) 
 { 
 	SetTimer(HIDE_WINDOW_TIMER, lms, NULL); 
+}
+
+void CToolTipEx::OnWindowPosChanging(WINDOWPOS* lpwndpos)
+{
+	CWnd::OnWindowPosChanging(lpwndpos);
+
+	m_DittoWindow.SnapToEdge(this, lpwndpos);
 }

+ 1 - 0
ToolTipEx.h

@@ -97,6 +97,7 @@ protected:
 	afx_msg void OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp); 
 	afx_msg void OnNcPaint();
 	afx_msg void OnOptions();
+	afx_msg void OnWindowPosChanging(WINDOWPOS* lpwndpos);
 	//}}AFX_MSG
 	DECLARE_MESSAGE_MAP()
 public:

+ 14 - 98
WndEx.cpp

@@ -19,13 +19,13 @@ static char THIS_FILE[] = __FILE__;
 #define CLOSE_HEIGHT		11
 #define CLOSE_BORDER		2
 #define TIMER_AUTO_MAX		5
+#define TIMER_BUTTON_UP		6
 
 CWndEx::CWndEx()
 {	
 	SetCaptionColorActive(false, TRUE);
 	m_crFullSizeWindow.SetRectEmpty();
 	m_lDelayMaxSeconds = 2;
-	m_lButtonDownOnCaption = false;
 }
 
 CWndEx::~CWndEx()
@@ -166,15 +166,11 @@ HITTEST_RET CWndEx::OnNcHitTest(CPoint point)
 
 void CWndEx::OnNcLButtonDown(UINT nHitTest, CPoint point) 
 {
-	m_DittoWindow.DoNcLButtonDown(this, nHitTest, point);
-
-	switch (nHitTest)
+	int buttonPressed = m_DittoWindow.DoNcLButtonDown(this, nHitTest, point);
+	
+	if (buttonPressed != 0)
 	{
-	case HTCAPTION:
-		m_lButtonDownOnCaption = true;
-		break;
-	default:
-		m_lButtonDownOnCaption = false;
+		SetTimer(TIMER_BUTTON_UP, 100, NULL);
 	}
 
 	CWnd::OnNcLButtonDown(nHitTest, point);
@@ -191,6 +187,8 @@ void CWndEx::OnNcLButtonUp(UINT nHitTest, CPoint point)
 		}
 		return;
 	}
+
+	KillTimer(TIMER_BUTTON_UP);
 	
 	CWnd::OnNcLButtonUp(nHitTest, point);
 }
@@ -369,98 +367,16 @@ void CWndEx::OnTimer(UINT_PTR nIDEvent)
 		KillTimer(TIMER_AUTO_MAX);
 		m_bMaxSetTimer = false;
 	}
-	
-	CWnd::OnTimer(nIDEvent);
-}
-
-void CWndEx::SnapToEdge(WINDOWPOS* lpwndpos)
-{
-	if (lpwndpos->cx == 0 &&
-		lpwndpos->cy == 0)
-	{
-		return;
-	}
-
-	const char threshold = 12;
-	RECT rect = { 0 };
-	HMONITOR hMonitor;
-	MONITORINFO mi;
-	
-	// Grab information about our monitors
-	// For multi-monitor support, we use this instead of SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0);
-	hMonitor = MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST);
-	mi.cbSize = sizeof(mi);
-	GetMonitorInfo(hMonitor, &mi);
-	rect = mi.rcWork;
-
-	bool edgeMove = true;
-	bool captionMove = false;
-
-	if (m_lButtonDownOnCaption)
+	else if (nIDEvent == TIMER_BUTTON_UP)
 	{
-		edgeMove = false;
-		captionMove = true;
-	}
-
-	// Snap to left
-	if (lpwndpos->x >= (rect.left - threshold) &&
-		lpwndpos->x <= (rect.left + threshold))
-	{
-		if (edgeMove)
-		{
-			int diff = lpwndpos->x - rect.left;
-			lpwndpos->cx += diff;
-		}
-		if (edgeMove || captionMove)
+		if ((GetKeyState(VK_LBUTTON) & 0x100) == 0)
 		{
-			lpwndpos->x = rect.left;
-		}
-	}
-
-	// Snap to right
-	if ((lpwndpos->x + lpwndpos->cx) >= (rect.right - threshold) &&
-		(lpwndpos->x + lpwndpos->cx) <= (rect.right + threshold))
-	{
-		if (edgeMove)
-		{
-			int diff = rect.right - (lpwndpos->x + lpwndpos->cx);
-			lpwndpos->cx += diff;
-		}
-		if (captionMove)
-		{
-			lpwndpos->x = (rect.right - lpwndpos->cx);
-		}
-	}
-
-	// Snap to top
-	if (lpwndpos->y >= (rect.top - threshold) &&
-		lpwndpos->y <= (rect.top + threshold))
-	{
-		if (edgeMove)
-		{
-			int diff = lpwndpos->y - rect.top;
-			lpwndpos->cy += diff;
-		}
-		if (edgeMove || captionMove)
-		{
-			lpwndpos->y = rect.top;
-		}
-	}
-
-	// Snap to bottom
-	if ((lpwndpos->y + lpwndpos->cy) >= (rect.bottom - threshold) &&
-		(lpwndpos->y + lpwndpos->cy) <= (rect.bottom + threshold))
-	{
-		if (edgeMove)
-		{
-			int diff = rect.bottom - (lpwndpos->y + lpwndpos->cy);
-			lpwndpos->cy += diff;
-		}
-		if (captionMove)
-		{
-			lpwndpos->y = (rect.bottom - lpwndpos->cy);
+			m_DittoWindow.DoNcLButtonUp(this, 0, CPoint(0, 0));
+			KillTimer(TIMER_BUTTON_UP);
 		}
 	}
+	
+	CWnd::OnTimer(nIDEvent);
 }
 
 void CWndEx::OnWindowPosChanging(WINDOWPOS* lpwndpos)
@@ -473,7 +389,7 @@ void CWndEx::OnWindowPosChanging(WINDOWPOS* lpwndpos)
 		m_bMaxSetTimer = false;
 	}
 
-	SnapToEdge(lpwndpos);
+	m_DittoWindow.SnapToEdge(this, lpwndpos);
 }
 
 void CWndEx::OnSize(UINT nType, int cx, int cy)

+ 0 - 3
WndEx.h

@@ -57,9 +57,6 @@ protected:
 	COleDateTime m_TimeMaximized;
 	int m_lDelayMaxSeconds;
 	CToolTipCtrl m_toolTip;
-	bool m_lButtonDownOnCaption;
-
-	void SnapToEdge(WINDOWPOS* lpwndpos);
 
 // Implementation
 public: