VC調用 JavaScript 難題:如何使當前程式的對象進入指令碼

來源:互聯網
上載者:User

本文所指的  JavaScript 為 MS Script,引入msscript.ocx 實現的,也就是ECMAScript(下載本例原始碼)。從題目咋眼看來對於沒有寫過VC調用msscript.ocx的人來說不是很好理解,因為這樣做似乎太容易了,何來難題?

例如寫JavaScript實 現數值計算,例如: _variant_t outpar=pScriptControl->Eval(_bstr_t("1+4*5")); 這樣的數值計算不涉及js呼叫指令碼外部的對象,例子到處可見,但是應用範圍非常窄小。也就是說,從現有的文獻來看,用VC調用 JavaScript 都是 JavaScript 單向的,但是從來沒見過把VC中的現有的對象交給 JavaScript 反過來調用(也就是雙向調用)。有些人已經實現或者看到, JavaScript 可以通過 obj = new ActiveXObject(...);的方式,把用VC編寫COM,然後讓 JavaScript 建立調用,但是,這樣new出來的對象,仍然不是VC應用的現有對象。如果要調用現有對象,需要通過被new的COM對象間接調用才行,而且應用程式被調 用的對象也是COM規範。如果通過COM來實現這個難題,應用程式結構比較複雜,JavaScript 建立COM,所建立的COM能訪問應用程式物件。

所以要擴大 JavaScript 的應用範圍,必須實現這樣的核心問題:雙向調用。

雙向調用的一個分解問題是,VC對象如何進入指令碼呢?下面介紹一種實現方法。

一、介面:

 

二、主要代碼

1 聲明定義可以被JavaScript調用的類和對象

//聲明可以被JavaScript調用的類並建立一個轉接對象g_Dialogimpl

BEGIN_DSRE_POPULAR_OBJECT(CCppCallJavaScriptDlg)

    DEFINE_POPULAR_METHOD(CCppCallJavaScriptDlg,Rectangle);
    DEFINE_POPULAR_METHOD(CCppCallJavaScriptDlg,MoveTo);
    DEFINE_POPULAR_METHOD(CCppCallJavaScriptDlg,LineTo);
    DEFINE_POPULAR_METHOD(CCppCallJavaScriptDlg,TextOut);
END_DSRE_POPULAR_OBJECT()g_Dialogimpl;

//定義可以被JavaScript調用的函數,分別是Rectangle, MoveTo, LineTo, TextOut
DEFINE_DSRE_FUNCTION(CCppCallJavaScriptDlg,Rectangle)
{
    int x,y,cx,cy;
    x=(*args)[0]->AsInt();
    y=(*args)[1]->AsInt();
    cx=(*args)[2]->AsInt();
    cy=(*args)[3]->AsInt();

    ::Rectangle(m_hDC,x,y,cx,cy);
}

DEFINE_DSRE_FUNCTION(CCppCallJavaScriptDlg,MoveTo)
{
    int x,y;
    x=(*args)[0]->AsInt();
    y=(*args)[1]->AsInt();

    ::MoveToEx(m_hDC,x,y,NULL);
}

DEFINE_DSRE_FUNCTION(CCppCallJavaScriptDlg,LineTo)
{
    int x,y;
    x=(*args)[0]->AsInt();
    y=(*args)[1]->AsInt();

    ::LineTo(m_hDC,x,y);
}

DEFINE_DSRE_FUNCTION(CCppCallJavaScriptDlg,TextOut)
{
    int x,y;
    x=(*args)[0]->AsInt();
    y=(*args)[1]->AsInt();
    wchar_t *text=(*args)[2]->AsString()->GetText();
    ::TextOutW(m_hDC,x,y,text,(*args)[2]->AsString()->GetLength());
}

 2 向msscript.ocx添加代碼

 

    code_w=L"function OnDialogPaint(dialog){dialog.Rectangle(20,20,220,220);dialog.MoveTo(270,20);dialog.LineTo(300,120);dialog.TextOut(280,150,\"Text from JavaScript\");}";
    code=code_w.GetText();
    JScriptWrapper->Invoke(NULL,L"AddCode",&code,&ret);

 

3 在VC的 OnPaint 事件調用 JavaScript 

        LWideString code_w=L"OnDialogPaint(theCppDialog);";
        code=code_w.GetText();
        JScriptWrapper->Invoke(NULL,L"Eval",&code,&ret);

 

這樣就完成了一下調用過程:

 

為真正的雙向調用。

後記:

如果有了雙向調用技術,不難想象Flash的ActionScript的實現方法,也不難想象Maxthon的Plug-in可以用MS Script來做。如果不能實現雙向,只能像WPS那樣,Script只能作為Add-on,而不是Plug-in(沒有貶低WPS之意)。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.