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

Hello World!

程序員那點事兒

首頁 新隨筆 聯系 聚合 管理
  20 Posts :: 6 Stories :: 0 Comments :: 0 Trackbacks

ActiveX異步回調JavaScript

       開發環境:VC6.0。

       背景知識:COM/ActiveX/JavaScript/MFC/Thread

 

       想必用過Ajax的童鞋們都知道xmlhttp這個東西吧,通過設定onreadystatechange屬性,我們就可以指定他狀態改變的回調函數,當狀態改變時,ActiveX控件就會調用我們通過onreadystatechange屬性制定的回調函數。從而就出現了Ajax給我們帶來的精彩。關于Ajax的技術我們這里不做討論,我們的目的就是實現像xmlhttp這樣具有異步回調JavaScript功能的ocx控件來。

 

       Let’s go!

 

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

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

3.       我們需要一個方法來觸發回調函數,添加方法Invoke包含一個short類型的參數param。在這個函數里將開啟一個線程進行運算,然后返回計算結果。并把結果以回調函數的形式調用JavaScript的函數。

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

#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 消息的消息映射函數:

ON_MESSAGE(WM_THREADFIREEVENT,OnFireEventForThread)

 

       6.    實現函數OnFireEventForThread

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

{

    //FireLengthyProcessDone();

       InvokeScript ();

       return TRUE;

}

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

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

      上代碼:

void  CThirdCtrl::OnSetClientSite()

{

     

      IOleClientSite*   pClientSite   =   GetClientSite(); 

     

      HRESULT   hr   =   S_OK; 

      IServiceProvider   *isp,   *isp2   =   NULL;//用于導航DHTML對象層次,作用就是提供服務 

     

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

這個方法。

8.    下面就是最關鍵的InvokeScript函數的實現,我們在這里使用上面獲取到的IWebBrowser2指針來獲取document對象,然后獲取Idispatch接口的script對象,然后調用Idispatch接口的Invoke方法。就可以調用JavaScript了。Idispatch接口真是強大啊。

廢話少說,上代碼:

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

//   設置函數參數 

DISPPARAMS   dispparams; 

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

dispparams.cArgs = 1;//表示參數的計數。 

dispparams.rgvarg = new VARIANT[dispparams.cArgs];//表示對參數數組的引用。 

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;//表示命名參數的計數。 

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頁面代碼。打開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.   測試:打開瀏覽器,打開test.html頁面。點擊“test“按鈕,將會先顯示對話框begin invoke,然后過5秒鐘再顯示對話框12。

11.   調試方法:我們可以直接調試瀏覽器。瀏覽器加載了控件,然后我們調用控件的方法,這時會自動觸發我們在工程中設置的斷點。在

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

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

 

說明:

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

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

參考:

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) 評論(0)  編輯 收藏 引用 所屬分類: 編程相關
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            国产精品亚洲一区| 亚洲在线一区二区三区| 99视频精品| 9i看片成人免费高清| 亚洲深夜福利| 校园春色综合网| 欧美在线综合视频| 老司机凹凸av亚洲导航| 亚洲国产导航| 一本色道久久综合亚洲精品婷婷 | 欧美电影免费观看高清| 欧美精品福利| 国产精品影音先锋| 在线观看亚洲一区| 亚洲视频图片小说| 久久女同精品一区二区| 亚洲美女黄色片| 欧美一区二区三区播放老司机 | 一区二区欧美亚洲| 欧美一级黄色录像| 欧美成人一区二区三区片免费| 欧美四级在线观看| 亚洲成色999久久网站| 一区二区三区av| 久久综合久久久| 一本久久综合亚洲鲁鲁五月天| 久久精品首页| 国产精品日韩久久久| 最新国产拍偷乱拍精品| 欧美在线观看一区二区三区| 亚洲黄色视屏| 久久国产直播| 国产精品手机视频| 99国产精品99久久久久久粉嫩| 亚洲淫性视频| 亚洲精品日韩综合观看成人91| 亚洲一区三区电影在线观看| 久久噜噜噜精品国产亚洲综合 | 国产精品二区二区三区| 亚洲黄色片网站| 久久午夜精品一区二区| 亚洲视频一二三| 欧美精品一线| 亚洲日本一区二区| 久久综合五月天婷婷伊人| 亚洲字幕一区二区| 国产精品久久久久久妇女6080 | 欧美一级理论性理论a| 国产精品sss| 亚洲视频精品| 99国产精品久久久久老师 | 欧美极品aⅴ影院| 亚洲国产精品免费| 免费观看30秒视频久久| 欧美中文在线视频| 国产性色一区二区| 久久精品夜色噜噜亚洲a∨| 亚洲专区欧美专区| 国产麻豆成人精品| 久久国产99| 久久国产精品黑丝| 在线观看成人av| 欧美激情视频网站| 欧美岛国在线观看| 一区二区日韩欧美| 一区二区三区久久精品| 国产精品免费看久久久香蕉| 欧美在线91| 久久久精品日韩| 亚洲人成艺术| 9l视频自拍蝌蚪9l视频成人| 国产精品国产三级国产普通话三级| 亚洲女女女同性video| 亚洲女性裸体视频| 黄色av成人| 亚洲娇小video精品| 欧美色精品在线视频| 久久se精品一区二区| 久久美女艺术照精彩视频福利播放| 亚洲人成网在线播放| 夜夜嗨av色一区二区不卡| 国产精自产拍久久久久久蜜| 久久婷婷成人综合色| 欧美激情第3页| 午夜久久99| 另类av一区二区| 亚洲四色影视在线观看| 香港久久久电影| 亚洲激情一区二区三区| 欧美日韩中文字幕精品| 亚洲人妖在线| 99精品热视频| 国产亚洲精品久久久| 亚洲福利视频网| 国产精品国产三级国产普通话蜜臀| 久久久久久久国产| 欧美片网站免费| 久久久久久久尹人综合网亚洲 | 亚洲一卡久久| 亚洲大胆女人| 亚洲永久免费精品| 亚洲精品国偷自产在线99热| 亚洲伊人伊色伊影伊综合网| 最新高清无码专区| 亚洲免费在线观看| 日韩亚洲欧美一区二区三区| 午夜日韩激情| 亚洲新中文字幕| 免费日韩成人| 久久久一区二区| 国产精品久久久爽爽爽麻豆色哟哟 | 亚洲一区免费在线观看| 亚洲精品色婷婷福利天堂| 欧美一区二区三区在| 亚洲摸下面视频| 欧美日韩国产小视频| 欧美v日韩v国产v| 国产有码在线一区二区视频| 亚洲一区二区精品在线观看| 这里只有精品在线播放| 欧美va天堂| 欧美成人亚洲成人| 永久免费精品影视网站| 欧美一区二区性| 久久精品国产第一区二区三区最新章节| 欧美日韩成人在线播放| 亚洲激情女人| 日韩视频专区| 欧美日韩国产探花| 99视频有精品| 亚洲欧美另类在线| 国产精品伦一区| 亚洲综合成人在线| 久久er99精品| 狠狠爱成人网| 另类专区欧美制服同性| 欧美成人官网二区| 最近中文字幕日韩精品| 欧美精品久久一区| 日韩一区二区精品葵司在线| 亚洲在线观看免费视频| 国产精品日韩| 久久精品男女| 亚洲黄色小视频| 亚洲欧美日韩电影| 国产亚洲欧美一区二区三区| 久久九九精品| 亚洲欧洲在线看| 亚洲你懂的在线视频| 国产亚洲激情在线| 久久综合五月| 一区二区国产精品| 欧美中文日韩| 欧美sm重口味系列视频在线观看| 另类春色校园亚洲| 性欧美1819sex性高清| 久久―日本道色综合久久| 欧美成人精品在线视频| 国产一区二区看久久| 亚洲主播在线| 午夜精品久久| 激情小说另类小说亚洲欧美 | 韩国精品久久久999| 欧美在线影院在线视频| 欧美一级欧美一级在线播放| 亚洲高清二区| 91久久国产精品91久久性色| 久久久综合香蕉尹人综合网| 亚洲免费成人av电影| 亚洲视频一区| 亚洲精品一区二区三区樱花| 一区二区三区回区在观看免费视频| 国产欧美一区二区精品忘忧草| 玖玖视频精品| 国产精品免费网站| 亚洲黄一区二区三区| 国内视频一区| 一区二区av在线| 日韩视频在线观看免费| 欧美一区二区在线| 午夜精品久久久久久久久久久久 | 亚洲日本电影| 久久精品视频免费观看| 午夜欧美大尺度福利影院在线看| 你懂的一区二区| 欧美高清免费| 在线观看一区二区精品视频| 亚洲一级黄色| 久久av一区二区三区漫画| 欧美日韩一区二区三区高清| 国产精品入口| 午夜精品一区二区三区四区| 久久国产手机看片| 国产偷自视频区视频一区二区| 欧美亚洲在线| 亚洲国产精品一区在线观看不卡| 亚洲韩国一区二区三区| 欧美激情精品久久久久久变态 | 加勒比av一区二区| 久久久久久久综合日本|