青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

技術(shù)備忘錄

c++及圖形學(xué)

 

C++中嵌入ie瀏覽器總結(jié)(2) - 雙向通訊

   第一步解決了邊框和上下文菜單問題,第二部就是要解決c++程序和html頁面交互的問題。最開始的想法是通過c++去更新頁面內(nèi)容的方式來完成c++->html的通訊,通過BeforeNavigate2 接口,截獲頁面url地址的方式來完成html->c++的通訊。但是這種方式存在以下缺點(diǎn): 

       (1) c++->html 的問題在于導(dǎo)致c++代碼復(fù)雜,需要通過c++代碼來完成頁面生成,如果修改頁面,將產(chǎn)生很大的工作量。雖然嘗試用了模板方法解決,但是還是比較繁瑣,而且會(huì)導(dǎo)致經(jīng)常通訊的時(shí)候,頁面會(huì)經(jīng)常刷新,產(chǎn)生其他的一些問題。
      (2) html->c++ 的問題在于 傳遞參數(shù)不方便,解析也不方便、無法獲取返回值、腳本中要調(diào)用不方便

     為了解決這些問題,經(jīng)過google后找到了問題的解決辦法 : 
    (1) c++->html  ,可以通過調(diào)用頁面腳本方法來實(shí)現(xiàn),調(diào)用方法如下:

wxVariant wxIEHtmlWin::ExecScript(const wxString &fun,const std::vector<wxString> &params )
{
    wxVariant result(
false);
    
if (! m_webBrowser.Ok())
        
return result;

    
// get document dispatch interface
    IDispatch *iDisp = NULL;
    HRESULT hr 
= m_webBrowser->get_Document(&iDisp);
    
if (hr != S_OK)
        
return result;

    
// Query for Document Interface
    wxAutoOleInterface<IHTMLDocument2> hd(IID_IHTMLDocument2, iDisp);
    iDisp
->Release();

    
if (! hd.Ok())
        
return result;

    IDispatch 
*spScript;
    hr 
= hd->get_Script(&spScript);

    
if(FAILED(hr))
        
return result;
    BSTR bstrMember 
= wxConvertStringToOle(fun);
    DISPID dispid 
= NULL;
    hr 
= spScript->GetIDsOfNames(IID_NULL,&bstrMember,1,
        LOCALE_SYSTEM_DEFAULT,
&dispid);
    
if(FAILED(hr))
    
{
        
        
return result;
    }

    
//Putting parameters
    DISPPARAMS dispparams;
    memset(
&dispparams, 0sizeof dispparams);
    dispparams.cArgs      
= params.size();
    dispparams.rgvarg     
= new VARIANT[dispparams.cArgs];
    dispparams.cNamedArgs 
= 0;

    
forint i = 0; i < params.size(); i++)
    
{
        CComBSTR bstr 
= wxConvertStringToOle(params[params.size() - 1 - i]);
        
// back reading
        bstr.CopyTo(&dispparams.rgvarg[i].bstrVal);

        dispparams.rgvarg[i].vt 
= VT_BSTR;
    }

    EXCEPINFO excepInfo;
    memset(
&excepInfo, 0sizeof excepInfo);
    VARIANT   varRet;
    UINT nArgErr 
= (UINT)-1;      // initialize to invalid arg
    
//Call JavaScript function
    hr = spScript->Invoke(dispid,IID_NULL,0,
        DISPATCH_METHOD,
&dispparams,
        
&varRet,&excepInfo,&nArgErr);
    delete [] dispparams.rgvarg;
    
if(FAILED(hr))
    
{
        
        
return result;
    }


    wxConvertOleToVariant(varRet,result);
    
return result;


}

  這個(gè)方法實(shí)現(xiàn)了C++對(duì)頁面腳本調(diào)用,而且參數(shù)個(gè)數(shù)可以任意。比如頁面腳本是 :
function fun(a,b,c)
{
}

  C++中的調(diào)用方法是 :
std::vector<wxString> params;
params.push_back("a");
params.push_back("b");
params.push_back("c");
xxx
->ExecScripts("fun",params);

還可以獲得腳本返回的結(jié)果。

  (2) html->c++  通過腳本的window.external 方法,首先,在前文提到過的IDocHostUIHandler 接口中,實(shí)現(xiàn)方法: 
HRESULT STDMETHODCALLTYPE FrameSite::GetExternal(IDispatch **ppDispatch)
{
     
    IDispatch 
* pDisp = m_window->getExternal();
    
if(pDisp)
    
{
        pDisp
->AddRef();
        
*ppDispatch = pDisp;
    }


    
return S_OK;
}
其中 m_window->getExternal();
 返回的是自定義的一個(gè)IDispatch 接口類: 
/*
 * IDispimp.H
 * IDispatch
 *
 * Copyright (c)1995-1999 Microsoft Corporation, All Rights Reserved
 
*/
 


#ifndef _IDISPIMP_H_
#define _IDISPIMP_H_
#include 
<oaidl.h>
class CustomFunction;
class CImpIDispatch : public IDispatch
{
    
protected:
        ULONG               m_cRef;

    
public:
        CImpIDispatch(
void);
        
~CImpIDispatch(void);

        STDMETHODIMP QueryInterface(REFIID, 
void **);
        STDMETHODIMP_(ULONG) AddRef(
void);
        STDMETHODIMP_(ULONG) Release(
void);

        
//IDispatch
        STDMETHODIMP GetTypeInfoCount(UINT* pctinfo);
        STDMETHODIMP GetTypeInfo(
/* [in] */ UINT iTInfo,
            
/* [in] */ LCID lcid,
            
/* [out] */ ITypeInfo** ppTInfo);
        STDMETHODIMP GetIDsOfNames(
            
/* [in] */ REFIID riid,
            
/* [size_is][in] */ LPOLESTR *rgszNames,
            
/* [in] */ UINT cNames,
            
/* [in] */ LCID lcid,
            
/* [size_is][out] */ DISPID *rgDispId);
        STDMETHODIMP Invoke(
            
/* [in] */ DISPID dispIdMember,
            
/* [in] */ REFIID riid,
            
/* [in] */ LCID lcid,
            
/* [in] */ WORD wFlags,
            
/* [out][in] */ DISPPARAMS  *pDispParams,
            
/* [out] */ VARIANT  *pVarResult,
            
/* [out] */ EXCEPINFO *pExcepInfo,
            
/* [out] */ UINT *puArgErr);

            
void setCustomFunction(CustomFunction *fun) {m_fun = fun;}
private:
    CustomFunction 
*m_fun;

}
;
#endif //_IDISPIMP_H_
主要實(shí)現(xiàn)以下兩個(gè)方法: 
wxString cszCB_CustomFunction = wxT("CB_CustomFunction");
  #define DISPID_CB_CustomFunction 3
STDMETHODIMP CImpIDispatch::GetIDsOfNames(
            
/* [in] */ REFIID riid,
            
/* [size_is][in] */ OLECHAR** rgszNames,
            
/* [in] */ UINT cNames,
            
/* [in] */ LCID lcid,
            
/* [size_is][out] */ DISPID* rgDispId)
{
    HRESULT hr;
    UINT    i;

    
// Assume some degree of success
    hr = NOERROR;


        
for ( i=0; i < cNames; i++{
        wxString cszName  
= rgszNames[i];
 
        
if(cszName == cszCB_CustomFunction)
        
{
            rgDispId[i] 
= DISPID_CB_CustomFunction;
        }
    
     
        
else {
            
// One or more are unknown so set the return code accordingly
            hr = ResultFromScode(DISP_E_UNKNOWNNAME);
            rgDispId[i] 
= DISPID_UNKNOWN;
        }

    }

    
return hr;
}


STDMETHODIMP CImpIDispatch::Invoke(
            
/* [in] */ DISPID dispIdMember,
            
/* [in] */ REFIID /*riid*/,
            
/* [in] */ LCID /*lcid*/,
            
/* [in] */ WORD wFlags,
            
/* [out][in] */ DISPPARAMS* pDispParams,
            
/* [out] */ VARIANT* pVarResult,
            
/* [out] */ EXCEPINFO* /*pExcepInfo*/,
            
/* [out] */ UINT* puArgErr)
{

     
    
    
if(dispIdMember == DISPID_CB_CustomFunction) 
    
{
        
if(wFlags & DISPATCH_PROPERTYGET)
        
{
            
if(pVarResult != NULL)
            
{
                
                VariantInit(pVarResult);
                V_VT(pVarResult)
=VT_BOOL;
                V_BOOL(pVarResult) 
= true;
            }

        }

        
        
if ( wFlags & DISPATCH_METHOD )
        
{
            
//arguments come in reverse order
            
//for some reason
            if(!m_fun) return S_OK;

            wxString arg1,arg2;
         
            
if(pDispParams->cArgs<1return S_FALSE;
            wxString cmd 
= pDispParams->rgvarg[pDispParams->cArgs-1].bstrVal;
            std::vector
<wxString> args;
            
if(pDispParams->cArgs>1)
            
{
                
for(int i=pDispParams->cArgs-2;i>=0;i--)
                    args.push_back(pDispParams
->rgvarg[i].bstrVal);
            }

            wxString re 
= m_fun->execute(cmd,args);
            
if(pVarResult != NULL)
            
{
                VariantInit(pVarResult);
                V_VT(pVarResult)
=VT_BSTR;
                wxVariant wVar(re);
                VariantToMSWVariant(wVar,
*pVarResult);
                
                 
            }

         
        }

        
    }


     

    
return S_OK;
}

  其中 CustomFunction 定義如下:
#pragma once
#include 
<wx/wx.h>
#include 
<vector>
class CustomFunction
{
public:

    CustomFunction(
void)
    
{
    }


    
virtual ~CustomFunction(void)
    
{
    }


    
virtual wxString execute(const wxString &cmd, const std::vector<wxString> &args) = 0;
}
;
  然后只要在自己類里面繼承這個(gè)接口,就可以接收來之腳本的調(diào)用請(qǐng)求。
腳本里面編寫函數(shù):
window._callFun = function()
                
{
                     
                    var fun 
= "window.external.CB_CustomFunction(";
                    
for(i=0;i<arguments.length;i++)
                    
{
                        
if(i!=0)
                            fun 
= fun+",";
                        fun 
= fun+"\""+arguments[i]+"\"";
                    }
    
                    fun 
= fun+")";
                    
//alert(fun);
                    return (eval(fun));
                }
   然后調(diào)用的地方寫: 
 
_callFun("fun","param1","param2",);
就可以調(diào)用c++的函數(shù),并且可以得到返回值,從而解決了html->c++的通訊問題

   解決了雙向通訊后,頁面就不需要用刷新來解決,網(wǎng)頁設(shè)計(jì)師和c++編程人員只要定義好通訊接口,大家各自實(shí)現(xiàn)好接口方法就可以完成界面功能了。

posted on 2008-12-20 22:26 jerrychan 閱讀(3939) 評(píng)論(1)  編輯 收藏 引用 所屬分類: C++

評(píng)論

# re: C++中嵌入ie瀏覽器總結(jié)(2) - 雙向通訊 2012-07-06 15:08 ma12155506

其中 m_window->getExternal();
返回的是自定義的一個(gè)IDispatch 接口類: ?
直接在這個(gè)m_window不太理解
難道直接m_window里面添加
IDispatch* wxActiveX::getExternal(){
return m_Dispatch;
}
??
還是聲明或者NEW一個(gè)CImpIDispatch出來?
  回復(fù)  更多評(píng)論   

導(dǎo)航

統(tǒng)計(jì)

常用鏈接

留言簿(7)

隨筆分類

隨筆檔案

搜索

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲欧洲精品一区二区三区不卡 | 免费观看亚洲视频大全| 亚洲电影免费观看高清完整版在线 | 国内外成人在线| 国产精品s色| 欧美高潮视频| 久热国产精品| 老牛影视一区二区三区| 久久综合色天天久久综合图片| 欧美一区二区精美| 久久精品一区二区三区四区| 午夜精品久久久久久久久久久| 一区二区三区四区五区视频| 亚洲日韩欧美视频一区| 亚洲国产黄色| 亚洲一区二区三区四区视频| 欧美一区二区三区在线免费观看| 午夜精品国产更新| 久久理论片午夜琪琪电影网| 99综合在线| 久久精品国产久精国产爱| 性色av一区二区三区| 久久亚洲精品中文字幕冲田杏梨| 欧美黑人在线观看| 亚洲综合日韩中文字幕v在线| 亚洲欧美在线一区二区| 噜噜噜在线观看免费视频日韩| 欧美日韩成人网| 在线精品国精品国产尤物884a| 亚洲一区二区视频在线观看| 久久精品在线视频| 国产精品99久久久久久久女警| 久久久蜜桃一区二区人| 国产情人综合久久777777| 亚洲每日更新| 久久―日本道色综合久久| 亚洲一区二区三区精品动漫| 欧美不卡视频| 亚洲高清自拍| 欧美高清影院| 久久亚洲综合| 亚洲三级电影在线观看| 老司机精品福利视频| 亚洲欧美久久久久一区二区三区| 国产精品九九| 欧美在线观看视频在线 | 99这里有精品| 99热精品在线观看| 国产三级精品在线不卡| 欧美在线看片a免费观看| 亚洲在线中文字幕| 狠狠色香婷婷久久亚洲精品| 亚洲一区二区三区中文字幕| 99精品热6080yy久久| 欧美日韩高清不卡| 裸体丰满少妇做受久久99精品| 久久久国产精品亚洲一区| 亚洲国产精品第一区二区三区| 亚洲激情视频在线| 国产精品电影观看| 久久精品三级| 亚洲私人影院| 在线看国产一区| 亚洲一区二区三区精品在线观看| 激情亚洲网站| 亚洲欧美色一区| 一区二区三区精密机械公司| 久久精品30| 欧美亚洲在线播放| 欧美激情在线免费观看| 久久视频在线免费观看| 国产精品久久久对白| 欧美国产91| 国产一区二区三区网站| 99视频超级精品| 亚洲视频网站在线观看| 美女国产精品| 免费日本视频一区| 加勒比av一区二区| 久久国产精彩视频| 久久嫩草精品久久久久| 国产亚洲欧美日韩日本| 亚洲欧美国产高清va在线播| 亚洲欧美一区二区三区在线| 欧美日韩欧美一区二区| 在线视频一区观看| 久久成人在线| 国产综合久久| 久久都是精品| 狠狠色狠狠色综合| 久久麻豆一区二区| 亚洲欧洲精品一区二区三区波多野1战4 | 国产区精品在线观看| 性欧美video另类hd性玩具| 久久久噜噜噜久久久| 亚洲第一成人在线| 欧美日韩大片| 久久久九九九九| 亚洲精品国产品国语在线app| 一区二区精品国产| 伊人夜夜躁av伊人久久| 国产精品久久久久秋霞鲁丝| 欧美在线播放| 亚洲午夜激情免费视频| 亚洲国产日韩欧美综合久久| 欧美在线3区| 亚洲欧美日韩专区| 日韩视频三区| 亚洲国产精品精华液2区45| 国产麻豆午夜三级精品| 欧美日韩妖精视频| 欧美成人一区二区| 欧美成人dvd在线视频| 欧美伊人久久大香线蕉综合69| 亚洲人成人一区二区在线观看| 久久久999国产| 久久精品亚洲一区| 午夜精品一区二区在线观看| 日韩视频一区二区三区在线播放免费观看| 国产日本欧美一区二区| 国产精品你懂的在线| 国产精品福利av| 欧美日韩中文另类| 国产午夜精品一区二区三区视频| 欧美视频日韩视频在线观看| 亚洲人成人99网站| 亚洲高清资源| 99在线精品视频| 亚洲免费在线观看| 久久狠狠久久综合桃花| 久久久久久穴| 欧美性猛交视频| 国产精品专区第二| 亚洲激情图片小说视频| 亚洲小说欧美另类婷婷| 欧美专区在线观看一区| 欧美国产91| 亚洲精品乱码久久久久| 亚洲一区二区在线| 久热精品在线视频| 国产亚洲成av人片在线观看桃| 亚洲国产天堂久久国产91| 在线视频日韩| 老司机成人网| 亚洲影视在线| 欧美午夜电影在线观看| 亚洲高清一区二区三区| 久久国产福利| 久久久久久穴| 亚洲神马久久| 欧美三级电影一区| 亚洲欧洲日夜超级视频| 欧美在线观看一区| 亚洲一区二区欧美日韩| 国产精品大片免费观看| 在线亚洲国产精品网站| 亚洲国产一区在线| 蘑菇福利视频一区播放| 国产一区二区三区黄| 欧美一区深夜视频| 一本在线高清不卡dvd| 欧美久久精品午夜青青大伊人| 亚洲高清在线观看一区| 牛牛精品成人免费视频| 久久蜜桃精品| 亚洲激情黄色| 一本色道久久综合一区| 国产精品香蕉在线观看| 欧美制服丝袜| 亚洲永久免费观看| 久久国产精品久久久久久久久久 | 激情久久一区| 欧美福利一区| 国产精品一区二区三区免费观看 | 亚洲肉体裸体xxxx137| 亚洲午夜影视影院在线观看| 黄网站色欧美视频| 91久久夜色精品国产九色| 国产精品久久久对白| 美女视频黄免费的久久| 国产精品都在这里| 亚洲黄色毛片| 影音先锋日韩资源| 翔田千里一区二区| 亚洲综合成人在线| 免费不卡亚洲欧美| 欧美成人蜜桃| 亚洲激情成人| 玖玖在线精品| 免费久久精品视频| 国产婷婷97碰碰久久人人蜜臀| 亚洲精品在线一区二区| 亚洲国产精品久久人人爱蜜臀 | 国产伦精品一区二区三区高清| 亚洲人成网在线播放| 亚洲国产精品一区二区尤物区| 欧美一区二区三区久久精品 | 日韩亚洲欧美成人一区| 久久精品动漫| 欧美激情在线免费观看|