Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лабораторная работа 32 / part31 / part31View
.cpp// part31View.cpp : implementation of the CPart31View class
//
#include "stdafx.h"
#include "part31.h"
#include "part31Doc.h"
#include "CntrItem.h"
#include "part31View.h"
#include <list>
#include "GraphDlg.h"
#include "LineDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CPart31View
IMPLEMENT_DYNCREATE(CPart31View, CScrollView)
BEGIN_MESSAGE_MAP(CPart31View, CScrollView)
//{{AFX_MSG_MAP(CPart31View)
ON_WM_DESTROY()
ON_WM_SETFOCUS()
ON_WM_SIZE()
ON_COMMAND(ID_OLE_INSERT_NEW, OnInsertObject)
ON_COMMAND(ID_CANCEL_EDIT_CNTR, OnCancelEditCntr)
ON_COMMAND(ID_CANCEL_EDIT_SRVR, OnCancelEditSrvr)
ON_WM_LBUTTONDBLCLK()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_CHAR()
ON_WM_RBUTTONUP()
ON_COMMAND(ID_FIGURE_DELETEELEMENT, OnFigureDeleteelement)
ON_COMMAND(ID_ELEMENTS_LINE, OnElementsLine)
ON_UPDATE_COMMAND_UI(ID_ELEMENTS_LINE, OnUpdateElementsLine)
ON_COMMAND(ID_FIGURE_DELETELINE, OnFigureDeleteline)
ON_COMMAND(ID_CONTEINER_GRAPHVIEW, OnConteinerGraphview)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CScrollView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPart31View construction/destruction
CPart31View::CPart31View()
{
m_pSelection = NULL;
// TODO: add construction code here
m_FirstPoint = CPoint(0,0);
m_SecondPoint = CPoint(0,0);
m_MoveLastPoint = CPoint(0,0);
m_pTempElement = 0;
m_pSelected = 0;
StringData="";
CaretCreated=false;
doMove=false;
m_Scale=1;
SetScrollSizes(MM_TEXT, CSize(0,0));
doLine=false;
first=0;
second=0;
}
CPart31View::~CPart31View()
{
}
BOOL CPart31View::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CScrollView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CPart31View drawing
void CPart31View::OnDraw(CDC* pDC)
{
CPart31Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
// TODO: also draw all OLE items in the document
// Draw the selection at an arbitrary position. This code should be
// removed once your real drawing code is implemented. This position
// corresponds exactly to the rectangle returned by CPart31CntrItem,
// to give the effect of in-place editing.
// TODO: remove this code when final draw code is complete.
if (m_pSelection == NULL)
{
POSITION pos = pDoc->GetStartPosition();
m_pSelection = (CPart31CntrItem*)pDoc->GetNextClientItem(pos);
}
if (m_pSelection != NULL)
m_pSelection->Draw(pDC, m_pSelection->m_Rect);
if (pDoc->graph.getCount()!=0) //Когда окно перерисовывается, рисуем элементы из контейнера
{
GrIterator<Shape*> it(pDoc->graph);
std::list<int> lways;
std::list<int>::iterator lwaysIt;
CString sind;
while(!it.isEnd())
{
if(pDC->RectVisible(it.currentElement()->GetBoundRect()))
{
sind.Format("%d",it.currentIndex());
pDC->TextOut(it.currentElement()->GetX()-10,it.currentElement()->GetY()-10,sind);
if (it.currentElement()==first)
{it.currentElement()->Draw(pDC,m_pSelected,true);}
else
{
it.currentElement()->Draw(pDC,m_pSelected);
}
}
lways=pDoc->graph.getNextWays(it.currentIndex());//Рисуем линии
lwaysIt=lways.begin();
while (lwaysIt!=lways.end())
{
CRect rect1=it.currentElement()->GetBoundRect();
CPoint fPoint(it.currentElement()->GetX()+rect1.Width()/2,it.currentElement()->GetY());
CRect rect2=pDoc->graph.getElement(*lwaysIt)->GetBoundRect();
CPoint sPoint(pDoc->graph.getElement(*lwaysIt)->GetX()+rect2.Width()/2,pDoc->graph.getElement(*lwaysIt)->GetY());
printLine(fPoint,sPoint);
lwaysIt++;
}
it.goNext();
}
}
}
void CPart31View::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
// TODO: remove this code when final selection model code is written
m_pSelection = NULL; // initialize selection
ResetScrollSizes();
}
/////////////////////////////////////////////////////////////////////////////
// CPart31View printing
BOOL CPart31View::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CPart31View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CPart31View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
void CPart31View::OnDestroy()
{
// Deactivate the item on destruction; this is important
// when a splitter view is being used.
CScrollView::OnDestroy();
COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
if (pActiveItem != NULL && pActiveItem->GetActiveView() == this)
{
pActiveItem->Deactivate();
ASSERT(GetDocument()->GetInPlaceActiveItem(this) == NULL);
}
}
/////////////////////////////////////////////////////////////////////////////
// OLE Client support and commands
BOOL CPart31View::IsSelected(const CObject* pDocItem) const
{
// The implementation below is adequate if your selection consists of
// only CPart31CntrItem objects. To handle different selection
// mechanisms, the implementation here should be replaced.
// TODO: implement this function that tests for a selected OLE client item
return pDocItem == m_pSelection;
}
void CPart31View::OnInsertObject()
{
// Invoke the standard Insert Object dialog box to obtain information
// for new CPart31CntrItem object.
COleInsertDialog dlg;
if (dlg.DoModal() != IDOK)
return;
BeginWaitCursor();
CPart31CntrItem* pItem = NULL;
TRY
{
// Create new item connected to this document.
CPart31Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
pItem = new CPart31CntrItem(pDoc);
ASSERT_VALID(pItem);
// Initialize the item from the dialog data.
if (!dlg.CreateItem(pItem))
AfxThrowMemoryException(); // any exception will do
ASSERT_VALID(pItem);
if (dlg.GetSelectionType() == COleInsertDialog::createNewItem)
pItem->DoVerb(OLEIVERB_SHOW, this);
ASSERT_VALID(pItem);
// As an arbitrary user interface design, this sets the selection
// to the last item inserted.
// TODO: reimplement selection as appropriate for your application
m_pSelection = pItem; // set selection to last inserted item
pDoc->UpdateAllViews(NULL);
}
CATCH(CException, e)
{
if (pItem != NULL)
{
ASSERT_VALID(pItem);
pItem->Delete();
}
AfxMessageBox(IDP_FAILED_TO_CREATE);
}
END_CATCH
EndWaitCursor();
}
// The following command handler provides the standard keyboard
// user interface to cancel an in-place editing session. Here,
// the container (not the server) causes the deactivation.
void CPart31View::OnCancelEditCntr()
{
// Close any in-place active item on this view.
COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
if (pActiveItem != NULL)
{
pActiveItem->Close();
}
ASSERT(GetDocument()->GetInPlaceActiveItem(this) == NULL);
}
// Special handling of OnSetFocus and OnSize are required for a container
// when an object is being edited in-place.
void CPart31View::OnSetFocus(CWnd* pOldWnd)
{
COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
if (pActiveItem != NULL &&
pActiveItem->GetItemState() == COleClientItem::activeUIState)
{
// need to set focus to this item if it is in the same view
CWnd* pWnd = pActiveItem->GetInPlaceWindow();
if (pWnd != NULL)
{
pWnd->SetFocus(); // don't call the base class
return;
}
}
CScrollView::OnSetFocus(pOldWnd);
}
void CPart31View::OnSize(UINT nType, int cx, int cy)
{
CScrollView::OnSize(nType, cx, cy);
COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
if (pActiveItem != NULL)
pActiveItem->SetItemRects();
}
/////////////////////////////////////////////////////////////////////////////
// OLE Server support
// The following command handler provides the standard keyboard
// user interface to cancel an in-place editing session. Here,
// the server (not the container) causes the deactivation.
void CPart31View::OnCancelEditSrvr()
{
GetDocument()->OnDeactivateUI(FALSE);
}
/////////////////////////////////////////////////////////////////////////////
// CPart31View diagnostics
#ifdef _DEBUG
void CPart31View::AssertValid() const
{
CScrollView::AssertValid();
}
void CPart31View::Dump(CDumpContext& dc) const
{
CScrollView::Dump(dc);
}
CPart31Doc* CPart31View::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CPart31Doc)));
return (CPart31Doc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CPart31View message handlers
CPart31CntrItem* CPart31View::OleClickTest(CPoint point)
{
CPart31CntrItem* myOle;
myOle=m_pSelection;
if (myOle!=NULL)
{
if (!myOle->m_Rect.PtInRect(point)) myOle=NULL;
}
return myOle;
}
void CPart31View::OnLButtonDblClk(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CPart31CntrItem* myOle;
myOle=OleClickTest(point);
if (myOle!=NULL) myOle->DoVerb(OLEIVERB_PRIMARY,this); //инициализация объекта ole
CScrollView::OnLButtonDblClk(nFlags, point);;
}
void CPart31View::printLine(CPoint First,CPoint Second)
{
CClientDC aDC(this);
OnPrepareDC(&aDC);
aDC.MoveTo(First.x,First.y);
aDC.LineTo(Second.x,Second.y);
}
Shape* CPart31View::CreateElement() //создаем элемент выбранного типа
{
CPart31Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
switch(pDoc->GetElementType())
{
case CIRCLE:
return new CCircle(m_FirstPoint.x,m_FirstPoint.y,(m_SecondPoint.x-m_FirstPoint.x)/2);
case ELLIPSE:
return new CEllipse(m_FirstPoint.x,m_FirstPoint.y,(m_SecondPoint.x-m_FirstPoint.x)/2,(m_SecondPoint.y-m_FirstPoint.y)/2);
case TEXT:
return new CText(m_FirstPoint.x,m_FirstPoint.y,StringData);
case ELLIPSETEXT:
return new CEllipseTxt(m_FirstPoint.x,m_FirstPoint.y,(m_SecondPoint.x-m_FirstPoint.x)/2,(m_SecondPoint.y-m_FirstPoint.y)/2,StringData);
default:
AfxMessageBox("Bad Element code", MB_OK);
AfxAbort();
return 0;
}
}
Shape* CPart31View::SelectElement(CPoint aPoint)
{ //Указатель на выделенный элемент
CPart31Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (pDoc->graph.getCount()!=0)
{
CClientDC aDC(this);
OnPrepareDC(&aDC);
aDC.DPtoLP(&aPoint);
Shape* element=0;
CRect aRect(0,0,0,0);
GrIterator<Shape*> it(pDoc->graph);
while(!it.isEnd())
{
element=it.currentElement();
aRect=it.currentElement()->GetBoundRect();
if(aRect.PtInRect(aPoint))
{
SelectedIndex=it.currentIndex();
return element;
}
it.goNext();
}
}
return 0;
}
void CPart31View::ShowCursor(CDC* pDC) //показать курсор
{ CPart31Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!CaretCreated)
{
TEXTMETRIC textmetric;
pDC->GetTextMetrics(&textmetric);
CreateSolidCaret(textmetric.tmAveCharWidth/8,textmetric.tmHeight);
if (pDoc->GetElementType()!=ELLIPSETEXT)
{
SetCaretPos(m_FirstPoint);
ShowCaret();
CaretCreated=true;
}
}
}
void CPart31View::ResetScrollSizes()
{
CClientDC aDC(this);
OnPrepareDC(&aDC);
CPart31Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CSize DocSize = pDoc->GetDocSize();
aDC.LPtoDP(&DocSize);
SetScrollSizes(MM_TEXT, DocSize);
}
void CPart31View::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CPart31Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CClientDC aDC(this);
if (doLine)
{ CRect aRect,bRect;
if (first)
{
if (second)
{
}
else
{second=m_pSelected;
if (second)
{
aRect = first->GetBoundRect();
bRect = second->GetBoundRect();
int w1=aRect.Width() / 2;
CPoint f(first->GetX()+w1,first->GetY());
w1=bRect.Width() /2;
CPoint s(second->GetX()+w1,second->GetY());
printLine(f,s);
GrIterator<Shape*> it(pDoc->graph);
int fIndex=0;
int sIndex=0;
while(!it.isEnd())
{
if (it.currentElement()==first) {fIndex=it.currentIndex();}
if (it.currentElement()==second) {sIndex=it.currentIndex();}
it.goNext();
}
pDoc->graph.AddLine(fIndex,sIndex);
}
aRect = first->GetBoundRect();
first = 0;
aDC.LPtoDP(aRect);
aRect.NormalizeRect();
InvalidateRect(aRect, FALSE);
second = 0;
}
}
else
{first=m_pSelected;
if (first)
{
aRect = first->GetBoundRect();
aDC.LPtoDP(aRect);
aRect.NormalizeRect();
InvalidateRect(aRect, FALSE);
}
}
}
else
{
m_FirstPoint = point;
StringData.Empty();
SetCapture();
HideCaret();
CaretCreated=false;
}
CScrollView::OnLButtonDown(nFlags, point);
}
void CPart31View::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CPart31Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CClientDC aDC(this);
if (pDoc->is_TextEnter)
{
if (!doMove)
{
m_SecondPoint = point;
ShowCursor(&aDC);
}
else
{
if(this == GetCapture())
ReleaseCapture();
}
}
else
{
if (m_pTempElement) //Если текст не вводим, то добавляем элемент в контейнер
{
pDoc->graph.AddElement(m_pTempElement,pDoc->index);
pDoc->index++;
Invalidate();
}
if(this == GetCapture())
ReleaseCapture();
}
if (doMove==true){doMove=false;} //если двигали, то больше не двигаем
if(m_pTempElement)
{
m_pTempElement = 0; //освобождение элемента
}
CScrollView::OnLButtonUp(nFlags, point);
}
void CPart31View::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CClientDC aDC(this);
OnPrepareDC(&aDC);
if((nFlags & MK_LBUTTON) && (this == GetCapture()))
{
if (!doMove)
{ //Если не двигаем, то перерисовываем
aDC.DPtoLP(&point);
m_SecondPoint = point;
if(m_pTempElement)
{
aDC.SetROP2(R2_NOTXORPEN);
m_pTempElement->Draw(&aDC);
delete m_pTempElement;
m_pTempElement = 0;
}
m_pTempElement = CreateElement();
m_pTempElement->Draw(&aDC);
}
else
{
aDC.SetROP2(R2_NOTXORPEN); //Если двигаем
m_pSelected->Draw(&aDC,m_pSelected);
m_pSelected->Move(point.x-m_MoveLastPoint.x,point.y-m_MoveLastPoint.y);
m_pSelected->Draw(&aDC,m_pSelected);
Invalidate();
}
}
else
{
CRect aRect; //Если кнопка мыши не нажата, выделяем красным нужные элементы
Shape* pCurrentSelection = SelectElement(point);
if ((pCurrentSelection==m_pSelected)&&(m_pSelected)){doMove=true;}
if(pCurrentSelection!=m_pSelected)
{ doMove=false;
if(m_pSelected)
{
aRect = m_pSelected->GetBoundRect();
aDC.LPtoDP(aRect);
aRect.NormalizeRect();
InvalidateRect(aRect, FALSE);
}
m_pSelected = pCurrentSelection;
if(m_pSelected)
{
aRect = m_pSelected->GetBoundRect();
aDC.LPtoDP(aRect);
aRect.NormalizeRect();
InvalidateRect(aRect, FALSE);
}
}
}
m_MoveLastPoint=point;
CScrollView::OnMouseMove(nFlags, point);
}
void CPart31View::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
HideCaret(); //Реакция на нажатие клавиш
CClientDC aDC(this);
CPart31Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (nChar==VK_SPACE) //Если нажат пробел
{
if(m_pTempElement) //добавляем в контейнер
{
m_pTempElement->Draw(&aDC);
pDoc->graph.AddElement(m_pTempElement,pDoc->index);
pDoc->index++;
m_pTempElement = 0;
Invalidate();
}
if(this == GetCapture())
{ ReleaseCapture(); }
HideCaret();CaretCreated=false;
StringData.Empty();
}
else
{ //если не пробел, то перерисовываем элемент
if(this == GetCapture())
{
StringData+=nChar;
if(m_pTempElement)
{
m_pTempElement->Draw(&aDC);
delete m_pTempElement;
m_pTempElement = 0;
}
m_pTempElement = CreateElement();
m_pTempElement->Draw(&aDC);
CSize size=aDC.GetTextExtent(StringData);
if (pDoc->GetElementType()!=ELLIPSETEXT)
{
CPoint point(m_FirstPoint.x+size.cx,m_FirstPoint.y);
SetCaretPos(point);
ShowCaret();
}
}
}
CScrollView::OnChar(nChar, nRepCnt, nFlags);
}
void CPart31View::OnRButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CMenu aMenu; //Показать контекстное меню
aMenu.LoadMenu(IDR_CONTEXT_MENU);
ClientToScreen(&point);
if(m_pSelected)
{
aMenu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON,
point.x, point.y, this);
}
else
{
WORD ElementType = GetDocument()->GetElementType();
aMenu.CheckMenuItem(ID_ELEMENTS_CIRCLE,
(CIRCLE==ElementType?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
aMenu.CheckMenuItem(ID_ELEMENTS_ELLIPSE,
(ELLIPSE==ElementType?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
aMenu.CheckMenuItem(ID_ELEMENTS_TEXT,
(TEXT==ElementType?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
aMenu.CheckMenuItem(ID_ELEMENTS_ELLIPSEWITHTEXT,
(ELLIPSETEXT==ElementType?MF_CHECKED:MF_UNCHECKED)|MF_BYCOMMAND);
aMenu.GetSubMenu(1)->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON, point.x, point.y, this);
}
CScrollView::OnRButtonUp(nFlags, point);
}
void CPart31View::OnFigureDeleteelement()
{
// TODO: Add your command handler code here
CPart31Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc); //Удаление элемента из контейнера
GrIterator<Shape*> it(pDoc->graph);
bool deleted=false;
while((!it.isEnd())&&(!deleted))
{
if (it.currentElement()==m_pSelected)
{pDoc->graph.delElem(it.currentIndex());
deleted=true;
}
it.goNext();
}
Invalidate();
}
void CPart31View::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
// TODO: Add your specialized code here and/or call the base class
if(pHint) //для перерисовки ползунков
{
CClientDC aDC(this);
OnPrepareDC(&aDC);
CRect aRect=((Shape*)pHint)->GetBoundRect();
aDC.LPtoDP(aRect);
aRect.NormalizeRect();
InvalidateRect(aRect);
}
else
InvalidateRect(0);
}
void CPart31View::OnElementsLine()
{
// TODO: Add your command handler code here
if (doLine==true)
{doLine=false;
first = 0;
second = 0;
}
else {doLine=true;}
}
void CPart31View::OnUpdateElementsLine(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(doLine);
}
void CPart31View::OnFigureDeleteline()
{
// TODO: Add your command handler code here
CPart31Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc); //Вызов диалогового окна для контейнера
LineDlg dlg;
if (pDoc->graph.getCount()!=0)
{
dlg.graph=pDoc->graph;
dlg.curIndex=SelectedIndex;
}
if (dlg.DoModal()==IDOK)
{
pDoc->graph=dlg.graph;
InvalidateRect(0);
}
}
void CPart31View::OnConteinerGraphview()
{
// TODO: Add your command handler code here
CPart31Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc); //Вызов диалогового окна для контейнера
GraphDlg dlg;
if (pDoc->graph.getCount()!=0)
{
dlg.graph=pDoc->graph;
GrIterator<Shape*> it(pDoc->graph);
dlg.m_x=it.currentElement()->GetX();
dlg.m_y=it.currentElement()->GetY();
dlg.m_name=it.currentElement()->getName();
dlg.m_cnt=pDoc->graph.getCount();
dlg.m_nom=1;
}
if (dlg.DoModal()==IDOK)
{
pDoc->graph=dlg.graph;
InvalidateRect(0);
}
}
Соседние файлы в папке part31