2013年10月25日金曜日

拡張性に魂を縛られた人々(2)

Google V8 に ActiveXObject サポートを追加する,の続き.とりあえず
ExcelSheet.ActiveSheet.Cells( 1, 1 ).Value = "hoge";
を通すことを目標にがんばる.

まず,Cells が関数じゃねぇというエラーについて.
Cells は GetFuncDesc() した結果,INVOKE_FUNC じゃなくて INVOKE_PROPERTYGET が返ってきている.つまり関数じゃなくて単なるプロパティとして v8 は扱うので,Cells() が function じゃねぇという指摘はごもっとも.

じゃ実際に Cells を Invoke した時に何が返ってきているかというと VT_DISPATCH が返ってきていた.つまり「ExcelSheet.ActiveSheet.Cells」ここまでは,ActiveXObject オブジェクトということになる.

ここで v8 に SetCallAsFunctionHandler というのがあったなぁとピンときた.
v8.h のコメントを読んでみると,「オブジェクトをファンクションコールのように呼んだ時に呼ばれるハンドラ関数を登録する」とのことで,ズバリそのものだった.このハンドラに,Cells の Invoke で得た ActiveXObject オブジェクト≒IDispatch に Invoke するハンドラを登録すれば良い (ハンドラ自体は普通の ActiveXObject オブジェクト のメンバ function を Invoke する関数と全く同じ).

問題は Cells の IDispatch のなんというメソッドを呼べばよいのか?
ここからはググっても明確なドキュメントが得られなかったので自分の推測になるが,おそらく _Default というプロパティが DispatchID 0 で登録されている決まりになっているらしく,_Default か DispatchID 0 かどちらかで Invoke するのが正解のようだ.

という訳で↓が動いたヽ(´ー`)ノ
var ExcelSheet = new ActiveXObject("Excel.Sheet");
ExcelSheet.Application.Visible = true;
ExcelSheet.ActiveSheet.Cells( 1, 1 ).Value = "This is column A, row 1";
ExcelSheet.SaveAs("TEST.XLS");
ExcelSheet.Application.Quit();

Excel はそこそこにして,お次は本命の XMLHttpRequest に挑戦する.

0 件のコメント:

コメントを投稿