【第7回】
eMbedded VisualBasicその2
eMbedded VisualBasicのTips
(01/01/23)
はじめに
「eMbedded VisualBasic 3.0」は前回の記事で書いたようにVisualBasic6.0との違いも多く、開発に手間取ることもあるかもしれない。この記事では最初に手間取りそうなところを中心にその対策を掲載してみた。
コントロール配列が無いことに対する対策
eMbedded VisualBasic3.0はコントロール配列が使えない。これはヘルプにも明記してある。だが、それをなんとかする対策を見つけたので、紹介しよう。
例として、TextBoxを3つ配置し、これをコントロール配列にしたいとする。まず、フォームにTextBoxを配置する。コピーして貼り付けても例の「コントロール配列にしますか?」のメッセージは出ない。そのまま配置し、計3個配置する。オブジェクト名は、それぞれText1,Text2,Text3とする。
次にフォームの(General)(Decralations)に以下のように書く。
Dim TextArray(3) As TextBox
つまりTextBoxの配列を宣言したわけだ。あとは、これにフォームで配置したTextBoxをSetしていくだけである。これはFormのLoadあたりでやっておけばいいだろう。
Set TextArray(0) = Text1
Set TextArray(1) = Text2
Set TextArray(2) = Text3
この部分はコントロールが多いと長くなっていくが、ツールを作れば簡単にソースコードを生成できるだろう。あとはTextArrayを使って、普通にコントロール配列の使い方をすればよい。例えば、以下のようにである。
For i = 0 To 2
TextArray(i).Text = i
Next i
PocketPCでメニューを使う
eMbedded VisualBasic 3.0ではフォーム上で右クリックしても[メニューエディタ]が無い。つまり、メニューが作れないのである。これはどうしたらよいのか。PocketPC用の場合の対策を紹介しよう。
まず、メニューの[プロジェクト]-[コンポーネント]から「Microsoft PocketPC MenuBar Control 3.0」にチェックを入れ、OKを押す。これでツールボックスにメニューバーが表示されるようになる
これをフォームの下の位置に配置する。あとはこのメニューに内容を設定し、それがクリックされたときの処理内容を記述する、ということになる。
まず、メニュー内容の設定だが、これはFormのLoadあたりでやると良いだろう。以下のように行う。
Dim MenuItem
Set MenuItem = MenuBar1.Controls.AddMenu("File")
MenuItem.Items.Add , , "About"
MenuItem.Items.Add , , "Exit"
この例ではFileメニューを作成し、その中にAboutとExitを作成している。
メニューが選択されたときの処理は、MenuBarコントロールのMenuClickイベントで以下のように行う。
Private Sub MenuBar1_MenuClick(ByVal Item As MenuBarLib.Item)
Dim Response As Integer
Select Case Item.Caption
Case "Exit"
Response = MsgBox("Quit?", vbYesNo, "MySoft")
If Response = 6 Then
App.End
End If
Case "About"
frmAbout.Show
End Select
End Sub
つまり、クリックされたItemのCaptionを判断して、処理を振り分けている。
ActiveXコントロールを実機に登録する
[プロジェクト]-[コンポーネント]からActiveXコントロールを挿入し、フォームに配置、いざ実機で実行しようとすると「コントロールを作成できませんでした」とエラーになる場合がある。これはActiveXコントロールを実機に転送、登録していないことが原因である。
このような場合には、[ツール]-[リモートツール]-[コントロールマネージャ]で登録すればよい。
通常は、[プロジェクト]-[xxxのプロパティ]でコンポーネントを更新のところの「周波数」(frequency=「頻度」の誤訳?)を「確認」にしておけば、コンポーネントがあるかどうか確認して、無い場合には自動的にインストールしてくれる。しかし、この確認作業は案外時間がかかるので、普段必要ない場合には「確認しない」にしておくと実行するまでの時間が速くなる。
ファイル処理
eMbedded VisualBasic 3.0では昔からおなじみのファイルを扱うOpen関数やClose関数などがない。ではどうするかというと、ファイルコントロールを使う。ファイルコントロールはファイルを扱うためのActiveXコントロールであり、[プロジェクト]-[コンポーネント]からMicrosoft CE File System Control 3.0にチェックを入れ、OKを押す。これでツールボックスにファイルコントロール及びファイルシステムが表示されるようになる。
まずはファイルコントロールをフォーム上に配置する。そして、ファイルを読み込むときには以下のようにする。
File1.Open "ファイル名", fsModeInput
data1 = File1.LineInputString
data2 = File1.LineInputString
data3 = File1.LineInputString
File1.Close
書き込むときには以下のように行う。
File1.Open "ファイル名",, fsModeOutput
File1.LinePrint data1
File1.LinePrint data2
File1.LinePrint data3
File1.Close
詳しくはヘルプのファイルコントロールのメソッドを参照してほしい。
終了するには?
VisualBasicでは通常、End で終了できる。だが、eMbedded VisualBasic 3.0ではEndが使えない。どうするか?。分かってしまえば簡単なことで、 App.End を使用するとよい。
Left関数が使えない?
Formモジュール中にLeft関数を使うと実行時にエラーになる。これはLeft関数が無いわけではなく、Formモジュールの中ではFormのLeftプロパティと区別が付かないため、エラーになるわけである。標準モジュールでLeft関数を使えば問題なく使える。対策としては、Formモジュール中ではLeft関数の代わりにMid関数を使えばよい。
実機上でハングアップしたときの対策
実機上でプログラムがハングアップしてしまい、どうしても終了できないときにはどうするか。このようなときには、[ツール]-[リモートツール]-[プロセスビューア]を使う。これで終了させたいプログラム(プロセス)を選択肢、×ボタンを押せばよい。VisualBasicプログラムの場合、pvbload.exeというファイル名である。
インストーラの作成
eMbedded VisualBasic 3.0で作成したソフトは、.vbファイルであるため単体では動作しない。また、たいていの場合、ActiveXコントロールをいくつか使っているだろうから、それを登録する必要がある。このようなことからインストーラを作成することは必須と言えるだろう。eMbedded VisualBasic 3.0ではアプリケーションインストールウィザードを使って、簡単にインストーラを作成出来る。
[ツール]-[リモートツール]-[アプリケーションインストールウィザード]を選択するとアプリケーションインストールウィザードを起動できる。指示に従って選択していくだけで指定したフォルダ配下のCD1フォルダにcabファイルとsetup.exeファイルが出来る。
オンラインで配布する場合には、このCD1フォルダにある全ファイルをLZHなどで圧縮して1ファイルにし、配布すればよい。CD-ROMで配布する場合には、CD1フォルダにある全ファイルをCDにコピーする。ランタイムなどがあるのでサイズがかなり大きくなる(全ファイルをLZHで圧縮したところ1MBぐらい)のが欠点だが、最近のオンラインソフトとしてはそれほど極端に大きいというわけではないだろう。
DoEventsに代わる関数
この記事でeMbedded VisualBasic 3.0にDoEventsが無いことに対する対策を募集したところ、株式会社システムインフィニティの川島 裕之様より以下のようなメールがあった。DoEventsに代わる関数をAPIで実現する、というのものだ。川島様、大変ありがとうございます。
DoEventsに関しての記事を見ましたので、参考になればと思いまして、
メールさせて頂きました。
私は、以下の処理でVBのDoEventsに対応する処理を実行しています。
Option Explicit
'APIの定義
'DoEvents用
Declare Function GetMessage Lib "Coredll.dll" Alias "GetMessageW" _
(ByVal Msg As String, ByVal hwnd As Long, ByVal wMsgFilterMin As Long, _
ByVal wMsgFilterMax As Long, ByVal wRemoveMsg As Long) As Long
Declare Function TranslateMessage Lib "Coredll.dll" (ByVal Msg As String) As Boolean
Declare Function DispatchMessage Lib "Coredll.dll" Alias "DispatchMessageW" _
(ByVal Msg As String) As Boolean
'*******************************************************************************
'* Proc Name : CE_DoEvents
'* Description : DoEvents処理
'* : Windows CE3.0
'* Input Param : #1 ctlForm(Object) : Form オブジェクト <<必須>>
'* Output Param : Nothing
'* Return Param : Nothing
'* Create Date : 2001/02/05 H.Kawashima Ver 1.0
'* Update Date :
'*******************************************************************************
Sub CE_DoEvents(ctlForm As Form)
On Error Resume Next
Dim PM_REMOVE As Integer
Dim Msg As String
Dim pHwnd As Object
pHwnd = ctlForm.hwnd
Msg = String(18, Chr(0))
PM_REMOVE = 1
If GetMessage(Msg, pHwnd, 0, 0, PM_REMOVE) Then
TranslateMessage (Msg)
DispatchMessage (Msg)
End If
Err.Clear
End Sub
さいごに
実際には私も移植作業を行ってみて、上記のようなテクニックを見つけたのだが、結局解決できない問題もあった。例えば、DoEventsの代わりになるような処理である。そういうことをご存じでしたら追加したいので是非教えてほしい。
もし、誤り等がありましたら、是非メールもしくは掲示板にご意見等ください。
関連URL
■感想・コメントは、Windows CE FAN の掲示板 (BBS)
へお願いします。
|
===更新履歴===
2001/01/20 作成
2001/01/21 Left関数について追加
2001/02/08 DoEventsについて追加
(古原伸介)