[!if RIBBON_TOOLBAR] // 这段 MFC 示例源代码演示如何使用 MFC Microsoft Office Fluent 用户界面 // (“Fluent UI”)。该示例仅供参考, // 用以补充《Microsoft 基础类参考》和 // MFC C++ 库软件随附的相关电子文档。 // 复制、使用或分发 Fluent UI 的许可条款是单独提供的。 // 若要了解有关 Fluent UI 许可计划的详细信息,请访问 // https://go.microsoft.com/fwlink/?LinkId=238214. // // 版权所有(C) Microsoft Corporation // 保留所有权利。 [!endif] // $docimpl$: $docclass$ 类的实现 // #include "pch.h" #include "framework.h" // SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的 // ATL 项目中进行定义,并允许与该项目共享文档代码。 #ifndef SHARED_HANDLERS #include "$appheader$" #endif [!if OLEDB_RECORD_VIEW || ODBC_RECORD_VIEW] #include "$rowsetheader$" [!endif] #include "$docheader$" [!if CONTAINER || CONTAINER_SERVER] #include "$containeritemheader$" [!endif] [!if MINI_SERVER || FULL_SERVER || CONTAINER_SERVER] #include "$serveritemheader$" [!endif] #include #ifdef _DEBUG #define new DEBUG_NEW #endif // $docclass$ IMPLEMENT_DYNCREATE($docclass$, $docbaseclass$) BEGIN_MESSAGE_MAP($docclass$, $docbaseclass$) [!if CONTAINER || CONTAINER_SERVER] // 启用默认的 OLE 容器实现 [!if !RICH_EDIT_VIEW] ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, &$docbaseclass$::OnUpdatePasteMenu) ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE_LINK, &$docbaseclass$::OnUpdatePasteLinkMenu) ON_UPDATE_COMMAND_UI(ID_OLE_EDIT_CONVERT, &$docbaseclass$::OnUpdateObjectVerbMenu) ON_COMMAND(ID_OLE_EDIT_CONVERT, &$docbaseclass$::OnEditConvert) [!endif] ON_UPDATE_COMMAND_UI(ID_OLE_EDIT_LINKS, &$docbaseclass$::OnUpdateEditLinksMenu) ON_UPDATE_COMMAND_UI(ID_OLE_VERB_POPUP, &$docclass$::OnUpdateObjectVerbPopup) ON_COMMAND(ID_OLE_EDIT_LINKS, &$docbaseclass$::OnEditLinks) ON_UPDATE_COMMAND_UI_RANGE(ID_OLE_VERB_FIRST, ID_OLE_VERB_LAST, &$docbaseclass$::OnUpdateObjectVerbMenu) [!endif] [!if MAPI] ON_COMMAND(ID_FILE_SEND_MAIL, &$docclass$::OnFileSendMail) ON_UPDATE_COMMAND_UI(ID_FILE_SEND_MAIL, &$docclass$::OnUpdateFileSendMail) [!endif] END_MESSAGE_MAP() [!if AUTOMATION] BEGIN_DISPATCH_MAP($docclass$, $docbaseclass$) END_DISPATCH_MAP() // 注意: 我们添加了对 IID_I$safeprojectidentifiername$ 的支持来支持类型安全绑定 // 以支持来自 VBA 的类型安全绑定。 此 IID 必须同附加到 .IDL 文件中的 // 调度接口的 GUID 匹配。 // {$guid_disp_iid$} static const IID IID_I$safeprojectidentifiername$ = $guid_disp_iid_staticconst$; BEGIN_INTERFACE_MAP($docclass$, $docbaseclass$) INTERFACE_PART($docclass$, IID_I$safeprojectidentifiername$, Dispatch) END_INTERFACE_MAP() [!endif] // $docclass$ 构造/析构 $docclass$::$docclass$() noexcept { [!if SUPPORT_COMPOUND_FILES && !COMPOUND_DOC_NONE] // 使用 OLE 复合文件 EnableCompoundFile(); [!endif] // TODO: 在此添加一次性构造代码 [!if AUTOMATION] EnableAutomation(); AfxOleLockApp(); [!endif] } $docclass$::~$docclass$() { [!if AUTOMATION] AfxOleUnlockApp(); [!endif] } BOOL $docclass$::OnNewDocument() { if (!$docbaseclass$::OnNewDocument()) return FALSE; [!if APP_TYPE_SDI] [!if EDIT_VIEW] if (!m_viewList.IsEmpty()) { [!if PROJECT_STYLE_EXPLORER] POSITION pos = GetFirstViewPosition(); GetNextView(pos); // 跳过树视图 reinterpret_cast(GetNextView(pos))->SetWindowText(nullptr); [!else] reinterpret_cast(m_viewList.GetHead())->SetWindowText(nullptr); [!endif] } [!endif] [!endif] // TODO: 在此添加重新初始化代码 // (SDI 文档将重用该文档) return TRUE; } [!if RICH_EDIT_VIEW] $containeritembaseclass$* $docclass$::CreateClientItem(REOBJECT* preo) const { return new $containeritemclass$(preo, const_cast<$docclass$*>(this)); } [!endif] [!if MINI_SERVER || FULL_SERVER || CONTAINER_SERVER] // $docclass$ 服务器实现 COleServerItem* $docclass$::OnGetEmbeddedItem() { // OnGetEmbeddedItem 由框架调用以获取与该文档关联的 COleServerItem。 // 只在必要时才调用它。 $serveritemclass$* pItem = new $serveritemclass$(this); ASSERT_VALID(pItem); return pItem; } [!endif] [!if ACTIVE_DOC_SERVER] // $docclass$ 活动文档服务器实现 CDocObjectServer *$docclass$::GetDocObjectServer(LPOLEDOCUMENTSITE pDocSite) { return new CDocObjectServer(this, pDocSite); } [!endif] [!if !DB_VIEW_NO_FILE && !HTML_EDITVIEW] // $docclass$ 序列化 void $docclass$::Serialize(CArchive& ar) { [!if EDIT_VIEW] // CEditView 包含一个处理所有序列化的编辑控件 if (!m_viewList.IsEmpty()) { [!if PROJECT_STYLE_EXPLORER] POSITION pos = GetFirstViewPosition(); GetNextView(pos); // 跳过树视图 reinterpret_cast(GetNextView(pos))->SerializeRaw(ar); [!else] reinterpret_cast(m_viewList.GetHead())->SerializeRaw(ar); [!endif] } #ifdef SHARED_HANDLERS if (m_viewList.IsEmpty() && ar.IsLoading()) { CFile* pFile = ar.GetFile(); pFile->Seek(0, FILE_BEGIN); ULONGLONG nFileSizeBytes = pFile->GetLength(); ULONGLONG nFileSizeChars = nFileSizeBytes/sizeof(TCHAR); LPTSTR lpszText = (LPTSTR)malloc(((size_t)nFileSizeChars + 1) * sizeof(TCHAR)); if (lpszText != nullptr) { ar.Read(lpszText, (UINT)nFileSizeBytes); lpszText[nFileSizeChars] = '\0'; m_strThumbnailContent = lpszText; m_strSearchContent = lpszText; } } #endif [!else] if (ar.IsStoring()) { // TODO: 在此添加存储代码 } else { // TODO: 在此添加加载代码 } [!if CONTAINER || CONTAINER_SERVER] // 调用基类 $docbaseclass$ 会启用序列化 // 容器文档的 COleClientItem 对象的序列化。 [!if RICH_EDIT_VIEW] // TODO: 如果作为文本进行序列化,则设置 CRichEditDoc::m_bRTF = FALSE [!endif] $docbaseclass$::Serialize(ar); [!if ACTIVE_DOC_CONTAINER] // 激活第一个 if (!ar.IsStoring()) { POSITION posItem = GetStartPosition(); if (posItem != nullptr) { CDocItem* pItem = GetNextItem(posItem); POSITION posView = GetFirstViewPosition(); COleDocObjectItem *pDocObjectItem = DYNAMIC_DOWNCAST(COleDocObjectItem, pItem); if (posView != nullptr && pDocObjectItem != nullptr) { CView* pView = GetNextView(posView); pDocObjectItem->DoVerb(OLEIVERB_SHOW, pView); } } } [!endif] [!endif] [!endif] } [!endif] #ifdef SHARED_HANDLERS // 缩略图的支持 void $docclass$::OnDrawThumbnail(CDC& dc, LPRECT lprcBounds) { // 修改此代码以绘制文档数据 dc.FillSolidRect(lprcBounds, RGB(255, 255, 255)); [!if !EDIT_VIEW] CString strText = _T("TODO: implement thumbnail drawing here"); [!endif] LOGFONT lf; CFont* pDefaultGUIFont = CFont::FromHandle((HFONT) GetStockObject(DEFAULT_GUI_FONT)); pDefaultGUIFont->GetLogFont(&lf); lf.lfHeight = 36; CFont fontDraw; fontDraw.CreateFontIndirect(&lf); CFont* pOldFont = dc.SelectObject(&fontDraw); [!if !EDIT_VIEW] dc.DrawText(strText, lprcBounds, DT_CENTER | DT_WORDBREAK); [!else] dc.DrawText(m_strThumbnailContent, lprcBounds, DT_CENTER | DT_WORDBREAK); [!endif] dc.SelectObject(pOldFont); } // 搜索处理程序的支持 void $docclass$::InitializeSearchContent() { [!if !EDIT_VIEW] CString strSearchContent; [!endif] // 从文档数据设置搜索内容。 // 内容部分应由“;”分隔 [!if !EDIT_VIEW] // 例如: strSearchContent = _T("point;rectangle;circle;ole object;"); SetSearchContent(strSearchContent); [!else] // 使用整个文本文件作为搜索内容。 SetSearchContent(m_strSearchContent); [!endif] } void $docclass$::SetSearchContent(const CString& value) { if (value.IsEmpty()) { RemoveChunk(PKEY_Search_Contents.fmtid, PKEY_Search_Contents.pid); } else { CMFCFilterChunkValueImpl *pChunk = nullptr; ATLTRY(pChunk = new CMFCFilterChunkValueImpl); if (pChunk != nullptr) { pChunk->SetTextValue(PKEY_Search_Contents, value, CHUNK_TEXT); SetChunkValue(pChunk); } } } #endif // SHARED_HANDLERS // $docclass$ 诊断 #ifdef _DEBUG void $docclass$::AssertValid() const { $docbaseclass$::AssertValid(); } void $docclass$::Dump(CDumpContext& dc) const { $docbaseclass$::Dump(dc); } #endif //_DEBUG // $docclass$ 命令