SHOJI's Code
 仕事や趣味で書いた各種言語のプログラミングコード(エクセルVBA,PHP,C/C++/C#,JavaScript等)、その他雑記。
2018.05<<123456789101112131415161718192021222324252627282930>>2018.07
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

前回の記事でも書いた、テスト用のCOM。そのイベント処理をJavaScriptで使う場合、WSHならば前回の記事の方法を使えばイベントハンドラも設定できるが、HTMLのJavaScriptだと、その方法も使えないので、イベントハンドラをプロパティとして指定するようにした。
ちなみに以下がテスト用のWSH。
var objTest = WScript.CreateObject("testcom.counter", "objTest_");

if( objTest )
{
msg( "CreateObject() succeeded." );

msg( "Default value is "+objTest.value );

objTest.onchange = changed;

objTest.inc();
objTest.dec();

for(var i=0;i<10;i++) WScript.Sleep(1000);
}
else
msg( "CreatetObject() failed." );



function objTest_onchange(c)
{
msg( "(EVENT)Value changed. New value is "+c.value+"(c) / "+this.value+"(this)" );
}
function changed(c)
{
msg( "(CALL)Value changed. New value is "+c.value+"(c) / "+this.value+"(this)" );
}

function msg(txt)
{
WScript.Echo( txt );
}


ここで、問題が出た。イベントハンドラ(objTest_onchange)では、thisがそのCOMオブジェクトなのだが、プロパティとして渡した方(changed)がthisが違うもの。とある方法で調べてみると、changedのthisのクラス名は全然別のもの・・・。困ったぞ・・・。
イベント発行は最初以下のようなコードで書いていた。
void Ccounter::Raise_onchange(Icounter *counter)
{
Fire_onchange(counter);

if( m_onchange!=NULL )
{
CComVariant avarParams[1];
avarParams[0] = counter;
CComVariant varResult;

DISPPARAMS params = { avarParams, NULL, 1, 0 };
m_onchange->Invoke(DISPID_VALUE,IID_NULL,LOCALE_USER_DEFAULT,DISPATCH_METHOD, ¶ms, &varResult, NULL, NULL);
}
}


Fire_onchangeは接続ポイントを使用したイベント処理である。詳細は書かないが通常のイベントはこちらで処理される。
if( m_onchange != NULL )以後がプロパティで指定したイベントハンドラの処理である。m_onchangeはプロパティをIDispatchとして受け、代入している。

途中は省き、いろいろ調べた結果が以下のコード。
void Ccounter::Raise_onchange(Icounter *counter)
{
Fire_onchange(counter);

if( m_onchange!=NULL )
{
CComVariant avarParams[2];
avarParams[0] = this;
avarParams[1] = counter;
CComVariant varResult;

DISPID id = DISPID_THIS;
DISPPARAMS params = { avarParams, &id, 2, 1 };
m_onchange->InvokeEx(DISPID_VALUE,LOCALE_USER_DEFAULT,DISPATCH_METHOD, ¶ms, &varResult, NULL, NULL);
}
}


いろいろ調べた結果、以上のように書くと、thisが指定したオブジェクトに設定されコールされるようだ。この方法を使う場合、m_onchangeはIDispatchでなくIDispatchExにする。dispex.hをインクルードしなければならない。うまく説明できないが、ま、自分の備忘録用(^^;

テーマ:プログラミング - ジャンル:コンピュータ
コメント
この記事へのコメント
コメントを投稿する

管理者にだけ表示を許可する
トラックバック
この記事のトラックバックURL
この記事へのトラックバック
copyright © 2004-2006 SHOJI, Powered By FC2ブログ all rights reserved.
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。