com: // MessBox.h : Declaration of the CMessBox#ifndef __MESSBOX_H_ #define __MESSBOX_H_#include "resource.h" // main symbols///////////////////////////////////////////////////////////////////////////// // CMessBox class ATL_NO_VTABLE CMessBox : public CComObjectRootEx<CComSingleThreadModel>, public CComCoClass<CMessBox, &CLSID_MessBox>, public IDispatchImpl<IMessBox, &IID_IMessBox, &LIBID_MESSAGEBOXLib> { public: CMessBox() { }DECLARE_REGISTRY_RESOURCEID(IDR_MESSBOX)DECLARE_PROTECT_FINAL_CONSTRUCT()BEGIN_COM_MAP(CMessBox) COM_INTERFACE_ENTRY(IMessBox) COM_INTERFACE_ENTRY(IDispatch) END_COM_MAP()// IMessBox public: STDMETHOD(MessBox)(); };#endif //__MESSBOX_H_ ***************************************** #include "stdafx.h" #include "resource.h" #include <initguid.h> #include "MessageBox.h" #include "dlldatax.h"#include "MessageBox_i.c" #include "MessBox.h"#ifdef _MERGE_PROXYSTUB extern "C" HINSTANCE hProxyDll; #endifCComModule _Module;BEGIN_OBJECT_MAP(ObjectMap) OBJECT_ENTRY(CLSID_MessBox, CMessBox) END_OBJECT_MAP()class CMessageBoxApp : public CWinApp { public:// Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CMessageBoxApp) public: virtual BOOL InitInstance(); virtual int ExitInstance(); //}}AFX_VIRTUAL //{{AFX_MSG(CMessageBoxApp) // NOTE - the ClassWizard will add and remove member functions here. // DO NOT EDIT what you see in these blocks of generated code ! //}}AFX_MSG DECLARE_MESSAGE_MAP() };BEGIN_MESSAGE_MAP(CMessageBoxApp, CWinApp) //{{AFX_MSG_MAP(CMessageBoxApp) // NOTE - the ClassWizard will add and remove mapping macros here. // DO NOT EDIT what you see in these blocks of generated code! //}}AFX_MSG_MAP END_MESSAGE_MAP()CMessageBoxApp theApp;BOOL CMessageBoxApp::InitInstance() { #ifdef _MERGE_PROXYSTUB hProxyDll = m_hInstance; #endif _Module.Init(ObjectMap, m_hInstance, &LIBID_MESSAGEBOXLib); return CWinApp::InitInstance(); }int CMessageBoxApp::ExitInstance() { _Module.Term(); return CWinApp::ExitInstance(); }///////////////////////////////////////////////////////////////////////////// // Used to determine whether the DLL can be unloaded by OLESTDAPI DllCanUnloadNow(void) { #ifdef _MERGE_PROXYSTUB if (PrxDllCanUnloadNow() != S_OK) return S_FALSE; #endif AFX_MANAGE_STATE(AfxGetStaticModuleState()); return (AfxDllCanUnloadNow()==S_OK && _Module.GetLockCount()==0) ? S_OK : S_FALSE; }///////////////////////////////////////////////////////////////////////////// // Returns a class factory to create an object of the requested typeSTDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) { #ifdef _MERGE_PROXYSTUB if (PrxDllGetClassObject(rclsid, riid, ppv) == S_OK) return S_OK; #endif return _Module.GetClassObject(rclsid, riid, ppv); }///////////////////////////////////////////////////////////////////////////// // DllRegisterServer - Adds entries to the system registrySTDAPI DllRegisterServer(void) { #ifdef _MERGE_PROXYSTUB HRESULT hRes = PrxDllRegisterServer(); if (FAILED(hRes)) return hRes; #endif // registers object, typelib and all interfaces in typelib return _Module.RegisterServer(TRUE); }///////////////////////////////////////////////////////////////////////////// // DllUnregisterServer - Removes entries from the system registrySTDAPI DllUnregisterServer(void) { #ifdef _MERGE_PROXYSTUB PrxDllUnregisterServer(); #endif return _Module.UnregisterServer(TRUE); } **************************************** // MessBox.cpp : Implementation of CMessBox #include "stdafx.h" #include "MessageBox.h" #include "MessBox.h"///////////////////////////////////////////////////////////////////////////// // CMessBox STDMETHODIMP CMessBox::MessBox() { AFX_MANAGE_STATE(AfxGetStaticModuleState()) // TODO: Add your implementation code here MessageBox(NULL,TEXT("com test!"),TEXT("Title"),MB_OK); return S_OK; } ****************************************** // MessageBox.idl : IDL source for MessageBox.dll //// This file will be processed by the MIDL tool to // produce the type library (MessageBox.tlb) and marshalling code.import "oaidl.idl"; import "ocidl.idl"; [ object, uuid(AC9616FE-5678-4A8C-AC30-CA8CFD238444), dual, helpstring("IMessBox Interface"), pointer_default(unique) ] interface IMessBox : IDispatch { [id(1), helpstring("method MessBox")] HRESULT MessBox(); };[ uuid(4C2BB01B-747F-4628-9F45-6A363DE3CB80), version(1.0), helpstring("MessageBox 1.0 Type Library") ] library MESSAGEBOXLib { importlib("stdole32.tlb"); importlib("stdole2.tlb"); [ uuid(EFA6F21E-9AA7-42AB-8E6B-A13CB2F82DE2), helpstring("MessBox Class") ] coclass MessBox { [default] interface IMessBox; }; }; *************************************************
调用代码: // comtestDlg.cpp : implementation file //#include "stdafx.h" #include "comtest.h" #include "comtestDlg.h"#include "MessBox.h" IMessBox * pMB; #define JIF(x) if (FAILED(hr=(x))) \ {return hr;}#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App Aboutclass CAboutDlg : public CDialog { public: CAboutDlg();// Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL// Implementation protected: //{{AFX_MSG(CAboutDlg) //}}AFX_MSG DECLARE_MESSAGE_MAP() };CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT }void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP }BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP END_MESSAGE_MAP()///////////////////////////////////////////////////////////////////////////// // CComtestDlg dialogCComtestDlg::CComtestDlg(CWnd* pParent /*=NULL*/) : CDialog(CComtestDlg::IDD, pParent) { //{{AFX_DATA_INIT(CComtestDlg) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); }void CComtestDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CComtestDlg) // NOTE: the ClassWizard will add DDX and DDV calls here //}}AFX_DATA_MAP }BEGIN_MESSAGE_MAP(CComtestDlg, CDialog) //{{AFX_MSG_MAP(CComtestDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_BUTTON1, OnButton1) //}}AFX_MSG_MAP END_MESSAGE_MAP()///////////////////////////////////////////////////////////////////////////// // CComtestDlg message handlersBOOL CComtestDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control }void CComtestDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } }// If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework.void CComtestDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } }// The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CComtestDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; }void CComtestDlg::OnButton1() { // TODO: Add your control notification handler code here CoInitialize(NULL); JIF(CoCreateInstance(CLSID_MessBox,NULL,CLSCTX_INPROC_SERVER,IID_IMessBox,(void **)&pMB)); pMB->MessBox(); }
错误提示信息: d:\temp\messagebox\comtest\messbox.h(10) : error C2079: 'CMessBox' uses undefined class 'ATL_NO_VTABLE' d:\temp\messagebox\comtest\messbox.h(10) : error C2239: unexpected token ':' following declaration of 'CMessBox' d:\temp\messagebox\comtest\messbox.h(11) : error C2059: syntax error : 'public' D:\temp\MessageBox\comtest\comtestDlg.cpp(9) : error C2143: syntax error : missing ';' before '*' D:\temp\MessageBox\comtest\comtestDlg.cpp(9) : error C2501: 'IMessBox' : missing storage-class or type specifiers D:\temp\MessageBox\comtest\comtestDlg.cpp(9) : error C2501: 'pMB' : missing storage-class or type specifiers D:\temp\MessageBox\comtest\comtestDlg.cpp(182) : error C2065: 'hr' : undeclared identifier D:\temp\MessageBox\comtest\comtestDlg.cpp(182) : error C2065: 'CLSID_MessBox' : undeclared identifier D:\temp\MessageBox\comtest\comtestDlg.cpp(182) : error C2065: 'IID_IMessBox' : undeclared identifier D:\temp\MessageBox\comtest\comtestDlg.cpp(183) : error C2227: left of '->MessBox' must point to class/struct/union Generating Code...
// MessBox.h : Declaration of the CMessBox#ifndef __MESSBOX_H_
#define __MESSBOX_H_#include "resource.h" // main symbols/////////////////////////////////////////////////////////////////////////////
// CMessBox
class ATL_NO_VTABLE CMessBox :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CMessBox, &CLSID_MessBox>,
public IDispatchImpl<IMessBox, &IID_IMessBox, &LIBID_MESSAGEBOXLib>
{
public:
CMessBox()
{
}DECLARE_REGISTRY_RESOURCEID(IDR_MESSBOX)DECLARE_PROTECT_FINAL_CONSTRUCT()BEGIN_COM_MAP(CMessBox)
COM_INTERFACE_ENTRY(IMessBox)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()// IMessBox
public:
STDMETHOD(MessBox)();
};#endif //__MESSBOX_H_
*****************************************
#include "stdafx.h"
#include "resource.h"
#include <initguid.h>
#include "MessageBox.h"
#include "dlldatax.h"#include "MessageBox_i.c"
#include "MessBox.h"#ifdef _MERGE_PROXYSTUB
extern "C" HINSTANCE hProxyDll;
#endifCComModule _Module;BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_MessBox, CMessBox)
END_OBJECT_MAP()class CMessageBoxApp : public CWinApp
{
public:// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMessageBoxApp)
public:
virtual BOOL InitInstance();
virtual int ExitInstance();
//}}AFX_VIRTUAL //{{AFX_MSG(CMessageBoxApp)
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};BEGIN_MESSAGE_MAP(CMessageBoxApp, CWinApp)
//{{AFX_MSG_MAP(CMessageBoxApp)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()CMessageBoxApp theApp;BOOL CMessageBoxApp::InitInstance()
{
#ifdef _MERGE_PROXYSTUB
hProxyDll = m_hInstance;
#endif
_Module.Init(ObjectMap, m_hInstance, &LIBID_MESSAGEBOXLib);
return CWinApp::InitInstance();
}int CMessageBoxApp::ExitInstance()
{
_Module.Term();
return CWinApp::ExitInstance();
}/////////////////////////////////////////////////////////////////////////////
// Used to determine whether the DLL can be unloaded by OLESTDAPI DllCanUnloadNow(void)
{
#ifdef _MERGE_PROXYSTUB
if (PrxDllCanUnloadNow() != S_OK)
return S_FALSE;
#endif
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return (AfxDllCanUnloadNow()==S_OK && _Module.GetLockCount()==0) ? S_OK : S_FALSE;
}/////////////////////////////////////////////////////////////////////////////
// Returns a class factory to create an object of the requested typeSTDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
#ifdef _MERGE_PROXYSTUB
if (PrxDllGetClassObject(rclsid, riid, ppv) == S_OK)
return S_OK;
#endif
return _Module.GetClassObject(rclsid, riid, ppv);
}/////////////////////////////////////////////////////////////////////////////
// DllRegisterServer - Adds entries to the system registrySTDAPI DllRegisterServer(void)
{
#ifdef _MERGE_PROXYSTUB
HRESULT hRes = PrxDllRegisterServer();
if (FAILED(hRes))
return hRes;
#endif
// registers object, typelib and all interfaces in typelib
return _Module.RegisterServer(TRUE);
}/////////////////////////////////////////////////////////////////////////////
// DllUnregisterServer - Removes entries from the system registrySTDAPI DllUnregisterServer(void)
{
#ifdef _MERGE_PROXYSTUB
PrxDllUnregisterServer();
#endif
return _Module.UnregisterServer(TRUE);
}
****************************************
// MessBox.cpp : Implementation of CMessBox
#include "stdafx.h"
#include "MessageBox.h"
#include "MessBox.h"/////////////////////////////////////////////////////////////////////////////
// CMessBox
STDMETHODIMP CMessBox::MessBox()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState()) // TODO: Add your implementation code here
MessageBox(NULL,TEXT("com test!"),TEXT("Title"),MB_OK);
return S_OK;
}
******************************************
// MessageBox.idl : IDL source for MessageBox.dll
//// This file will be processed by the MIDL tool to
// produce the type library (MessageBox.tlb) and marshalling code.import "oaidl.idl";
import "ocidl.idl";
[
object,
uuid(AC9616FE-5678-4A8C-AC30-CA8CFD238444),
dual,
helpstring("IMessBox Interface"),
pointer_default(unique)
]
interface IMessBox : IDispatch
{
[id(1), helpstring("method MessBox")] HRESULT MessBox();
};[
uuid(4C2BB01B-747F-4628-9F45-6A363DE3CB80),
version(1.0),
helpstring("MessageBox 1.0 Type Library")
]
library MESSAGEBOXLib
{
importlib("stdole32.tlb");
importlib("stdole2.tlb"); [
uuid(EFA6F21E-9AA7-42AB-8E6B-A13CB2F82DE2),
helpstring("MessBox Class")
]
coclass MessBox
{
[default] interface IMessBox;
};
};
*************************************************
// comtestDlg.cpp : implementation file
//#include "stdafx.h"
#include "comtest.h"
#include "comtestDlg.h"#include "MessBox.h"
IMessBox * pMB;
#define JIF(x) if (FAILED(hr=(x))) \
{return hr;}#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App Aboutclass CAboutDlg : public CDialog
{
public:
CAboutDlg();// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA // ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
// CComtestDlg dialogCComtestDlg::CComtestDlg(CWnd* pParent /*=NULL*/)
: CDialog(CComtestDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CComtestDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}void CComtestDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CComtestDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}BEGIN_MESSAGE_MAP(CComtestDlg, CDialog)
//{{AFX_MSG_MAP(CComtestDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
// CComtestDlg message handlersBOOL CComtestDlg::OnInitDialog()
{
CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
} // Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}void CComtestDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.void CComtestDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CComtestDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}void CComtestDlg::OnButton1()
{
// TODO: Add your control notification handler code here
CoInitialize(NULL);
JIF(CoCreateInstance(CLSID_MessBox,NULL,CLSCTX_INPROC_SERVER,IID_IMessBox,(void **)&pMB));
pMB->MessBox();
}
d:\temp\messagebox\comtest\messbox.h(10) : error C2079: 'CMessBox' uses undefined class 'ATL_NO_VTABLE'
d:\temp\messagebox\comtest\messbox.h(10) : error C2239: unexpected token ':' following declaration of 'CMessBox'
d:\temp\messagebox\comtest\messbox.h(11) : error C2059: syntax error : 'public'
D:\temp\MessageBox\comtest\comtestDlg.cpp(9) : error C2143: syntax error : missing ';' before '*'
D:\temp\MessageBox\comtest\comtestDlg.cpp(9) : error C2501: 'IMessBox' : missing storage-class or type specifiers
D:\temp\MessageBox\comtest\comtestDlg.cpp(9) : error C2501: 'pMB' : missing storage-class or type specifiers
D:\temp\MessageBox\comtest\comtestDlg.cpp(182) : error C2065: 'hr' : undeclared identifier
D:\temp\MessageBox\comtest\comtestDlg.cpp(182) : error C2065: 'CLSID_MessBox' : undeclared identifier
D:\temp\MessageBox\comtest\comtestDlg.cpp(182) : error C2065: 'IID_IMessBox' : undeclared identifier
D:\temp\MessageBox\comtest\comtestDlg.cpp(183) : error C2227: left of '->MessBox' must point to class/struct/union
Generating Code...