none
.Net C# 如何像C++那样从未注册的dll中实例化出ActiveX控件的对象并添加到Window.Form中,C++代码见正文 RRS feed

  • 问题

  •                     #import "../Bin/APlayer.dll"             // 导入 APlayer 引擎的类型库
                        HWND g_hAxWnd = NULL;                    // APlayer 控件容器
                        APlayer3Lib::IPlayer * g_pPlayer = NULL; // 指向 APlayer 对象的指针

                        BOOL CreateAPlayerFromFile(void)
                        {
                            // Get aplayer path
                            TCHAR szPath[MAX_PATH];
                            wsprintf(szPath, _T("%s\\APlayer.dll"), g_szAppPath);

                            // Create APlayer instance
                            IDispatch * pDispatch = NULL;
                        HRESULT hr = CreateInstanceFromFile
                                    (szPath, __uuidof(APlayer3Lib::Player), __uuidof(IDispatch), NULL, (void **)&pDispatch);
                        if(FAILED(hr) || pDispatch == NULL)
                            {
                                return FALSE;
                        }

                            // Create AX window
                    g_hAxWnd = ::CreateWindowEx(WS_EX_TOOLWINDOW, _T(ATLAXWIN_CLASS), _T(""),
                                                        WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
                                                        0, 0, 1, 1,
                                                        m_hParentWnd, NULL, NULL, NULL);
                            if(g_hAxWnd == NULL)
                            {
                                return FALSE;
                        }

                            // Attach aplayer
                            hr = AtlAxAttachControl(pDispatch, g_hAxWnd, NULL);
                            if(FAILED(hr))
                            {
                                pDispatch->Release();
                                return FALSE;
                            }

                            hr = pDispatch->QueryInterface(__uuidof(APlayer3Lib::IPlayer), (void **)&g_pPlayer);
                            if(FAILED(hr) || m_pPlayer == NULL)
                            {
                                return FALSE;
                            }
                            return TRUE;
                        }

                上面函数中用到的 CreateInstanceFromFile 函数定义如下:
           
                HRESULT CreateInstanceFromFile(const TCHAR * pcszPath, REFCLSID rclsid, REFIID riid, IUnknown * pUnkOuter, LPVOID * ppv)
                        {
                            // Load the library
                            //HMODULE hDll = ::LoadLibraryEx(pcszPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
                            //if(hDll == NULL)
                            //    return TYPE_E_CANTLOADLIBRARY;

                            // Get pointer of DllGetClassObject
                            typedef HRESULT (STDAPICALLTYPE *_pfnDllGetClassObject)(REFCLSID, REFIID, LPVOID*);
                            _pfnDllGetClassObject pfnDllGetClassObject = (_pfnDllGetClassObject)
                                  GetProcAddress(hDll, "DllGetClassObject");
                            if(pfnDllGetClassObject == NULL)
                                return CO_E_ERRORINDLL;

                            // Call DllGetClassObject
                            CComPtr<IClassFactory> spCF;
                            HRESULT hr = (*pfnDllGetClassObject)(rclsid, IID_IClassFactory, (LPVOID*)&spCF);
                            if(FAILED(hr))
                                return hr;

                            // Create instance
                            hr = spCF->CreateInstance(pUnkOuter, riid, ppv);
                            if(FAILED(hr))
                                return hr;

                            // Create completed
                            return S_OK;
                        }
                    }
    2013年8月12日 9:39

答案