Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
249 views
in Technique[技术] by (71.8m points)

c++ - Implement IDispatch Interface for MFC automation

I have a COM project which does not support MFC and needs to communicate with another App through a MFC interface. I cannot use directly in MFC interface with my COM project as it is not an MFC project.

A solution was to create an automation interface for the Of the MFC interface which I would be able to use as a layer through which my COM project can communicate to the MFC project.

As I understood, the automation app will run in a different thread. My COM project will invoke methods from the automation interface to call the MFC interface.

The Automation project and its IDL file were provided to me and provides me with a Pure Dispinterface.

Before integrating the implementation of the IDispatch interface to my COM project I decided to create a new C++ console project in order to focus on simply using the automation interface. Using the documentation provided by microsoft (https://docs.microsoft.com/en-us/previous-versions/windows/desktop/automat/implementing-the-idispatch-interface) I implemented the IDispatch interface as follows:

#include "TTAutomate.h"

HRESULT hresult;
DISPID dispid;
DISPPARAMS dispparamsNoArgs = { NULL, NULL, 0, 0 };
EXCEPINFO excepinfo;
UINT nArgErr;
ClassFromIDL* m_ClassFromIDL;
_DTTAutomateEvents* m_DTTAutomateEvents;
_DTTAutomate* m_DTTAutomate;


hresult = OleInitialize(NULL);

// OLE function CoCreateInstance starts application using GUID.
hresult = CoCreateInstance(CLSID_TTfromIDL, NULL, CLSCTX_INPROC_SERVER, DIID__DTTAutomateEvents, (LPVOID*)m_Automate);


// Call QueryInterface to see if object supports IDispatch.
hresult = m_ClassFromIDL->QueryInterface(DIID__DTTfromIDL, (LPVOID*)pdisp);

// Retrieve the dispatch identifier for the SayHello method.
// Use defaults where possible.
OLECHAR* szMember = "SayHello";
DISPID dispid_Item;
hresult = pdisp->GetIDsOfNames(
    IID_NULL,
    &szFunction,
    1,
    LOCALE_USER_DEFAULT,
    &dispid_Item);

First of all the implementation is a bit different as the one in the documentation because with the line :

hresult = CoCreateInstance(CLSID_Hello, NULL, CLSCTX_SERVER, IID_IUnknown, (void **)&punk);

I would get an error "amp undefined".

With the code above I currently get an error stating a const char * cannot initialize a OLECHAR *.

On my COM project I have a line:

LPOLESTR szFunction = OLESTR("SayHello");

which compiles but the same line on my test project does not work.

Did I miss some includes to add? Did I not create the right kind of test project?

question from:https://stackoverflow.com/questions/65599123/implement-idispatch-interface-for-mfc-automation

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

So I found a way to fix my code so that it compiles but not exactly sure if it is a proper solution:

#include "TTAutomate.h"
#include <string>

HRESULT hresult;
DISPID dispid;
DISPPARAMS dispparamsNoArgs = { NULL, NULL, 0, 0 };
EXCEPINFO excepinfo;
UINT nArgErr;
ClassFromIDL* m_ClassFromIDL;
IDispatch* m_Automate; // fixed


hresult = OleInitialize(NULL);

// OLE function CoCreateInstance starts application using GUID.
hresult = CoCreateInstance(CLSID_TTfromIDL, NULL, CLSCTX_INPROC_SERVER, DIID__DTTAutomateEvents, (void**)&m_Automate); // fixed


// Call QueryInterface to see if object supports IDispatch.
hresult = m_ClassFromIDL->QueryInterface(DIID__DTTfromIDL, (void**)&pdisp); // fixed

// Retrieve the dispatch identifier for the SayHello method.
// Use defaults where possible.

// here I create a wchar_t* variable as LPOESTR is casted from that.
std::string functionName = "SayHello";
int wchars_num = MultiByteToWideChar(CP_UTF8, 0, functionName.c_str(), -1, NULL, 0);
wchar_t* wstr = new wchar_t[wchars_num];

LPOLESTR szMember = wstr;
DISPID dispid_Item;
hresult = pdisp->GetIDsOfNames(
IID_NULL,
&szFunction,
1,
LOCALE_USER_DEFAULT,
&dispid_Item);

I now get a E_NOINTERFACE No such interface supported but it is probably unrelated to this topic.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...