📄 polyline.cpp
字号:
* Ignorantly writes our current data into an opened file in a
* particular version.
*
* Parameters:
* pszFile LPTSTR filename in which to store the data.
* lVer LONG providing version number Major (HI)
* and Minor (Low)
*
* Return Value:
* LONG A POLYLINE_E_* value.
*/
LONG CPolyline::WriteToFile(LPTSTR pszFile, LONG lVer)
{
OFSTRUCT of;
HFILE hFile;
UINT cb;
UINT cbExpect=0;
WORD wVerMaj=HIWORD(lVer);
WORD wVerMin=LOWORD(lVer);
POLYLINEDATA pl;
if (NULL==pszFile)
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;
hFile=OpenFileW(pszFile, &of, OF_CREATE | OF_WRITE);
if (HFILE_ERROR==hFile)
return DOCERR_COULDNOTOPEN;
cb=_lwrite(hFile, (LPCSTR)&pl, cbExpect);
_lclose(hFile);
return (cbExpect==cb) ? POLYLINE_E_NONE
: POLYLINE_E_WRITEFAILURE;
}
/*
* CPolyline::OpenFileW (Private)
*
* Purpose:
* Under Win32, OpenFile does not take Unicode strings. This
* function converts a Unicode string into an ANSI string and
* calls OpenFile. This just maps to OpenFile without Unicode.
*
* Parameters, Return Value:
* Same as OpenFile.
*/
HFILE CPolyline::OpenFileW(LPTSTR pszFile, LPOFSTRUCT pof
, UINT uFlags)
{
#ifdef UNICODE
CHAR szTemp[CCHPATHMAX];
UNICODETOANSI(pszFile, szTemp, CCHPATHMAX);
return OpenFile(szTemp, pof, uFlags);
#else
return OpenFile(pszFile, pof, uFlags);
#endif
}
/*
* CPolyline::DataSet
*
* Purpose:
* Sets the current data in this Polyline to a given structure.
*
* Parameters:
* ppl PPOLYLINEDATA to initialize to.
* fSizeToData BOOL indicating if we're to size to the data or
* scale it.
* fNotify BOOL indicating if we're to send an advise on
* this change.
*
* Return Value:
* LONG A POLYLINE_E_* value.
*/
LONG CPolyline::DataSet(PPOLYLINEDATA ppl, BOOL fSizeToData
, BOOL fNotify)
{
RECTS rcs;
RECT rc;
UINT i;
/*
* Copy the structure in ppl and repaint to reflect the new
* point set. Note that unlike the RectSet message, we do no
* scaling, assuming that the rect in the structure is
* appropriate for the data.
*/
if (NULL==ppl)
return POLYLINE_E_INVALIDPOINTER;
//Preserve the old rectangle
rcs=m_pl.rc;
/*
* For version 2.0 we perform a straight copy. For version
* 1.0 we copy the 1.0 structure and fill in defaults for
* the 2.0 additions.
*/
switch (ppl->wVerMaj)
{
case VERSIONMAJOR: //2.x
switch (ppl->wVerMin)
{
case VERSIONMINOR: //2.0
m_pl=*ppl;
break;
default:
return POLYLINE_E_UNSUPPORTEDVERSION;
}
break;
case 1: //1.x
switch (ppl->wVerMin)
{
case 0: //1.0
*((PPOLYLINEDATA10)&m_pl)=
*((PPOLYLINEDATA10)ppl);
/*
* Update this structure to 2.0. Note that we
* assume whoever loaded us to save the loaded
* version so it can later ask what version
* the user wants to save.
*/
m_pl.wVerMaj=VERSIONMAJOR;
m_pl.wVerMin=VERSIONMINOR;
/*
* Version 1.0 stored rc in parent coordinates.
* We need those now in our client coodinates.
*/
RECTSTORECT(m_pl.rc, rc);
OffsetRect(&rc, -m_pl.rc.left, -m_pl.rc.top);
/*
* 1.0 data had points relative to size of the
* rectangle. We need to scale these to 0-32767
* independent of the rectangle for the version
* upgrade.
*/
for (i=0; i < m_pl.cPoints; i++)
PointScale(&rc, &m_pl.rgpt[i], FALSE);
RECTTORECTS(rc, m_pl.rc);
//New 2.0 features
m_pl.rgbBackground=GetSysColor(COLOR_WINDOW);
m_pl.rgbLine=GetSysColor(COLOR_WINDOWTEXT);
m_pl.iLineStyle=PS_SOLID;
break;
default:
return POLYLINE_E_UNSUPPORTEDVERSION;
}
break;
default:
return POLYLINE_E_UNSUPPORTEDVERSION;
}
//Inform our parent of the data change
if (NULL!=m_pAdv)
m_pAdv->OnDataChange();
/*
* If we're scaling the window to fit the data, then use
* RectSet passing our current rectangle as the new one.
* That makes sure that the data won't change but that the
* window is resized.
*/
if (fSizeToData)
{
POINT pt;
/*
* Get our offset in the parent window so we can RectSet
* to the right place since RectSet expects rectangle in
* parent coordinates and we get it in client coordinates.
*/
GetWindowRect(m_hWnd, &rc);
pt.x=rc.left;
pt.y=rc.top;
ScreenToClient(GetParent(m_hWnd), &pt);
RECTSTORECT(m_pl.rc, rc);
OffsetRect(&rc, pt.x, pt.y);
//This will also cause a repaint.
RectSet(&rc, fNotify);
}
else
{
//Make sure we're updated.
InvalidateRect(m_hWnd, NULL, TRUE);
UpdateWindow(m_hWnd);
}
return POLYLINE_E_NONE;
}
/*
* CPolyline::DataGet
*
* Purpose:
* Retrieves the Polyline's current data.
*
* Parameters:
* ppl PPOLYLINEDATA into which we copy the data.
* lVer LONG version of the data to retrieve. Use
* VERSIONCURRENT to retrieve the most current.
*
* Return Value:
* LONG A POLYLINE_E_* value
*/
LONG CPolyline::DataGet(PPOLYLINEDATA ppl, LONG lVer)
{
UINT i;
RECT rc;
//Retieve the current version
if (lVer==MAKELONG(VERSIONMINOR, VERSIONMAJOR)
|| VERSIONCURRENT==lVer)
{
*ppl=m_pl;
return POLYLINE_E_NONE;
}
//Check for versions we support, 1.x
if (HIWORD(lVer)!=1)
return POLYLINE_E_UNSUPPORTEDVERSION;
if (LOWORD(lVer)==0) //Check for 1.0
{
//Do 2.0 to 1.0 conversion
*((PPOLYLINEDATA10)ppl)=*((PPOLYLINEDATA10)&m_pl);
RECTSTORECT(ppl->rc, rc);
//Get the parent coordinates of our rectangle
if (!IsWindow(m_hWnd))
OffsetRect(&rc, 8, 8); //This is always the offset.
else
RectGet(&rc);
/*
* 1.0 data has points relative to size of the rectangle.
* We need to scale these from 0-32767 so we have the
* right values.
*/
for (i=0; i < ppl->cPoints; i++)
PointScale(&rc, &ppl->rgpt[i], TRUE);
RECTTORECTS(rc, ppl->rc);
//Insure old version numbers.
ppl->wVerMaj=1;
ppl->wVerMin=0;
((PPOLYLINEDATA10)ppl)->fDrawEntire=TRUE;
return POLYLINE_E_NONE;
}
return POLYLINE_E_UNSUPPORTEDVERSION;
}
/*
* CPolyline::DataSetMem
*
* Purpose:
* Sets the Polyline's data using a global memory handle
* instead of a pointer.
*
* Parameters:
* hMem HGLOBAL containing the data.
* fFree BOOL indicating if we're to free the data.
* The memory will be freed regardless of any
* error returned from here.
* fSizeToData BOOL indicating if we're to size to the data
* or scale it.
* fNotify BOOL indicating if we're to send an advise
* on this change.
*
* Return Value:
* LONG A POLYLINE_E_* value.
*/
LONG CPolyline::DataSetMem(HGLOBAL hMem, BOOL fFree
, BOOL fSizeToData, BOOL fNotify)
{
PPOLYLINEDATA ppl;
LONG lRet=POLYLINE_E_INVALIDPOINTER;
if (NULL!=hMem)
{
ppl=(PPOLYLINEDATA)GlobalLock(hMem);
lRet=DataSet(ppl, fSizeToData, fNotify);
GlobalUnlock(hMem);
if (fFree)
GlobalFree(hMem);
}
return lRet;
}
/*
* CPolyline::DataGetMem
*
* Purpose:
* Retrieves the Polyline's data in a global memory handle.
*
* Parameters:
* lVer LONG version of data to retrieve.
* phMem HGLOBAL * in which to store the handle.
*
* Return Value:
* LONG A POLYLINE_E_* value.
*/
LONG CPolyline::DataGetMem(LONG lVer, HGLOBAL *phMem)
{
HGLOBAL hMem;
PPOLYLINEDATA ppl;
LONG lRet;
if (NULL==phMem)
return POLYLINE_E_INVALIDPOINTER;
hMem=GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE
, CBPOLYLINEDATA);
if (NULL!=hMem)
{
ppl=(PPOLYLINEDATA)GlobalLock(hMem);
lRet=DataGet(ppl, lVer);
GlobalUnlock(hMem);
if (POLYLINE_E_NONE!=lRet)
{
GlobalFree(hMem);
hMem=NULL;
}
}
*phMem=hMem;
return lRet;
}
/*
* CPolyline::RectGet
*
* Purpose:
* Returns the rectangle of the Polyline in parent coordinates.
*
* Parameters:
* pRect LPRECT in which to return the rectangle.
*
* Return Value:
* None
*/
void CPolyline::RectGet(LPRECT pRect)
{
RECT rc;
POINT pt;
//Retrieve the size of our rectangle in parent coordinates.
GetWindowRect(m_hWnd, &rc);
pt.x=rc.left;
pt.y=rc.top;
ScreenToClient(GetParent(m_hWnd), &pt);
SetRect(pRect, pt.x, pt.y, pt.x+(rc.right-rc.left)
, pt.y+(rc.bottom-rc.top));
return;
}
/*
* CPolyline::SizeGet
*
* Purpose:
* Retrieves the size of the Polyline in parent coordinates.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -