您的位置:首页 > 编程语言 > C语言/C++

WIN32 DLL调用ACTIVEX控件

2017-04-22 22:30 148 查看

WIN32 DLL调用ACTIVEX控件

前段时间手头上有一个刷脸的项目,需要在WIN32 DLL中调用第三方提供的ACTIVEX控件,同时人脸检测的过程中需要显示视屏流,同时需要响应控件的回调函数,项目过程中遇到许多的问题,项目刚结束终于有时间总结一下了。

一、WIN32 DLL调用ACTIVEX控件
由于第三方提供的ocx控件使用时需要提供窗口句柄,故在创建ocx控件的实例时,首先需要创建一个窗口,同时需要使用CAxWindow来承载ocx控件。

HANDLE g_hInst              = NULL;
HWND g_hMainWindow          = NULL;
_DCieCloudWalkOCX*  IRCameraPtr = NULL;
static CAxWindow WinContainer;

//功能:注册窗口类。
//输入:szClassName : 类名;
//返回:成功,类原子,否则NULL。
ATOM RegisterWndClass(LPSTR szClassName, WNDPROC pProc, HINSTANCE hInst)
{
WNDCLASSEX wc;
ZeroMemory(&wc, sizeof(wc));
wc.cbSize           = sizeof(wc);
wc.style            = 0;
wc.lpfnWndProc      = pProc;
wc.cbClsExtra       = 0;
wc.cbWndExtra       = 0;
wc.hInstance        = hInst;
wc.hIcon            = NULL;
wc.hCursor          = NULL;
wc.hbrBackground    = GetSysColorBrush(COLOR_BACKGROUND);
wc.lpszMenuName     = NULL;
wc.lpszClassName    = szClassName;
wc.hIconSm          = NULL;
return RegisterClassEx(&wc);
}
//事件窗口过程
//功能:处理CLOSE和CANCEL消息,TIMER消息和同步处理消息。
//输入:hwnd : 窗口句柄;
//      uMsg : 窗口消息;
//      wParam, lParam : 消息参数;
//返回:0。
LRESULT CALLBACK SPEventWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
const char *const ThisModule = "SPEventWindowProc";

RECT rc;
GetWindowRect(g_hMainWindow, &rc);
switch(uMsg)
{
case WM_CREATE:
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
break;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

UINT WINAPI CreateCloudWalkWindow()
{
//初始化com组建运行环境
AtlAxWinInit();

LPOLESTR pszName=OLESTR("{bd0f48b3-ec69-4107-af33-107c35d09e2c}");

//注册类
char WindowName[260] = {0};
sprintf(WindowName, "WINDOW-%s", "CLOUDWALK");
ATOM aClass = RegisterWndClass(XFSEVENTWINDOWCLASSNAME, SPEventWindowProc, (HINSTANCE)g_hInst);
if(!aClass)
{
log_write(EVENT_FILE, THIS_FILE, ThisModule, -1, "RegisterWndClass(%s)返回错误码: %u", WindowName, GetLastError());
return 0;
}

//创建窗口,创建一个无标题栏,无系统菜单,无边框的窗口
DWORD dwStyle = WS_OVERLAPPEDWINDOW;
dwStyle = dwStyle &~WS_CAPTION &~WS_SYSMENU &~WS_SIZEBOX;
g_hMainWindow = CreateWindow(XFSEVENTWINDOWCLASSNAME, WindowName,
dwStyle, m_left, m_top, m_width, m_height, NULL, NULL, (HINSTANCE)g_hInst, NULL);
if(!g_hMainWindow)
{
log_write(EVENT_FILE, THIS_FILE, ThisModule, -1, "CreateWindow返回错误码: %u", GetLastError());
return -1;
}

SetWindowLong(g_hMainWindow, GWL_EXSTYLE, GetWindowLong(g_hMainWindow, GWL_EXSTYLE) & ~(WS_EX_WINDOWEDGE | WS_EX_DLGMODALFRAME) & WS_EX_TOPMOST);  //去边框

//窗口置顶
SetWindowPos(g_hMainWindow, HWND_TOPMOST, 0, 0, 600, 400, SWP_NOMOVE | SWP_DRAWFRAME | SWP_NOSIZE);

ShowWindow(g_hMainWindow, SW_HIDE);
UpdateWindow(g_hMainWindow);

RECT rc;
GetWindowRect(g_hMainWindow, &rc);
if(IRCameraPtr == NULL)
{
rc.right = rc.right - rc.left;
rc.bottom = rc.bottom - rc.top;
rc.left = 0;
rc.top = 0;
WinContainer.Create(g_hMainWindow, rc, 0,WS_CHILD |WS_VISIBLE);
WinContainer.CreateControl(pszName);
//查询接口指针
WinContainer.QueryControl(&IRCameraPtr);
if (IRCameraPtr == NULL)
{
log_write(EVENT_FILE, THIS_FILE, ThisModule, -1, "QueryControl返回错误码: %u", GetLastError());
return -1;
}
}

return 0;
}


二、处理第三方ocx控件的回调函数

//创建连接点

HRESULT CIRCamera::CreateConnectPoint()

{

HRESULT hr;

CComQIPtr spContainer(IRCameraPtr);

if( !spContainer )// 组件没有提供连接点功能

{

spContainer.Release();

return S_FALSE;

}

//查找事件连接点
spContainer->FindConnectionPoint(__uuidof(_DCieCloudWalkOCXEvents), &m_spCP);
if( !m_spCP )// 没有找到连接点接口
{
spContainer.Release();
return S_FALSE;
}

hr = m_spCP->Advise( &m_sink, &m_dwCookie);
if (FAILED(hr))// 连接失败
{
spContainer.Release();
return S_FALSE;
}

spContainer.Release();
return S_OK;


}

/*

*函数功能:释放连接点

*返回值 :无

*/

void CIRCamera::ReleaseConnectPoint()

{

if( m_spCP )

{

m_spCP->Unadvise( m_dwCookie );

m_spCP.Release();

}

}

class CSINK : public IDispatch

{

public:

CSINK();

virtual ~CSINK();

public:

// IUnknown

STDMETHOD(QueryInterface)(const struct _GUID &iid,void ** ppv);

ULONG __stdcall AddRef(void);

ULONG __stdcall Release(void);

// IDispatch

STDMETHOD(GetTypeInfoCount)(unsigned int *);

STDMETHOD(GetTypeInfo)(unsigned int,unsigned long,struct ITypeInfo ** );

STDMETHOD(GetIDsOfNames)(const struct _GUID &,unsigned short * ,unsigned int,unsigned long,long );

STDMETHOD(Invoke)(long dispID,const struct _GUID &,unsigned long,unsigned short,struct tagDISPPARAMS * pParams,struct tagVARIANT ,struct tagEXCEPINFO ,unsigned int *);

short WaitForNextEvent(long timeOut, string &strImg);

private:

string m_strResult;

string m_strImg;

HANDLE m_LiveDetEvent;

};

//只需要实现Invoke函数即可

STDMETHODIMP CSINK::Invoke(

long dispID,

const struct _GUID &,

unsigned long,

unsigned short,

struct tagDISPPARAMS * pParams,

struct tagVARIANT *pVarResult,

struct tagEXCEPINFO *,

unsigned int *)

{

const char *ThisModule = “CSINK::Invoke”;

// 只需要实现这个就足够啦

switch(dispID)//根据不同的dispID,完成不同的回调函数

{

case 3:

if (pParams != NULL)

{

SetEvent(m_LiveDetEvent);

tagVARIANT* pvars = pParams->rgvarg;

unsigned int cArgs = pParams->cArgs;

if (cArgs >= 1)

{

_bstr_t Data = _bstr_t(*pvars);

string strRet = (char*)Data;

CJSONHelper cJson;

vectorMapString vtUnPackJSON;

cJson.UnPackObjectData(strRet.c_str(), vtUnPackJSON);

vectorMapString::iterator it = vtUnPackJSON.begin();
for (; it != vtUnPackJSON.end(); it++)
{
if (it->first == "image")
{
m_strImg = it->second;
}
if (it->first == "result")
{
m_strResult = it->second;
}
}
}
}
break;
default:
break;
}
return S_OK;


}

-------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++ activex win32