MAINFRM.CPP
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:14k
源码类别:
Windows编程
开发平台:
Visual C++
- // MainFrm.cpp : implementation of the CMFCMainFrame class
- //
- // This is a part of the Active Template Library.
- // Copyright (C) 1996-1998 Microsoft Corporation
- // All rights reserved.
- //
- // This source code is only intended as a supplement to the
- // Active Template Library Reference and related
- // electronic documentation provided with the library.
- // See these sources for detailed information regarding the
- // Active Template Library product.
- #include "stdafx.h"
- #include "MFCTangram.h"
- #include "MainFrm.h"
- #include "MFCTangramConfigDlg.h"
- #include "objbase.h"
- #include <oleauto.h>
- #include <stdlib.h> //for rand()
- #include <time.h>
- // Interface definitions.
- #include "ATLModel.h"
- #include "ATLModel_i.c"
- #include "AtlTangramCanvas.h"
- #include "AtlTangramCanvas_i.c"
- #include "AtlGdiWorld_i.c"
- #include "AtlGdiWorld.h"
- #include "AtlGLWorld.h"
- #include "AtlGLWorld_i.c"
- // Others
- #include "util.h"
- #include "util.cpp"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- const int POLYGONS = 7;
- ///////////////////////////////////////////////////////////
- //
- // Statics
- //
- CString CMFCMainFrame::s_strClassName = "" ;
- /////////////////////////////////////////////////////////////////////////////
- // CMFCMainFrame
- BEGIN_MESSAGE_MAP(CMFCMainFrame, CFrameWnd)
- //{{AFX_MSG_MAP(CMFCMainFrame)
- ON_WM_CREATE()
- ON_WM_PAINT()
- ON_WM_MOUSEMOVE()
- ON_WM_LBUTTONDOWN()
- ON_WM_LBUTTONUP()
- ON_WM_RBUTTONDOWN()
- ON_WM_RBUTTONUP()
- ON_WM_PALETTECHANGED()
- ON_WM_QUERYNEWPALETTE()
- ON_WM_DESTROY()
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- static UINT indicators[] =
- {
- ID_SEPARATOR, // status line indicator
- ID_INDICATOR_CAPS,
- ID_INDICATOR_NUM,
- ID_INDICATOR_SCRL,
- };
- /////////////////////////////////////////////////////////////////////////////
- // CMFCMainFrame construction/destruction
- ///////////////////////////////////////////////////////////
- //
- // Constructor
- //
- CMFCMainFrame::CMFCMainFrame()
- : m_pWorld(NULL),
- m_pSelectedVisual(NULL)
- {
- m_sizedDiff.cx = 0.0 ;
- m_sizedDiff.cy = 0.0 ;
- }
- ///////////////////////////////////////////////////////////
- //
- // Destructor
- //
- CMFCMainFrame::~CMFCMainFrame()
- {
- if (m_pWorld != NULL)
- {
- m_pWorld->Release() ;
- }
- POSITION pos = m_ModelList.GetHeadPosition();
- while( pos != NULL )
- {
- IATLTangramModel* pITangramModel = m_ModelList.GetNext( pos ) ;
- pITangramModel->Release();
- m_ModelList.RemoveHead();
- }
- m_ModelList.RemoveAll();
- /**/
- }
- int CMFCMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
- {
- if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
- {
- TRACE0("Could not create main window.rn") ;
- return -1;
- }
- // Initialize
- CRect aRect ;
- GetClientRect(&aRect) ;
- if (!Initialize(aRect.Width(), aRect.Height()))
- {
- TRACE0("Cannot initialize main window.rn") ;
- return -1 ;
- }
- return 0;
- }
- BOOL CMFCMainFrame::PreCreateWindow(CREATESTRUCT& cs)
- {
- // TODO: Modify the Window class or styles here by modifying
- // the CREATESTRUCT cs
- return CFrameWnd::PreCreateWindow(cs);
- }
- /////////////////////////////////////////////////////////////////////////////
- // CMFCMainFrame diagnostics
- #ifdef _DEBUG
- void CMFCMainFrame::AssertValid() const
- {
- CFrameWnd::AssertValid();
- }
- void CMFCMainFrame::Dump(CDumpContext& dc) const
- {
- CFrameWnd::Dump(dc);
- }
- #endif //_DEBUG
- ///////////////////////////////////////////////////////////
- //
- // Initialize
- //
- BOOL CMFCMainFrame::Initialize(int cx, int cy)
- {
- ASSERT( (cx != 0) && (cy != 0)) ;
- // Which components are in the IWorldComponent Category.
- CMFCTangramConfigDlg dlg;
- if (dlg.DoModal() != IDOK)
- {
- TRACE0("User canceled the dialog box. Fail initialization.rn") ;
- return FALSE ;
- }
- // Did the user want to use local or inproc?
- DWORD clsctx = (dlg.m_bLocalModel) ? CLSCTX_LOCAL_SERVER : CLSCTX_INPROC_SERVER ;
- // Create the desired world selected component.
- HRESULT hr = ::CoCreateInstance( dlg.m_clsid, // either Gdi or GL
- NULL,
- CLSCTX_INPROC_SERVER,
- IID_IAtlTangramWorld,
- reinterpret_cast<void**>(&m_pWorld)) ;
- if (FAILED(hr))
- {
- ErrorMessage("Failed to create the world component.", hr) ;
- return FALSE ;
- }
- // Initialize the world.
- hr = m_pWorld->Initialize(m_hWnd, 20.0, 20.0) ;
- if (FAILED(hr))
- {
- ErrorMessage("Cannot initialize World.rn", hr) ;
- m_pWorld->Release() ;
- m_pWorld = NULL ;
- return FALSE ;
- }
- // Create and initialize the tangrams pieces.
- struct PolygonInit{
- int iSides ;
- TangramPoint2d points[4] ;
- };
- PolygonInit polygons[7] = {
- // Sides Vertex 0 1 2 3
- { 4, {{0.0, 0.0 }, {1.0, 0.0 }, {1.0, 1.0 }, {0.0, 1.0 }} }, // Square
- { 3, {{0.0, 0.0 }, {1.0, 0.0 }, {0.0, 1.0 }, {9.9, 9.9 }} }, // Small Triangle
- { 3, {{0.0, 0.0 }, {1.0, 0.0 }, {0.0, 1.0 }, {9.9, 9.9 }} }, // Small Triangle
- { 3, {{0.0, 0.0 }, {2.0, 0.0 }, {1.0, 1.0 }, {9.9, 9.9 }} }, // Medium Triangle
- { 3, {{0.0, 0.0 }, {2.0, 0.0 }, {0.0, 2.0 }, {9.9, 9.9 }} }, // Big Triangle
- { 3, {{0.0, 0.0 }, {2.0, 0.0 }, {0.0, 2.0 }, {9.9, 9.9 }} }, // Big Triangle
- { 4, {{0.0, 0.0 }, {1.0, 0.0 }, {2.0, 1.0 }, {1.0, 1.0 }} }, // Paralelagram
- };
- double x = 0.0 ;
- IATLTangramModel* pITangramModel = NULL ;
- for (int i = 0 ; i < POLYGONS ; i ++)
- {
- hr = ::CoCreateInstance(CLSID_ATLTangramModel,
- NULL,
- clsctx ,
- IID_IATLTangramModel,
- (void**)&pITangramModel);
- if (FAILED(hr))
- {
- ErrorMessage("Failed to create Tangram piece.", hr) ;
- return FALSE ;
- }
- // Set the vertices for this model.
- hr = pITangramModel->SetVertices(polygons[i].iSides, polygons[i].points) ;
- ASSERT_HRESULT(hr) ;
- // Add the interface to the array.
- // This makes a copy of the pointer without
- // an AddRef(), so we don't have to Release() the
- // model
- m_ModelList.AddTail(pITangramModel) ;
- hr = m_pWorld->CreateVisualForModel(pITangramModel) ;
- ASSERT_HRESULT(hr) ;
- // Get the IATLTangramTransform interface.
- IATLTangramTransform* pITangramTransform = NULL ;
- HRESULT hr = pITangramModel->QueryInterface(IID_IATLTangramTransform, (void**)&pITangramTransform ) ;
- ASSERT_HRESULT(hr) ;
- // Place the tangram piece.
- pITangramTransform->Translate(x, 1.0) ;
- x += 2.0 ;
- // We are done with IATLTangramTransform.
- pITangramTransform->Release() ;
- }
- return TRUE ;
- }
- ///////////////////////////////////////////////////////////
- //
- // Create - Helper function for creating the window class
- // and window.
- //
- BOOL CMFCMainFrame::Create()
- {
- if (s_strClassName.IsEmpty())
- {
- s_strClassName = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,
- AfxGetApp()->LoadStandardCursor(IDC_ARROW),
- 0,
- AfxGetApp()->LoadIcon(IDR_MAINFRAME));
- }
- // Set screen size.
- CClientDC dc(NULL) ;
- int cx = 640 ;
- int cy = 480 ;
- return CWnd::CreateEx( 0, s_strClassName, AfxGetAppName(),
- WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|
- WS_BORDER|WS_MINIMIZEBOX|WS_VISIBLE,
- 0,0, cx, cy,
- NULL, NULL);
- }
- ///////////////////////////////////////////////////////////
- //
- // OnPaint
- //
- void CMFCMainFrame::OnPaint()
- {
- CPaintDC dc(this);
- // Get ICanvas interface pointer.
- IAtlTangramCanvas* pCanvas = NULL ;
- HRESULT hr = m_pWorld->QueryInterface(IID_IAtlTangramCanvas, (void**)&pCanvas) ;
- ASSERT_HRESULT(hr) ;
- // Use it.
- hr = pCanvas->Paint(dc.m_hDC, dc.m_ps.rcPaint) ;
- ASSERT_HRESULT(hr) ;
- // Lose it.
- pCanvas->Release() ;
- }
- ///////////////////////////////////////////////////////////
- //
- // Handle both left and right button down messages.
- //
- void CMFCMainFrame::DoButtonDown(UINT nWhichButton, CPoint point)
- {
- if (m_pSelectedVisual != NULL)
- {
- // User may have pressed right button then left button.
- TRACE0("OnLButtonDown: Visual already selected.rn") ;
- return ;
- }
- HRESULT hr = m_pWorld->VisualFromPoint(point, IID_IAtlTangramVisual, (IUnknown**)&m_pSelectedVisual) ; //@
- ASSERT(SUCCEEDED(hr)) ;
- if (hr == S_OK)
- {
- ASSERT(m_pSelectedVisual != NULL) ;
- //
- // Get mouse pointer offset from model's origin.
- //
- // Convert to Model Coordinates.
- TangramPoint2d ptModel ;
- hr = m_pWorld->DeviceToModel(point, &ptModel);
- ASSERT_HRESULT(hr) ;
- // Get the Model's ITrangramTransform interface.
- IATLTangramTransform* pITangramTransform = NULL ;
- hr = m_pSelectedVisual->GetModel(IID_IATLTangramTransform, (IUnknown**)&pITangramTransform) ;
- ASSERT_HRESULT(hr) ;
- // Where does the model reside.
- TangramPoint2d ptOrigin ;
- hr = pITangramTransform->GetTranslation(&ptOrigin) ;
- ASSERT_HRESULT(hr) ;
- // Release ITangramTransfrom.
- pITangramTransform->Release() ;
- pITangramTransform = NULL ;
- // Get difference between where the mouse clicked and the origin of the piece.
- m_sizedDiff.cx = ptModel.x - ptOrigin.x ;
- m_sizedDiff.cy = ptModel.y - ptOrigin.y ;
- // Select the visual.
- hr = m_pWorld->SelectVisual(m_pSelectedVisual, TRUE) ;
- ASSERT_HRESULT(hr) ;
- // Update the display
- hr = m_pWorld->Animate() ;
- ASSERT_HRESULT(hr) ;
- // Capture the mouse.
- SetCapture() ;
- }
- else
- {
- TRACE0("DoButtonDown: PtInVisual returned Null.rn") ;
- }
- }
- void CMFCMainFrame::PostNcDestroy()
- {
- delete this;
- }
- ///////////////////////////////////////////////////////////
- //
- // OnLButtonDown Message Handler
- //
- void CMFCMainFrame::OnLButtonDown(UINT nWhichButton, CPoint point)
- {
- DoButtonDown(nWhichButton, point) ;
- }
- ///////////////////////////////////////////////////////////
- //
- // OnLButtonUp Message Handler
- //
- void CMFCMainFrame::OnLButtonUp(UINT nWhichButton, CPoint point)
- {
- if (::GetCapture() != m_hWnd)
- {
- return ;
- }
- if (m_pSelectedVisual != NULL)
- {
- // De-select the currently selected model.
- HRESULT hr = m_pWorld->SelectVisual(m_pSelectedVisual, FALSE) ;
- ASSERT_HRESULT(hr) ;
- // Cleanup
- m_pSelectedVisual->Release() ;
- m_pSelectedVisual = NULL ;
- }
- // We don't need the mouse capture any more.
- ::ReleaseCapture() ;
- }
- ///////////////////////////////////////////////////////////
- //
- // OnMouseMove Message Handler
- //
- void CMFCMainFrame::OnMouseMove(UINT nWhichButton, CPoint point)
- {
- if ((::GetCapture() != m_hWnd) ||
- (nWhichButton & (MK_SHIFT | MK_CONTROL)))
- {
- // Return if another window has captured the mouse or
- // if the SHIFT or CTRL key is pressed, signaling rotation.
- return ;
- }
- // Make sure that mouse is not outside of our client area.
- CRect rectClient ;
- GetClientRect(&rectClient) ;
- if (!rectClient.PtInRect(point))
- {
- return ;
- }
- ASSERT(m_pSelectedVisual != NULL) ;
- // Convert to Model Coordinates.
- TangramPoint2d ptModel ;
- HRESULT hr = m_pWorld->DeviceToModel(point, &ptModel);
- ASSERT_HRESULT(hr) ;
- //Get the Model's ITangramTransfrom interface.
- IATLTangramTransform* pITangramTransform = NULL ;
- hr = m_pSelectedVisual->GetModel(IID_IATLTangramTransform, (IUnknown**)&pITangramTransform) ;
- ASSERT_HRESULT(hr) ;
- // Move the model.
- hr = pITangramTransform->Translate(ptModel.x - m_sizedDiff.cx, ptModel.y - m_sizedDiff.cy);
- ASSERT_HRESULT(hr) ;
- // Release the interface.
- pITangramTransform->Release() ;
- }
- ///////////////////////////////////////////////////////////
- //
- // Rotate using the right mouse button.
- //
- void CMFCMainFrame::OnRButtonDown(UINT nWhichButton, CPoint point)
- {
- DoButtonDown(nWhichButton, point) ;
- }
- ///////////////////////////////////////////////////////////
- //
- // Rotate the model. Shift key determines direction.
- //
- void CMFCMainFrame::OnRButtonUp(UINT nWhichButton, CPoint point)
- {
- if (::GetCapture() != m_hWnd)
- {
- return ;
- }
- if (m_pSelectedVisual != NULL)
- {
- //----- Rotate the shape. -----
- // Check to see of the mouse pointer is still over the same visual.
- IAtlTangramVisual* pSameVisual = NULL ;
- HRESULT hr = m_pWorld->VisualFromPoint(point, IID_IAtlTangramVisual, (IUnknown**)&pSameVisual) ;
- ASSERT_HRESULT(hr) ;
- ASSERT(pSameVisual != NULL) ;
- if (::InterfacesAreOnSameComponent(m_pSelectedVisual, pSameVisual))
- {
- //Get the Model's IATLTangramTransform interface.
- IATLTangramTransform* pITangramTransform = NULL ;
- hr = m_pSelectedVisual->GetModel(IID_IATLTangramTransform, (IUnknown**)&pITangramTransform);
- ASSERT_HRESULT(hr) ;
- // Rotate the model.
- int iRotationDirection = (nWhichButton & MK_SHIFT) ? -1 : 1 ;
- double dDegrees ;
- pITangramTransform->GetRotation(&dDegrees) ;
- pITangramTransform->Rotate(dDegrees + 45.0*iRotationDirection);
- // Release IATLTangramTransform
- pITangramTransform->Release() ;
- pITangramTransform = NULL ;
- }
- // Cleanup
- pSameVisual->Release() ;
- pSameVisual = NULL ;
- // De-select the currently selected model.
- hr = m_pWorld->SelectVisual(m_pSelectedVisual, FALSE) ;
- ASSERT_HRESULT(hr) ;
- // Cleanup
- m_pSelectedVisual->Release() ;
- m_pSelectedVisual = NULL ;
- }
- // We don't need the mouse capture any more.
- ::ReleaseCapture() ;
- }
- ///////////////////////////////////////////////////////////
- //
- // OnPaletteChanged Message Handler
- //
- void CMFCMainFrame::OnPaletteChanged(CWnd* pFocusWnd)
- {
- if (pFocusWnd != this)
- {
- OnQueryNewPalette() ;
- }
- }
- ///////////////////////////////////////////////////////////
- //
- // QueryNewPalette Message Handler
- //
- BOOL CMFCMainFrame::OnQueryNewPalette()
- {
- if (m_hWnd == NULL)
- {
- return FALSE ;
- }
- // Get ICanvas interface pointer.
- IAtlTangramCanvas* pCanvas = NULL ;
- HRESULT hr = m_pWorld->QueryInterface(IID_IAtlTangramCanvas, (void**)&pCanvas) ;
- if (SUCCEEDED(hr))
- {
- // Use it.
- hr = pCanvas->OnQueryNewPalette(m_hWnd);
- // Lose it.
- pCanvas->Release() ;
- }
- return SUCCEEDED(hr);
- }
- void CMFCMainFrame::OnDestroy()
- {
- CFrameWnd::OnDestroy();
- /*
- POSITION pos = m_ModelList.GetHeadPosition();
- while( pos != NULL )
- {
- IATLTangramModel* pITangramModel = m_ModelList.GetNext( pos ) ;
- pITangramModel->Release();
- m_ModelList.RemoveHead();
- }
- m_ModelList.RemoveAll();
- if (m_pWorld != NULL)
- {
- m_pWorld->Release() ;
- }
- */
- }