なんかこのままの状態で明日を向かえると、結構まずいので、 体力回復のため早く寝ます。 Win32OLEの標準添付化作業はちょっとお休み。
Linux Japanが届きました。 早速 CD-ROM から Mozilla 0.9.8 をインストールしました。 今月で定期講読の期間が終わります。 継続手続きはしないかも知れません。
ちょっと疲れている感じなので、のんびり過ごす。
IceWMではタスクバーに時刻を表示できたのだがgolemにはその機能がありません。 ちょっとつらいので ActTitleをインストールしました。
./configure make make install
設定ファイル ~/.acttrc を acttrc.ja を元に作ります。
date @ now { format = "%Y-%m-%d(%a) %H:%M"; }
で acttitle を起動します。あれっ? 何も表示してくれませんよ。 それどころか、元々表示されてたタイトルの文字まで消してくれてます。
いろいろフォーマットを変更して試して、ようやくタイトルに日本語を表示できないことに気づきました。 別に日本語を表示できなくても構わないので、
LC_LANG=C LC_LANGUAGE=C LC_ALL=C acttitle
と実行することにしました。 デフォルトでは更新間隔が1分なので実際の時刻とちょっとずれてしまいます。 1秒間隔にするほどのこともないので、とりあえず、更新間隔を10秒間隔にしておくことにしました。
date @ now { interval=10s; format = "%Y-%m-%d(%a) %H:%M"; }
標準添付へ向けて残りの作業
1.7対応。
ほったらかしのドキュメントは別にしちゃった方がいいのかな?
リファクタリング
1.7対応に関しては、ちょっと調べた範囲だとさほどインパクトが無さそう。 ドキュメントはちょっと時間がかかるかな。
また、ここまで、とりあえず動くように実装するのを優先して、作業を進めてきたので、 リファクタリングの時間をちょっとだけ取ることにした。
sampleとtestsはそのまま入れておくことにした。 だけど、どんな環境でも動くようなものにはなってない。 Excelをはじめ、いろんなものが入ってないと駄目。 そもそも、自分では何もしない、何もできない、 他力本願コバンザメ拡張ライブラリだからしょうがない。
testsの方は、test専用OLEサーバーを作れば、自己完結するけど そこまでするだけの気力が無い。
artonさんの意見も取り入れて、 WIN32OLE_EVENT.on_event_with_out_args というのを追加。 WIN32OLE_EVENT.on_event_with_array_argv は削除しました。 次のようにします。
require 'win32ole' def new_window2(ppdisp, cancel, args) puts "new_window2 Event" # prevent the new window args[1] = true end ev = WIN32OLE_EVENT.new(ie, 'DWebBrowserEvents2') ev.on_event_with_out_args("NewWindow2") {|ppdisp, cancel, args| new_window2(ppdisp, cancel, args) }
第3引数は、Internet Explorerに返すための配列の引数です。 argsは空の配列なので、引数を参照したい場合は、ppdisp, cancelの方を参照してください。
標準添付に向けて残っている作業は
WIN32OLE_METHOD#offset_vtbl VTBLのオフセット(FUNCDESC の oVft)を返すやつ。
WIN32OLE_TYPE#new あった方がいいよなあ。多分。
WIN32OLE_METHOD#new 同上。
1.7対応。
ほったらかしのドキュメントは別にしちゃった方がいいのかな?
sampleとtestsはそのまま入れちゃっていい?
こんなとこでしょうか。
私は、他人に影響されやすいです。 今回も影響されて、Icewm をやめて golem を使い始めました。 なかなか軽くていいです。
以前、blackboxを試したことがありました。 そのときは、フォーカスの切り替えなどの操作に違和感を覚え、すぐにIcewmに戻りました。 今回はそのような違和感も無いので、このまましばらく使い続けるかも知れません。
なんかインストールはうまくいかなくて、一部のファイルを手動でコピーする必要がありました。
golem.installを実行すると、~/.xinitrc と ~/.xsession を作ります。その中で、
exec golem
として、golemを起動するようになってます。
この方法は、Vineとはちょっと違うので、Vineに合わせて(?) ~/.Xclientsを使うことにしました。
cp /etc/X11/xinit/Xclients ~/.Xclients
としてから .Xclients の中に
golem*) startWM golem golem ;;
というのを追加しました。 後は、~/.wm_style を
golem
に変更しておけばOKです。
と言いながら、sawfishもちょっと気になってインストールしました。
Emacs 21にしたので、気づいたのだけど、 emacs-w3mにはタブブラウザ機能があったり、 Forwardボタンなどがあったりして、 w3mとは別物のように思えてしまう。
別物だと割り切ってしまえば、 w3mとのキーバインドの違いも気にならないのだが、 なまじ名前にw3mとついているのでどうもひっかかる。 いっそのこと全然違う名前にしちゃったらどうだろうかと思ったのだが それでは、w3mに対して失礼ではないかとも考え、w3mの雰囲気を残しつつ w3mとは全然違う名前ということで、
w3m
を180度ひっくり返して
mEw
なんて名前はどうだろうかとふと思ったんだけど、それだと キーバインドの違いじゃなくて、 「なんでメールが送信できないんだよお。」と機能の違いが気になる人が 出てくるんじゃないかと心配になり、 ひっくり返す方がよほど、w3mに対して失礼なんじゃないかとも思えてきて この名前も良くないなあという結論になってしまった。
名前は難しい。
なんだ。RDocでも同じようなことが できるようになってたのか([ruby-talk:33673])。
Win32OLEに対するnew_window2
メソッドの中で、
呼出元(EVENTSINK_Invoke)の値にまで影響を与えるという最近の取り組み。
[ruby-list:33931]でまつもとさんから引導を
渡されちゃったような気がするのは気のせいだな。きっと。うん。そうに違いない。
いや。まあ。Rubyレベルでできないことは最初から百も承知なんですけど。
インストールしてみた。
めでたく、screen内で emacs -nw -f cmail
でも色がつくようになった。
結局、WIN32OLE_EVENT.on_event_with_array_argv というのを導入してみました。
require 'win32ole' def new_window2(args) puts "new_window2 Event" # prevent the new window args[1] = true end ev = WIN32OLE_EVENT.new(ie, 'DWebBrowserEvents2') ev.on_event_with_array_argv("NewWindow2") {|args| new_window2(args) }
引数を配列で渡すという方法です。 new_window2の引数は必ず配列にする必要があります。 かなり苦しいです。
artonさんの案がどういうものかまだよくわかっていません。 artonさんの案の方がよいとわかればそっちに変更します。
なかなか、すんなりといい案が出てきません。 結局、OLEとRubyの仕組みというか、設計思想というか、デザインというか、なんかわからんけど、 何かが根本的にどこかで違っているから、 すんなりいかないのではないだろうか と思ったり、思わなかったりしないでもない今日この頃です。
Rubyの拡張ライブラリからクラスやモジュールやメソッド定義を抜き出すツール RUDE4C。 あとで、Win32OLEに試してみよう。
[ruby-list:33853]が最近の私のWin32OLEに対する取り組みと重なって 興味深く感じてしまいました。 決して、ここから続くスレッドの中で、RubyUnitが取り上げられたり、 極道編が取り上げられたりしているからではありません。
私が取り組んでいるのは、ここで触れていることとは逆のことだからです。 つまり、def文の中の実行文で外部の変数に影響を与えたいのですね。
def new_window2(ppdisp, cancel) cancel = true end
EVENTSINK_Invokeの中から上のnew_window2を呼び出したときに、 new_window2の中の実行文による、cancelの変更を 外部(呼び出し元)のEVENTSINK_Invokeにまで影響させたい訳ですから。
で、この後に続く[ruby-list:33856]で配列やハッシュを戻り値にして 呼び出し元に伝える話が出てきます。 実は、この手法も1つの解決案として考えたことがあります。
def new_window2(ppdisp, cancel) cancel = true [ppdisp, cancel] end
という風にしてから、EVENTSINK_Invoke側でnew_window2の戻り値をそのまま、 InternetExplorer側に返してやるというものです。
残念ながらこれもボツになりました。 採用に至らなかった理由は、結局 new_window2を定義する側が、必ず戻り値を意識しなければならなくなるのが面倒だからです。
例えば、
$args = [] def new_window2(ppdisp, cancel) $args.push ppdisp $args.push cancel end
とした場合でも、戻り値は、
[ppdisp, cancel]
になってしまいます。 これをそのままInternet Explorerに返してしまっては、new_window2を 定義した側が驚き、予想外の結果を引き起こす可能性もあります。 そういう訳でボツになってしまったのでした。
しつこく続く...。
安直な解決編は、やはり安直でしかなく、欠陥が見つかりました。
ボツにした案その2です。
その案は、WIN32OLE_EVENT::ARGV という定数を導入するというものです。
まず、Init_win32ole
の中で WIN32OLE_EVENT::VARIANT を定義します。
rb_define_const(cWIN32OLE_EVENT, "ARGV", rb_ary_new());
でもって、EVENTSINK_Invoke
の中で、new_window2
を呼び出す直前にARGVを空にします。
new_window2
を呼び出した後で、pdispparams
の中身をARGVの中身で書き換えてやります。
/* ARGVの中身をクリア */ argv = rb_cvar_get(cWIN32OLE_EVENT, rb_intern("ARGV")); rb_funcall(argv, rb_intern("clear"), 0); /* new_window2 を呼び出す。*/ rb_apply(handler, rb_intern("call"), args); /* ARGVでpdispparams構造体の中身を書き換える */ ary2ptr_dispparams(argv, pdispparams);
new_window2
側では、WIN32OLE_EVENT::ARGVに上書きしたい内容をセットするというものです。
def new_window2(ppdisp, cancel) WIN32OLE_EVENT::ARGV[1] = true end
WIN32OLE_EVENT::ARGV[0] が NewWindow2イベントの第1引数ppdispに、 WIN32OLE_EVENT::ARGV[1] が NewWindow2イベントの第2引数 cancelに対応します。
cancel = true
と上書きする代わりに
WIN32OLE_EVENT::ARGV[1] = true
としてもらおうということです。
スクリプトを書く方にすれば、ちょっとわかりにくいシンタックスになってしまいます。 この方法は、いい方法とは言えません。
でも、欠陥というのは、そのことではありません。
EVENTSINK_InvokeはInternet Explorerから呼び出されます。 どんなタイミングで呼び出されるかわかりません。 その中で、WIN32OLE_EVENT::ARGV というグローバルな定数を利用しているのが欠陥です。
Internet Explorer が EVENTSINK_Invoke を呼び出す。
WIN32OLE_EVENT::ARGV クリア
EVENTSINK_Invokeが new_window2 を呼び出す。
new_window2の実行が終了する前に EVENTSINK_Invokeが呼び出される。
WIN32OLE_EVENT::ARGV クリア
EVENTSINK_Invoke が new_window2 または他のコールバックルーチン(ブロック)を呼び出す。
最初の new_window2の処理が終了。
WIN32OLE_EVENT::ARGV を pdispparams にセット...したいけど、 WIN32OLE_EVENT::ARGVの値はどうなってるの???
ということでなんかまずそうな気がしたのでボツになりました。
以下続く...。
ちょっと間が空きましたが、続きです。
new_window2で第2引数がtrueになったことをEVENTSINK_Invokeが認識する。 (または、new_window2から、EVENTSINK_Invokeに第2引数がtrueになったことを伝える。)
EVENTSINK_InvokeがInternet ExplorerにNewWindow2の第2引数がtrueになったことを伝える。
これらの問題を解決する方法ですがボツになった案を紹介します。
ボツにしたのはWIN32OLE_VARIANT クラスを導入する方法です。
次のような構造体を定義します。
struct variant { VARIANT *pvar; }
次に、Init_win32ole の中で、WIN32OLE_VARIANT クラスを定義しておきます。
また、WIN32OLE_VARIANT#=
メソッドを定義しておきます
cWIN32OLE_VARIANT = rb_define_class("WIN32OLE_VARIANT", rb_cObject); rb_define_method(cWIN32OLE_VARIANT, "=", folevariant_setval, 1);
new_window2への引数を生成している次の部分
args = rb_ary_new(); ...(中略) // make argument of event handler for (i = 0; i < pdispparams->cArgs; ++i) { VARIANT *pVariant = &pdispparams->rgvarg[pdispparams->cArgs-i-1]; rb_ary_push(args, ole_variant2val(pVariant)); }
を、次のように書き変えます。
args = rb_ary_new(); ...(中略) // make argument of event handler for (i = 0; i < pdispparams->cArgs; ++i) { v = Data_Make_Struct(cWIN32OLE_VARIANT, struct variant,0,variant_free, pvariant); pvariant->pvar = &pdispparams->rgvarg[pdispparams->cArgs-i-1]; rb_ary_push(args, v); }
こうしておけば、new_window2の引数はWIN32OLE_VARIANT型になります。
def new_window2(ppdisp, cancel) cancel = true end
としたときに cancel は WIN32OLE_VARIANT型なので、cancel = true
で
WIN32OLE_VARIANT#=
メソッド、つまり folevariant_setval
関数が呼ばれます。
あとは、この関数の中で、pvariant->pvar
の値を変更すればいいのです。
一見良さそうに思えたのですが、次のようなことをされると困りそうです。
$cancel def new_window2(ppdisp, cancel) $cancel = cancel end .... $cancel = false
$cancelの実体である variant 構造体の pvar メンバは
pvariant->pvar = &pdispparams->rgvarg[pdispparams->cArgs-i-1];
なので、EVENTSINK_Invoke 関数の中だけで有効なのです。
$cancelの値は new_window2の外部でどうするか決められなかったので、この案はボツにしました。
イベントに対するコールバックの引数は、そのコールバックの中だけで有効
というルールにすることも考えました。 ですが、ルールはルールでしかありません。 上のような困ってしまうコードを防ぐことができません。 残念ながらボツにしてしまいました。
えーと...。 ボツにした理由を書いておかないと、忘れそうなので、ここに書いておくことにしました。
以下、安直な解決篇へ続く...。 (←誰も読んでないんじゃないかという気がするが、それは気のせいだと思うことにしよう。)
ありがとうございます。 使わせてもらいます。
最後の作品だけちょっと無理矢理、科学とミステリを結びつけたような気がしないでもありません。 『爆ぜる』で本当は最後にするつもりだったんじゃないかと邪推してます。
『探偵ガリレオ』東野圭吾
連作ミステリーだったので。長い話よりも短編の方が気楽に読める。
『御手洗潔のメロディ』島田荘司
久々に読む御手洗シリーズ。これも連作だということで。
Cマガジン
XP(eXtreme Programming)の記事があったので。
ruby-talkは、Subjectに番号がつかなくなってしまった。 このページを書くときに、[ruby-talk:XXXX]などと参照するときにcmailを起動しても番号がわからない。 そこで、X-Mail-Countも表示するように、cmail-always-shown-headers に追加した。
昨日の続きです。
Internet Explorerからは、NewWindow2イベントがRubyスクリプトに通知され、 次のnew_window2が実行されます。
def new_window2(ppdisp, cancel) puts "new_window2 Event" # prevent the new window cancel = true end
ここで、
cancel = true
としているにも関わらず、そのことはInternet Explorer側には伝わりません。 Internet Explorerは何事もなかったかのように新しいウィンドウを開いてしまうのです。
ここから先は、Win32OLEのソースコードを調べる必要があります。
ソースコードの中でnew_window2
を呼び出しているのは、EVENTSINK_Invoke
関数の
rb_apply(handler, rb_intern("call"), args);
です。この後、EVENTSINK_Invoke
関数は、何もしないで
return NOERROR;
として終了します。これが問題なのです。
EVENTSINK_Invoke
関数は、「NewWindow2イベントが発生したよ」という通知とともに
Internet Explorer側から呼び出されます。
NewWindow2
には
NewWindow2 A new, hidden, non-navigated WebBrowser window is needed. DISPATCH ppDisp in out BOOL Cancel in out
ということからわかる通り、ppDisp
とCancel
という2つの引数があります。
これら2つのNewWindow2の引数の情報もInternet ExplorerからEVENTSINK_Invoke
に渡されます。
この2つの引数の情報は1つのDISPPARAMS構造体にまとめられ、そのポインタがEVENTSINK_Invoke
の
第6引数としてEVENTSINK_Invoke
側に渡されるのです。
EVENTSINK_Invoke
関数は、この通知を受けて、new_window2メソッドを呼び出します。
このときEVENTSINK_Invoke
関数は第6引数DISPPPARAMS *pdispparams
(=NewWindow2の2つの引数)の
内容をnew_window2用の引数args
に変換します。この引数の変換処理が次の部分です。
args = rb_ary_new(); ...(中略) // make argument of event handler for (i = 0; i < pdispparams->cArgs; ++i) { VARIANT *pVariant = &pdispparams->rgvarg[pdispparams->cArgs-i-1]; rb_ary_push(args, ole_variant2val(pVariant)); }
new_window2呼び出し用の引数 args
を作ったらEVENTSINK_Invoke
は
rb_apply(hander, rb_intern("call"), args)
を実行して、new_window2メソッドを呼び出します。 new_window2メソッドは
cancel = true
を実行して、第2引数を変更しています。
このあと、EVENTSINK_Invoke
関数は、new_window2
で第2引数が変更されたことを無視して
return NOERROR;
とInternet Explorerに返しています。
だから、Internet Explorerは、new_window2で、 NewWindow2の第2引数(=new_window2の第2引数)がtrueになったことを知らず、 新しいウィンドウを開いてしまうのです。
問題は2つです。
new_window2で第2引数がtrueになったことをEVENTSINK_Invokeが無視している。
このため、EVENTSINK_InvokeからInternet Explorerに第2引数がtrueになっていることが伝わらない。
2つの問題を解決するためには、
new_window2で第2引数がtrueになったことをEVENTSINK_Invokeが認識する。 (または、new_window2から、EVENTSINK_Invokeに第2引数がtrueになったことを伝える。)
EVENTSINK_InvokeがInternet ExplorerにNewWindow2の第2引数がtrueになったことを伝える。
とする必要があります。
2は実現できます。 NewWindow2の引数は、DISPPARAMS構造体ヘのポインタとしてEVENTSINK_Invokeへ渡されてきています。 EVENTSINK_Invoke側で、そのポインタの中身を書き変えれば、 Internet Explorerに第2引数がtrueになったことが伝わります。 (ただし、配列など、すべてのケースに真面目に対応しようとするとかなり面倒です。 今回は、簡単に対応できそうなものだけ対応するつもりです。)
残りは1の方です。 (以下続く...)
昨日までのヘルプを表示する話はちょっと横に置いといて、[ruby-talk:32343]の話です。
本題に入る前に断っておきます。 Win32OLE 0.3.5a を使わないとここに書いてあるスクリプトは動作しません。
私は、最初、[ruby-talk:32343]がどういう意味なのかよくわかりませんでした。 ようやく、[ruby-talk:33057]で何がやりたかったのか理解しました。 結論から言うと、現状のWin32OLEで同様のことを実現するのは不可能です。
何が不足しているかを調べる前に、同じものをWin32OLEを使って書くにはどうするかを考えてみます。
まずは、NewWindow2が何者か調べることにします。 [ruby-talk:33105]のメールから、Internet Explorer(internet control)のメソッドらしいということがわかります。そこで、
require 'win32ole' ie = WIN32OLE.new('InternetExplorer.Application') ie.visible = true ie.ole_methods.each do |m| puts m.name end ie.quit
なんてスクリプトを実行してみます。 ところが、NewWindow2という名前のメソッドは残念ながら見あたりません。
そこで、ExcelのVBE(Visual Basic Editor)で調べてみることにしました。
まず、[ツール]メニューの[参照設定]を選択します。 注意深く参照可能なライブラリファイルを見ていくと
Microsoft Internet Controls
というのが見つかります。
ここから先もVBEを使って調べてもいいのですが、せっかくなのでWin32OLEを使ってみましょう。
require 'win32ole' classes = WIN32OLE_TYPE.ole_classes('Microsoft Internet Controls') classes.each do |c| puts c.name puts c.helpstring c.ole_methods.each do |m| puts " " + m.name end end
上のスクリプトを実行すると、見事に NewWindow2 が見つかりました。
ちょっと話がそれてしまいますが、 「タイプライブラリ名をリストアップするメソッドがあると便利」というのは ExcelのVBEを使わなくても、
WIN32OLE_TYPE.typelibs
なんていうメソッドで参照可能なライブラリファイルをリストアップできれば便利だろうと いうことを意図しています。
話を元に戻しましょう。NewWindow2は何ヶ所かで出てくるのですが、
DWebBrowserEvents2 Web Browser Control events interface ...(中略) NewWindow2
というのが最も気になるところです。 ここを狙い打って調べてみましょう。
require 'win32ole' classes = WIN32OLE_TYPE.ole_classes('Microsoft Internet Controls') web = classes.find {|c| c.name == 'DWebBrowserEvents2'} puts web.name puts web.helpstring new_window2 = web.ole_methods.find{|m| m.name == 'NewWindow2'} puts " " + new_window2.name puts " " + new_window2.helpstring new_window2.params.each do |param| print " " + param.ole_type + " " + param.name print " in" if param.input? print " out" if param.output? puts "" end
ちょっとまだるっこしいスクリプトです。
classes = WIN32OLE_TYPE.ole_classes('Microsoft Internet Controls') web = classes.find {|c| c.name == 'DWebBrowserEvents2'}
じゃなくて
web = WIN32OLE_TYPE.new('Microsoft Internet Controls', 'DWebBrowserEvents')
と書けた方が便利だろうし、
new_window2 = WIN32OLE_METHOD.new('Microsoft Internet Controls', 'DWebBrowserEvents', 'NewWindow2")
か、
new_window2 = WIN32OLE_METHOD.new(web, 'NewWindow2')
と書けた方がスマートです。(というのが5日に書いたことの意図ですね。) この辺は、今後のWin32OLEのToDoということで。
さて、スクリプトを実行すると出力結果は次のようになります。
DWebBrowserEvents2 Web Browser Control events interface NewWindow2 A new, hidden, non-navigated WebBrowser window is needed. DISPATCH ppDisp in out BOOL Cancel in out
見事に、[ruby-talk:33057]のVBのサンプルと一致しています。
Win32OLEを使ってVBのサンプルをRubyに「翻訳」するとこんな感じでしょうか。
require 'win32ole' def stop_msg_loop puts "Now Stop IE..." $LOOP = FALSE; end def new_window2(ppdisp, cancel) puts "new_window2 Event" # prevent the new window cancel = true end ie = WIN32OLE.new('InternetExplorer.Application') ie.visible = TRUE ev = WIN32OLE_EVENT.new(ie, 'DWebBrowserEvents2') ev.on_event("NewWindow2") {|ppdisp, cancel| new_window2(ppdisp, cancel) } ev.on_event("OnQuit") {|*args| stop_msg_loop} $LOOP = TRUE while ($LOOP) WIN32OLE_EVENT.message_loop end
スクリプトは動きます。 IEが起動したあと、新しいウィンドウでリンク先を開こうとすると、 イベントが発生して、ちゃんとnew_window2は実行されます。 ですが、残念ながら、期待している通りにはなりません。 新しいウィンドウが開いてしまうのです。 (以下続く...)
HtmlHelpA API の使い方は間違ってませんでした。
間違っていたのは、Ruby API rb_scan_args
の使い方です。
fole_s_showhelp(argc, argv, self) int argc; VALUE *argv; VALUE self; { VALUE helpfile; VALUE helpcontext; rb_scan_args(argc, argv, "1*", &helpfile, &helpcontext); if(helpcontext == Qnil) helpcontext = INT2FIX(0); pfnHtmlHelpA(GetDesktopWindow(), STR2CSTR(helpfile), 0x0f, FIX2INT(helpcontext)); }
ここで、pfnHtmlHelpA は GetProcAddress で取得した "HtmlHelpA" のポインタです。
rb_scan_args
の第3引数に "1*" を指定した場合、argvの1番目が helpfileに、
argvの残りがすべて配列の形でhelpcontextに設定されます。
例えば、argvの内容が
['VBAXL.HLP', 10425]
の場合、
helpfile = 'VBAXL.HLP' helpcontext = [10425]
となってしまいます。
ここで、第2引数の(1つの要素から成る)配列をFIX2INT
でCの整数に変換するととんでもないことになります。
(今回は偶然にも動き続けましたが、core dump することもあるかも知れません。)
FIX2INTは何のチェックもしないでいきなりCの整数に変換しようとするからです。
たまたま値がどうなっているんだろうと思って、
fprintf(stderr, "%d\n", FIX2INT(helpcontext));
としたらとんでもない大きい数に変換されてました。なんか変だなあと思って
NUM2INT(helpcontext);
としてやっと配列になっていることに気付きました。 (FIX2INTと違ってNUM2INTは数値に変換できるかどうかを事前にチェックしてくれます。)
本来は、第2引数が配列にならないように
rb_scan_args(argc, argv, "11", &helpfile, &helpcontext);
とすべきでした。 また、今回の場合は、チェックなしでいきなり、FIX2INTやSTR2CSTRを 使ってCの整数や文字列に変換しているのもまずかったです。 チェックが必要でした。
著者と訳者が同じであることは別に疑問でも何でもないですね。 その通りなんでしょう。 IじゃなくてIIだけをLinux Japanで紹介しているというのは相変わらず疑問です。
タイプライブラリ周辺のメソッドをいくつか追加した方が、より使い勝手が良くなるかと考えています。 タイプライブラリ名をリストアップするメソッドとか、WIN32OLE_TYPE.new や、WIN32OLE_METHOD.new とか。
ITypeLibのGetDocumentationを使うとヘルプファイルとヘルプコンテキストを得ることができます。 これを使ってヘルプファイルを表示するメソッドをWin32OLEに追加しようとしているのですが、 何も表示してくれません。 (←このようなメソッドをWin32OLEに組み込むべきかどうかは意見の別れるところでしょうが、 表示できないことには、意見もへったくれもないので(笑)、とりあえずそれは横に置いときます。)
きっと HtmlHelpA API の使い方を間違えているんでしょう。 先に純粋なCのプログラムを書いて実験してみますか。
大幅にいじったので、0.3.5a としてリリース。 olegen.rbも動くようにしたつもり。 ぼちぼちドキュメントも整備しよう。
久々にコンパイルしようとしてconfigure
したら
Inline image support (you need Imlib library) [n]?
と聞いてきた。 標準サポートになったのか。
いろいろといじってます。 今から予告しておくと、
ole_methods
ole_get_methods
ole_put_methods
ole_func_methods
ole_method
ole_obj_help
なんかは互換性がなくなります。
3月号の「新刊採って出し」で 『理論物理学のための幾何学とトポロジーII』 が紹介されています。 なぜなんでしょうか? さらに、『理論物理学のための幾何学とトポロジーI』は見あたらないようです。
アンケート葉書を出して、編集部にこの疑問をぶつけてみようかと考えております。
さらにさらに、「中原幹夫 著/中原幹夫、佐久間一浩 訳」となっております。 一瞬誤植かと思ったのですが、本の表紙の写真の方も「中原幹夫 著/中原幹夫、佐久間一浩 訳」 となっているように見えます。 謎は深まるばかりです。
原書のタイトルと著者がどうなっているのかという疑問もぶつけてみようかと思います。