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

Hello World!

程序員那點(diǎn)事兒

首頁(yè) 新隨筆 聯(lián)系 聚合 管理
  20 Posts :: 6 Stories :: 0 Comments :: 0 Trackbacks

ActiveX異步回調(diào)JavaScript

       開發(fā)環(huán)境:VC6.0。

       背景知識(shí):COM/ActiveX/JavaScript/MFC/Thread

 

       想必用過Ajax的童鞋們都知道xmlhttp這個(gè)東西吧,通過設(shè)定onreadystatechange屬性,我們就可以指定他狀態(tài)改變的回調(diào)函數(shù),當(dāng)狀態(tài)改變時(shí),ActiveX控件就會(huì)調(diào)用我們通過onreadystatechange屬性制定的回調(diào)函數(shù)。從而就出現(xiàn)了Ajax給我們帶來的精彩。關(guān)于Ajax的技術(shù)我們這里不做討論,我們的目的就是實(shí)現(xiàn)像xmlhttp這樣具有異步回調(diào)JavaScript功能的ocx控件來。

 

       Let’s go!

 

1.       建立MFC ActiveX Control(方法略)

2.       ClassWizard中添加屬性callbackfunction屬性,并為該屬性生成getset方法。我們將在ActiveX控件中開啟線程,線程執(zhí)行完后將調(diào)用通過該屬性執(zhí)行的JavaScript函數(shù)。在該實(shí)例中,通過callbackfunction屬性指定的JavaScript函數(shù)必須是返回值是void的,并且含有一個(gè)short類型的參數(shù)的函數(shù)。

3.       我們需要一個(gè)方法來觸發(fā)回調(diào)函數(shù),添加方法Invoke包含一個(gè)short類型的參數(shù)param。在這個(gè)函數(shù)里將開啟一個(gè)線程進(jìn)行運(yùn)算,然后返回計(jì)算結(jié)果。并把結(jié)果以回調(diào)函數(shù)的形式調(diào)用JavaScript的函數(shù)。

4.       Invoke方法中開啟線程。進(jìn)行計(jì)算。線程同步的方法采用PostMessage自定義消息。這個(gè)很重要,否則的話,我們?cè)诰€程中操作界面控件是不正確的。(我就是忘記了進(jìn)行線程同步才多走了好多彎路)

#define WM_THREADFIREEVENT WM_USER+101

void f(void * r)

{

       CThirdCtrl* p = (CThirdCtrl*)r;

       Sleep(5000);

       p->m_param +=10;

        PostMessage(p->m_hWnd,WM_THREADFIREEVENT,(WPARAM)NULL,(LPARAM)NULL);

       return;

}

 

void CThirdCtrl::invoke(short param)

{

       m_param = param;

       _beginthread(f, 0, (void*)(this));

}

 

5.       添加THREADFIREEVENT 消息的消息映射函數(shù):

ON_MESSAGE(WM_THREADFIREEVENT,OnFireEventForThread)

 

       6.    實(shí)現(xiàn)函數(shù)OnFireEventForThread

LRESULT CThirdCtrl::OnFireEventForThread(WPARAM wParam, LPARAM lParam)

{

    //FireLengthyProcessDone();

       InvokeScript ();

       return TRUE;

}

7.   在實(shí)現(xiàn)InvokeScript前,先說一個(gè)重要的東西,就是OnSetClientSite這是一個(gè)CThirdCtrl 的父類ColeControl的一個(gè)虛方法。我們需要重寫他來獲得IWebBrowser2指針,有了IWebBrowser2我們就可以為所欲為了。比方說獲得document對(duì)象,獲得html中的elements,設(shè)定他們的屬性,調(diào)用方法。也可以執(zhí)行頁(yè)面中的JavaScript函數(shù)。

      為獲得頂層IWebBrowser2 引用, 從客戶站點(diǎn)獲取IServiceProvider接口并且執(zhí)行一個(gè)QueryService 操作獲取IID_IServiceProvider服務(wù):SID_STopLevelBrowser (這在Shlguid.h中定義);對(duì)第二個(gè)IServiceProvider,執(zhí)行一個(gè)QueryService 獲取IID_IWebBrowser2 服務(wù):SID_SWebBrowserApp.

      上代碼:

void  CThirdCtrl::OnSetClientSite()

{

     

      IOleClientSite*   pClientSite   =   GetClientSite(); 

     

      HRESULT   hr   =   S_OK; 

      IServiceProvider   *isp,   *isp2   =   NULL;//用于導(dǎo)航DHTML對(duì)象層次,作用就是提供服務(wù) 

     

      if   (!pClientSite) 

      { 

       if(browser!=NULL)

       {

              browser->Release();

              browser = NULL;

       }

       return;//   !S_OK; 

      } 

      else 

      { 

       hr   =   pClientSite->QueryInterface(IID_IServiceProvider,   reinterpret_cast<void   **>(&isp)); 

       if   (FAILED(hr))   

       { 

              hr   =   S_OK; 

              goto   cleanup; 

       } 

      

       hr   =   isp->QueryService(SID_STopLevelBrowser,   IID_IServiceProvider,   reinterpret_cast<void   **>(&isp2)); 

       if   (FAILED(hr)) 

       { 

              hr   =   S_OK; 

              goto   cleanup; 

       } 

      

       //獲得瀏覽器 

       hr   =   isp->QueryService(SID_SWebBrowserApp,   IID_IWebBrowser2,   reinterpret_cast<void   **>(&browser));

       if   (FAILED(hr))   

       { 

              hr   =   S_OK; 

              goto   cleanup; 

       } 

      

cleanup: 

       //   Free   resources. 

       if(isp!=NULL)

       {

              isp->Release();

              isp = NULL;

       }

       if(isp2!=NULL)

       {

              isp2->Release();

              isp2 = NULL;

       }

       return;//   hr; 

      } 

     

      return;//   hr;

     

}

              同樣的道理,如果我們是ATL做的ActiveX,則需要重寫

STDMETHODIMP   CThirdCtrl::SetClientSite()

這個(gè)方法。

8.    下面就是最關(guān)鍵的InvokeScript函數(shù)的實(shí)現(xiàn),我們?cè)谶@里使用上面獲取到的IWebBrowser2指針來獲取document對(duì)象,然后獲取Idispatch接口的script對(duì)象,然后調(diào)用Idispatch接口的Invoke方法。就可以調(diào)用JavaScript了。Idispatch接口真是強(qiáng)大啊。

廢話少說,上代碼:

void   CThirdCtrl::InvokeScript() 

{ 

if(!browser) 

{ 

        if(browser!=NULL)

        {

               browser->Release();

               browser = NULL;

        }

        return; 

} 

CComPtr<IHTMLDocument2> m_spDoc; 

HRESULT hr = browser->get_Document((IDispatch**)&m_spDoc);   

if(FAILED(hr)) 

        throw(""); 

CComPtr<IDispatch> pScript; 

hr = m_spDoc->get_Script(&pScript); 

if(FAILED(hr)) 

        throw(""); 

CComBSTR   bstrMember(m_callbackfunction);   

DISPID   dispid; 

hr=pScript->GetIDsOfNames(IID_NULL,&bstrMember,1,LOCALE_SYSTEM_DEFAULT,&dispid); 

//   設(shè)置函數(shù)參數(shù) 

DISPPARAMS   dispparams; 

memset(&dispparams,0,sizeof(dispparams)); 

dispparams.cArgs = 1;//表示參數(shù)的計(jì)數(shù)。 

dispparams.rgvarg = new VARIANT[dispparams.cArgs];//表示對(duì)參數(shù)數(shù)組的引用。 

for(int i = 0; i < 1; i++) 

{ 

        //CComBSTR  bstr  =  "111";   //   back   reading 

        //bstr.CopyTo(&dispparams.rgvarg[i].bstrVal); 

        dispparams.rgvarg[i].iVal = m_param;

        dispparams.rgvarg[i].vt = VT_I2; 

} 

dispparams.cNamedArgs =0;//表示命名參數(shù)的計(jì)數(shù)。 

EXCEPINFO excepInfo; 

memset(&excepInfo,0,sizeof(excepInfo)); 

CComVariant vaResult; 

UINT nArgErr = (UINT)-1;   //   initialize   to   invalid   arg 

hr = pScript->Invoke(dispid, IID_NULL,0,DISPATCH_METHOD,&dispparams,&vaResult,&excepInfo,&nArgErr); 

} 

這樣,ActiveX控件就完成了。

9.       編寫html頁(yè)面代碼。打開Microsoft ActiveX Control Pad,插入控件。然后編寫JavaScript代碼。

<HTML>

<HEAD>

<TITLE>New Page</TITLE>

</HEAD>

<BODY>

    <SCRIPT LANGUAGE="JavaScript" >

function invoke()

{

        Third1.callbackfunction = "callback";

        Third1.invoke(2);

        alert("begin invoke");

}

function callback(param)

{

        alert(param);

}

 

    </SCRIPT>

<OBJECT ID="Third1" WIDTH=100 HEIGHT=51

 CLASSID="CLSID:E9D38528-0F4E-468B-858D-69905F16942F">

    <PARAM NAME="_Version" VALUE="65536">

    <PARAM NAME="_ExtentX" VALUE="2646">

    <PARAM NAME="_ExtentY" VALUE="1323">

    <PARAM NAME="_StockProps" VALUE="0">

</OBJECT>

<input type="button" value="test" onclick="invoke();" />

</BODY>

</HTML>

10.   測(cè)試:打開瀏覽器,打開test.html頁(yè)面。點(diǎn)擊“test“按鈕,將會(huì)先顯示對(duì)話框begin invoke,然后過5秒鐘再顯示對(duì)話框12。

11.   調(diào)試方法:我們可以直接調(diào)試瀏覽器。瀏覽器加載了控件,然后我們調(diào)用控件的方法,這時(shí)會(huì)自動(dòng)觸發(fā)我們?cè)诠こ讨性O(shè)置的斷點(diǎn)。在

project---settings---debug---executable for debug sessions設(shè)置瀏覽器的exe文件的路徑。我用的世界之窗瀏覽器。所以值設(shè)置為:C:\Program Files\TheWorld\TheWorld.exe

如果你用IE瀏覽器,可設(shè)置為:C:\Program Files\Internet Explorer\iexplore.exe

 

說明:

1.    上述控件與xmlhttp不同的地方是callbackfunction我傳的是一個(gè)字符串,而xmlhttp傳的是一個(gè)JavaScript的函數(shù)指針。

2.    COM中的線程模型不在本文討論范圍之內(nèi)。還有瀏覽器安全問題和打包CAB的問題也不在本文討論范圍之內(nèi)。

參考:

http://vcfaq.mvps.org/com/1.htm

http://vcfaq.mvps.org/com/11.htm

http://support.microsoft.com/kb/q157437/

posted on 2012-03-26 13:39 hello wold! 閱讀(1064) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 編程相關(guān)
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲精品在线免费观看视频| 日韩午夜电影av| 午夜亚洲性色视频| 国产精品久久国产愉拍| 久久裸体艺术| 欧美专区亚洲专区| 亚洲天堂男人| 亚洲视频一区二区免费在线观看| 国产一区二区三区黄视频| 国产精品自在欧美一区| 国产精品a久久久久久| 欧美三级在线视频| 亚洲精品字幕| 亚洲卡通欧美制服中文| 久久爱另类一区二区小说| 亚洲影视中文字幕| 欧美日韩国产黄| 一本一本a久久| 亚洲一区二区三区激情| 久久久精品国产99久久精品芒果| 欧美一区二区三区喷汁尤物| 久久久久一区| 亚洲美女中文字幕| 99在线精品视频| 欧美一区=区| 欧美精品一区二区三区视频| 国产精品播放| 亚洲激情在线| 欧美日韩一区二区三区在线视频 | 国产精品日韩欧美一区| 宅男66日本亚洲欧美视频| 欧美一区二区性| 欧美激情一区在线| 午夜在线播放视频欧美| 免费观看一级特黄欧美大片| 国产精品久久久久9999| 91久久夜色精品国产网站| 亚洲国产毛片完整版| 亚洲午夜精品一区二区| 蜜桃av一区二区三区| 一本色道久久99精品综合| 国产亚洲精品bt天堂精选| 夜夜嗨av一区二区三区网站四季av| 久久免费少妇高潮久久精品99| 欧美一区日韩一区| 亚洲调教视频在线观看| 国产精品va在线播放| 99精品欧美一区| 亚洲黄色高清| 欧美三级视频在线播放| 亚洲午夜一区| 亚洲欧美日韩在线一区| 国产一区二区主播在线| 国模精品一区二区三区色天香 | 久久精品中文字幕免费mv| 国产精品免费在线| 免费观看成人鲁鲁鲁鲁鲁视频| 国产精品v片在线观看不卡| 亚洲一区制服诱惑| 午夜一级久久| 久久综合精品国产一区二区三区| 亚洲欧美在线aaa| 欧美一区二区三区视频在线 | 亚洲私人影院| 欧美激情综合色| 亚洲图色在线| 亚洲欧美日韩中文播放| 午夜亚洲福利在线老司机| 国产一区二区三区黄| 欧美二区在线| 久久国产精品久久久久久电车 | 久久天堂成人| 1769国内精品视频在线播放| 欧美国产欧美亚洲国产日韩mv天天看完整| 久久久人人人| 99精品久久久| 久久精品综合| 激情久久久久| 亚洲女同在线| 久久综合中文字幕| 亚洲欧美日韩精品久久亚洲区 | 亚洲国产天堂久久国产91| 一区二区三区高清视频在线观看 | 国产精品系列在线| 免费视频亚洲| 国产亚洲精品久久久久动| 亚洲精品女人| 蜜臀久久久99精品久久久久久| 亚洲一区二区精品| 欧美电影资源| 亚洲三级电影全部在线观看高清| 99在线精品视频| 精品成人久久| 美女黄毛**国产精品啪啪| 亚洲激情偷拍| 国产日韩一区欧美| 亚洲网站在线看| 亚洲欧美日韩专区| 国产精品日韩| 久久国产黑丝| 欧美激情在线免费观看| 亚洲精品国产系列| 欧美国产一区二区在线观看| 亚洲国产成人91精品| 99在线|亚洲一区二区| 欧美精品激情blacked18| 一本色道久久加勒比88综合| 亚洲大胆女人| 亚洲精品久久7777| 欧美福利一区二区| 亚洲一区免费视频| 免费人成精品欧美精品| 久久人人爽国产| 亚洲精品欧美日韩| 国产精品一区二区久久精品| 亚洲深夜福利| 在线观看国产成人av片| 欧美日韩播放| 美国十次成人| 中文欧美日韩| 欧美国产亚洲精品久久久8v| 一区二区三区四区五区精品视频| 国产一区二区三区在线观看视频| 欧美成人午夜| 性欧美长视频| 亚洲免费视频在线观看| 亚洲精品黄网在线观看| 亚洲欧美日韩国产综合在线| 国产欧美日韩一区| 欧美日韩成人网| 久久综合激情| 中文精品视频| a91a精品视频在线观看| 亚洲精品久久久久| 亚洲黄色免费| 91久久极品少妇xxxxⅹ软件| 欧美在线黄色| 亚洲女人av| 国产精品免费看片| 国产伦精品一区二区三区四区免费| 欧美日韩中文字幕在线视频| 欧美久久久久久久久久| 欧美日韩精品免费看| 一本大道久久a久久精二百| 亚洲国产视频直播| 欧美日韩的一区二区| 欧美特黄一级| 精品成人国产| av成人动漫| 麻豆国产精品777777在线| 亚洲第一天堂无码专区| 日韩一区二区精品视频| 欧美在线啊v一区| 久久久亚洲成人| 国产精品久久久久久久app | 欧美大片一区二区| 欧美高清日韩| 国产视频不卡| av成人免费| 久久精品导航| 欧美成人乱码一区二区三区| 欧美深夜福利| 亚洲免费av片| 欧美国产成人在线| 亚洲一区影院| 国产精品ⅴa在线观看h| 亚洲人成网站影音先锋播放| 久久国产福利| 亚洲自拍偷拍一区| 国产精品国产a级| 在线亚洲美日韩| 亚洲精品影视| 欧美午夜在线一二页| 一级成人国产| 一本综合久久| 99re66热这里只有精品3直播| 欧美精品偷拍| 亚洲欧美日韩在线综合| 亚洲午夜激情网站| 亚洲国产精品一区二区久| 一区二区激情| 国产资源精品在线观看| 毛片av中文字幕一区二区| 免费欧美视频| 亚洲一区在线播放| 久久精品一区二区三区不卡| 久久gogo国模裸体人体| 亚洲啪啪91| 亚洲一区精品电影| 尤物九九久久国产精品的特点| 欧美丰满少妇xxxbbb| 美女视频黄 久久| 亚洲欧美日韩在线综合| 西瓜成人精品人成网站| 欧美日韩国产在线看| 亚洲国产日日夜夜| 亚洲日本va在线观看| 欧美影院在线| 美女999久久久精品视频| 亚洲一区二区视频在线|