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++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// 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;
}