今回は、RADツールとは離れ、構造体についての説明をします。扱うプログラムも、プロジェクトではなく、単体ファイル(*.abp)になるので、そのつもりで読んでいって下さい。

構造体

いくつかの変数を集めたものを、構造体と呼びます。1つのものに対して、複数のデータが存在するときに利用されます。構造体の定義方法、利用方法は下のようになります。

' 構造体の定義
Type 構造体名
   メンバ変数1 As データ型1
   メンバ変数2 As データ型2
   メンバ変数3 As データ型3
   ...
End Type

'構造体を利用するとき
Dim a As 構造体名
a.メンバ変数1 = ...
a.メンバ変数2 = ...
構造体の定義はType ~ End Type文を利用します。構造体の中に構造体を定義することも可能です。
Dim命令語のデータ型に構造体を指定すると、その後、その変数は、「変数名.メンバ変数」というように、変数名の後のドット(.)に続き、メンバ変数を参照することができるようになります。

構造体の使用例

ただ構造体を宣言し、値を格納、参照するのではなく、ここではプロシージャ間での構造体引渡しについてチャレンジしてみましょう。

適当な空のプログラム ファイル(test.abpなど)を作成し、下のようなプログラムを入力してみて下さい。

Type HUMAN
   name As String
   YearOfBirth As Long
   address As String
   tel As String
End Type

Sub GetOneHuman(ByRef h As HUMAN)
   h.name="コザック前田"
   h.YearOfBirth=1979
   h.address="神戸のどこか??"
   h.tel="123-456-7890"
End Sub

Dim a As HUMAN
Dim buf As String
GetOneHuman(a)
buf="名前: "+a.name
buf=buf+Chr$(13)+Chr$(10) '改行
buf=buf+"生まれた年: "+Str$(a.YearOfBirth)
buf=buf+Chr$(13)+Chr$(10) '改行
buf=buf+"住所: "+a.address
buf=buf+Chr$(13)+Chr$(10) '改行
buf=buf+"℡: "+a.tel
MessageBox(0,buf,"構造体テスト",MB_OK)



ガガガSPの前田さんはこっちに置いといて(苦)、GetOneHuman関数のパラメータ部に注目して下さい。"ByRef" なんていうものがありますが、これは構造体をプロシージャ引渡しするときには指定するものだと覚えておいて下さい。厳密には、

「ByRef」 = 「(構造体の)ポインタ引渡しを行いますよ」

ということなのですが、ポインタがよくわかってない方にはちょっと難しいかもしれません。少し強引ですが、構造体とプロシージャが絡み合ったら "ByRef" なんだと思っておきましょう。

OPENFILENAME構造体とGetOpenFileName関数


Windowsを使っているひとなら誰でも見かける「ファイルを開く」ダイアログボックスを作ってみましょう。

なんだか、ボタンやコントロールがあって、複雑そ~な感じがしますが、このダイアログボックス、1つ関数を呼び出すだけで作ることができてしまうという、プログラマーにとっては非常にありがたいものなのです。


GetOpenFileName関数を呼び出すと、このダイアログボックスが表示されるのですが、その前に、OPENFILENAME構造体を定義し、メンバ変数を初期化しなければなりません。OPENFILANEM構造体はけっこう多くのメンバを持ち、いきなりすべてを解説するわけにはいきませんので、今回は最低限おさえておきたいメンバ変数を利用していきます(詳細を知りたい方はヘルプを参照して下さい)。

Dim ofn As OPENFILENAME
Dim FileFilter As String
Dim buffer As String

'OPENFILENAME構造体の初期化
FillMemory(VarPtr(ofn),Len(ofn),0)
ofn.lStructSize=Len(ofn) '構造体のサイズ
ofn.hwndOwner=GetDesktopWindow() '親ウィンドウ(ここではデスクトップ ウィンドウを指定)
FileFilter="テキスト ファイル(*.txt)" + Chr$(0) + "*.txt" + Chr$(0) + _
               "すべてのファイル(*.*)" + Chr$(0) + "*" + Chr$(0)
ofn.lpstrFilter=StrPtr(FileFilter)
ofn.nFilterIndex=1 'ファイル フィルターの数
buffer=ZeroString(MAX_PATH) 'パスを格納するための文字列バッファを確保
ofn.lpstrFile=StrPtr(buffer)
ofn.nMaxFile=MAX_PATH 'バッファのバイト数
ofn.lpstrTitle="ファイルを開く" 'タイトル
ofn.Flags=OFN_FILEMUSTEXIST or OFN_HIDEREADONLY or OFN_PATHMUSTEXIST

'「ファイルを開く」ダイアログ ボックスを表示
If GetOpenFileName(ofn)=0 Then
'キャンセル ボタンが押されたとき(プロセス終了)
ExitProcess(0)
End If

MessageBox(0,ofn.lpstrFile,"選択されたファイルのパス",MB_OK)

'プロセス終了
ExitProcess(0)



このようなOPENFILENAME構造体の初期化を行うと、ほぼデフォルトの形の「ファイルを開く」ダイアログボックスが表示されます。ユーザーがキャンセルボタンを押すと、GetOpenFileName関数の戻り値が0になるので、その場合はExitProcess関数でプロセスを終了します。

「開く」ボタンが押されると、選択したファイルの絶対パスが ofn.lpstrFilter に格納されます。

あと、GetOpenFileName関数のほかに、GetSaveFileNameという兄弟関数が存在し、こちらは「ファイルの保存」ダイアログボックスを扱うことができるようになっています。OPENFILENAME構造体の内容の初期化動作も非常に似ているので、GetOpenFileName関数をマスターしてしまえば、GetSaveFileName関数も難なく利用することができるでしょう。