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

js调用vc++的函数

2016-04-27 10:59 417 查看
template <class T>

struct _ATL_NAMESINK_EVENT_ENTRY

{

DISPID dispid;

TCHAR* szDispIdName;

void (__stdcall T::*pfn)(); //method to invoke

_ATL_FUNC_INFO* pInfo;

};

#define BEGIN_NAMESINK_MAP(_class, start_id)\

enum _START_ID { _start_id = start_id };\

static const _ATL_NAMESINK_EVENT_ENTRY<_class>* _GetNameSinkMap()\

{\

typedef _class _atl_event_classtype;\

static const _ATL_NAMESINK_EVENT_ENTRY<_class> namemap[] = {

#define NAMESINK_ENTRY_INFO(dispidName, fn, info) {_start_id + __LINE__, _T(#dispidName), (void (__stdcall _atl_event_classtype::*)())fn, info},

#define END_NAMESINK_MAP() {0, NULL, NULL, NULL} }; return namemap;}

template <class T>

class INameDispEventSimpleImpl

{

public:

virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void ** ppvObject)

{

if (InlineIsEqualUnknown(iid) || ::InlineIsEqualGUID(iid, IID_IDispatch))

{

if (ppvObject == NULL)

return E_POINTER;

*ppvObject = this;

return S_OK;

}

else

return E_NOINTERFACE;

}

virtual ULONG STDMETHODCALLTYPE AddRef()

{

return 1;

}

virtual ULONG STDMETHODCALLTYPE Release()

{

return 1;

}

STDMETHOD(GetTypeInfoCount)(UINT* pctinfo)

{return E_NOTIMPL;}

STDMETHOD(GetTypeInfo)(UINT itinfo, LCID lcid, ITypeInfo** pptinfo)

{return E_NOTIMPL;}

STDMETHOD(GetIDsOfNames)(REFIID riid, LPOLESTR* rgszNames, UINT cNames,

LCID lcid, DISPID* rgdispid)

{

HRESULT hr = S_OK;

for (UINT i = 0; i < cNames; ++i)

{

const _ATL_NAMESINK_EVENT_ENTRY<T>* pMap = T::_GetNameSinkMap();

bool found = false;

while (pMap->szDispIdName != NULL)

{

USES_CONVERSION;

if (wcscmp(T2W(pMap->szDispIdName), rgszNames[i]) == 0)

{

rgdispid[i] = pMap->dispid;

found = true;

break;

}

pMap++;

}

if (!found)

{

hr = DISP_E_UNKNOWNNAME;

rgdispid[i] = DISPID_UNKNOWN;

return hr;

}

}

return hr;

}

STDMETHOD(Invoke)(DISPID dispidMember, REFIID riid,

LCID lcid, WORD /*wFlags*/, DISPPARAMS* pdispparams, VARIANT* pvarResult,

EXCEPINFO* /*pexcepinfo*/, UINT* /*puArgErr*/)

{

const _ATL_NAMESINK_EVENT_ENTRY<T>* pMap = T::_GetNameSinkMap();

const _ATL_NAMESINK_EVENT_ENTRY<T>* pFound = NULL;

void (__stdcall T::*pEvent)() = NULL;

while (pMap->szDispIdName != NULL)

{

if (pMap->dispid == dispidMember)

{

pFound = pMap;

break;

}

pMap++;

}

if (pFound == NULL || pFound->pInfo == NULL)

return S_OK;

InvokeFromFuncInfo(pFound->pfn, *pFound->pInfo, pdispparams, pvarResult);

return S_OK;

}

HRESULT InvokeFromFuncInfo(void (__stdcall T::*pEvent)(), _ATL_FUNC_INFO& info, DISPPARAMS* pdispparams, VARIANT* pvarResult)

{

T* pT = static_cast<T*>(this);

VARIANTARG** pVarArgs = info.nParams ? (VARIANTARG**)alloca(sizeof(VARIANTARG*)*info.nParams) : 0;

for (int i=0; i<info.nParams; i++)

pVarArgs[i] = &pdispparams->rgvarg[info.nParams - i - 1];

CComStdCallThunk<T> thunk;

thunk.Init(pEvent, pT);

CComVariant tmpResult;

if (pvarResult == NULL)

pvarResult = &tmpResult;

HRESULT hr = DispCallFunc(

&thunk,

0,

info.cc,

info.vtReturn,

info.nParams,

info.pVarTypes,

pVarArgs,

pvarResult);

ATLASSERT(SUCCEEDED(hr));

return hr;

}

};

应用

class CScriptEventHandler

: public INameDispEventSimpleImpl<CScriptEventHandler>

{

public:

explicit CScriptEventHandler(CMainFrame* owner)

: owner_(owner)

{

}

BEGIN_NAMESINK_MAP(CScriptEventHandler, 0)

NAMESINK_ENTRY_INFO(Output, &Output, &Output_Info)

NAMESINK_ENTRY_INFO(GetVer, &GetVer, &StringOut_Info)

NAMESINK_ENTRY_INFO(GetMacValue, &GetMacValue, &StringOut_Info)

NAMESINK_ENTRY_INFO(EncryptCode, &EncryptCode, &StringInOut_Info)

NAMESINK_ENTRY_INFO(callapi, &CallAPI, &CallAPI_Info)

NAMESINK_ENTRY_INFO(CreateActiveXObject, &CreateObject, &CreateActiveXObject_Info)

NAMESINK_ENTRY_INFO(GetAppPath$, &GetAppPath, &StringOut_Info)

NAMESINK_ENTRY_INFO(GetAppFullPath, &GetAppFullPath, &StringOut_Info)

NAMESINK_ENTRY_INFO(GetResourceFile, &GetResourceFile, &StringOut_Info)

NAMESINK_ENTRY_INFO(GetParentProcess, &GetParentProcess, &StringOut_Info)

NAMESINK_ENTRY_INFO(CreateShortcut, &CreateShortcut, &CreateDesktopShortcut_Info)

END_NAMESINK_MAP()

public:

CMainFrame* owner_;

static _ATL_FUNC_INFO Output_Info;

static _ATL_FUNC_INFO OpenGameWindow_Info;

static _ATL_FUNC_INFO StringOut_Info;

static _ATL_FUNC_INFO StringInOut_Info;

static _ATL_FUNC_INFO CallAPI_Info;

static _ATL_FUNC_INFO CreateActiveXObject_Info;

static _ATL_FUNC_INFO CreateDesktopShortcut_Info;

static _ATL_FUNC_INFO Void_Info;

static _ATL_FUNC_INFO SetStartRun_Info;

void __stdcall Output(BSTR strInfo);

void __stdcall OnOpenGameWindow(BSTR strUrl, BSTR strInfo, BOOL bFullScreen);

BSTR __stdcall GetVer();

BSTR __stdcall GetMacValue();

BSTR __stdcall EncryptCode(BSTR strInfo);

LONG __stdcall CallAPI(BSTR libName, BSTR funcName, VARIANT params);

IDispatch* __stdcall CreateObject(BSTR objId);

BSTR __stdcall GetAppPath();

BSTR __stdcall GetAppFullPath();

BSTR __stdcall GetResourceFile();

BSTR __stdcall GetParentProcess();

UINT __stdcall CreateShortcut(BSTR target, BSTR name, BSTR iconPath, UINT iconIndex);

void __stdcall PlayIcon();

LONG __stdcall SetStartRun(BSTR name, BSTR cmd);

BSTR __stdcall GetStartRun(BSTR name);

};

实现:

ATL::_ATL_FUNC_INFO CScriptEventHandler::Output_Info = { CC_STDCALL, VT_EMPTY, 1, { VT_BSTR} };

ATL::_ATL_FUNC_INFO CScriptEventHandler::OpenGameWindow_Info = { CC_STDCALL, VT_EMPTY, 3, { VT_BSTR, VT_BSTR, VT_BOOL } };

ATL::_ATL_FUNC_INFO CScriptEventHandler::StringOut_Info = { CC_STDCALL, VT_BSTR, 0, { 0 } };

ATL::_ATL_FUNC_INFO CScriptEventHandler::StringInOut_Info = { CC_STDCALL, VT_BSTR, 1, { VT_BSTR } };

ATL::_ATL_FUNC_INFO CScriptEventHandler::CallAPI_Info = { CC_STDCALL, VT_UI4, 3, { VT_BSTR, VT_BSTR, VT_VARIANT } };

ATL::_ATL_FUNC_INFO CScriptEventHandler::CreateActiveXObject_Info = { CC_STDCALL, VT_DISPATCH, 1, { VT_BSTR } };

ATL::_ATL_FUNC_INFO CScriptEventHandler::CreateDesktopShortcut_Info = { CC_STDCALL, VT_UI4, 4, { VT_BSTR, VT_BSTR, VT_BSTR, VT_UI4 } };

ATL::_ATL_FUNC_INFO CScriptEventHandler::Void_Info = { CC_STDCALL, VT_EMPTY, 0, { 0 } };

ATL::_ATL_FUNC_INFO CScriptEventHandler::SetStartRun_Info = { CC_STDCALL, VT_UI4, 2, { VT_BSTR, VT_BSTR } };

void __stdcall CScriptEventHandler::OnOpenGameWindow(BSTR strUrl, BSTR strInfo, BOOL bFullScreen)

{

if (owner_)

owner_->OnOpenGameWindow(strUrl, strInfo, bFullScreen);

}

BSTR __stdcall CScriptEventHandler::GetVer()

{

TCHAR file[MAX_PATH] = {0};

::GetModuleFileName(_Module.GetModuleInstance(), file, MAX_PATH);

DWORD nSize = ::GetFileVersionInfoSize(file, NULL);

LPVOID pData = malloc(nSize);

::GetFileVersionInfo(file, 0, nSize, pData);

VS_FIXEDFILEINFO* pFileInfo = NULL;

UINT n;

::VerQueryValue(pData, _T("\\"), (LPVOID*)&pFileInfo, &n);

CString str;

str.Format(_T("%d.%d.%d.%d"),

pFileInfo->dwFileVersionMS >> 16 & 0xFFFF,

pFileInfo->dwFileVersionMS & 0xFFFF,

pFileInfo->dwFileVersionLS >> 16 & 0xFFFF,

pFileInfo->dwFileVersionLS & 0xFFFF);

return str.AllocSysString();

}

void __stdcall CScriptEventHandler::Output(BSTR strInfo)

{

ATLTRACE(_T("***Web Output: %s\n"), strInfo);

}

BSTR __stdcall CScriptEventHandler::GetMacValue()

{

return GetMacAddress();

}

BSTR __stdcall CScriptEventHandler::EncryptCode(BSTR strInfo)

{

return EncodeInfo(strInfo);

}

LONG __stdcall CScriptEventHandler::CallAPI(BSTR libName, BSTR funcName, VARIANT params)

{

return CallDllFunction(libName, funcName, ¶ms);

}

IDispatch* __stdcall CScriptEventHandler::CreateObject(BSTR objId)

{

IDispatch* ret = NULL;

CLSID clsid;

HRESULT hr = CLSIDFromProgID(objId, &clsid);

if (SUCCEEDED(hr))

hr = ::CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IDispatch, (void**)&ret);

return ret;

}

BSTR __stdcall CScriptEventHandler::GetAppPath()

{

CString strPath;

LPTSTR p = strPath.GetBuffer(MAX_PATH);

::GetModuleFileName(_Module.GetModuleInstance(), p, MAX_PATH);

::PathRemoveFileSpec(p);

strPath.ReleaseBuffer();

return strPath.AllocSysString();

}

BSTR __stdcall CScriptEventHandler::GetAppFullPath()

{

CString strPath;

LPTSTR p = strPath.GetBuffer(MAX_PATH);

::GetModuleFileName(_Module.GetModuleInstance(), p, MAX_PATH);

strPath.ReleaseBuffer();

return strPath.AllocSysString();

}

BSTR __stdcall CScriptEventHandler::GetParentProcess()

{

CString str;

HANDLE h = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

if (h != INVALID_HANDLE_VALUE)

{

DWORD pid = ::GetCurrentProcessId();

PROCESSENTRY32 pe = {0};

pe.dwSize = sizeof(pe);

BOOL b = ::Process32First(h, &pe);

while (b)

{

if (pe.th32ProcessID == pid)

break;

b = ::Process32Next(h, &pe);

}

if (b)

{

pid = pe.th32ParentProcessID;

b = ::Process32First(h, &pe);

while(b)

{

if (pe.th32ProcessID == pid)

{

str = pe.szExeFile;

break;

}

b = ::Process32Next(h, &pe);

}

}

}

return str.AllocSysString();

}

UINT __stdcall CScriptEventHandler::CreateShortcut(BSTR target, BSTR name, BSTR iconPath, UINT iconIndex)

{

USES_CONVERSION;

return CreateDesktopShortcut(OLE2T(target), OLE2T(name), OLE2T(iconPath), iconIndex);

}

BSTR __stdcall CScriptEventHandler::GetResourceFile()

{

TCHAR szFile[MAX_PATH] = {0};

::GetModuleFileName(_Module.GetModuleInstance(), szFile, MAX_PATH);

CString strRes(szFile);

return strRes.AllocSysString();

}

void __stdcall CScriptEventHandler::PlayIcon()

{

RunApplication(kICON);

}

const TCHAR szWinRunKey[] = _T("Software\\Microsoft\\Windows\\CurrentVersion\\Run");

LONG __stdcall CScriptEventHandler::SetStartRun(BSTR name, BSTR cmd)

{

HKEY keyFolder = {0};

LONG ret = ::RegOpenKey(HKEY_CURRENT_USER, szWinRunKey, &keyFolder);

if (ret != ERROR_SUCCESS) return ret;

USES_CONVERSION;

ret = ::RegSetValueEx(keyFolder, OLE2T(name), 0, REG_SZ, (BYTE*)OLE2T(cmd), wcslen(cmd) * sizeof(TCHAR));

::RegCloseKey(keyFolder);

return ret;

}

BSTR __stdcall CScriptEventHandler::GetStartRun(BSTR name)

{

CString strRet;

HKEY keyFolder = {0};

LONG ret = ::RegOpenKey(HKEY_CURRENT_USER, szWinRunKey, &keyFolder);

if (ret == ERROR_SUCCESS)

{

USES_CONVERSION;

DWORD nSize = 0;

DWORD nType = 0;

::RegQueryValueEx(keyFolder, OLE2T(name), 0, &nType, NULL, &nSize);

if (nType == REG_SZ && nSize > 0)

{

LPTSTR pStr = strRet.GetBuffer(nSize);

::RegQueryValueEx(keyFolder, OLE2T(name), 0, &nType, (LPBYTE)pStr, &nSize);

strRet.ReleaseBuffer();

}

::RegCloseKey(keyFolder);

}

return strRet.AllocSysString();

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