js调用vc++的函数



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, &params);
}


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();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值