初音 玲 HATSUNE, Akira
|
準備その1〜クラス (サンプル1:Samp0704) |
|---|
Set objSamp0704 = New clsSamp0704のようにオブジェクト変数を割り当てるとクラスモジュールのロジックは、そのオブジェクト変数ごとに別々の変数領域が取られた状態で管理されることになる。この変数領域とは、プログラム中で宣言したり使ったりしている変数ばかりではなく、内部的な変数もすべて含んでいる。よって、クラスモジュールの中で管理している値を参照すると図1のようにオブジェクトごとに別々の値が返却されてくる。

|
準備その2〜インプロセスCOMサーバー (サンプル2:Samp0802) |
|---|
Option Explicit Private mintCount As Integer Public Function intCountDisp() As Integer mintCount = mintCount + 1 intCountDisp = mintCount End Function |


Option Explicit ' インプロセスCOMサーバーオブジェクト変数 Private maobjSamp(0 To 4) As clsSamp0802 Private Sub Form_Initialize() ' インプロセスCOMサーバーオブジェクトの生成 Set maobjSamp(0) = New clsSamp0802 Set maobjSamp(1) = New clsSamp0802 Set maobjSamp(2) = New clsSamp0802 Set maobjSamp(3) = New clsSamp0802 Set maobjSamp(4) = New clsSamp0802 End Sub Private Sub Form_Terminate() ' インプロセスCOMサーバーオブジェクトの解放 Set maobjSamp(0) = Nothing Set maobjSamp(1) = Nothing Set maobjSamp(2) = Nothing Set maobjSamp(3) = Nothing Set maobjSamp(4) = Nothing End Sub Private Sub cmdObjUse_Click(Index As Integer) ' [オブジェクトを使う]ボタン lblObjUse(Index).Caption = maobjSamp(Index).intCountDisp End Sub |



| COLUMN1 ActiveX DLLファイルの使い方 |
|
開発環境でActiveX DLLを実行したとき、自動的に行なわれるためにあまり意識されないもののひとつにActiveX DLLファイルのレジストリへの登録がある。 ActiveX DLLファイルを配布したときなどは、DOSプロンプトでActiveX DLLファイルのディレクトリに移動し、 REGSVR32 ActiveX DLLファイル名としてレジストリへ登録する。レジストリには、ActiveX DLLファイルのディレクトリ位置も記憶されているので、もしActiveX DLLファイルを削除したりディレクトリを移動するときは、削除や移動前に、 REGSVR32 -u ActiveX DLLファイル名としてレジストリからActiveX DLLファイルの情報を削除しなければならない。 また、ActiveX DLLファイルのバージョンを変更したときも同様な操作が必要だ。 |
|
準備その3〜ローカルCOMサーバー (サンプル3:Samp0803) |
|---|


| COLUMN2 ActiveX EXEファイルの使い方 |
|
開発環境でActiveX EXEを実行したとき、自動的に行なわれるためにあまり意識されないもののひとつにActiveX EXEファイルのレジストリへの登録がある。 ActiveX EXEファイルを配布したときなどは、DOSプロンプトでActiveX EXEファイルのディレクトリに移動し、 ActiveX EXEファイル名 /regserverとしてレジストリへ登録する。レジストリには、ActiveX EXEファイルのディレクトリ位置も記憶されているので、もし、ActiveX EXEファイルを削除したりディレクトリを移動するときは、削除や移動前に、 ActiveX EXEファイル名 /unregserver としてレジストリからActiveX EXEファイルの情報を削除しなければならない。 また、ActiveX EXEファイルのバージョンを変更したときも同様な操作が必要だ。 |
|
非同期通知を作成する (サンプル4:Samp0804) |
|---|

Option Explicit
Private Declare Sub Sleep Lib "kernel32" _
(ByVal dwMilliseconds As Long)
Public Event evtSamp0804(ByVal vintCount As Integer)
Private mintCount As Integer
Public Sub psubCountDisp()
Dim lngSleep As Long
' (1)イベントを発生させる
RaiseEvent evtSamp0804(0)
' (2)非同期処理を行なう
mintCount = mintCount + 1
' (3)非同期動作を実感するために5秒処理を待つ
lngSleep = 5000
Sleep (lngSleep)
' (4)イベントを発生させる
RaiseEvent evtSamp0804(mintCount)
End Sub
|
オブジェクト名_イベント名というイベントに対応したサブプロシージャがクライアント側で利用可能となるので(図10)、そこにイベント発生時の処理を記述する(リスト4)。

Option Explicit
Private Declare Function timeGetTime Lib "WINMM" () As Long
' ローカルCOMサーバーオブジェクト変数
Private WithEvents maobjSamp0 As clsSamp0804
Private WithEvents maobjSamp1 As clsSamp0804
Private WithEvents maobjSamp2 As clsSamp0804
Private WithEvents maobjSamp3 As clsSamp0804
Private WithEvents maobjSamp4 As clsSamp0804
Private Sub Form_Initialize()
' ローカルCOMサーバーオブジェクトの生成
Set maobjSamp0 = New clsSamp0804
Set maobjSamp1 = New clsSamp0804
Set maobjSamp2 = New clsSamp0804
Set maobjSamp3 = New clsSamp0804
Set maobjSamp4 = New clsSamp0804
End Sub
Private Sub Form_Terminate()
' ローカルCOMサーバーオブジェクトの解放
Set maobjSamp0 = Nothing
Set maobjSamp1 = Nothing
Set maobjSamp2 = Nothing
Set maobjSamp3 = Nothing
Set maobjSamp4 = Nothing
End Sub
Private Sub cmdObjUse_Click(Index As Integer)
' [イベントを使う]ボタン
cmdObjUse(Index).Enabled = False
Select Case Index
Case 0
Call maobjSamp0.psubCountDisp
Case 1
Call maobjSamp1.psubCountDisp
Case 2
Call maobjSamp2.psubCountDisp
Case 3
Call maobjSamp3.psubCountDisp
Case 4
Call maobjSamp4.psubCountDisp
End Select
End Sub
Private Sub maobjSamp0_evtSamp0804(ByVal vintCount As Integer)
lblObjUse(0).Caption = vintCount
If vintCount > 0 Then
cmdObjUse(0).Enabled = True
End If
End Sub
Private Sub maobjSamp1_evtSamp0804(ByVal vintCount As Integer)
lblObjUse(1).Caption = vintCount
If vintCount > 0 Then
cmdObjUse(1).Enabled = True
End If
End Sub
Private Sub maobjSamp2_evtSamp0804(ByVal vintCount As Integer)
lblObjUse(2).Caption = vintCount
If vintCount > 0 Then
cmdObjUse(2).Enabled = True
End If
End Sub
Private Sub maobjSamp3_evtSamp0804(ByVal vintCount As Integer)
lblObjUse(3).Caption = vintCount
If vintCount > 0 Then
cmdObjUse(3).Enabled = True
End If
End Sub
Private Sub maobjSamp4_evtSamp0804(ByVal vintCount As Integer)
lblObjUse(4).Caption = vintCount
If vintCount > 0 Then
cmdObjUse(4).Enabled = True
End If
End Sub
|

|
非同期処理を作成する (サンプル5:Samp0805) |
|---|


Option Explicit
Public Event evtSamp0805(ByVal vintCount As Integer)
Public Sub psubCountDisp()
' (1)イベントを発生させる
RaiseEvent evtSamp0805(0)
' (2)タイマーを起動する
Call psubBeginTimer(Me)
End Sub
Friend Sub Notify(ByVal vintCount As Integer)
' (9)終了イベントを発生させる
RaiseEvent evtSamp0805(vintCount)
End Sub
Public Sub StopTimer()
Call psubEndTimer
End Sub
Private Sub Class_Terminate()
' タイマーが停止していることを確認
Call psubEndTimer
End Sub
|
Option Explicit
Private Declare Function SetTimer Lib "user32" _
(ByVal hwnd As Long, _
ByVal nIDEvent As Long, _
ByVal uElapse As Long, _
ByVal lpTimerFunc As Long) As Long
Private Declare Function KillTimer Lib "user32" _
(ByVal hwnd As Long, _
ByVal nIDEvent As Long) As Long
Private Declare Sub Sleep Lib "kernel32" _
(ByVal dwMilliseconds As Long)
Private mlngTimerID As Long
Private mobjSamp0805 As clsSamp0805
Private mintCount As Integer
Public Sub psubEndTimer()
Dim lngRet As Long
lngRet = KillTimer(0, mlngTimerID)
End Sub
Public Sub psubBeginTimer(ByRef robjSamp0805 As clsSamp0805)
' (3)クラスモジュールへの参照を保存
Set mobjSamp0805 = robjSamp0805
' (4)タイマーをセットして、とりあえず処理終了
mlngTimerID = SetTimer(0, 0, 1, AddressOf subTimerProc)
End Sub
Private Sub subTimerProc(ByVal hwnd As Long, _
ByVal umsg As Long, _
ByVal idEvent As Long, _
ByVal dwtime As Long)
Dim lngSleep As Long
Dim lngRet As Long
' (5)タイマーを停止
lngRet = KillTimer(0, mlngTimerID)
' (6)非同期処理を行なう
mintCount = mintCount + 1
' (7)非同期動作を実感するために5秒処理を待つ
lngSleep = 5000
Sleep (lngSleep)
'(8)処理完了通知
mobjSamp0805.Notify (mintCount)
End Sub
|
| COLUMN3 IDE上で実行時の注意点 |
|
ローカルCOMサーバーのインスタンシングに「オブジェクトごとのスレッド」を指定していたとしてもActiveX EXEとバイナリ互換性のあるVisual Basicプロジェクトを実行してデバッグしているときは、IDEのスレッドしか起動されない。したがって、オブジェクトごとのスレッドにはならないので注意が必要だ。 |
|
非同期処理を隠蔽する (サンプル6:Samp0806) |
|---|
Option Explicit
' ローカルCOMサーバーオブジェクト変数
Private WithEvents maobjSamp As clsSamp0805
' 公開メソッド
Public Event evtSamp0806(ByVal vintCount As Integer)
Private Sub maobjSamp_evtSamp0805(ByVal vintCount As Integer)
' 公開イベントの発行
RaiseEvent evtSamp0806(vintCount)
End Sub
Private Sub UserControl_Initialize()
' ローカルCOMサーバーオブジェクトの生成
Set maobjSamp = New clsSamp0805
End Sub
Private Sub UserControl_Terminate()
' ローカルCOMサーバーオブジェクトの解放
Set maobjSamp = Nothing
End Sub
Public Sub psubCountDisp()
' 公開メソッド
' 非同期処理の実行
Call maobjSamp.psubCountDisp
End Sub
|

Option Explicit
Private Declare Function timeGetTime Lib "WINMM" () As Long
Private Sub cmdObjUse_Click(Index As Integer)
' [イベントを使う]ボタン
cmdObjUse(Index).Enabled = False
utlSamp(Index).psubCountDisp
End Sub
Private Sub utlSamp_evtSamp0806(Index As Integer, ByVal vintCount As Integer)
lblObjUse(Index).Caption = vintCount
If vintCount > 0 Then
cmdObjUse(Index).Enabled = True
End If
End Sub
|
| 最後に |
|---|
□稼動確認環境 Windows 98 SE 4.10.2222a Visual Basic 6.0(SP3)