WIN32OLE

Comパッケージのデフォルトの使い方では、以下のように使いたいアプリケーション毎にクラスを定義するような感じのようだ。

ie := Examples.InternetExplorerApplicationController new.

なのでrubyと同じようにnewするときにProgIDを引数に与えられるWIN32OLEクラスを作ってみる。

クラス定義

スーパークラスはExamples.InternetExplorerApplicationController等と同じExternal.COMAutomationApplicationControllerクラスにする。

Smalltalk defineClass: #WIN32OLE
	superclass: #{External.COMAutomationApplicationController}
	indexedType: #none
	private: false
	instanceVariableNames: ''
	classInstanceVariableNames: 'progID '
	imports: ''
	category: 'Com- Automation'

クラスメソッド定義

versionIndependentProgIDメソッドがsubclassResponsibilityになっているので必ず実装する必要がある。ここでnew:のときに与えておいたprogIDを返すようにすればよい。

new: str 
	progID := str.
	^super new

versionIndependentProgID
	^progID

使用例

 | ie |
ie := WIN32OLE new: 'InternetExplorer.Application'.
ie isVisible: true.
ie invokeMethod: 'navigate' with: 'http://www.google.com/'

問題点

progIDはクラス変数なのでいろいろなインスタンスを作っているとおかしなことになってしまう。

 | ie excel |
ie := WIN32OLE new: 'InternetExplorer.Application'.
Transcript show: ie class versionIndependentProgID  "→ieオブジェクトなのでInternetExplorer.Applicationと出る"
excel := WIN32OLE new: 'Excel.Application'.
Transcript show: ie class versionIndependentProgID  "→ieオブジェクトなのにExcel.Applicationと出る"

ちなみに、versionIndependentProgIDメソッドを使っているのは、Examples.*クラスを除くと、COMAutomationControllerクラスのクラスメソッドclsidが使っていた