?? ipolylin.cpp
字號:
/*
* IPOLYLIN.CPP
* Polyline Component Chapter 8
*
* Implementation of the IPolyline8 interface that we expose on the
* CPolyline object.
*
* Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
*
* Kraig Brockschmidt, Microsoft
* Internet : kraigb@microsoft.com
* Compuserve: >INTERNET:kraigb@microsoft.com
*/
#include "polyline.h"
/*
* CImpIPolyline:CImpIPolyline
* CImpIPolyline::~CImpIPolyline
*
* Constructor Parameters:
* pObj PCPolyline pointing to the object we live in.
* pUnkOuter LPUNKNOWN of the controlling unknown.
*/
CImpIPolyline::CImpIPolyline(PCPolyline pObj, LPUNKNOWN pUnkOuter)
{
m_cRef=0;
m_pObj=pObj;
m_pUnkOuter=pUnkOuter;
return;
}
CImpIPolyline::~CImpIPolyline(void)
{
return;
}
/*
* CImpIPolyline::QueryInterface
* CImpIPolyline::AddRef
* CImpIPolyline::Release
*/
STDMETHODIMP CImpIPolyline::QueryInterface(REFIID riid, PPVOID ppv)
{
return m_pUnkOuter->QueryInterface(riid, ppv);
}
STDMETHODIMP_(ULONG) CImpIPolyline::AddRef(void)
{
++m_cRef;
return m_pUnkOuter->AddRef();
}
STDMETHODIMP_(ULONG) CImpIPolyline::Release(void)
{
--m_cRef;
return m_pUnkOuter->Release();
}
/*
* CImpIPolyline::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
*
* Return Value:
* HRESULT NOERROR if successful, otherwise E_OUTOFMEMORY
*/
STDMETHODIMP CImpIPolyline::Init(HWND hWndParent, LPRECT pRect
, DWORD dwStyle, UINT uID)
{
SCODE sc;
m_pObj->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_pObj->m_hInst, m_pObj);
sc=(NULL!=m_pObj->m_hWnd) ? S_OK : E_OUTOFMEMORY;
return ResultFromScode(sc);
}
//CHAPTER8MOD
/*
* ReadFromFile and WriteToFile are replaced by the IPersistStorage
* implementation. We no longer read from files, instead we use
* storages.
*/
//End CHAPTER8MOD
/*
* CImpIPolyline::DataSet
*
* Purpose:
* Sets the current data in this Polyline to a given structure.
*
* Parameters:
* pplIn 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:
* HRESULT NOERROR if successful, otherwise a
* POLYLINE_E_ value.
*/
STDMETHODIMP CImpIPolyline::DataSet(PPOLYLINEDATA pplIn
, BOOL fSizeToData, BOOL fNotify)
{
PPOLYLINEDATA ppl=&m_pObj->m_pl;
RECT rc;
/*
* Copy the structure in pplIn 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==pplIn)
return ResultFromScode(POLYLINE_E_INVALIDPOINTER);
*ppl=*pplIn;
//Inform our parent of the data change
if (NULL!=m_pObj->m_pAdv)
{
m_pObj->m_fDirty=TRUE;
m_pObj->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_pObj->m_hWnd, &rc);
pt.x=rc.left;
pt.y=rc.top;
ScreenToClient(GetParent(m_pObj->m_hWnd), &pt);
RECTSTORECT(ppl->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_pObj->m_hWnd, NULL, TRUE);
UpdateWindow(m_pObj->m_hWnd);
}
return NOERROR;
}
/*
* CImpIPolyline::DataGet
*
* Purpose:
* Retrieves the Polyline's current data.
*
* Parameters:
* pplIn PPOLYLINEDATA into which we copy the data.
*
* Return Value:
* HRESULT NOERROR if successful, otherwise a
* POLYLINE_E_ value.
*/
STDMETHODIMP CImpIPolyline::DataGet(PPOLYLINEDATA pplIn)
{
if (NULL==pplIn)
return ResultFromScode(POLYLINE_E_INVALIDPOINTER);
*pplIn=m_pObj->m_pl;
return NOERROR;
}
/*
* CImpIPolyline::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:
* HRESULT NOERROR if successful, otherwise a
* POLYLINE_E_ value.
*/
STDMETHODIMP CImpIPolyline::DataSetMem(HGLOBAL hMem, BOOL fFree
, BOOL fSizeToData, BOOL fNotify)
{
PPOLYLINEDATA ppl;
HRESULT hr=ResultFromScode(POLYLINE_E_INVALIDPOINTER);
if (NULL!=hMem)
{
ppl=(PPOLYLINEDATA)GlobalLock(hMem);
hr=DataSet(ppl, fSizeToData, fNotify);
GlobalUnlock(hMem);
if (fFree)
GlobalFree(hMem);
}
return hr;
}
/*
* CImpIPolyline::DataGetMem
*
* Purpose:
* Retrieves the Polyline's data in a global memory handle.
*
* Parameters:
* phMem HGLOBAL * in which to store the handle.
*
* Return Value:
* HRESULT NOERROR if successful, otherwise a
* POLYLINE_E_ value.
*/
STDMETHODIMP CImpIPolyline::DataGetMem(HGLOBAL *phMem)
{
HGLOBAL hMem;
PPOLYLINEDATA ppl;
HRESULT hr=ResultFromScode(POLYLINE_E_INVALIDPOINTER);
if (NULL==phMem)
return ResultFromScode(POLYLINE_E_INVALIDPOINTER);
hMem=GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, CBPOLYLINEDATA);
if (NULL!=hMem)
{
ppl=(PPOLYLINEDATA)GlobalLock(hMem);
hr=DataGet(ppl);
GlobalUnlock(hMem);
if (FAILED(hr))
{
GlobalFree(hMem);
hMem=NULL;
}
}
*phMem=hMem;
return hr;
}
/*
* CImpIPolyline::RenderBitmap
*
* Purpose:
* Creates a bitmap image of the current Polyline.
*
* Parameters:
* phBmp HBITMAP * in which to return the bitmap.
*
* Return Value:
* HRESULT NOERROR if successful, otherwise a
* POLYLINE_E_ value.
*/
STDMETHODIMP CImpIPolyline::RenderBitmap(HBITMAP *phBmp)
{
HDC hDC;
HDC hMemDC;
HBITMAP hBmp;
RECT rc;
HGDIOBJ hObj;
if (NULL==phBmp)
return ResultFromScode(POLYLINE_E_INVALIDPOINTER);
//Render a bitmap the size of the current rectangle.
hDC=GetDC(m_pObj->m_hWnd);
hMemDC=CreateCompatibleDC(hDC);
GetClientRect(m_pObj->m_hWnd, &rc);
hBmp=CreateCompatibleBitmap(hDC, rc.right, rc.bottom);
if (NULL!=hBmp)
{
//Draw the POLYLINEDATA into the bitmap.
hObj=SelectObject(hMemDC, hBmp);
m_pObj->Draw(hMemDC, FALSE, TRUE);
SelectObject(hMemDC, hObj);
}
DeleteDC(hMemDC);
ReleaseDC(m_pObj->m_hWnd, hDC);
*phBmp=hBmp;
return NOERROR;
}
/*
* CImpIPolyline::RenderMetafile
*
* Purpose:
* Renders the current image of the Polyline into a metafile.
*
* Parameters:
* phMF HMETAFILE * in which to return the
* new metafile.
*
* Return Value:
* HRESULT NOERROR if successful, otherwise a
* POLYLINE_E_ value.
*/
STDMETHODIMP CImpIPolyline::RenderMetafile(HMETAFILE *phMF)
{
HDC hDC;
HMETAFILE hMF;
RECT rc;
if (NULL==phMF)
return ResultFromScode(POLYLINE_E_INVALIDPOINTER);
//Create a memory metafile and return its handle.
hDC=(HDC)CreateMetaFile(NULL);
hMF=NULL;
if (NULL!=hDC)
{
/*
* This is absolutely essential to the metafile so it
* can be scaled in the clipboard and any destination
* application.
*/
SetMapMode(hDC, MM_ANISOTROPIC);
GetClientRect(m_pObj->m_hWnd, &rc);
SetWindowOrgEx(hDC, 0, 0, NULL);
SetWindowExtEx(hDC, rc.right, rc.bottom, NULL);
m_pObj->Draw(hDC, TRUE, TRUE);
hMF=CloseMetaFile(hDC);
}
*phMF=hMF;
return NOERROR;
}
/*
* CImpIPolyline::RenderMetafilePict
*
* Purpose:
* Renders the current Polyline into a METAFILEPICT structure in
* global memory.
*
* Parameters:
* phMem HGLOBAL * in which to return the
* METAFILEPICT.
*
* Return Value:
* HRESULT NOERROR if successful, otherwise a
* POLYLINE_E_ value.
*/
STDMETHODIMP CImpIPolyline::RenderMetafilePict(HGLOBAL *phMem)
{
HGLOBAL hMem;
HMETAFILE hMF;
LPMETAFILEPICT pMF;
RECT rc;
HRESULT hr;
if (NULL==phMem)
return ResultFromScode(POLYLINE_E_INVALIDPOINTER);
//Get the metafile
hr=RenderMetafile(&hMF);
if (FAILED(hr))
return hr;
//Allocate the METAFILEPICT structure.
hMem=GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE
, sizeof(METAFILEPICT));
if (NULL==hMem)
{
DeleteMetaFile(hMF);
return ResultFromScode(E_FAIL);
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -