通过全局接口编组 ActiveX Table
Marshalling ActiveX through Global Interface Table
我一直在尝试为跨线程访问进行基本的 ActiveX 组件编组。我通过全局接口 Table (GIT) 来完成。我有一个简单的 MFC 对话框,我向其中添加了任意 AciveX 控件,例如 IDC_PDF。
Inserting activeX control to MFC dialog in C++
之后,我将表示此控件的变量添加到代码中。这有效地向项目添加了 pdf1.h 和 pdf1.cpp。在初始化 OnInitDialog() 中的对话框时,我尝试将接口编组到此 ActiveX 组件,以便可以从另一个线程使用它而不会违反 STA 单元。
bool CLMC_mfcDlg::CreateMarshalledController()
{
::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
CComPtr<IGlobalInterfaceTable> pGIT;
// get pointer to GIT
CoCreateInstance(CLSID_StdGlobalInterfaceTable,
NULL,
CLSCTX_INPROC_SERVER,
IID_IGlobalInterfaceTable,
(void **)&pGIT);
// get IID and IUnknown interface pointer
REFIID iid = Pd_OCX_fControl.GetClsid();
IUnknown* active_x_pointer = Pd_OCX_fControl.GetControlUnknown();
// register interface inside the GIT
if (active_x_pointer != NULL) {
HRESULT hr = pGIT->RegisterInterfaceInGlobal(active_x_pointer, iid, &dwCookie);
if (SUCCEEDED(hr))
{
// OK, wir haben das interface im GIT registriert
assert(dwCookie != 0);
}
else
dwCookie = 0;
//pGIT->Release();
}
else
dwCookie = 0;
active_x_pointer->Release();
return dwCookie!=0;
}
因此 dwCookie 的值被设置为 256,虽然不是 0,但仍然感觉像是一个错误值。
当我尝试从另一个线程获取编组接口时。收到的编组接口是 0x0000。
bool CLMC_mfcDlg::FetchMarshalledController()
{
HRESULT res = ::OleInitialize(NULL);
switch (res)
{
case S_OK:
break;
case OLE_E_WRONGCOMPOBJ:
case RPC_E_CHANGED_MODE:
return false;
}
CComPtr<IGlobalInterfaceTable> pThreadGIT;
CoCreateInstance(CLSID_StdGlobalInterfaceTable,
NULL,
CLSCTX_INPROC_SERVER,
IID_IGlobalInterfaceTable,
(void **)&pThreadGIT);
REFIID iid = Pd_OCX_fControl.GetClsid();
pThreadGIT->GetInterfaceFromGlobal(
dwCookie, iid, (void**)&pMarshalledOCX);
pThreadGIT->RevokeInterfaceFromGlobal(dwCookie);
return pMarshalledOCX != nullptr;
}
我做错了什么?我正在使用标准的 ActiveX,使用标准的编组模式。有人让这个工作吗?
Aurora 是正确的。要获得正确的 IID,您需要使用 oleview.exe 在注册表中找到接口:
您使用该发现在您的代码中定义接口 IID:
static REFIID const intf_id
= { 0x5CD5C9C3, 0x0CD7, 0x453A,{ 0x8D, 0x27, 0xE3, 0xBB, 0x32, 0xB7, 0xEA, 0xFC } };
你得到它的接口指针是这样的:
IUnknown * pUnknown = CBaldorOCXCard.GetControlUnknown();
// get _DMintControllerCtrl interface pointer
void* IMint = NULL;
pUnknown->QueryInterface(intf_id, (void **)&IMint);
现在可以在编组中使用接口指针和 IID。
(关于如何在没有包装器的情况下使用此接口指针的问题 class:)仍在寻找答案)
我一直在尝试为跨线程访问进行基本的 ActiveX 组件编组。我通过全局接口 Table (GIT) 来完成。我有一个简单的 MFC 对话框,我向其中添加了任意 AciveX 控件,例如 IDC_PDF。 Inserting activeX control to MFC dialog in C++
之后,我将表示此控件的变量添加到代码中。这有效地向项目添加了 pdf1.h 和 pdf1.cpp。在初始化 OnInitDialog() 中的对话框时,我尝试将接口编组到此 ActiveX 组件,以便可以从另一个线程使用它而不会违反 STA 单元。
bool CLMC_mfcDlg::CreateMarshalledController()
{
::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
CComPtr<IGlobalInterfaceTable> pGIT;
// get pointer to GIT
CoCreateInstance(CLSID_StdGlobalInterfaceTable,
NULL,
CLSCTX_INPROC_SERVER,
IID_IGlobalInterfaceTable,
(void **)&pGIT);
// get IID and IUnknown interface pointer
REFIID iid = Pd_OCX_fControl.GetClsid();
IUnknown* active_x_pointer = Pd_OCX_fControl.GetControlUnknown();
// register interface inside the GIT
if (active_x_pointer != NULL) {
HRESULT hr = pGIT->RegisterInterfaceInGlobal(active_x_pointer, iid, &dwCookie);
if (SUCCEEDED(hr))
{
// OK, wir haben das interface im GIT registriert
assert(dwCookie != 0);
}
else
dwCookie = 0;
//pGIT->Release();
}
else
dwCookie = 0;
active_x_pointer->Release();
return dwCookie!=0;
}
因此 dwCookie 的值被设置为 256,虽然不是 0,但仍然感觉像是一个错误值。 当我尝试从另一个线程获取编组接口时。收到的编组接口是 0x0000。
bool CLMC_mfcDlg::FetchMarshalledController()
{
HRESULT res = ::OleInitialize(NULL);
switch (res)
{
case S_OK:
break;
case OLE_E_WRONGCOMPOBJ:
case RPC_E_CHANGED_MODE:
return false;
}
CComPtr<IGlobalInterfaceTable> pThreadGIT;
CoCreateInstance(CLSID_StdGlobalInterfaceTable,
NULL,
CLSCTX_INPROC_SERVER,
IID_IGlobalInterfaceTable,
(void **)&pThreadGIT);
REFIID iid = Pd_OCX_fControl.GetClsid();
pThreadGIT->GetInterfaceFromGlobal(
dwCookie, iid, (void**)&pMarshalledOCX);
pThreadGIT->RevokeInterfaceFromGlobal(dwCookie);
return pMarshalledOCX != nullptr;
}
我做错了什么?我正在使用标准的 ActiveX,使用标准的编组模式。有人让这个工作吗?
Aurora 是正确的。要获得正确的 IID,您需要使用 oleview.exe 在注册表中找到接口:
您使用该发现在您的代码中定义接口 IID:
static REFIID const intf_id
= { 0x5CD5C9C3, 0x0CD7, 0x453A,{ 0x8D, 0x27, 0xE3, 0xBB, 0x32, 0xB7, 0xEA, 0xFC } };
你得到它的接口指针是这样的:
IUnknown * pUnknown = CBaldorOCXCard.GetControlUnknown();
// get _DMintControllerCtrl interface pointer
void* IMint = NULL;
pUnknown->QueryInterface(intf_id, (void **)&IMint);
现在可以在编组中使用接口指针和 IID。
(关于如何在没有包装器的情况下使用此接口指针的问题 class:)仍在寻找答案)