home *** CD-ROM | disk | FTP | other *** search
- /*
- * AUTOFIG.CPP
- * Cosmo Chapter 14
- *
- * "Figure" object for Cosmo's OLE Automation support, derived
- * from CAutoBase.
- *
- * Copyright (c)1993-1995 Microsoft Corporation, All Right Reserved.
- *
- * Kraig Brockschmidt, Microsoft
- * Internet : kraigb@microsoft.com
- * Compuserve: INTERNET>kraigb@microsoft.com
- */
-
-
- #include "cosmo.h"
-
-
- /*
- * CAutoFigure::CAutoFigure
- * CAutoFigure::~CAutoFigure
- *
- * Constructor Parameters:
- * pDoc PCCosmoDoc to the dpcument object that we
- * use to implement much of this interface.
- */
-
- CAutoFigure::CAutoFigure(PCCosmoDoc pDoc)
- : CAutoBase(pDoc, pDoc->m_hInst, IID_ICosmoFigure
- , DIID_DICosmoFigure, ObjectDestroyed)
- {
- return;
- }
-
-
- /*
- * CAutoFigure::QueryInterface
- * CAutoFigure::AddRef
- * CAutoFigure::Release
- */
-
- STDMETHODIMP CAutoFigure::QueryInterface(REFIID riid, PPVOID ppv)
- {
- *ppv=NULL;
-
- if (IID_IUnknown==riid || IID_ICosmoFigure==riid)
- *ppv=(IUnknown *)this;
-
- if (IID_IDispatch==riid || m_diid==riid)
- *ppv=m_pImpIDispatch;
-
- if (IID_IExternalConnection==riid)
- *ppv=m_pImpIExtConn;
-
- if (NULL!=*ppv)
- {
- ((LPUNKNOWN)*ppv)->AddRef();
- return NOERROR;
- }
-
- return ResultFromScode(E_NOINTERFACE);
- }
-
- STDMETHODIMP_(ULONG) CAutoFigure::AddRef(void)
- {
- return ++m_cRef;
- }
-
- STDMETHODIMP_(ULONG) CAutoFigure::Release(void)
- {
- /*
- * Since this object might have come from a class factory,
- * we count it's existence (see NewFigure below) for
- * controlling shutdown of the application when we call
- * ObjectDestroyed. Otherwise we always close the document.
- */
- if (0L!=--m_cRef)
- return m_cRef;
-
- put_Visible(FALSE);
- SendMessage(m_pDoc->Window(), WM_CLOSE, 0, 0L);
-
- if (NULL!=m_pfnDestroy)
- (*m_pfnDestroy)();
-
- return 0L;
- }
-
-
- /*
- * CAutoFigure::VTableInterface
- *
- * Purpose:
- * Returns the right vtable pointer to use when calling
- * ITypeInfo::Invoke (see CImpIDispatch::Invoke in AUTOBASE.CPP).
- */
- void *CAutoFigure::VTableInterface(void)
- {
- return (ICosmoFigure *)this;
- }
-
-
-
- //All that follows is the ICosmoFigure implementation
-
- /*
- * CAutoFigure::Application
- * CAutoFigure::Parent
- * Properties, read-only
- *
- * The application object (CAutoApp) in which we're contained,
- * which is stored in the frame object
- */
-
- STDMETHODIMP_(IDispatch *) CAutoFigure::get_Application(void)
- {
- PCCosmoFrame pFR;
-
- pFR=(PCCosmoFrame)m_pDoc->m_pFR;
- return pFR->AutoApp()->get_Application();
- }
-
- STDMETHODIMP_(IDispatch *) CAutoFigure::get_Parent(void)
- {
- return get_Application();
- }
-
-
- /*
- * CAutoFigure::FullName, Name, Path
- * Properties, read-only
- *
- * Retrieve the full pathname of the figure file (FullName),
- * just the file name (Name), or just the path (Path).
- *
- * Note that these functions are very similar to the same
- * ones in CAutoApp, and there is probably some code that could
- * be shared between them, but this sample won't bother with
- * such an optimization.
- */
-
- STDMETHODIMP_(BSTR) CAutoFigure::get_FullName(void)
- {
- if ((TCHAR)0==m_pDoc->m_szFile[0])
- return NULL;
-
- #ifdef WIN32ANSI
- OLECHAR szTemp[512];
-
- MultiByteToWideChar(CP_ACP, 0, m_pDoc->m_szFile, -1, szTemp, 512);
- return SysAllocString(szTemp);
- #else
- return SysAllocString(m_pDoc->m_szFile);
- #endif
- }
-
- STDMETHODIMP_(BSTR) CAutoFigure::get_Name(void)
- {
- BSTR bstrFull=NULL;
- BSTR bstrName=NULL;
- const int cch=256;
- TCHAR szName[256];
-
- //Get the full path
- bstrFull=get_FullName();
-
- if (NULL==bstrFull)
- return NULL;
-
- //Now retrieve just the filename
- #ifdef WIN32ANSI
- char szTemp[cch];
- OLECHAR szTempW[cch];
-
- WideCharToMultiByte(CP_ACP, 0, bstrFull, -1, szTemp
- , cch, NULL, NULL);
- if (0==GetFileTitle(szTemp, szName, cch))
- {
- MultiByteToWideChar(CP_ACP, 0, szName, -1, szTempW, cch);
- bstrName=SysAllocString(szTempW);
- }
- #else
- if (0==GetFileTitle(bstrFull, szName, cch))
- bstrName=SysAllocString(szName);
- #endif
-
- SysFreeString(bstrFull);
- return bstrName;
- }
-
- STDMETHODIMP_(BSTR) CAutoFigure::get_Path(void)
- {
- BSTR bstrFull=NULL;
- BSTR bstrName=NULL;
- BSTR bstrPath=NULL;
-
- bstrFull=get_FullName();
-
- if (NULL==bstrFull)
- return NULL;
-
- bstrName=get_Name();
-
- if (NULL!=bstrName)
- {
- LPOLESTR psz;
-
- /*
- * Find the position of bstrName in bstrFull then copy
- * only charaters up to that point into bstrPath.
- */
- #ifdef WIN32ANSI
- psz=wcsstr(bstrFull, bstrName);
- #else
- psz=_tcsstr(bstrFull, bstrName);
- #endif
-
- //The -1 accounts for the \ before the filename
- bstrPath=SysAllocStringLen(bstrFull
- , ((psz-bstrFull)/sizeof(TCHAR))-1);
- SysFreeString(bstrName);
- }
-
- SysFreeString(bstrFull);
- return bstrPath;
- }
-
-
- /*
- * CAutoFigure::Saved
- * Property, read-only
- *
- * TRUE if the document is clean, FALSE otherwise.
- */
-
- STDMETHODIMP_(VARIANT_BOOL) CAutoFigure::get_Saved(void)
- {
- return !m_pDoc->FDirtyGet();
- }
-
-
- /*
- * CAutoFigure::NumberOfPoints
- * Property, read-only
- *
- * Number of points in the current figure.
- */
-
- STDMETHODIMP_(short)CAutoFigure::get_NumberOfPoints(void)
- {
- POLYLINEDATA pl;
-
- m_pDoc->m_pPL->DataGet(&pl, VERSIONCURRENT);
- return pl.cPoints;
- }
-
-
- /*
- * CAutoFigure::BackColor
- * CAutoFigure::LineColor
- * Properties, read-write
- *
- * Colors used in the figure.
- */
-
- STDMETHODIMP_(long) CAutoFigure::get_BackColor(void)
- {
- return m_pDoc->ColorGet(POLYLINECOLOR_BACKGROUND);
- }
-
- STDMETHODIMP_(void) CAutoFigure::put_BackColor(long clrBack)
- {
- m_pDoc->ColorSet(POLYLINECOLOR_BACKGROUND, clrBack);
- return;
- }
-
- STDMETHODIMP_(long) CAutoFigure::get_LineColor(void)
- {
- return m_pDoc->ColorGet(POLYLINECOLOR_LINE);
- }
-
- STDMETHODIMP_(void) CAutoFigure::put_LineColor(long clrLine)
- {
- m_pDoc->ColorSet(POLYLINECOLOR_LINE, clrLine);
- return;
- }
-
-
- /*
- * CAutoFigure::LineStyle
- * Property, read-write
- *
- * Line style used to draw the figure
- */
-
- STDMETHODIMP_(short)CAutoFigure::get_LineStyle(void)
- {
- return m_pDoc->LineStyleGet();
- }
-
- STDMETHODIMP_(void) CAutoFigure::put_LineStyle(short iStyle)
- {
- m_pDoc->LineStyleSet(iStyle);
- return;
- }
-
-
- /*
- * CAutoFigure::Left, Top, Width, Height
- * Properties, read-write
- *
- * Horizontal (Left) and vertical (Top) positions of the frame
- * window from the left and top edges of the application client
- * area; horizontal (Width) and vertical (Height) dimensions of
- * document window. All of these functions call our private member
- * MoveSize, a helper function.
- */
-
- STDMETHODIMP_(long) CAutoFigure::get_Left(void)
- {
- return MoveSize(MOVESIZEACTION_GETLEFT, 0, 0, 0, 0);
- }
-
- STDMETHODIMP_(void) CAutoFigure::put_Left(long x)
- {
- MoveSize(MOVESIZEACTION_LEFT, x, 0, 0, 0);
- return;
- }
-
- STDMETHODIMP_(long) CAutoFigure::get_Top(void)
- {
- return MoveSize(MOVESIZEACTION_GETTOP, 0, 0, 0, 0);
- }
-
- STDMETHODIMP_(void) CAutoFigure::put_Top(long y)
- {
- MoveSize(MOVESIZEACTION_TOP, 0, y, 0, 0);
- return;
- }
-
- STDMETHODIMP_(long) CAutoFigure::get_Width(void)
- {
- return MoveSize(MOVESIZEACTION_GETWIDTH, 0, 0, 0, 0);
- }
-
- STDMETHODIMP_(void) CAutoFigure::put_Width(long cx)
- {
- MoveSize(MOVESIZEACTION_WIDTH, 0, 0, cx, 0);
- return;
- }
-
- STDMETHODIMP_(long) CAutoFigure::get_Height(void)
- {
- return MoveSize(MOVESIZEACTION_GETHEIGHT, 0, 0, 0, 0);
- }
-
- STDMETHODIMP_(void) CAutoFigure::put_Height(long cy)
- {
- MoveSize(MOVESIZEACTION_HEIGHT, 0, 0, 0, cy);
- return;
- }
-
-
-
- /*
- * CAutoFigure::Visible
- * Properties, read-write
- *
- * Controls visibility of the figure window (which is hidden by
- * default when created through automation).
- */
-
- STDMETHODIMP_(VARIANT_BOOL) CAutoFigure::get_Visible(void)
- {
- return (VARIANT_BOOL)IsWindowVisible(m_pDoc->Window());
- }
-
- STDMETHODIMP_(void) CAutoFigure::put_Visible(VARIANT_BOOL fShow)
- {
- ShowWindow(m_pDoc->Window(), fShow ? SW_SHOW : SW_HIDE);
- return;
- }
-
-
- /*
- * CAutoFigure::Activate
- * Method
- *
- * Activate this window, that is, bring it to the foreground
- */
-
- STDMETHODIMP_(void) CAutoFigure::Activate(void)
- {
- HWND hWndDoc;
-
- hWndDoc=m_pDoc->Window();
- SendMessage(GetParent(hWndDoc), WM_MDIACTIVATE
- , (WPARAM)hWndDoc, 0L);
- return;
- }
-
-
-
- /*
- * CAutoFigure::Close
- * Method
- *
- * Closes this document.
- *
- * Parameters (optional)
- * fSaveChanges BOOL that indicates if we're to save
- * changes or not. If not, then we just nuke
- * the figure.
- * bstrPath BSTR with the filename into which to save
- * the figure if fSaveChanges is TRUE. Note that
- * this overrides any other pathname we are
- * already using.
- */
-
- STDMETHODIMP_(void) CAutoFigure::Close(VARIANT varSave
- , VARIANT varPath)
- {
- //If we got varSave and it's TRUE, then save
- if (VT_ERROR!=varSave.vt && varSave.boolVal)
- {
- /*
- * If we got a filename, call SaveAs. Otherwise
- * call Save. If we don't have a filename for
- * Save, then Save just fails and we don't have
- * to care.
- */
- if (VT_ERROR!=varPath.vt)
- SaveAs(varPath.bstrVal);
- else
- Save();
- }
-
- //Hiding the document first suppresses any UI on closure.
- put_Visible(FALSE);
- SendMessage(m_pDoc->Window(), WM_CLOSE, 0, 0L);
- return;
- }
-
-
-
- /*
- * CAutoFigure::RevertToSaved
- * Method
- *
- * Reloads the contents of the document from the saved state.
- */
-
- STDMETHODIMP_(void) CAutoFigure::RevertToSaved(void)
- {
- //Can't do this if we don't have a file
- if ((TCHAR)0==m_pDoc->m_szFile[0])
- return;
-
- /*
- * Since we "open" a document by loading it and closing
- * it, then we can just "re-open" it with Load again.
- */
- m_pDoc->Load(FALSE, m_pDoc->m_szFile);
-
- /*
- * Load set the document as dirt when loading from a file
- * in this manner (the behavior of Import). But this actually
- * makes the file clean, so we change the dirty flag here.
- */
- m_pDoc->FDirtySet(FALSE);
- return;
- }
-
-
-
- /*
- * CAutoFigure::Save
- * Method
- *
- * Saves the document to a known file if one exists.
- */
-
- STDMETHODIMP_(void) CAutoFigure::Save(void)
- {
- if ((TCHAR)0==m_pDoc->m_szFile[0])
- return;
-
- m_pDoc->Save(0, (LPTSTR)NULL);
- return;
- }
-
-
-
- /*
- * CAutoFigure::SaveAs
- * Method
- *
- * Saves the current figure to a new file.
- */
-
- STDMETHODIMP_(void) CAutoFigure::SaveAs(BSTR bstrPath)
- {
- if (NULL==bstrPath)
- return;
-
- //This also renames the document
- #ifdef WIN32ANSI
- char szTemp[512];
-
- WideCharToMultiByte(CP_ACP, 0, bstrPath, -1, szTemp
- , 512, NULL, NULL);
- m_pDoc->Save(0, szTemp);
- #else
- m_pDoc->Save(0, bstrPath);
- #endif
- return;
- }
-
-
-
- /*
- * CAutoFigure::Import
- * Method
- *
- * Initializes the figure from the contents of a file
- */
-
- STDMETHODIMP_(void) CAutoFigure::Import(BSTR bstrImportPath)
- {
- if (NULL==bstrImportPath)
- return;
-
- /*
- * Like we have for RevertToSaved, we can just "open"
- * this file and the new information becomes current.
- */
- #ifdef WIN32ANSI
- char szTemp[512];
-
- WideCharToMultiByte(CP_ACP, 0, bstrImportPath, -1
- , szTemp, 512, NULL, NULL);
- m_pDoc->Load(FALSE, szTemp);
- #else
- m_pDoc->Load(FALSE, bstrImportPath);
- #endif
- return;
- }
-
-
-
- /*
- * CAutoFigure::Copy
- * CAutoFigure::Cut
- * CAutoFigure::Paste
- * Methods
- *
- * Perform clipboard operations
- */
-
- STDMETHODIMP_(void) CAutoFigure::Copy(void)
- {
- m_pDoc->Clip(m_pDoc->m_pFR->Window(), FALSE);
- return;
- }
-
- STDMETHODIMP_(void) CAutoFigure::Cut(void)
- {
- m_pDoc->Clip(m_pDoc->m_pFR->Window(), TRUE);
- return;
- }
-
- STDMETHODIMP_(void) CAutoFigure::Paste(void)
- {
- if (m_pDoc->FQueryPaste())
- m_pDoc->Paste(m_pDoc->m_pFR->Window());
-
- return;
- }
-
-
-
-
- /*
- * CAutoFigure::AddPoint
- * Method
- *
- * Adds a new point, expressed on a 0-32767 scale, to the figure.
- */
-
- STDMETHODIMP_(VARIANT_BOOL) CAutoFigure::AddPoint(short x, short y)
- {
- RECT rc;
- POINTS pt;
- HWND hWndPL;
-
- /*
- * This is the only semi-tricky method to implement here because
- * normally this processing is done inside the Polyline's
- * WM_LBUTTONDOWN. In order to get the same behavior, we'll
- * just send the same message to it. However, we have to
- * convert from a 0-32767 range to a window coordinate range
- * which is nicely handled by CPolyline::PointScale (the only
- * small modification to CPolyline I had to make was to make
- * PointScale public instead of private).
- *
- * This is a non-invasive way to add Automation support.
- * The invasive way would require a change to the CPolyline
- * class and it's window procedure so both this function
- * and the WM_LBUTTONDOWN handling called the same function
- * with 0-32767 scaled points.
- */
-
- //See if we can add any more
- if (CPOLYLINEPOINTS==get_NumberOfPoints())
- return FALSE;
-
- hWndPL=m_pDoc->m_pPL->Window();
- GetClientRect(hWndPL, &rc);
- SETPOINT(pt, x, y);
- m_pDoc->m_pPL->PointScale(&rc, &pt, TRUE);
- SendMessage(hWndPL, WM_LBUTTONDOWN, 0, MAKELPARAM(pt.x, pt.y));
- return TRUE;
- }
-
-
-
- /*
- * CAutoFigure::RemovePoint
- * Method
- *
- * Removes the last point added to a figure
- */
-
- STDMETHODIMP_(void) CAutoFigure::RemovePoint(void)
- {
- m_pDoc->Undo();
- return;
- }
-
-
-
-
- /*
- * CAutoFigure::MoveSize
- *
- * Purpose:
- * Helper function for the Left, Top, Width, and Height properties
- * that centralizes calls to GetWindowRect and SetWindowPos,
- * reducing overall code somewhat.
- *
- * Parameters:
- * iAction MOVESIZEACTION enum value to indicate what
- * type of moving/sizing to perform
- * x, y long position coordinates; x is only meaningful
- * with MOVESIZEACTION_LEFT, y only with _TOP
- * cx, cy long extents; cx is only meaningful
- * with MOVESIZEACTION_WIDTH, cy only with _HEIGHT
- *
- * Return Value:
- * long The current x, y, cx, or cy value depending on
- * iAction being _GETLEFT, _GETTOP, _GETWIDTH, or
- * _GETHEIGHT.
- */
-
- long CAutoFigure::MoveSize(MOVESIZEACTION iAction, long x, long y
- , long cx, long cy)
- {
- RECT rc;
- POINT pt1, pt2;
- long x1, y1, cx1, cy1;
- UINT uFlags;
-
- GetWindowRect(m_pDoc->Window(), &rc);
- SETPOINT(pt1, rc.left, rc.top);
- ScreenToClient(GetParent(m_pDoc->Window()), &pt1);
- SETPOINT(pt2, rc.right, rc.bottom);
- ScreenToClient(GetParent(m_pDoc->Window()), &pt2);
-
- //By default we'll do nothing
- x1=pt1.x;
- y1=pt1.y;
- cx1=pt2.x-pt1.x;
- cy1=pt2.y-pt1.y;
- uFlags=0L;
-
- switch (iAction)
- {
- /*
- * Each individual property modifies the appropriate
- * variable x1, y1, cx1, cy1, as well as uFlags to set
- * up SetWindowPos call.
- */
- case MOVESIZEACTION_LEFT:
- x1=x;
- uFlags=SWP_NOSIZE;
- break;
-
- case MOVESIZEACTION_TOP:
- y1=y;
- uFlags=SWP_NOSIZE;
- break;
-
- case MOVESIZEACTION_WIDTH:
- cx1=cx;
- uFlags=SWP_NOMOVE;
- break;
-
- case MOVESIZEACTION_HEIGHT:
- cy1=cy;
- uFlags=SWP_NOMOVE;
- break;
-
-
- case MOVESIZEACTION_GETLEFT:
- return x1;
-
- case MOVESIZEACTION_GETTOP:
- return y1;
-
- case MOVESIZEACTION_GETWIDTH:
- return cx1;
-
- case MOVESIZEACTION_GETHEIGHT:
- return cy1;
-
- default:
- return 0;
- }
-
- //We only get here on propety changes
- SetWindowPos(m_pDoc->Window(), NULL
- , (int)x1, (int)y1, (int)cx1, (int)cy1
- , SWP_NOZORDER | SWP_NOACTIVATE | uFlags);
-
- //Irrelevant for property changes.
- return 0;
- }
-