📄 ex27cdoc.cpp
字号:
}
STDMETHODIMP CEx27cDoc::XDataObject::EnumFormatEtc(DWORD dwDirection,
LPENUMFORMATETC* ppenumFormatEtc)
{
TRACE("CEx27cDoc::XDataObject::EnumFormatEtc\n");
METHOD_PROLOGUE(CEx27cDoc, DataObject)
ASSERT_VALID(pThis);
return E_NOTIMPL;
}
STDMETHODIMP CEx27cDoc::XDataObject::DAdvise(FORMATETC* pFormatEtc,
DWORD advf, LPADVISESINK pAdvSink, DWORD* pdwConnection)
{
TRACE("CEx27cDoc::XDataObject::DAdvise\n");
METHOD_PROLOGUE(CEx27cDoc, DataObject)
ASSERT_VALID(pThis);
*pdwConnection = 555;
// create the advise holder, if necessary
if (pThis->m_lpDataAdviseHolder == NULL &&
CreateDataAdviseHolder(&pThis->m_lpDataAdviseHolder) != S_OK) {
return E_OUTOFMEMORY;
}
ASSERT(pThis->m_lpDataAdviseHolder != NULL);
HRESULT hr = pThis->m_lpDataAdviseHolder->Advise(this, pFormatEtc, advf,
pAdvSink, pdwConnection);
return hr;
}
STDMETHODIMP CEx27cDoc::XDataObject::DUnadvise(DWORD dwConnection)
{
TRACE("CEx27cDoc::XDataObject::DUnadvise\n");
METHOD_PROLOGUE(CEx27cDoc, DataObject)
ASSERT_VALID(pThis);
return E_NOTIMPL;
}
STDMETHODIMP CEx27cDoc::XDataObject::EnumDAdvise(
LPENUMSTATDATA* ppenumAdvise)
{
TRACE("CEx27cDoc::XDataObject::EnumDAdvise\n");
METHOD_PROLOGUE(CEx27cDoc, DataObject)
ASSERT_VALID(pThis);
return E_NOTIMPL;
}
/////////////////////////////////////////////////////////////
STDMETHODIMP_(ULONG) CEx27cDoc::XPersistStorage::AddRef()
{
TRACE("CEx27cDoc::XPersistStorage:::AddRef\n");
METHOD_PROLOGUE(CEx27cDoc, PersistStorage)
return pThis->InternalAddRef();
}
STDMETHODIMP_(ULONG) CEx27cDoc::XPersistStorage::Release()
{
TRACE("CEx27cDoc::XPersistStorage::Release\n");
METHOD_PROLOGUE(CEx27cDoc, PersistStorage)
return pThis->InternalRelease();
}
STDMETHODIMP CEx27cDoc::XPersistStorage::QueryInterface(
REFIID iid, LPVOID* ppvObj)
{
ITrace(iid, "CEx27cDoc::XPersistStorage::QueryInterface");
METHOD_PROLOGUE(CEx27cDoc, PersistStorage)
return pThis->InternalQueryInterface(&iid, ppvObj);
}
STDMETHODIMP CEx27cDoc::XPersistStorage::GetClassID(LPCLSID lpClassID)
{
TRACE("CEx27cDoc::XPersistStorage::GetClassID\n");
METHOD_PROLOGUE(CEx27cDoc, PersistStorage)
ASSERT_VALID(pThis);
*lpClassID = clsid;
return NOERROR;
}
STDMETHODIMP CEx27cDoc::XPersistStorage::IsDirty()
{
TRACE("CEx27cDoc::XPersistStorage::IsDirty\n");
METHOD_PROLOGUE(CEx27cDoc, PersistStorage)
ASSERT_VALID(pThis);
return pThis->IsModified() ? NOERROR : S_FALSE;
}
STDMETHODIMP CEx27cDoc::XPersistStorage::InitNew(LPSTORAGE pStg)
{
TRACE("CEx27cDoc::XPersistStorage::InitNew\n");
METHOD_PROLOGUE(CEx27cDoc, PersistStorage)
ASSERT_VALID(pThis);
ASSERT(pStg != NULL);
pThis->SetModifiedFlag(); // new storage-based documents are dirty!
pThis->SendInitialUpdate(); // in CDocument
return NOERROR;
}
STDMETHODIMP CEx27cDoc::XPersistStorage::Load(LPSTORAGE pStgLoad)
{
TRACE("CEx27cDoc::XPersistStorage::Load\n");
METHOD_PROLOGUE(CEx27cDoc, PersistStorage)
ASSERT_VALID(pThis);
ASSERT(pStgLoad != NULL);
LPSTREAM pStream;
ULONG nBytesRead;
char buffer[101]; // 100 characters max for m_strText
try {
pThis->DeleteContents();
if(pStgLoad->OpenStream(L"Ex27c Text", NULL,
STGM_READ|STGM_SHARE_EXCLUSIVE,
0, &pStream) == NOERROR) {
pStream->Read(buffer, 100, &nBytesRead);
pStream->Release();
pThis->m_strText = buffer;
}
}
catch(CException* pe) {
pe->Delete();
return E_FAIL;
}
pThis->SetModifiedFlag(); // new storage-based documents are dirty!
pThis->SendInitialUpdate(); // in CDocument
return NOERROR;
}
STDMETHODIMP CEx27cDoc::XPersistStorage::Save(LPSTORAGE pStgSave,
BOOL fSameAsLoad)
{
TRACE("CEx27cDoc::XPersistStorage::Save\n");
METHOD_PROLOGUE(CEx27cDoc, PersistStorage)
ASSERT_VALID(pThis);
// don't bother saving if destination is up-to-date
if (fSameAsLoad && !pThis->IsModified())
return NOERROR;
ASSERT(pStgSave != NULL);
LPSTREAM pStream;
ULONG nBytesWritten;
try {
if(pStgSave->CreateStream(L"Ex27c Text",
STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE,
0, 0, &pStream) == NOERROR) {
pStream->Write((const char*) pThis->m_strText,
pThis->m_strText.GetLength() + 1, &nBytesWritten);
pStream->Release();
}
else return E_FAIL;
}
catch(CException* pe) {
pe->Delete();
return E_FAIL;
}
pThis->SetModifiedFlag(); // new storage-based documents are dirty!
pThis->SendInitialUpdate(); // in CDocument
return NOERROR;
}
STDMETHODIMP CEx27cDoc::XPersistStorage::SaveCompleted(LPSTORAGE pStgSaved)
{
TRACE("CEx27cDoc::XPersistStorage::SaveCompleted\n");
METHOD_PROLOGUE(CEx27cDoc, PersistStorage)
ASSERT_VALID(pThis);
return E_NOTIMPL;
}
STDMETHODIMP CEx27cDoc::XPersistStorage::HandsOffStorage()
{
TRACE("CEx27cDoc::XPersistStorage::HandsOffStorage\n");
METHOD_PROLOGUE(CEx27cDoc, PersistStorage)
ASSERT_VALID(pThis);
return E_NOTIMPL;
}
/////////////////////////////////////////////////////////////////////////////
// CEx27cDoc construction/destruction
CEx27cDoc::CEx27cDoc()
{
// TODO: add one-time construction code here
TRACE("CEx27cDoc ctor\n");
m_lpClientSite = NULL;
m_lpOleAdviseHolder = NULL;
m_lpDataAdviseHolder = NULL;
}
CEx27cDoc::~CEx27cDoc()
{
TRACE("CEx27cDoc dtor\n");
}
BOOL CEx27cDoc::OnNewDocument()
{
TRACE("CEx27cDoc::OnNewDocument\n");
if (!CDocument::OnNewDocument())
return FALSE;
m_strText = "Default text";
return TRUE;
}
HGLOBAL CEx27cDoc::MakeMetaFile()
{
HGLOBAL hPict;
CMetaFileDC dcm;
VERIFY(dcm.Create());
CSize size(5000, 5000); // initial size of object in Excel & Word
dcm.SetMapMode(MM_ANISOTROPIC);
dcm.SetWindowOrg(0,0);
dcm.SetWindowExt(size.cx, -size.cy);
// drawing code
dcm.Rectangle(CRect(500, -1000, 1500, -2000));
CFont font;
font.CreateFont(-500, 0, 0, 0, 400, FALSE, FALSE, 0,
ANSI_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH | FF_SWISS, "Arial");
CFont* pFont = dcm.SelectObject(&font);
dcm.TextOut(0, 0, m_strText);
dcm.SelectObject(pFont);
HMETAFILE hMF = dcm.Close();
ASSERT(hMF != NULL);
hPict = ::GlobalAlloc(GMEM_SHARE|GMEM_MOVEABLE, sizeof(METAFILEPICT));
ASSERT(hPict != NULL);
LPMETAFILEPICT lpPict;
lpPict = (LPMETAFILEPICT) ::GlobalLock(hPict);
ASSERT(lpPict != NULL);
lpPict->mm = MM_ANISOTROPIC;
lpPict->hMF = hMF;
lpPict->xExt = size.cx;
lpPict->yExt = size.cy; // HIMETRIC height
::GlobalUnlock(hPict);
return hPict;
}
/////////////////////////////////////////////////////////////////////////////
// CEx27cDoc serialization
void CEx27cDoc::Serialize(CArchive& ar)
{
// not needed by OLE
if (ar.IsStoring())
{
// TODO: add storing code here
}
else
{
// TODO: add loading code here
}
}
/////////////////////////////////////////////////////////////////////////////
// CEx27cDoc diagnostics
#ifdef _DEBUG
void CEx27cDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CEx27cDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
// global diagnostic function
void ITrace(REFIID iid, const char* str)
{
LPOLESTR lpszIID;
::StringFromIID(iid, &lpszIID);
CString strIID = lpszIID;
TRACE("%s - %s\n", (const char*) strIID, (const char*) str);
AfxFreeTaskMem(lpszIID);
}
/////////////////////////////////////////////////////////////////////////////
// CEx27cDoc commands
void CEx27cDoc::OnFinalRelease()
{
TRACE("CEx27cDoc::OnFinalRelease\n"); // so we can see it happen
CDocument::OnFinalRelease();
}
void CEx27cDoc::OnCloseDocument()
{
InternalAddRef();
if(m_lpClientSite != NULL) {
m_lpClientSite->OnShowWindow(FALSE); // no hatch
m_lpClientSite->Release();
}
if (m_lpOleAdviseHolder != NULL)
m_lpOleAdviseHolder->SendOnClose(); // you need to send a close notification
// finish closing the document (before m_lpClientSite->Release)
BOOL bAutoDelete = m_bAutoDelete;
m_bAutoDelete = FALSE;
CDocument::OnCloseDocument();
// disconnect the object
LPUNKNOWN lpUnknown = (LPUNKNOWN)GetInterface(&IID_IUnknown);
ASSERT(lpUnknown != NULL);
CoDisconnectObject(lpUnknown, 0); // this is very important to close circular references
if(m_lpOleAdviseHolder != NULL)
m_lpOleAdviseHolder->Release();
if(m_lpDataAdviseHolder != NULL)
m_lpDataAdviseHolder->Release();
m_lpClientSite = NULL;
m_lpOleAdviseHolder = NULL;
m_lpDataAdviseHolder = NULL;
InterlockedDecrement(&m_dwRef); // remove InternalAddRef above
if (bAutoDelete) {
delete this;
}
}
void CEx27cDoc::OnModify()
{
CTextDialog dlg;
dlg.m_strText = m_strText;
if(dlg.DoModal() == IDOK) {
m_strText = dlg.m_strText;
UpdateAllViews(NULL); // redraw view
// Notify the client that the metafile has changed.
// Client must call IViewObject::SetAdvise.
LPDATAOBJECT lpDataObject =
(LPDATAOBJECT) GetInterface(&IID_IDataObject);
HRESULT hr =
m_lpDataAdviseHolder->SendOnDataChange(lpDataObject, 0, NULL);
ASSERT(hr == NOERROR);
SetModifiedFlag(); // won't update without this
}
}
void CEx27cDoc::OnFileUpdate()
{
if(m_lpClientSite == NULL) return;
VERIFY(m_lpClientSite->SaveObject() == NOERROR);
if (m_lpOleAdviseHolder != NULL)
m_lpOleAdviseHolder->SendOnSave();
SetModifiedFlag(FALSE);
}
void CEx27cDoc::OnUpdateFileUpdate(CCmdUI* pCmdUI)
{
pCmdUI->Enable(IsModified());
}
BOOL CEx27cDoc::SaveModified()
{
OnFileUpdate();
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -