Скачиваний:
11
Добавлен:
01.05.2014
Размер:
22.58 Кб
Скачать
// SketcherView.cpp : implementation of the CSketcherView class
//

#include "stdafx.h"
#include "Sketcher.h"


#include "ChildFrm.h"
#include "ScaleDialog.h"
#include "Elements.h"
#include "Line.h"
#include "Triangle.h"
#include "TextInTriangle.h"
#include "Text.h"
#include "SketcherDoc.h"
#include "SketcherView.h"
//#include "CMemDC.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CSketcherView

IMPLEMENT_DYNCREATE(CSketcherView, CScrollView)

BEGIN_MESSAGE_MAP(CSketcherView, CScrollView)
	//{{AFX_MSG_MAP(CSketcherView)
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_RBUTTONDOWN()
	ON_WM_RBUTTONUP()
	ON_COMMAND(ID_MOVE, OnMove)
	ON_COMMAND(ID_SENDTOBACK, OnSendtoback)
	ON_COMMAND(ID_DELETE, OnDelete)
	ON_COMMAND(ID_VIEW_SCALE, OnViewScale)
	ON_COMMAND(ID_SET_COLOR_BLACK, OnSetColorBlack)
	ON_COMMAND(ID_SET_COLOR_BLUE, OnSetColorBlue)
	ON_COMMAND(ID_SET_COLOR_GREEN, OnSetColorGreen)
	ON_COMMAND(ID_FIND, OnFind)
	ON_COMMAND(ID_FREE_VIEW, OnFreeView)
	ON_WM_KEYDOWN()
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSketcherView construction/destruction

CSketcherView::CSketcherView()
{
    m_FirstPoint = CPoint(0,0);         // Set 1st recorded point to 0,0
    m_SecondPoint = CPoint(0,0);        // Set 2nd recorded point to 0,0
	m_ThirdPoint = CPoint(0,0);         // Set 2nd recorded point to 0,0
    m_pTempElement = 0;                 // Set temporary element pointer to 0
    m_pSelected = 0;                    // No element selected initially
	m_kSelected = "";                   // And no key
    m_MoveMode = FALSE;                 // Set move mode off
    m_CursorPos = CPoint(0,0);          // Initialize as zero
    m_FirstPos = CPoint(0,0);           // Initialize as zero
    m_Scale = 1;                        // Set scale to 1:1
    SetScrollSizes(MM_TEXT, CSize(0,0));// Set arbitrary scrollers
    m_triangleState = 0;                
    m_text = "";
	m_counter = 0;
}

CSketcherView::~CSketcherView()
{
}

BOOL CSketcherView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CSketcherView drawing

void CSketcherView::OnDraw(CDC* pDC)
{
	
   CSketcherDoc* pDoc = GetDocument();
   ASSERT_VALID(pDoc);

   pDoc->getHashStart();

   Hash<stringKey, CElement*>::iterator it = pDoc->getHashStart();
   Hash<stringKey, CElement*>::iterator end = pDoc->getHashEnd();
   while(it != end){
	  pair<stringKey, CElement*> he = it++;

	  CElement* pElement = he.second;
	  string keyText = (m_MoveMode)? "": he.first.getKey(); // if if drag object - don't show it's key

      if(pDC->RectVisible(pElement->GetBoundRect()))
         pElement->Draw(pDC, m_pSelected, keyText);  // ...draw it
   }
}

/////////////////////////////////////////////////////////////////////////////
// CSketcherView printing

BOOL CSketcherView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CSketcherView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CSketcherView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CSketcherView diagnostics

#ifdef _DEBUG
void CSketcherView::AssertValid() const
{
	CView::AssertValid();
}

void CSketcherView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CSketcherDoc* CSketcherView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CSketcherDoc)));
	return (CSketcherDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CSketcherView message handlers

void CSketcherView::OnLButtonDown(UINT nFlags, CPoint point) {
	CClientDC aDC(this);                // Create a device context
	OnPrepareDC(&aDC);                  // Get origin adjusted
	aDC.DPtoLP(&point);                 // convert point to Logical

	if(nFlags & MK_CONTROL) {
		this->OnMove();
	}
	else {
		// Get a pointer to the document for this view
		CSketcherDoc* pDoc = GetDocument();
		ASSERT_VALID(pDoc);                  // Verify the pointer is good

		if (pDoc->GetElementType() == TEXT){
			
			if (inputDialog.DoModal()==IDOK){
				if (inputDialog.m_textBox.IsEmpty())
					AfxMessageBox("Text should be at least 1 character long");
				else{
					m_FirstPoint = point;               // Record the cursor position
					m_text = inputDialog.m_textBox;
					inputDialog.m_textBox = "";
					// Define a Device Context object for the view
					CClientDC aDC(this);
					aDC.SetROP2(R2_NOTXORPEN);  // Set the drawing mode
					draw(aDC);
					stopDrawing();
				}
			}
		}
		else if (m_triangleState == 0){
			m_triangleState = 1;
			m_text = "";
			m_FirstPoint = point;               // Record the cursor position
			SetCapture();                       // Capture subsequent mouse messages
		}
		else if (m_triangleState == 2){
			bool cancel = false;

			if(this == GetCapture())	// Stop capturing mouse messages
				ReleaseCapture();        

			if (pDoc->GetElementType() == TEXTINTRIANGLE ){
				if (inputDialog.DoModal()==IDOK){
					if (inputDialog.m_textBox.IsEmpty())
						AfxMessageBox("Text should be at least 1 character long");
					else{
						m_text = inputDialog.m_textBox;
						inputDialog.m_textBox = "";
						draw(aDC);
					}
				}
				else{
					cancel = true;
				}
			}
			stopDrawing(cancel);
			m_triangleState = 0;
		}
		else{
			m_FirstPoint = point;               // Record the cursor position
			SetCapture();                       // Capture subsequent mouse messages
		}
	}
}

void CSketcherView::OnLButtonUp(UINT nFlags, CPoint point) {
	if(m_MoveMode){
		if(this == GetCapture())
			ReleaseCapture();        // Stop capturing mouse messages

		// In moving mode, so drop the element
		m_MoveMode = FALSE;                 // Kill move mode
		GetDocument()->UpdateAllViews(0);   // Redraw all the views
		//m_pSelected = 0;                    // De-select the element
	}
	else {  
		if (GetDocument()->GetElementType() != TRIANGLE && GetDocument()->GetElementType() != TEXTINTRIANGLE){
			stopDrawing();
		}
		else if (m_triangleState == 1){
			m_triangleState = 2;
			if(this == GetCapture())
				ReleaseCapture();        // Stop capturing mouse messages
			SetCapture();                // Capture subsequent mouse messages
		}
	}
}


void CSketcherView::stopDrawing(bool cancel){
	if(this == GetCapture())
		ReleaseCapture();        // Stop capturing mouse messages

	//if there is an element, add it to the document
	if(m_pTempElement){ 
		if (!cancel){
			// add key
			string key = "";
			if (keyInputDialog.DoModal()==IDOK){
				if (keyInputDialog.m_textBox.IsEmpty())
					AfxMessageBox("Text should be at least 1 character long");
				else{
					key = keyInputDialog.m_textBox;
					keyInputDialog.m_textBox = "";
				}
			}
			if (key != ""){
				// put element with given key in hash
				bool res = GetDocument()->AddElement(m_pTempElement, key);
				if (!res)
					AfxMessageBox("Element w/ given key is already in hash.");			}
		}
		//AfxMessageBox("alarm!");
		//GetDocument()->UpdateAllViews(0,0,m_pTempElement);  // Tell all the views
		GetDocument()->UpdateAllViews(0);   // Redraw all the views
		m_pTempElement = 0;      // Reset the element pointer
	}
}

void CSketcherView::draw(CClientDC& aDC){
	if(m_pTempElement)
	{
		aDC.SetROP2(R2_NOTXORPEN);      // Set drawing mode

		// Redraw the old element so it disappears from the view
		m_pTempElement->Draw(&aDC);

		delete m_pTempElement;        // Delete the old element
		m_pTempElement = 0;           // Reset the pointer to 0
	}

	// Create a temporary element of the type and color that
	// is recorded in the document object, and draw it
	m_pTempElement = CreateElement();  // Create a new element
	m_pTempElement->Draw(&aDC);        // Draw the element
}

void CSketcherView::OnMouseMove(UINT nFlags, CPoint point) {
	// Define a Device Context object for the view
	CClientDC aDC(this);
	OnPrepareDC(&aDC);            // Get origin adjusted

	// If we are in move mode, move the selected element and return
	if(nFlags == (MK_LBUTTON | MK_CONTROL)) {
		m_MoveMode = TRUE;
		aDC.DPtoLP(&point);        // Convert to logical coordinatess
		MoveElement(aDC, point);   // Move the element
		return;
	}   

	if((nFlags & MK_LBUTTON) && (this == GetCapture()) && (m_triangleState != 2)) {
		aDC.DPtoLP(&point);        // convert point to Logical
		m_SecondPoint = point;     // Save the current cursor position

		draw(aDC);
	}
	else if((m_triangleState == 2) && (this == GetCapture())) {
		aDC.DPtoLP(&point);        // convert point to Logical

		m_text = "";
		// Save the current cursor position
		m_ThirdPoint = point; 
		draw(aDC);
	}
	else {/* if (nFlags & MK_CONTROL)*/       // We are not drawing an element...
		// ...so do highlighting
		CRect aRect;
		pair<stringKey, CElement*> pSelection = SelectElement(point);
		CElement* pCurrentSelection = pSelection.second;
		string pCurrentKey = pSelection.first.getKey();

		if(pCurrentSelection!=m_pSelected) {
			if(m_pSelected) {             // Old elemented selected?
										   // Yes, so draw it unselected
				aRect = m_pSelected->GetBoundRect(); // Get bounding rectangle
				aDC.LPtoDP(aRect);                   // Conv to device coords
				aRect.NormalizeRect();               // Normalize
				InvalidateRect(aRect, FALSE);        // Invalidate area
			}

			m_pSelected = pCurrentSelection;        // Save elem under cursor
			m_kSelected = pCurrentKey;

			if(m_pSelected) {                        // Is there one?
			                                       // Yes, so get it redrawn
				aRect = m_pSelected->GetBoundRect(); // Get bounding rectangle
				aDC.LPtoDP(aRect);                   // Conv to device coords
				aRect.NormalizeRect();               // Normalize
				InvalidateRect(aRect, FALSE);        // Invalidate area
			}
			// E:
			//GetDocument()->UpdateAllViews(0,0,m_pSelected);  // Tell all views
		}
	}
}

CElement* CSketcherView::CreateElement() {
	// Get a pointer to the document for this view
	CSketcherDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);                  // Verify the pointer is good

	// Now select the element using the type stored in the document
	switch(pDoc->GetElementType())
	{     
		case LINE:                  
			return new Line(m_FirstPoint, m_SecondPoint, pDoc->GetElementColor());

		case TRIANGLE: 
			if (m_triangleState == 1)
				return new Line(m_FirstPoint, m_SecondPoint, pDoc->GetElementColor());
			else if (m_triangleState == 2)
				return new Triangle(m_FirstPoint, m_SecondPoint, m_ThirdPoint, pDoc->GetElementColor());

		case TEXT:
			return new Text(m_text, m_FirstPoint, pDoc->GetElementColor());

		case TEXTINTRIANGLE: 
			if (m_triangleState == 1)
				return new Line(m_FirstPoint, m_SecondPoint, pDoc->GetElementColor());
			else if (m_triangleState == 2)
				return new TextInTriangle(m_FirstPoint, m_SecondPoint, m_ThirdPoint, m_text, pDoc->GetElementColor());

		default:
			//	Something's gone wrong
			AfxMessageBox("Bad Element code", MB_OK);
			AfxAbort();
			return NULL;
	}
}

// Find the element at the cursor
pair<stringKey, CElement*> CSketcherView::SelectElement(CPoint aPoint) {
	// Convert parameter aPoint to logical coordinates
	CClientDC aDC(this);
	OnPrepareDC(&aDC);
	aDC.DPtoLP(&aPoint);

	CSketcherDoc* pDoc=GetDocument();      // Get a pointer to the document
	CElement* pElement = 0;                // Store an element pointer
	CRect aRect(0,0,0,0);                  // Store a rectangle

	Hash<stringKey, CElement*>::iterator it = pDoc->getHashStart();
	Hash<stringKey, CElement*>::iterator end = pDoc->getHashEnd();

	while(it != end){
		pair<stringKey, CElement*> he = it++;

		pElement = he.second;
		aRect = pElement->GetBoundRect();

		// Select the first element that appears under the cursor
		if(aRect.PtInRect(aPoint))
		return he;
	}

	return pair<stringKey, CElement*>(stringKey(),0);                              // No element found
}

void CSketcherView::MoveElement(CClientDC& aDC, CPoint& point) {
	CSize Distance = point - m_CursorPos;   // Get move distance
	m_CursorPos = point;          // Set current point as 1st for next time

	// If there is an element, selected, move it
	if(m_pSelected)	{
		//if current element is text -> invaldate it's encloding rectangle
		//(GetDocument()->GetElementType() == TEXT)

		CRect     aRect = m_pSelected->GetBoundRect(); // Get bounding rectangle
		aDC.LPtoDP(aRect);                   // Conv to device coords
		aRect.NormalizeRect();               // Normalize
		InvalidateRect(aRect);        // Invalidate area

		CRect     aRect1 = m_pSelected->getKeyRectangle(); // Get bounding rectangle
		aDC.LPtoDP(aRect1);                   // Conv to device coords
		aRect1.NormalizeRect();               // Normalize
		InvalidateRect(aRect1);        // Invalidate area

		aDC.SetROP2(R2_NOTXORPEN);
		m_pSelected->Draw(&aDC,m_pSelected); // Draw the element to erase it
		m_pSelected->Move(Distance);         // Now move the element
		m_pSelected->Draw(&aDC,m_pSelected); // Draw the moved element
	}
}

void CSketcherView::OnRButtonDown(UINT nFlags, CPoint point) {
	if(m_MoveMode) {
		// In moving mode, so drop element back in original position
		CClientDC aDC(this);
		OnPrepareDC(&aDC);                  // Get origin adjusted
		MoveElement(aDC, m_FirstPos);       // Move element to orig position
		m_MoveMode = FALSE;                 // Kill move mode
		m_pSelected = 0;                    // De-select element
		GetDocument()->UpdateAllViews(0);   // Redraw all the views
		return;                             // We are done
	}
}


void CSketcherView::OnRButtonUp(UINT nFlags, CPoint point) {
	// Create the cursor menu
	CMenu aMenu;
	aMenu.LoadMenu(IDR_CURSOR_MENU);    // Load the cursor menu
	ClientToScreen(&point);             // Convert to screen coordinates

	// Display the pop-up at the cursor position
	if(m_pSelected) {
		// Check color menu items
		COLORREF Color = m_pSelected->getColor();
		aMenu.CheckMenuItem(ID_SET_COLOR_BLACK, (BLACK==Color?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
		aMenu.CheckMenuItem(ID_SET_COLOR_GREEN, (GREEN==Color?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
		aMenu.CheckMenuItem(ID_SET_COLOR_BLUE, (BLUE==Color?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);

		aMenu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON, point.x, point.y, this);
	}
	else {
		// Check color menu items
		COLORREF Color = GetDocument()->GetElementColor();
		aMenu.CheckMenuItem(ID_COLOR_BLACK, (BLACK==Color?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
		aMenu.CheckMenuItem(ID_COLOR_GREEN, (GREEN==Color?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
		aMenu.CheckMenuItem(ID_COLOR_BLUE, (BLUE==Color?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);

		// Check element menu items
		WORD ElementType = GetDocument()->GetElementType();
		aMenu.CheckMenuItem(ID_ELEMENT_LINE, (LINE==ElementType?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
		aMenu.CheckMenuItem(ID_ELEMENT_TRIANGLE, (TRIANGLE==ElementType?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
		aMenu.CheckMenuItem(ID_ELEMENT_TEXT, (TEXT==ElementType?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
		aMenu.CheckMenuItem(ID_ELEMENT_TEXTINTRIANGLE, (TEXTINTRIANGLE==ElementType?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);

		// Display the context pop-up
		aMenu.GetSubMenu(1)->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON, point.x, point.y, this);
	}
}

void CSketcherView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) {
	// Invalidate the area corresponding to the element pointed to
	// if there is one, otherwise invalidate the whole client area
	if(pHint) {
		CClientDC aDC(this);            // Create a device context
		OnPrepareDC(&aDC);              // Get origin adjusted

		// Get the enclosing rectangle and convert to client coordinates
		CRect aRect=((CElement*)pHint)->GetBoundRect();
		aDC.LPtoDP(aRect);
		aRect.NormalizeRect();
		InvalidateRect(aRect);          // Get the area redrawn
	}
	else
		InvalidateRect(0);
}

void CSketcherView::OnInitialUpdate() {
	ResetScrollSizes();               // Set up the scrollbars
	CScrollView::OnInitialUpdate();
}

void CSketcherView::OnMove() {
	CClientDC aDC(this);
	OnPrepareDC(&aDC);              // Set up the device context
	GetCursorPos(&m_CursorPos);     // Get cursor position in screen coords
	ScreenToClient(&m_CursorPos);   // Convert to client coords
	aDC.DPtoLP(&m_CursorPos);       // Convert to logical
	m_FirstPos = m_CursorPos;       // Remember first position
	m_MoveMode = TRUE;              // Start move mode	
}

void CSketcherView::OnSendtoback() 
{
	GetDocument()->SendToBack(m_pSelected);  // Move element in list	
}

void CSketcherView::OnDelete() {
	if(m_pSelected) {
		deleteElement(m_kSelected);
	}	
}

void CSketcherView::deleteElement(string key) {
		CSketcherDoc* pDoc = GetDocument();	// Get the document pointer
		pDoc->DeleteElement(key);			// Delete the element
		pDoc->UpdateAllViews(0);			// Redraw all the views
		m_pSelected = 0;					// Reset selected element ptr
}

void CSketcherView::OnViewScale() {
	CScaleDialog aDlg;            // Create a dialog object
	aDlg.m_Scale = m_Scale;       // Pass the view scale to the dialog

	if(aDlg.DoModal() == IDOK) {
		m_Scale = aDlg.m_Scale;    // Get the new scale

		// Get the frame window for this view
		CChildFrame* viewFrame = (CChildFrame*)GetParentFrame();

		// Build the message string
		CString StatusMsg("View Scale:");
		StatusMsg += (char)('0' + m_Scale);

		// Write the string to the status bar
		viewFrame->m_StatusBar.GetStatusBarCtrl().SetText(StatusMsg, 0, 0);
		ResetScrollSizes();        // Adjust scrolling to the new scale
		InvalidateRect(0);         // Invalidate the whole window
	}
}

void CSketcherView::ResetScrollSizes() {
   CClientDC aDC(this);
   OnPrepareDC(&aDC);                            // Set up the device context
   CSize DocSize = GetDocument()->GetDocSize();  // Get the document size
   aDC.LPtoDP(&DocSize);                         // Get the size in pixels
   SetScrollSizes(MM_TEXT, DocSize);             // Set up the scrollbars
}

void CSketcherView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo) {
	CScrollView::OnPrepareDC(pDC, pInfo);
	CSketcherDoc* pDoc = GetDocument();
	pDC->SetMapMode(MM_ANISOTROPIC);           // Set the map mode
	CSize DocSize = pDoc->GetDocSize();        // Get the document size

	// y extent must be negative because we want MM_LOENGLISH
	DocSize.cy = -DocSize.cy;                  // Change sign of y
	pDC->SetWindowExt(DocSize);                // Now set the window extent

	// Get the number of pixels per inch in x and y
	int xLogPixels = pDC->GetDeviceCaps(LOGPIXELSX);
	int yLogPixels = pDC->GetDeviceCaps(LOGPIXELSY);

	// Calculate the viewport extent in x and y
	long xExtent = (long)DocSize.cx*m_Scale*xLogPixels/100L;
	long yExtent = (long)DocSize.cy*m_Scale*yLogPixels/100L;

	pDC->SetViewportExt((int)xExtent, (int)-yExtent); // Set viewport extent
}

void CSketcherView::setColor(COLORREF aColor) {
	if(m_pSelected)
	{
		CSketcherDoc* pDoc = GetDocument();  // Get the document pointer
		m_pSelected->setColor(aColor);
		pDoc->UpdateAllViews(0);             // Redraw all the views
		//m_pSelected = 0;                     // Reset selected element ptr
	}
}

void CSketcherView::OnSetColorBlack() {
	setColor(BLACK);
}

void CSketcherView::OnSetColorBlue() {
	setColor(BLUE);
}

void CSketcherView::OnSetColorGreen() {
	setColor(GREEN);
}

void CSketcherView::OnFind() {
	string key = "";
	if (keyInputDialog.DoModal()==IDOK){
		if (keyInputDialog.m_textBox.IsEmpty())
			AfxMessageBox("Text should be at least 1 character long");
		else{
			key = keyInputDialog.m_textBox;
			keyInputDialog.m_textBox = "";
		}
	}

	if (key == "")
		return;

	CSketcherDoc* pDoc = GetDocument();  // Get the document pointer
	Hash<stringKey, CElement*>::iterator it = pDoc->findElement(key);
	Hash<stringKey, CElement*>::iterator end = pDoc->getHashEnd();

	if (it != end){
		m_pSelected = (*it).second;
		pDoc->UpdateAllViews(0);
	}
	else{
		AfxMessageBox("Element was not found!", MB_OK);
	}
}

void CSketcherView::OnFreeView() {
	// TODO: Add your command handler code here
	
}

void CSketcherView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) {
	CSketcherDoc* pDoc = GetDocument();  // Get the document pointer

	if (nChar == VK_RIGHT){
		Hash<stringKey, CElement*>::iterator& it = pDoc->getHashIterator();
		Hash<stringKey, CElement*>::iterator end = pDoc->getHashEnd();

		if (it == end)
			return;

		it++;
		if (it != end){
			m_pSelected = (*it).second;
			m_kSelected = (*it).first.getKey();
			pDoc->UpdateAllViews(0);
		}
		else{
			// iterator points to the end of Hash, decrement it so it'll point on the last element
			it--;
		}
	}

	else if (nChar == VK_LEFT){
		Hash<stringKey, CElement*>::iterator& it = pDoc->getHashIterator();
		Hash<stringKey, CElement*>::iterator begin = pDoc->getHashStart();

		if (it == begin)
			return;

		it--;
		m_pSelected = (*it).second;
		m_kSelected = (*it).first.getKey();
		pDoc->UpdateAllViews(0);
	}

	else if (nChar == VK_DELETE){
		if (m_pSelected){
			string key = m_kSelected;
			if (AfxMessageBox("Are you sure you want to delete this element?", MB_YESNO) == IDYES){
				deleteElement(key);
			}
		}
	}

	CScrollView::OnKeyDown(nChar, nRepCnt, nFlags);
}
Соседние файлы в папке Sketcher05