米国カリフォルニアで11月初頭に開催されたProfessionel Developers Conference(PDC)の席上で、Visual Basic 5.0 Control Creation Edition(CCE)が配布された。同時に、米国MicrosoftのWWWサイトからもダウンロードできるようになった。まだ正式には発表されていないVisual Basic 5.0だが、すでにここからもどのような形になるのかが見えてきた。早速、このVisual Basic 5.0 CCEの概要についてレポートしよう。
Visual Basic 5.0といえば、ネイティブコンパイラやActiveXコントロールが作れるといった機能を持つ次世代のVisual Basicとして、まだまだ整備されていないActiveX開発環境を一気に整備するツールとして期待されている。しかし、その正式なアナウンスはまだない。ところが、例によってPDCでいきなり機能限定版のVisual Basic 5.0 CCEが発表され、同時にWWWからダウンロードすることができるようになった。URLは次の通り。
http://www.microsoft.com/vbasic/controls/controls.htm
ちなみに、Netscape Navigatorなどでは正常にページが表示されないので注意して欲しい。
実際には、Visual Basic 5.0 CCE本体以外に、ヘルプファイルやドキュメント、サンプルプログラムなどが別モジュールでダウンロードできる。
面白いのは、ヘルプファイルやドキュメントはCCE専用のものではなく、開発中のVisual Basic 5.0からの抜粋である。当然ながらCCE以外の機能についてもこの中には入っている。したがって、よく読むとActiveX Documentsアプリケーションのサポートやそれに伴う新しい仕様などが分かってしまう。これは大変興味深いところだ。
まずはインストールということになるが、これについてはたいした問題はない。例によってカンタンである。
図1:VisualBasic5.0CCE 起動画面
ここに表示されているものは、それぞれ次の通り。
ここでは、ActiveX Controlを選ぶことにしよう。いよいよVisual Basic 5.0の本体に触れるときがきた。
図2 Developer Studio風なMDIインターフェイス
図3 プロパティウィンドウ
では、さっそくActiveXコントロールを作ってみよう。ここではWWWコンテンツとして一応少しは役立ちそうなものをと考え、次のようなものを作ることにした。
ActiveXコントロールのインターフェイス(外部公開オブジェクト)は次のようにする
まずはデザインである。これは、通常のVisual Basicと同じだ。というより、ActiveXコントロールはVisual Basic 4.0でClassを使ってOLE Serverを作ったことがあれば、その流れでユーザーインターフェイスも作ることができると思えばよい。ただ、デザインするコンテナがフォームではなくて、サブフォームのようなコントロールモジュール(.CTLファイル)であるということだ。逆に、このへんのことが分かっていないと説明が非常に複雑になってしまうので、ここではOLE Serverを作る知識はあるものとして話を進める。OLE Server作成についての情報はマニュアルまたは私が以前に書いた記事を参照してほしい。
ここでは、ラベルはひとつだけコントロール配列として配置した。さらに必要なプロパティ設定などをする。このあたりの手順は基本的にまったく同じなので、Visual Basic 5.0 CCEが作った定義を示す。
次に、実際にコントロールとして動くようなコードを追加していこう。
まずは、コントロールの初期化である。
通常のフォームモジュールにForm_Initializeイベントがあったように、ActiveXコントロール起動時には、UserControl_Initializeイベントが発生する。ここで、必要な初期化をする。
図4: 自動インクリメンタルサーチをサポート
このコントロールを使うには、ラベルに表示されるタイトル文字列と、対応するURLを呼び出し元から指定してやらなくてはならない。そうしないと汎用に使えないからだ。
ここでは、AddItemというメソッドを作って、これらを引数として渡す。コントロールでは呼び出されるごとにラベルをコントロール配列としてLoadし、必要な設定をする。ちなみに、一石二鳥になるからURLはToolTipTextプロパティに入れておくことにしよう。
また、このときコントロール自体のサイズも大きくしておく必要がある。
次に、マウスが移動したら色が変わるという部分を記述する。これは特に面倒なことはないが、マウスカーソルがコントロールから外れたときに色が変わっているリストボックスがないようにしなくてはならない。ここでは簡易的にリストボックスの周りをわざと空けておき、そこにマウスカーソルが移動したときにクリアするようにしている。ただし、この方法は簡易的なものであり、マウスをすばやく移動したときにはうまく動かない。
クリックされたとき、コンテナにイベントを発生させる部分のコーディングだ。
まず、Generalに次のようにイベントのプロトタイプを記述する。
以上で、ActiveXコントロールとして動作させる最低限の部分はできた。しかし、開発環境中で使うことを前提としたプロパティなどの指定が必要なときには、もうちょっとワザがいる。というのも、開発環境中でもActiveXコントロールは動作するからだ。プロパティウィンドウなどとのやり取りも必要になる。
ここでは、BackColorおよびDispFontプロパティをテスト的に作ってみた。実際には、BackColorプロパティは実行時には反映されないし、DispFontプロパティは本来ならFontプロパティとしたかったのだが、ActiveX Control Padの不具合からFontという名前を使うことができないので、このような暫定的なものにしてある。
基本的には、プロパティプロシージャまたはモジュールレベルのPublicな変数がプロパティとなるので、このへんはClassでのプロパティの作り方となんら変わっていない。
図5: Property Page Wizard
また、同じくアドインとしてActiveX Control Interface Wizard(図6)も用意されているので、利用するとよいだろう。また、カスタムのプロパティページは、埋め込みフォームのようなPropertyPageモジュールを追加してデザインすることもできる。
図6: ActiveX Control Interface Wizard
こうして作成したプロパティやメソッドなどは、[Tools][Procedure Attribute]で開くダイアログ(図7)を使って、デフォルトプロパティやストックプロパティとのオーバーライド、プロパティページへの割り振り、プロパティのカテゴライズ、さらにはデータバインドコントロールとしての動作なども規定することができる。
図7:Procedure Attribute設定ダイアログ
これで一通りの作業は終了だ。プロジェクトの名前を設定しておけば[File][Makeプロジェクト名.ocx]というメニューからActiveXコントロールを作成することができる。
しかし、これでいちいちもう一つのVisual Basicを起動してデバッグしてはいられない。Visual Basic 5.0 CCEでは、ひとつの環境でコントロールと通常のプロジェクトを同時に動かしてデバッグできるようになっている。
図8:MDIなのですぐに収集がつかなくなるDesktop
図9:プロジェクトナビゲーターの出番である
ちなみに、こうして作成するコントロールと標準のEXEプロジェクトなどは、Project Groupとしてまとめて管理するファイルを作ることができる。
図10:正常に動作するとこのようになる。
これで作成したActiveXコントロールが動作することを確認したら、Setup Wizardを使って他のマシンでも動作するようなインストーラーを作成する。
図11:SetupWizardが Webに対応している
こうして作成したActiveXコントロールを実際に使うためには、VB ScriptまたはJava ScriptをHTMLに埋め込んで、タイトルやURLの初期化をし、さらにイベントに対応して指定されたURLに飛ばさなくてはならない。ここでは、次のように記述して、新しいブラウザを起動してそのURLに飛ばすようにした。
超特急でVisual Basic 5.0 CCEの使い方を紹介してきたが、実際使ってみた時間が短いこともあって、現状では不明点も多かった。間違いや説明不足の点もあると思うが、ご勘弁いただきたい。
なお、 PCDN (http://pcdn.int21.co.jp/pcdn/)では、Visual Basic 5.0 CCEで作成したActiveXコントロールを使ったページおよび、ソースコードなどをダウンロードして使うことができるページを用意する予定だ。おそらくこの本が並んでいるころには、面白いActiveXコントロールを使ったページが並んでいることだろう。
Visual Basic 5.0 CCEと、ActiveX Control Padなどを組み合わせると、現実的にActiveXコントロールを使ったWWWページを作ることができる。私も早速チャレンジしてみた。
結果から言うと、懸案となっていたActiveXコントロールを使ったページの作成まで、一通りのことを実現することができた。
能書きはこれくらいにして、早速レポートしよう。
ただ、デフォルトの設定ではレジストリに余計なことを書いてしまうので、Visual Basic 4.0などでレジストリからカスタムコントロール一覧などを取得しようとしたときにエラーになってしまう。その他にも制限事項はいろいろあるので、Radmeをきちんと読んでおこう。
さて、Visual Basic 5.0 CCEのインストールが終了すると、フォルダーにはCCE本体の他に、Application Setup WizardとReadMeがインストールされる。Setup Wizardは作成したActiveXコントロールをディスクの形またはWWWからのダウンロードを可能にするもので、ActiveXはOCXであり、インターネット用のコントロールであることは、ここからも分かる。
Visual Basic 5.0 CCEを起動すると、図1のようなダイアログが開く。今回からVisual Basicはいろいろなタイプのプログラムを作ることができるようになったので、このようにタイプを選ぶことができるのだ。面白いのは、新規以外のときにも、同様のダイアログが表示され、既存のものや最近使ったものなどもリストから選ぶことができるようになっている。
ActiveX Control ActiveXコントロールプロジェクトを作る
Standard EXE 標準的なアプリケーションを作る(CCEではEXEは作成できない)
CtlGroup ActiveXコントロールと標準アプリを組み合わせてグループ化したプロジェクト
すでに、このダイアログの下に見えていたように、Visual Basic 5.0からはMDIが採用された(図2)。従来のSDIインターフェイスは残されてはいるが、今後の標準はMDIということだろう。この環境はVisualC++などのDeveloper Studioに似ているが、まったく違うものである。
この環境で面白いのは、複雑化するプロジェクトに合わせて、プロジェクトナビゲータが採用されたことだ。また、プロパティもグループごとに表示できる(図)。ツールボックスにしても、<General>の表記があるように、おそらくグループ化されるのだろう。このように、かなりDelphiっぽく使いやすくなっている。また、Immediate Windowや追加さりたFormLayout Windowなども規定位置に表示されるようになっている。このように、一見使いやすそうなのだが、実際にはこのMDIの中ですべての作業をしだすと、画面サイズとして1024x768は最低必要であろう。
この他にもメニューまわりに細かい変更や追加があるが、必要なものだけ随時述べることにしよう。
これで、プロパティ、メソッド、イベントを一通り使うことができる。
VERSION 5.00
Begin VB.UserControl URLGuide
BackColor = &H80000001&
ClientHeight = 750
ClientLeft = 0
ClientTop = 0
ClientWidth = 5250
EditAtDesignTime= -1 'True
PropertyPages = "URLGuide.ctx":0000
ScaleHeight = 750
ScaleWidth = 5250
Begin VB.Label lblURL
Alignment = 2 'Center
BackColor = &H0000FFFF&
Caption = "lblURL"
BeginProperty Font
Name = "MS Pゴシック"
Size = 11.25
Charset = 128
Weight = 700
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
Height = 255
Index = 0
Left = 240
TabIndex = 0
Top = 240
Width = 4815
End
End
Attribute VB_Name = "URLGuide"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = True
Attribute VB_Ext_KEY = "PropPageWizardRun" ,"Yes"
また、定数および変数は、次のようなものをあらかじめ定義・宣言した。
maxurlは、表示されるラベルの数 +1である。
lastIndexは、前回マウスがあった位置のラベルのインデックスだ。
Option Explicit
Private Const COLOR_NOMAL = &HFFFF&
Private Const COLOR_MOVE = &HFF00&
Private Const COLOR_SELECT = &HFFFF00
Private maxurl As Integer
Private lastIndex As Integer
' Initialize Color, Value
Private Sub UserControl_Initialize()
lblURL(0).BackColor = COLOR_NOMAL
maxurl = 0
lastIndex = -1
End Sub
一般的にコントロールをコンテナから使ったとき、貼り付けるとCtlName1, CtlName2のように自動的に数値が表示される。これは、コンテナがこの番号を管理しているのだが、 ExtenderオブジェクトのNameプロパティとして知ることができる。したがって、ActiveXコントロールのラベルにこの名前を表示すれば、区別がつきやすくなる。
ちなみに最適なイベントは、UserControl_InitPropertiesイベントである。
ただし、このExtenderオブジェクトをサポートしていないコンテナ環境もある。たとえばActiveX Control Padではサポートしていないため、エラーとなってコントロールをロードできない。そこで、ここにはエラーをスキップするコードを入れておく。
' Display Control Name
Private Sub UserControl_InitProperties()
On Error Resume Next
lblURL(0).Caption = Extender.Name
End Sub
ところで、Visual Basic 5.0からはオブジェクト名のあとに.(ピリオド)を入力した瞬間に、図のようにオブジェクトの中身がリストされインクリメンタルサーチされる。これは便利なのだが、Spaceで決定するもので、Enterでは入らない。また、遅いマシンだとつらいかもしれない。
' Method for Title & URL
Public Sub AddItem(title As String, url As String)
If maxurl <> 0 Then
Load lblURL(maxurl)
End If
With lblURL(maxurl)
.Caption = title
.ToolTipText = url
If maxurl <> 0 Then
.Top = lblURL(maxurl - 1).Top + .Height
End If
Height = lblURL(0).Top * 2 + .Height * (maxurl + 1)
.Visible = True
End With
maxurl = maxurl + 1
End Sub
' Switch Selected Color
Private Sub lblURL_MouseDown(Index As Integer, Button As Integer, Shift As Integer, X As Single, Y As Single)
lblURL(Index).BackColor = COLOR_SELECT
End Sub
' Switch Moving Color
Private Sub lblURL_MouseUp(Index As Integer, Button As Integer, Shift As Integer, X As Single, Y As Single)
lblURL(Index).BackColor = COLOR_MOVE
End Sub
' Moving Color
Private Sub lblURL_MouseMove(Index As Integer, Button As Integer, Shift As Integer, X As Single, Y As Single)
If lastIndex <> Index Then
lblURL(Index).BackColor = COLOR_MOVE
If lastIndex <> -1 Then
lblURL(lastIndex).BackColor = COLOR_NOMAL
End If
lastIndex = Index
End If
End Sub
' Return to Normal Color by Border (BackStyle must be 1- Opaque)
Private Sub UserControl_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
If lastIndex <> -1 Then
lblURL(lastIndex).BackColor = COLOR_NOMAL
End If
lastIndex = -1
End Sub
Public Event URLChange(url As String)
実際にイベントを発生させるには、RaiseEventメソッドを使う。ここに、プロトタイプに記述した内容に添って、イベントを発生させるためのイベント名や引数を指定する。ここでは、引数としてURLを渡す。
' Fire Event
Private Sub lblURL_Click(Index As Integer)
RaiseEvent URLChange(lblURL(Index).ToolTipText)
Beep
End Sub
' DispFont Get Property
Public Property Get DispFont() As Font
Attribute DispFont.VB_ProcData.VB_Invoke_Property = "StandardFont;Font"
Set DispFont = lblURL(0).Font
End Property
' DispFont Set Property
Public Property Set DispFont(ByVal vNewValue As Font)
Set lblURL(0).Font = vNewValue
lblURL(0).Refresh
End Property
' BackColor Get Property
Public Property Get BackColor() As OLE_COLOR
Attribute BackColor.VB_ProcData.VB_Invoke_Property = "StandardColor;Appearance"
Attribute BackColor.VB_UserMemId = -501
BackColor = UserControl.BackColor
End Property
' BackColor Set Property
Public Property Let BackColor(c As OLE_COLOR)
UserControl.BackColor = c
UserControl.Refresh
End Property
問題となるのは、デザイン時のプロパティの処理である。
これは、 UserControl_ReadPropertiesとUserControl_WritePropertiesというメソッドを作って対処する。それぞれ、プロパティウィンドウの内容を読む、プロパティウィンドウに設定を書くものだ。プロパティウィンドウとのやりとりはPropertyBagオブジェクトを使う。このオブジェクトは、実はプロパティのコレクションになっていて、各プロパティの内容に連想配列でアクセスできる。データの受け渡しには、PropertyBagオブジェクトのReadPropertyとWritePropertyメソッドを使う。
このあたりのインターフェイスがコンテナとうまく行かなかったときに対応するために、エラー処理を入れてある。
また、このコードを記述したあとは、UserControlのEditAtDesignTimeプロパティをTrueにしておく必要がある。
' Read Property Bag
Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
On Error Resume Next
Set lblURL(0).Font = PropBag.ReadProperty("DispFont")
If (Err) Then MsgBox Err.Description
Err.Clear
UserControl.BackColor = PropBag.ReadProperty("BackColor")
If (Err) Then MsgBox Err.Description
End Sub
' Write Property Bag
Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
On Error Resume Next
PropBag.WriteProperty "DispFont", lblURL(0).Font
If (Err) Then MsgBox Err.Description
Err.Clear
PropBag.WriteProperty "BackColor", UserControl.BackColor
If (Err) Then MsgBox Err.Description
End Sub
こうした作成したプロパティは、ActiveXコントロールというかOCXの常で、プロパティページで管理できた方がいい。もちろん、Visual Basic 5.0 CCEでも対応している。プロパティページは、アドインとして用意されているProperty Page Wizardで作成し、UserControlのPropertyPagesプロパティで指定することができる(図5)。
[File Add Project]でStandard EXEを追加すると通常のフォームが入ったMDI子ウィンドウが現れる。ActiveXコントロールモジュールのウィンドウを閉じると、ツールボックスにActiveXコントロールのアイコンが表示される。あとは、これをふつうにフォームに配置すればよい。
図8のように、MDIなのでウィンドウだらけになって何がナンだかわからなくなってくる。こんなときにも、プロジェクトナビゲーター(図9)を使えば、構造が分かりやすい。

ここでは、次のようなコードを追加した。
Private Sub Form_Load()
URLGuide1.AddItem "int21", "http://www.int21.co.jp/"
URLGuide1.AddItem "int21net", "http://www.int21net.or.jp/"
URLGuide1.AddItem "PCDN", "http://pcdn.int21.co.jp/pcdn/"
URLGuide1.AddItem "MSKK", "http://www.microsoft.co.jp/"
URLGuide1.AddItem "MSHQ", "http://www.microsoft.com/"
URLGuide1.AddItem "yahoo! Japan", "http://www.yahoo.co.jp/"
End Sub
Private Sub URLGuide1_URLChange(url As String)
Caption = url
End Sub
デバッグ自体は通常のデバッグと変わらない。ただ、コントロールのウィンドウが出ているときには、フォーム上のコントロールが暗い顔をしたちびまるこちゃん状態になったりするので注意してほしい。
実際に動かしてみると、図10のように動作する。

ここで、ActiveXコントロールは通常のOCX的な使い方の他に、インターネットにも対応することになるから、インターネットからのダウンロードできるような設定も作ることができる(図11)。こうして作成すると、CABファイルとインストールするためのHTMLのテンプレート(次のリスト)ができる。あとは、必要に応じて変更すればよい。
<HTML>
<!-- If any of the controls on this page require licensing, you must create a license package file.
Run LPK_TOOL.EXE in the tools directory to create the required LPK file.
<OBJECT CLASSID="clsid:5220cb21-c88d-11cf-b347-00aa00a28331">
<PARAM NAME="LPKPath" VALUE="LPKfilename.LPK">
</OBJECT>
-->
<OBJECT
classid="clsid:132EDE2E-3B26-11D0-B2F1-0040C79407A8"
id=URLGuide
codebase="URLCtl2.CAB#version=1,0,0,0">
</OBJECT>
</HTML>
ちなみに、当然ながら現在は対応するブラウザはIE 3.01以降ということになる。このとき、IEのセキュリティオプション、すなわち[表示][オプション]の[セキュリティ]タグから<安全性のレベル>を選び、「中」あるいは「なし」に設定しておく必要がある。デフォルトの「高」の状態では安全なActiveXコントロールと認証されないので、自動的にダウンロードが行われない。
PCDNにある実際に動いているページもご覧いただきたい。
<HTML>
<HEAD>
<SCRIPT LANGUAGE="VBScript">
<!--
Sub window_onLoad()
URLGuide1.AddItem "int21", "http://www.int21.co.jp/"
URLGuide1.AddItem "int21net", "http://www.int21net.or.jp/"
URLGuide1.AddItem "PCDN", "http://pcdn.int21.co.jp/pcdn/"
URLGuide1.AddItem "MSKK", "http://www.microsoft.co.jp/"
URLGuide1.AddItem "MSHQ", "http://www.microsoft.com/"
URLGuide1.AddItem "yahoo! Japan", "http://www.yahoo.co.jp/"
end sub
Sub URLGuide1_URLChange(url)
call window.open(url, "Hello", windowFeatures, width, height)
end sub
-->
</SCRIPT>
<TITLE>Guide URL ActiveX Control Test Page</TITLE>
<H1>Guide URL ActiveX Control Test Page</H1>
<P>
</HEAD>
<BODY>
<HR>
<H3>これはVisual Basic 5.0 CCEで作ったActiveX Controlです。</H3>
<P>
<UL>
<LI>表示されているタイトルの上にマウスが移動すると、色が変わります。<BR>
<LI>そのままマウスを動かさないと、ToolTipに対応するURLが表示されます。<BR>
<LI>タイトルをクリックすると、ブラウザが開いて指定されたURLが表示されます。<BR>
</UL>
<P>
<OBJECT ID="URLGuide1" WIDTH=351 HEIGHT=51
CLASSID="CLSID:132EDE2E-3B26-11D0-B2F1-0040C79407A8">
<PARAM NAME="_ExtentX" VALUE="9260">
<PARAM NAME="_ExtentY" VALUE="1323">
<PARAM NAME="BackColor" VALUE="-2147483647">
</OBJECT>
<P>
<H4>なかなかかわいいですね。</H4>
</BODY>
</HTML>
Visual Basic5.0 CCEを使いこなすには、細かい部分で新たに学習が必要なところは多々ある。しかし、実にカンタンにActiveXコントロールを作成でき、しかもWWWページからダウンロードできる設定なども半自動化して作業ができる。ただ、β版ということもあり、細かい部分での言語仕様の詰めの甘さや、Visual Basic以外のツールとの不整合なども見えてきて、まだまだこれからが本番だなという印象だ。
しかし、こんな面白いオモチャは久しぶりである。読者諸氏も今後のためにもぜひDownloadしてチャレンジしていただきたい。なお、次号のVisual Basic Magazineの付録CD-ROMには、このVisual Basic 5.0 CCEが収められる予定だ。