vs2008中,在OCX控件中应用doc/view基本步骤
?
1、利用向?qū)?chuàng)建一個MFC ActiveX Control控件CMyOCX;
2、在工程中加入ActivDoc頭文件和執(zhí)行文件;
class CActiveXDocTemplate : public CSingleDocTemplate
{
??? enum { IDR_NOTUSED = 0x7FFF };
??? CWnd* m_pParentWnd;
??? CFrameWnd* m_pFrameWnd;
??? CString m_docFile;
?CView*? m_pView;
public:
??? CActiveXDocTemplate(CRuntimeClass* pDocClass,
??????? CRuntimeClass* pFrameClass, CRuntimeClass* pViewClass);
??? CFrameWnd* CreateDocViewFrame(CWnd* pParentWnd);
??? void SaveDocumentFile();
??? virtual CFrameWnd* CreateNewFrame(CDocument* pDoc,
??????? CFrameWnd* pOther);
??? virtual CDocument* OpenDocumentFile(
??????? LPCTSTR lpszPathName, BOOL bVerifyExists = TRUE);
};
/
class CActiveXDocControl : public COleControl
{
??? enum { WM_IDLEUPDATECMDUI = 0x0363 };
??? static BOOL m_bDocInitialized;
??? CActiveXDocTemplate* m_pDocTemplate;
??? CFrameWnd* m_pFrameWnd;
??? DECLARE_DYNAMIC(CActiveXDocControl)
protected:
??? void AddDocTemplate(CActiveXDocTemplate* pDocTemplate);
??? CDocTemplate* GetDocTemplate() { return m_pDocTemplate; }
??? //{{AFX_MSG(CActiveXDocControl)
??? afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
??? afx_msg void OnSize(UINT nType, int cx, int cy);
??? afx_msg void OnTimer(UINT nIDEvent);
??? afx_msg void OnDestroy();
??? //}}AFX_MSG
??? //{{AFX_DISPATCH(CActiveXDocControl)
??? //}}AFX_DISPATCH
??? //{{AFX_EVENT(CActiveXDocControl)
??? //}}AFX_EVENT
??? DECLARE_MESSAGE_MAP()
??? DECLARE_DISPATCH_MAP()
??? DECLARE_EVENT_MAP()
public:
?CFrameWnd* GetFrameWnd();
??? CActiveXDocControl();
??? virtual ~CActiveXDocControl();
??? enum {
??? //{{AFX_DISP_ID(CActiveXDocControl)
??? //}}AFX_DISP_ID
??? };
};
///
// ActivDoc.cpp : implementation file
//
#include "stdafx.h"
#include "ActivDoc.h"
CActiveXDocTemplate::CActiveXDocTemplate(CRuntimeClass* pDocClass,
??? CRuntimeClass* pFrameClass, CRuntimeClass* pViewClass)
??????? : CSingleDocTemplate(IDR_NOTUSED, pDocClass, pFrameClass,
??????????? pViewClass)
{
??? ASSERT(pFrameClass);
?m_pView = (CView*)pViewClass;
}
CFrameWnd* CActiveXDocTemplate::CreateDocViewFrame(CWnd* pParentWnd)
{
??? ASSERT(pParentWnd && IsWindow(*pParentWnd));
??? ASSERT_KINDOF(CActiveXDocControl, pParentWnd);
??? m_pParentWnd = pParentWnd;
??? m_pFrameWnd = NULL;
??? // OpenDocumentFile is a virtual method (implemented in
??? // the CSingleDocTemplate base class) that creates
??? // the document (either empty or loaded from the specified
??? // file) and calls our CreateNewFrame function. Passing
??? // NULL to the function creates a new document. Incidentally,
??? // the view is created by the CFrameWnd's OnCreateClient()
??? // method.
??? if (!OpenDocumentFile(NULL))
??????? return NULL;
??? // Since OpenDocumentFile sets m_pFrame, we can now use it.
??? ASSERT(m_pFrameWnd);
??? ASSERT_KINDOF(CFrameWnd, m_pFrameWnd);
??? m_pFrameWnd->ShowWindow(SW_SHOWNORMAL);
??? return m_pFrameWnd;
}
CFrameWnd* CActiveXDocTemplate::CreateNewFrame(CDocument* pDoc,
??????? CFrameWnd* pOther)
{
??? ASSERT(pOther == NULL);
??? ASSERT(m_pFrameClass != NULL);
??? if (pDoc != NULL)
??????? ASSERT_VALID(pDoc);
??? // Create a frame wired to the specified document
??? CCreateContext context;
??? context.m_pCurrentFrame = pOther;
??? context.m_pCurrentDoc = pDoc;
??? context.m_pNewViewClass = m_pViewClass;
??? context.m_pNewDocTemplate = this;
??? m_pFrameWnd = (CFrameWnd*)m_pFrameClass->CreateObject();
??? if (m_pFrameWnd == NULL)
??? {
??????? TRACE1("Warning: Dynamic create of frame %hs failed.\n",
??????????? m_pFrameClass->m_lpszClassName);
??????? return NULL;
??? }
??? ASSERT_KINDOF(CFrameWnd, m_pFrameWnd);
??? if (context.m_pNewViewClass == NULL)
??????? TRACE0("Warning: creating frame with no default view.\n");
??? // The frame is created as a menu-less child of the
??? // CActiveXDocControl in which it will reside.
??? ASSERT_KINDOF(CActiveXDocControl, m_pParentWnd);
??? if (!m_pFrameWnd->Create(NULL, "", WS_CHILD|WS_VISIBLE,
??????? CFrameWnd::rectDefault, m_pParentWnd, NULL, 0, &context))
??? {
??????? TRACE0("Warning: CDocTemplate couldn't create a frame.\n");
??????? return NULL;
??? }
??? return m_pFrameWnd;
}
CDocument* CActiveXDocTemplate::OpenDocumentFile(
??? LPCTSTR lpszPathName, BOOL bVerifyExists)
{
??? SaveDocumentFile();
??? m_docFile = lpszPathName;
??? if (bVerifyExists)
??? {
??????? DWORD dwAttrib = GetFileAttributes(m_docFile);
??????? if (dwAttrib == 0xFFFFFFFF ||
??????????? dwAttrib == FILE_ATTRIBUTE_DIRECTORY)
??????? {
??????????? lpszPathName = NULL;
??????? }
??? }
??? return CSingleDocTemplate::OpenDocumentFile(
??????? lpszPathName, TRUE);
}
void CActiveXDocTemplate::SaveDocumentFile()
{
??? if (m_pOnlyDoc != NULL)
??? {
??????? if (!m_docFile.IsEmpty())
??????????? m_pOnlyDoc->OnSaveDocument(m_docFile);
??????? else
??????????? m_pOnlyDoc->SetModifiedFlag(FALSE);
??? }
}
/
// CActiveXDocControl
IMPLEMENT_DYNAMIC(CActiveXDocControl, COleControl)
BEGIN_MESSAGE_MAP(CActiveXDocControl, COleControl)
??? //{{AFX_MSG_MAP(CActiveXDocControl)
??? ON_WM_CREATE()
??? ON_WM_SIZE()
??? ON_WM_TIMER()
??? ON_WM_DESTROY()
??? //}}AFX_MSG_MAP
??? ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
END_MESSAGE_MAP()
BEGIN_DISPATCH_MAP(CActiveXDocControl, COleControl)
??? //{{AFX_DISPATCH_MAP(CActiveXDocControl)
??? //}}AFX_DISPATCH_MAP
END_DISPATCH_MAP()
BEGIN_EVENT_MAP(CActiveXDocControl, COleControl)
??? //{{AFX_EVENT_MAP(COleFrameCtrl)
??? //}}AFX_EVENT_MAP
END_EVENT_MAP()
int CActiveXDocControl::m_bDocInitialized = FALSE;
CActiveXDocControl::CActiveXDocControl()
{
??? m_pDocTemplate = NULL;
??? m_pFrameWnd = NULL;
??? // Since we're in an OCX, CWinApp::InitApplication() is
??? // not called by the framework. Unfortunately, that method
??? // performs CDocManager initialization that is necessary
??? // in order for our DocTemplate to clean up after itself.
??? // We simulate the same initialization by calling the
??? // following code the first time we create a control.
??? if (!m_bDocInitialized)
??? {
??????? CDocManager docManager;
??????? docManager.AddDocTemplate(NULL);
??????? m_bDocInitialized = TRUE;
??? }
}
CActiveXDocControl::~CActiveXDocControl()
{
??? // Note that the frame, the document, and the view are
??? // all deleted automatically by the framework!
???
??? delete m_pDocTemplate;
}
void CActiveXDocControl::AddDocTemplate(CActiveXDocTemplate* pDocTemplate)
{
??? // I've decided to call this function AddDocTemplate to
??? // be consistent with naming of CWinApp::AddDocTemplate.
??? // However, only one DocTemplate is allowed per control.
???
??? ASSERT(pDocTemplate);
??? ASSERT(m_pDocTemplate == NULL);
??? m_pDocTemplate = pDocTemplate;
}
int CActiveXDocControl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
??? if (COleControl::OnCreate(lpCreateStruct) == -1)
??????? return -1;
??? // The CActiveXDocTemplate object will create the
??? // document, the view, and the frame inside the
??? // control. The reason we need a handle to the frame
??? // is so that we can resize it when the control is
??? // resized.
???
??? ASSERT(m_pDocTemplate);??? // Set in call to AddDocTemplate
??? m_pFrameWnd = m_pDocTemplate->CreateDocViewFrame(this);
??? ASSERT_KINDOF(CFrameWnd, m_pFrameWnd);
??? // By default, we'll create the control with a border,
??? // since it looks better for frames containing a toolbar.
??? SetBorderStyle(TRUE);
??? SetTimer(WM_IDLEUPDATECMDUI, 300, NULL);
??? return 0;
}
void CActiveXDocControl::OnSize(UINT nType, int cx, int cy)
{
??? COleControl::OnSize(nType, cx, cy);
??? // The CFrameWnd should always fill up the entire client
??? // area of the control.
??? if (m_pFrameWnd != NULL)
??? {
??????? ASSERT(IsWindow(*m_pFrameWnd));
??????? CRect area;
??????? GetClientRect(area);
??????? m_pFrameWnd->MoveWindow(area.left, area.top, area.right,
??????????? area.bottom);
??? }
}
void CActiveXDocControl::OnTimer(UINT nIDEvent)
{
??? // Since we're in an OCX, we don't control the message loop,
??? // so CWinThread::OnIdle is never called. That means we have
??? // to periodically pump the ON_UPDATE_COMMAND_UI messages
??? // by hand.
???
??? SendMessageToDescendants(WM_IDLEUPDATECMDUI, TRUE);
??? COleControl::OnTimer(nIDEvent);
}
void CActiveXDocControl::OnDestroy()
{
??? AfxGetApp()->m_pMainWnd = NULL;
??? m_pDocTemplate->SaveDocumentFile();
??? COleControl::OnDestroy();
}
CFrameWnd* CActiveXDocControl::GetFrameWnd()
{
?return m_pFrameWnd;
}
3、在CMyOCX頭文件中包含#include "ActivDoc.h";
4、將CMyOCX頭文件和執(zhí)行文件中的COleControl全部用CActiveXDocControl替換;
5、添加CMyView、CMyDocument、CMyFrame三個類,它們分別繼承于CView、CDocument、CFrameWnd,在它們的頭文件中分別將它們
的構(gòu)造函數(shù)和析構(gòu)函數(shù)有protected該成public;
6、在CMyOCX執(zhí)行文件中包含#include "MyDocument.h"? #include "MyView.h"?? #include "MyFrame.h";
7、在CMyOCX執(zhí)行文件中的構(gòu)造函數(shù)中添加語句:
?AddDocTemplate(new CActiveXDocTemplate(
??RUNTIME_CLASS(CMyDocument),
??RUNTIME_CLASS(CMyFrame),
??RUNTIME_CLASS(CMyView)));
基本模型形成,然后就可以按照自己的需要向里面添加?xùn)|西了。
總結(jié)
以上是生活随笔為你收集整理的vs2008中,在OCX控件中应用doc/view基本步骤的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在对话框中应用CScrollView显示
- 下一篇: C#命名空间