You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

279 lines
6.7 KiB
C++

1 month ago
// QTracker.cpp
//
//===============================
// Version 1.0, August 20, 2003
// (c) Sjaak Priester, Amsterdam
// www.sjaakpriester.nl
#include "StdAfx.h"
#include ".\QTracker.h"
#include "QBufferDC.h"
#include "afxpriv.h"
//#include "DrawMainFrame.h"
using namespace NItem;
QTracker::QTracker()
: m_pWnd(NULL)
, m_Point(0)
, m_StartPoint(0)
, m_bTracking(false)
, m_bEnableRotate(true)
{
m_nAllowMovePixel=3;
m_bCanMoved=false;
m_bRotateState=false;
}
QTracker::QTracker(CWnd * pWnd)
: m_pWnd(pWnd)
, m_Point(0)
, m_StartPoint(0)
, m_bTracking(false)
, m_bEnableRotate(true)
{
m_nAllowMovePixel=5;
m_bCanMoved=false;
m_bRotateState=false;
ASSERT_VALID(pWnd);
}
QTracker::~QTracker(void)
{
}
void QTracker::SetParent(CWnd* pWnd)
{
m_pWnd=pWnd;
}
// Track mouse, starting at positiom point.
int QTracker::Track(CDC * pDC, UINT nFlags, CPoint point, bool bClipCursor /*= false*/)
{
// Give derived class the opportunity to process starting message
int r = TrackContinue;// OnBeginTrack(nFlags, point);
//if (r != TrackContinue) return r; // cancel or success, even before tracking starts...
//m_bCanMoved=false;
bool m_bDirty=false;
//m_Point = point;
//m_PreviousPoint = m_Point;
//m_StartPoint = m_Point;
//nFlags &= UpdateMouseFlags; // to be sure
//m_bTracking = true;
// Undocumented; don't know what this does, but MFC's CRectTracker calls it too.
//::AfxLockTempMaps();
int oldROP2(R2_COPYPEN);
COLORREF oldBkColor(RGB(0, 0, 0));
if (pDC)
{
// Prepare the dc for NOT-XOR drawing on white.
oldROP2 = pDC->SetROP2(R2_NOTXORPEN);
oldBkColor = pDC->SetBkColor(RGB(255, 255, 255));
}
if (m_nSteps == 0)
{
TRACE(_T("QTracker::Track::m_nSteps:%d\n"), m_nSteps);
// Let user draw first track object
OnUpdate(pDC, nFlags | UpdateDraw | UpdateFirst);
m_nSteps++;
}
//if (bClipCursor)
//{
// CRect rcClient;
// m_pWnd->GetClientRect(rcClient);
// m_pWnd->ClientToScreen(rcClient);
// VERIFY(::ClipCursor(rcClient));
//}
//m_pWnd->SetCapture();
//ASSERT(CWnd::GetCapture() == m_pWnd);
ASSERT(r == TrackContinue);
//Draw(pDC);//ȥ<><C8A5>HANDLE<4C><45>
//while (r == TrackContinue)
if(r == TrackContinue)
{
//MSG msg;
//int cnt = 0;
//while (! ::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
//{
// // Give the statusbar the opportunity to update itself
// // by sending a private MFC message (see <afxpriv.h>).
// if (cnt == 0)
// {
// //CDrawMainFrame *pMainFrame = ::GetDrawMainFrame(m_pWnd);
// //pMainFrame->SendMessageToDescendants(WM_IDLEUPDATECMDUI, TRUE);
// }
// cnt++;
//}
//if (CWnd::GetCapture() != m_pWnd || msg.message == WM_CANCELMODE)
// r = TrackFailed;
//else if (msg.message >= WM_MOUSEFIRST && msg.message <= WM_MOUSELAST)
//{
// We use our own class QBufferDC for double buffered drawing.
// We accumulate the removing of the old tracking rectangle
// and the drawing of the new one, and update the screen with
// the result. Thus, screen flicker is avoided.
QBufferDC * pXDC = NULL;
if (pDC)
{
pXDC = new QBufferDC(pDC, NOTSRCINVERT);
// Prepare for NOT-XOR drawing (background color is white by default).
pXDC->SetROP2(R2_NOTXORPEN);
}
// Remove old display feedback
//OnUpdate(pXDC, nFlags | UpdateRemove | UpdateEnter);
// These casts ensure that sign is preserved
//int x = (int)(short) LOWORD(msg.lParam);
//int y = (int)(short) HIWORD(msg.lParam);
//// Convert to logical coordinates
//CPoint pnt(x, y);
//if (pDC) pDC->DPtoLP(& pnt);
if (m_Point != m_PreviousPoint) m_bDirty = true;
m_PreviousPoint = m_Point;
//m_Point = pnt;
//if (pnt != m_PreviousPoint) m_bDirty = true;
//nFlags = (UINT) msg.wParam & UpdateMouseFlags;
// Let user change state
//r = OnMouseMessage(msg.message, nFlags, pnt);
// QTracker's state is updated, now draw new track objects.
OnUpdate(pXDC, nFlags | UpdateDraw | UpdateLeave);
// QBufferDC's destructor will update the screen.
if (pDC) delete pXDC;
//}
//else if (msg.message >= WM_KEYFIRST && msg.message <= WM_KEYLAST)
// r = OnKeyMessage(msg.message, (UINT) msg.wParam, (UINT) LOWORD(msg.lParam), (UINT) HIWORD(msg.lParam));
//else
// r = OnMessage(msg);
}
//VERIFY(::ReleaseCapture());
if (bClipCursor) VERIFY(::ClipCursor(NULL));
//::AfxUnlockTempMaps();
//m_bTracking = false;
// Let user clean up
//OnUpdate(pDC, nFlags | UpdateRemove | UpdateLast);
if (r > 0 && !m_bDirty)
{
r = TrackNoMove;
if(!m_bCanMoved)
{
bool bAlt=::IsKeyDown(VK_MENU);
bool bShift=::IsKeyDown(VK_SHIFT);
bool bCtrl=::IsKeyDown(VK_CONTROL);
if(!bShift && !bCtrl && !bAlt)
SetRotateState(!IsRotateState());
}
}
//Draw(pDC);
//r = OnEndTrack(r);
if (pDC)
{
// Clean up pDC
pDC->SetROP2(oldROP2);
pDC->SetBkColor(oldBkColor);
}
return r;
}
void QTracker::Draw(CDC * pDC)
{
}
int QTracker::OnBeginTrack(UINT /*nFlags*/, CPoint /*point*/)
{
return TrackContinue;
}
int QTracker::OnEndTrack(int trackResult)
{
return trackResult;
}
// Update the state of QTracker; should be overridden.
int QTracker::OnMouseMessage(UINT msg, UINT nFlags, CPoint /*point*/)
{
// Default just checks for end of tracking operation.
// return TrackSucceeded if msg == WM_LBUTTONUP,
// return TrackCopy if msg == WM_LBUTTONUP and Ctrl pressed,
// cancel tracking if msg == WM_RBUTTONDOWN,
// otherwise, continue tracking.
if (msg == WM_LBUTTONUP) return (nFlags & MK_CONTROL) ? TrackCopy : TrackSucceeded;
if (msg == WM_RBUTTONDOWN) return TrackCancelled;
return TrackContinue;
}
// Called after pressing or releasing a key during track. May be overridden.
int QTracker::OnKeyMessage(UINT msg, UINT nChar, UINT /*nRepCnt*/, UINT /*nFlags*/)
{
// Default: cancel tracking if escape key pressed.
if (msg == WM_KEYDOWN && nChar == VK_ESCAPE) return TrackCancelled;
return TrackContinue;
}
// Called for any other message during track. May be overridden.
int QTracker::OnMessage(MSG& msg)
{
::DispatchMessage(& msg);
return TrackContinue;
}
// Called during tracking when screen should be updated. Should be overridden.
void QTracker::OnUpdate(CDC * pDC, UINT /*nMode*/)
{
// Default draws line in debug build, does nothing in release build.
//#ifdef _DEBUG
if (pDC)
{
pDC->MoveTo(m_StartPoint);
pDC->LineTo(m_Point);
}
//#endif
}
bool QTracker::IsCanMove(const CPoint& nPrevPoint, const CPoint& nCurPoint)
{
if(m_bCanMoved)
return true;
CSize sz=nCurPoint-nPrevPoint;
//Ϊ<>˷<EFBFBD>ֹ<EFBFBD><D6B9>С<EFBFBD><D0A1><EFBFBD>ƶ<EFBFBD>Ԫ<EFBFBD>أ<EFBFBD><D8A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵʱ<D6B5><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD>ظ<EFBFBD><D8B8><EFBFBD><EFBFBD><EFBFBD>
if(abs(sz.cx)>=m_nAllowMovePixel || abs(sz.cy)>=m_nAllowMovePixel)
{
m_bCanMoved=true;
return true;
}
return false;
}
bool QTracker::IsRotateState(void)
{
return m_bRotateState;
}
void QTracker::SetRotateState(bool bRotate)
{
m_bRotateState=bRotate;
}