2002年5月の雑感

更新日:2002-06-01
[トップページへ] [4月] [6月] [過去の雑感へ]

5月31日(金)

Win32OLE

つらつらと Cygwinの oaidl.hを眺めていました。

ITypeInfo::CreateInstanceITypeInfo::Invokeなる関数があることを初めて知りました。 Win32OLEで使えるかも知れないと思って、試行錯誤しました。 ITypeInfo::Invokeの方が、どうもうまくいきません。 引数の指定の仕方がよくわかりません。

ITypeInfo::CreateInstanceの方は、

pTypeInfo->lpVtbl->CreateInstance(pTypeInfo, NULL, &IID_IDispatch, &pDispatch);

とすれば、うまくいくことを確認しました。

pTypeInfo->lpVtbl->CreateInstance(pTypeInfo, NULL, &IID_IUnknown, &pUnknown);

としても、うまくいきます。 ですが、IDispatchインターフェースを取るんじゃ面白くないし、 IUnknownインターフェースじゃ、そこから先をどうすればいいのやらわかりません。

この2つを使えば、Dispatchインターフェースを持たないサーバー相手でも、 色々できるんじゃないかと思ったんですけど...。


5月30日(木)

Win32OLE イベントの謎

ExcelのSheetChangeイベントを調べるため次のスクリプトを実行します。

require 'win32ole'

type = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'WorkbookEvents')
method = WIN32OLE_METHOD.new(type, 'SheetChange')
method.params.each_with_index do |arg, i|
  puts "arg#{i} = " + arg.ole_type + " " + arg.name
end

結果は次の通りです。

arg0 = DISPATCH Sh
arg1 = Range Target

SheetChangeイベントの第1引数はイベントが発生したWorksheetで、第二引数はRangeオブジェクトであることがわかります。 これは、Excelのヘルプの内容とも一致しています。 では、実際にSheetChangeイベントを使った次のようなスクリプトを実行してみましょう。

require 'win32ole'
def event_handler(*args)
  args.each_with_index do |arg, i|
    if arg.kind_of?(WIN32OLE)
      puts "arg#{i} = " + arg.ole_obj_help.name 
    else
      puts "arg#{i} = " + arg.type.to_s 
    end
  end
end

excel = WIN32OLE.new('Excel.Application')
excel.visible = true
book = excel.workbooks.add

event = WIN32OLE_EVENT.new(book, 'WorkbookEvents')
event.on_event('SheetChange') {|*args|
  event_handler(*args)
}

book.Worksheets(1).cells(1, 1).value = "TEST"

実行結果は、次のようになってしまいます。

arg0 = Range
arg1 = _Worksheet

どういう訳か、引数の順序が逆転してしまいます。 event_handlerを呼び出すときに引数の順序を逆にしてしまう バグがWin32OLEに残っていたかと思いました。

ですが、Internet Explorerを使った次のスクリプトを実行すると、

require 'win32ole'

puts "------ from TYPELIB ------"
type = WIN32OLE_TYPE.new('Microsoft Internet Controls', 'DWebBrowserEvents')
method = WIN32OLE_METHOD.new(type, 'BeforeNavigate')
method.params.each_with_index do |arg, i|
  puts "arg#{i} = " + arg.ole_type + " " + arg.name
end

puts "------ from EVENT ------"

def event_handler(*args)
  args.each_with_index do |arg, i|
    if arg.kind_of?(WIN32OLE)
      puts "arg#{i} = " + arg.ole_obj_help.name 
    else
      puts "arg#{i} = " + arg.type.to_s 
    end
  end
end

ie = WIN32OLE.new('InternetExplorer.Application')
ie.visible = true

event = WIN32OLE_EVENT.new(ie, 'DWebBrowserEvents')
event.on_event('BeforeNavigate') {|*args|
  event_handler(*args)
}
ie.Navigate('http://www.ruby-lang.org/')

結果は次のようになります。

------ from TYPELIB ------
arg0 = BSTR URL
arg1 = I4 Flags
arg2 = BSTR TargetFrameName
arg3 = VARIANT PostData
arg4 = BSTR Headers
arg5 = BOOL Cancel
------ from EVENT ------
arg0 = String
arg1 = Fixnum
arg2 = String
arg3 = NilClass
arg4 = String
arg5 = FalseClass

この場合は、Type Libraryの情報と実際のBeforeNavigateの引数の順序が一致しています。

ちなみに、Excel 2000 と Internet Explorer 5.5 を使ったときの結果です。 一体、どうするのがいいんでしょうか?

今まで、誰にもこの点を指摘されたことはありませんでした。 Win32OLEを使って、ExcelのSheetChangeを使ったスクリプトを 書いたことがある人はほとんどいないものと思われます。 もっとも、SheetChangeを使ったExcel VBAを書く人も少ないでしょうけど。

Win32OLEイベントの謎の補足

上で出てくるRangeは、EXCEL VBA でおなじみのRangeのことです。 RubyのRangeクラスのことではありません。念のため。


5月29日(水)

Win32OLE

さらにバグフィックスなどをしました。 今度こそ1.7にコミットできるでしょうか。


5月28日(火)

Win32OLE

EVENTを利用したいとき、情報を得る手段が無いと思ったので、 WIN32OLE_METHOD#event_interface を追加しました。

それから、私の環境(Windows 2000)ではBCC32でもちゃんと動くようになりました。


5月27日(月)

BCC32とWin32OLE

いつの間にか sampleの ie.rb が無茶苦茶なことになってました。修正。 さらにバグフィクスとリファクタリング。 ついでに、on_eventのテスト testOLEEVENT.rbを追加。 テストメソッドは1つですけど、無いよりはましです。


5月26日()

本日買った本


5月25日()

BCC32 と Win32OLE

EVENTSINK_Constructor

pEv = (PIEVENTSINKOBJ)malloc(sizeof(IEVENTSINKOBJ));

pEv = ALLOC_N(IEVENTSINKOBJ, 1);

にして、pEv の各メンバーを初期化したら動くようになりました。 これで、コミットします。

しかし、こんな基本的な原因を見つけるのに1週間近くかかるのは駄目すぎです。


5月24日(金)

BCC32 と Win32OLE

hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, dispid,
                                 &bstr, 1, &count);

のあとの

pev = ole_wc2mb(bstr);

が2度目以降失敗しているような感じ。ole_wc2mbを使わないで、直接

fprintf(stderr, "pre\n");
pev = ALLOC_N(char, size);
fprintf(stderr, "post\n");

とやると二度目以降、postが出力されずにpreが出力され続けるというような状況です。 メモリアロケーションかGC絡みとか、なんかその辺りに問題がありそうな気がしてます。


5月23日(木)

BCC32 と Win32OLE

ienavi.rbがうまく動かない件。

よくわかりません。最初のIEからのInvoke呼び出しだけうまく拾えるけど、それ以降は全滅。

どうも 二度目以降の EVENTSINK_Invoke の処理の中の

hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, dispid,
                                 &bstr, 1, &count);

から先へ進まないような感じです。 ひょっとして、次々とやってくるIEからのInvoke呼び出しに追いつけない状態になっている?


5月22日(水)

BCC32 と Win32OLE

再度試してみたら

-LC:\borland\bcc55\lib
-LC:\borland\bcc55\lib\psdk

でもうまくできました。 ひょっとしてCRLFじゃなくてLFだったから駄目だったのかもと思い、 (ilink.cfg, bcc32.cfg ともにCygwinのvimで編集してました。)

d2u *.cfg

してから、試してみましたがやっぱりうまくいきました。 ...なんか私は疲れているみたいです。

そういえば、dependからwin32ole.cを外したことを思い出しました。 なんか、Ruby標準の拡張ライブラリだと*.cをdependに追記しているのが主流みたいでしたし、 BCC32だと depend に win32ole.c を含めないと駄目だとなんか勘違いしたみたいです。 ...重症です。

Cygwin、Mingw32、VC++、BCC32 それぞれの Ruby 1.6 と Ruby 1.7 を 1台のPCでコンパイルしていると、混乱して訳がわからなくなってきます。


5月21日(火)

BCC32 と Win32OLE

わたなべさんの情報により

-LC:\borland\bcc55\lib\psdk

を追加してみました。いつもありがとうございます。助けてもらってばかり。

最初

-LC:\borland\bcc55\lib
-LC:\borland\bcc55\lib\psdk

と書いてしまったためエラーになってしまいました。 順番が違うのでもなくて、正解は、

-LC:\borland\bcc55\lib -LC:\borland\bcc55\lib\psdk

あっ。dependファイルに、win32ole.cを記述していないことを発見。

うーむ。 コンパイルできるし、have_libraryのチェックは期待通りに動くようになったけど、 ienavi.rbはやっぱりまともに動かないなあ。

うん?

-LC:\borland\bcc55\lib\psdk -LC:\borland\bcc55\lib

の方が正解か?


5月20日(月)

BCC と Win32OLE

allocation framework を使っているから駄目なのかと思い、 使わないバージョンのWin32OLEで試してみましたが、症状は変わりませんでした。

どうも、ienavi.rb の

while ($LOOP)
  WIN32OLE_EVENT.message_loop
end

がずーっと動き続けているようです。

ちなみに、Borland C++ 対応版は、 Ruby bcc32の bcc32_ruby172patch020512.zip を利用しています。

1.6版のBCCパッチも試してみるべきか。


5月19日()

Borland C++ Compiler 5.5

遅ればせながら、インストールしました。 Rubyをコンパイルして、make test まで通ることを確認しました。素晴しい。

Win32OLEのコンパイルにも挑戦してみました。

have_library("ole32")

のチェックに失敗します。 チェック飛ばして、強引にMakefileを作ってしまえば、コンパイルできました。 うーむ。ienavi.rbが落ちてしまいます。

ienavi.rb が落ちるのは、fev_s_allocate でallocateしたオブジェクトを返してなかったからみたい。

VALUE fev_s_allocate(klass) 
    VALUE klass;
{
    obj = Data_Make_Struct(klass,struct oleeventdata,0,ole_event_free,poleev);
    ...
    return obj; //コレを忘れてました。
}

でもCygwinもVC++もMingwも無くても平気だったのはなぜ???

落ちなくなりましたが、Internet Explorer 終了しても、スクリプトが終了しません。


5月18日()

Win32OLE

Ruby 1.7 で導入された allocation framework を使うようにしました。


5月13日(月)

Fluxbox (Vine Linux 2.5)

ソースを調べて、移動量を指定できることがわかりました。

Control Mod1 l  :NudgeRight 5
Control Mod1 h  :NudgeLeft  5
Control Mod1 j  :NudgeDown  5
Control Mod1 k  :NudgeUp    5

などと後に数字を指定すればOKです。省略した場合は2に設定されます。また、

Control Mod1 l  :BigNudgeRight

Control Mod1 l  :NudgeRight 10

と同じです(ヴァージョンは、0.1.8)。


5月12日()

半角/全角キーとEscキー (Vine Linux 2.5)

コンソールだと両方のキーがESCになってました。 Xを立ち上げると半角/全角キーがKanjiになってしまいます。

調べてみたら /etc/X11/xinit/Xmodmap.jp というファイルがあって

keycode 49 = Kanji

という行が見つかりました。

直接Xmodmap.jpからこの行を削除してしまおうかと思ったのですが、それはやめて、~/.Xmodmap で

keycode 49 = Escape

としておくことにしました。

Fluxbox (Vine Linux 2.5)

Blackboxの後継になるらしいウィンドウマネージャです。 うちの環境では、ハングアップするのでずっと悩んでいました。 今日になってようやく原因がわかりました。 どうやらLANGUAGEなどで日本語を設定しているとハングアップするみたいです。

キーボードだけでほとんどすべての操作をできる点が気に入りました。 (今使っているThinkPad i1620を買ったときには、マウスも必要かと思い、USB接続のマウスも買いました。 かれこれ、1年以上経ちますが、(トラックポイントが使いやすいということもあって) 今だにマウスを使ったことがありません。)

IceWM ではウィンドウの移動をキーボードで操作できないのが、ちょっと不満でした。 それで、IceWMをやめて、(自分でプログラムしさえすれば)何でもありのsawfishを使っていたんです。 今回 Fluxboxでほぼ同じことができることがわかりました。しばらくこれを使ってみようと思います。 と言っても大した設定はしてなくて、私の設定は、この程度です。

Mod1 j  :NextWindow
Mod1 k  :PrevWindow
Control Mod1 l  :NudgeRight
Control Mod1 h  :NudgeLeft
Control Mod1 j  :NudgeDown
Control Mod1 k  :NudgeUp

あとは、1回のキーボード操作で移動量を指定できれば言うことないんですけどね。


5月11日()

Vine Linux (ThinkPad i1620)

2.1.5からのアップグレードインストールをやってみました。 (UNIX USERの付録のCD-ROM Vine 2.5 と Vine Plus を使用。)

USB接続のCD-ROMからインストールしました。 途中、エラーで1回異常終了しましたが、再度インストールをやり直したら 何とか最後まで進んだみたいです。


5月10日(金)

『さらば、愛しき鈎爪』 エリック・ガルシア

読了。

バッタもんはバッタもんでも超一流のバッタもんでした。

私は、マイクル・Z・リューインぐらいは読んだことがあるのですが、 それほどハードボイルドには馴染みがありません。 ですから、パロディがあったとしても、良くわかりませんでした。 馴染みのある人だったら、結構ニヤリとするシーンがあるのかも知れません。

そんな私でも、謎解きとして十分楽しめました。 ところどころにきっちりと伏線を張ってあります。

早くも気になっているのは、このシリーズ第二段のできです。 シリーズ第1作が一番面白いなんてことになりませんように。

Win32OLE

この前、extconf.rb の中でPLATFORMを調べて Makefileを作るかどうか判断するように 修正したのですが、やはり、方向性が間違っていました。

元々Makefileを作るかどうか判断するために利用していたhave_libraryのチェックが 生きてないことに昨日の段階で気づいたんです。

調べてみたら、

require "mkmf"
puts have_library("ole32", nil)

というのを実行すると結果は、必ずtrue になることがわかりました。 元々have_libraryを使ったチェックがチェックになってなかった訳です。

have_library("ole32")

とすれば、ちゃんとチェックしてくれるので、PLATFORMを調べるのはやめて

have_library("ole32")

でチェックするように修正しました。


5月9日(木)

Win32OLE

昨日の修正は、ちょっと方向性が間違っているような気がしてきました。 元気になったら考えてみます。(今日は体調が悪いのです。)

ruby-core

ちょっと前にsubscribeしたのですが、今だに一通も届きません。 ruby-talkの流量からして、絶対変です。 そろそろ、statで自分がちゃんとsubscribeされているかどうか確認した方がいいかも知れません。 などとと思い始めていたのですが...。 どうやら、まだ1通も流れていないらしいです(ruby-list:35020)。 もうしばらく様子を見ます。


5月8日(水)

Win32OLE

Vine Linux 2.1.5 で makeしてみました。 extconf.rb が Makefileを作って、makeを実行してしまいました。 当たり前ですがコンパイルエラーでこけてしまいました。 結局、rubyができませんでした。 まずいので、extconf.rbをちょこっと修正しました。

標準添付に向けての作業です。 コンパイルできないと最初からわかっている環境では、 他に悪影響をおよぼすことなくrubyができることを確認しておこうと思ったのでした。


5月7日(火)

仕事

今日から仕事。

ミステリなリンク

他のサイトにリンクしないのは あんまり他の(ミステリ関係の)サイト(のミステリな記述)を読んでないからなんです。


5月6日(月)

黄金週間終了

だらだらと過ごした黄金週間も終わり。

『私の!名探偵。』 (都築紫亜) 読了

2時間以内で読んでしまいました(笑)。

出だしの文章にちょっと戸惑ってしまい、素直に入りこめませんでした。

1人の登場人物が物語の語り手となる小説があります。 そのような小説は、私も読み慣れています。

ですが、この小説では、あたかも一人の登場人物が語るかのように作者が語るのです。 地の文章が、いわゆる客観的な文章でなくて、作者が表に登場してきている文章とでも言えばいいでしょうか。 ちょっとその手法に不慣れだったもので、戸惑ってしまいました。 もっとも、最初の出だしだけで、後はそれほど気にならなくなりましたが。 (最初の出だしの部分で、それが顕著だったのかも知れません。)

「読む2時間サスペンス」なので、いわゆる謎解きミステリを期待するとがっかりするかも知れません。


5月4日()

今日買った本

今日読んだ本


5月2日(木)

今日買った本

探したけど見つからなかった本


5月1日(水)

2001年度ベスト10

SRの会から届きました。

海外ミステリは、ベスト10のうち1作だけ読んでいました。

悔しかったのは、何度も書店で目についたのに 手を出さなかった本が上位にランクされていたことです。

だって、タイトルが『さらば、愛しき鈎爪』ですよ。 主人公が恐竜なんですよ。 しかも、人間社会で探偵をやるんですよ。 恐竜がハードボイルドやるんですよ。(←日本語の使い方間違ってます。) 表紙は、恐竜が帽子つけてトレンチコートを着てる絵ですよ。 いかにもバッタもん臭いじゃないですか。

国内の方では、1冊も読まなかった癖に17冊も適当に取り上げたうち 3冊がベスト10に入ってました。(今もまだ1冊も読んでいません。) 実は短篇集は別集計になっているのですが、この17冊のうち2冊が短篇集部門の上位にランクされていました。 合計5冊ということです。 1冊も読まずして、合計5冊がランクインしていたというのは我ながら見事という他ないでしょう。 (←意味不明です。)

...そんなことはどうでも良くて、ちょっとショックだったのは、 サラ・コードウェルが亡くなったということです。 知りませんでした。 『セイレーンは死の歌を歌う』『黄泉の国へまっしぐら』などのタイトルが思い出されます。 原作では探偵役のテイマー教授が男性か女性かわからないという凝った書き方をしているそうです。 翻訳でもその点には注意したというのをどこかで読んだことがあります。 結局、男性か女性かわからないままになってしまったんでしょうか。

Emacs で Unicode

遅ればせながらcmailでUTF-8のメールでも読めるようにしました。

Mule-UCS をインストールします。

tar zxvf Mule-UCS-0.84.tar.gz
cd Mule-UCS-0.84
emacs -q -no-site-file -batch -l mucs-comp.el
su
cp -r lisp /usr/local/share/emascs/site-lisp/mule-ucs

あとは、.emacs

(setq load-path (append '("/usr/local/share/emacs/site-lisp/mule-ucs") load-path))
(require 'un-define)

と書いておくだけです。

Emacs 21.2 だと起動に時間がかかるため、そのためのパッチがあります。 URL忘れました。 patch emacs 21.2 mule-ucs あたりで Google などで検索してみれば それらしきものが見つかると思います。


[トップページへ] [4月] [6月] [過去の雑感へ]