📄 polyline.cpp
字号:
/*
* POLYLINE.CPP
* Cosmo Chapter 23
*
* Implementation of the CPolyline class.
*
* Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
*
* Kraig Brockschmidt, Microsoft
* Internet : kraigb@microsoft.com
* Compuserve: >INTERNET:kraigb@microsoft.com
*/
#include "cosmo.h"
/*
* CPolyline:CPolyline
* CPolyline::~CPolyline
*
* Constructor Parameters:
* hInst HINSTANCE of the application we're in.
*/
CPolyline::CPolyline(HINSTANCE hInst)
: CWindow(hInst)
{
m_pAdv=NULL;
m_hWnd=NULL;
m_fReadFromOLE10=FALSE;
return;
}
CPolyline::~CPolyline(void)
{
return;
}
/*
* CPolyline::Init
*
* Purpose:
* Instantiates a polyline window within a given parent. The
* parent may be a main application window, could be an MDI child
* window. We really do not care.
*
* Parameters:
* hWndParent HWND of the parent of this window
* pRect LPRECT that this window should occupy
* dwStyle DWORD containing the window's style flags
* uID UINT ID to associate with this window
* pAdv PCPolylineAdviseSink of the sink wanting our
* notifications.
*
* Return Value:
* BOOL TRUE if the function succeeded, FALSE otherwise.
*/
BOOL CPolyline::Init(HWND hWndParent, LPRECT pRect, DWORD dwStyle
, UINT uID, PCPolylineAdviseSink pAdv)
{
m_hWnd=CreateWindowEx(WS_EX_NOPARENTNOTIFY, SZCLASSPOLYLINE
, SZCLASSPOLYLINE, dwStyle, pRect->left, pRect->top
, pRect->right-pRect->left, pRect->bottom-pRect->top
, hWndParent, (HMENU)uID, m_hInst, this);
if (NULL!=m_hWnd)
m_pAdv=pAdv;
return (NULL!=m_hWnd);
}
/*
* CPolyline::New
*
* Purpose:
* Cleans out and reinitializes the data to defaults.
*
* Parameters:
* None
*
* Return Value:
* None
*/
void CPolyline::New(void)
{
UINT i;
RECT rc;
m_pl.wVerMaj=VERSIONMAJOR;
m_pl.wVerMin=VERSIONMINOR;
//Our rectangle is the size of our window's client area.
GetClientRect(m_hWnd, &rc);
RECTTORECTS(rc, m_pl.rc);
//Clean out the POLYLINE structure and repaint the window.
for (i=0; i< CPOLYLINEPOINTS; i++)
{
m_pl.rgpt[i].x=0;
m_pl.rgpt[i].y=0;
}
m_pl.cPoints =0;
m_pl.rgbBackground=GetSysColor(COLOR_WINDOW);
m_pl.rgbLine =GetSysColor(COLOR_WINDOWTEXT);
m_pl.iLineStyle =PS_SOLID;
InvalidateRect(m_hWnd, NULL, TRUE);
UpdateWindow(m_hWnd);
//Inform the advise sink of this data change.
if (NULL!=m_pAdv)
m_pAdv->OnDataChange();
return;
}
/*
* CPolyline::Undo
*
* Purpose:
* Reverses previous actions in a Polyline.
*
* Parameters:
* None
*
* Return Value:
* BOOL TRUE if we can Undo more, FALSE otherwise.
*/
BOOL CPolyline::Undo(void)
{
//Decrement the number of active points and repaint.
if (m_pl.cPoints > 0)
{
m_pl.cPoints--;
InvalidateRect(m_hWnd, NULL, TRUE);
UpdateWindow(m_hWnd);
}
if (NULL!=m_pAdv)
m_pAdv->OnPointChange();
//Return if we can undo any more.
return (0!=m_pl.cPoints);
}
/*
* CPolyline::ReadFromStorage
*
* Purpose:
* Loads our data (any known version) from an IStorage returning
* the version number of the data or an error value.
*
* Parameters:
* pIStorage LPSTORAGE from which we'll read.
*
* Return Value:
* LONG Version number or negative POLYLINE_E_* value.
*/
LONG CPolyline::ReadFromStorage(LPSTORAGE pIStorage)
{
LONG lRet;
LPSTREAM pIStream;
HRESULT hr;
if (NULL==pIStorage)
return POLYLINE_E_READFAILURE;
//Open the CONTENTS stream
hr=pIStorage->OpenStream(SZSTREAM, 0, STGM_DIRECT | STGM_READ
| STGM_SHARE_EXCLUSIVE, 0, &pIStream);
if (FAILED(hr))
return POLYLINE_E_READFAILURE;
/*
* Since we had to create ReadFromStream for IPersistStorage,
* use it ourselves.
*/
lRet=ReadFromStream(pIStream);
pIStream->Release();
return lRet;
}
/*
* CPolyline::WriteToStorage
*
* Purpose:
* Ignorantly writes our current data into a storage in a
* particular version.
*
* Parameters:
* pIStorage LPSTORAGE in which to save.
* lVer LONG providing version number Major (HI) and
* Minor (Low)
*
* Return Value:
* LONG A POLYLINE_E_* value.
*/
LONG CPolyline::WriteToStorage(LPSTORAGE pIStorage, LONG lVer)
{
LONG lRet;
LPSTREAM pIStream;
HRESULT hr;
if (NULL==pIStorage)
return POLYLINE_E_READFAILURE;
hr=pIStorage->CreateStream(SZSTREAM, STGM_DIRECT | STGM_CREATE
| STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &pIStream);
if (FAILED(hr))
return POLYLINE_E_WRITEFAILURE;
/*
* Use our function that will save to a stream now that
* we needed it for IPersistStorage.
*/
lRet=WriteToStream(pIStream, lVer);
pIStream->Release();
return lRet;
}
/*
* CPolyline::ReadFromStream
*
* Purpose:
* Loads our data (any known version) from an IStream that we
* do not open nor maintain. This is for the compound document
* object's implementation of IPersistStorage.
*
* Parameters:
* pIStream LPSTREAM from which we'll read.
*
* Return Value:
* LONG Version number or negative POLYLINE_E_* value.
*/
LONG CPolyline::ReadFromStream(LPSTREAM pIStream)
{
POLYLINEDATA pl;
ULONG cb=(ULONG)-1;
ULONG cbExpect=0;
HRESULT hr;
LARGE_INTEGER li;
if (NULL==pIStream)
return POLYLINE_E_READFAILURE;
/*
* If IPersistStorage::Load failed to find CONTENTS but did
* open "\1Ole10Native" then m_fReadFromOLE10 is set. So
* we have to start reading past the leading DWORD.
*/
if (m_fReadFromOLE10)
{
DWORD dw;
/*
* Skip the DWORD length at the beginning of the
* Ole10Native stream.
*/
pIStream->Read(&dw, sizeof(DWORD), &cb);
}
//Read version numbers and seek back to file beginning.
hr=pIStream->Read(&pl, 2*sizeof(WORD), &cb);
//If we read OLE 1, seek back but skip the size header.
LISet32(li, m_fReadFromOLE10 ? sizeof(DWORD) : 0);
pIStream->Seek(li, STREAM_SEEK_SET, NULL);
if (FAILED(hr) || 2*sizeof(WORD)!=cb)
{
pIStream->Release();
return POLYLINE_E_READFAILURE;
}
/*
* For version 2.0, read the entire file. For version 1.0 read
* the file up to CBPOLYLINEDATAVER10. For anything else, give
* an error.
*/
switch (pl.wVerMaj)
{
case VERSIONMAJOR: //2.x
switch (pl.wVerMin)
{
case VERSIONMINOR: //2.0
cbExpect=CBPOLYLINEDATA;
break;
default:
break;
}
break;
case 1: //1.x
switch (pl.wVerMin)
{
case 0: //1.0
cbExpect=CBPOLYLINEDATA10;
break;
default:
break;
}
break;
default:
break;
}
if (0==cbExpect)
return POLYLINE_E_UNSUPPORTEDVERSION;
hr=pIStream->Read(&pl, cbExpect, &cb);
if (cbExpect!=cb)
return POLYLINE_E_READFAILURE;
/*
* If we loaded successfully, make the data current. By using
* DataSet we centralize our version upgrading. We size the
* polyline window to the data AND notify the document so it
* sizes to the polyline.
*/
DataSet(&pl, TRUE, TRUE);
//Return what version we just loaded.
return MAKELONG(pl.wVerMin, pl.wVerMaj);
}
/*
* CPolyline::WriteToStream
*
* Purpose:
* Ignorantly writes our current data into a stream in a
* particular version.
*
* Parameters:
* pIStream LPSTREAM in which to save.
* lVer LONG providing version number Major (HI) and
* Minor (Low)
*
* Return Value:
* LONG A POLYLINE_E_* value.
*/
LONG CPolyline::WriteToStream(LPSTREAM pIStream, LONG lVer)
{
ULONG cb;
ULONG cbExpect=0;
WORD wVerMaj=HIWORD(lVer);
WORD wVerMin=LOWORD(lVer);
POLYLINEDATA pl;
HRESULT hr;
if (NULL==pIStream)
return POLYLINE_E_READFAILURE;
//Get a copy of our data in the version we're going to save.
DataGet(&pl, lVer);
switch (wVerMaj)
{
case VERSIONMAJOR: //2.x
switch (wVerMin)
{
case VERSIONMINOR: //2.0
cbExpect=CBPOLYLINEDATA;
break;
default:
break;
}
break;
case 1: //1.x
switch (wVerMin)
{
case 0: //1.0
cbExpect=CBPOLYLINEDATA10;
break;
default:
break;
}
break;
default:
break;
}
if (0==cbExpect)
return POLYLINE_E_UNSUPPORTEDVERSION;
/*
* If writing to an OLE 1 storage, include the length of
* data as the first DWORD in the stream.
*/
if (m_fReadFromOLE10 && CBPOLYLINEDATA10==cbExpect)
{
hr=pIStream->Write(&cbExpect, sizeof(DWORD), &cb);
if (FAILED(hr) || sizeof(DWORD)!=cb)
return POLYLINE_E_WRITEFAILURE;
}
hr=pIStream->Write(&pl, cbExpect, &cb);
if (FAILED(hr) || cbExpect!=cb)
return POLYLINE_E_WRITEFAILURE;
return POLYLINE_E_NONE;
}
/*
* CPolyline::ReadFromFile
*
* Purpose:
* Loads our data (any known version) from a file handle returning
* the version number of the data or an error value.
*
* Parameters:
* pszFile LPTSTR of the file to open.
*
* Return Value:
* LONG Version number or negative POLYLINE_E_* value.
*/
LONG CPolyline::ReadFromFile(LPTSTR pszFile)
{
OFSTRUCT of;
HFILE hFile;
POLYLINEDATA pl;
UINT cb=(UINT)-1;
UINT cbExpect=0;
if (NULL==pszFile)
return POLYLINE_E_READFAILURE;
//OpenFileW is a member of CPolyline.
hFile=OpenFileW(pszFile, &of, OF_READ);
if (HFILE_ERROR==hFile)
return POLYLINE_E_READFAILURE;
//Read version numbers and seek back to file beginning.
cb=_lread(hFile, &pl, 2*sizeof(WORD));
_llseek(hFile, 0L, 0);
if (2*sizeof(WORD)!=cb)
{
_lclose(hFile);
return POLYLINE_E_READFAILURE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -