WIN32 DLL调用ACTIVEX控件

来源:互联网 发布:python 数据缺失 编辑:程序博客网 时间:2024/05/16 16:00

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;

}

-------------------
1 0
原创粉丝点击