「ステップ14 「DLLを作る」」の編集履歴(バックアップ)一覧はこちら

ステップ14 「DLLを作る」」(2010/06/23 (水) 22:04:15) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

Basic言語でDLLを作るだって?冗談言うなよ! それが、ActiveBasicでは自然な形で作れてしまいます。ネイティブ コードにコンパイルされるため、DLLプログラムとして要求されるだけの実行速度、プログラム サイズが期待できます。 作り方はとてもシンプル 通常のEXEプログラムと違う点は以下の2つだけ。 ① プロジェクト作成時に「DLL」を選択する ② エクスポートする関数には "Export" 指定をする ①は画面の説明に従うだけなので解説の必要はありませんね。②に関してですが、今までは関数を定義するというと、 Sub func1(parm...) ... End Sub Function func2(oarm...) As Long ... End Sub という感じに定義するのに対し、エクスポートする関数に関しては、 Sub Export func1(parm...) ... End Sub Function Export func2(oarm...) As Long ... End Sub などと、"Sub/Function" の後に "Export" という指定をしましょうということです。エクスポートとは、外部プログラムから呼び出すことができる関数のことです。例えば、func1という関数をエクスポートし、test.dllを作成すると、 Declare Sub func1 Lib "test.dll" (parm...) というように、外部プログラム(EXEやDLL)からの呼び出しが可能になります。 実際にDLLを作ってみよう DLLの利点は、なんといっても汎用性の高いプログラムを様々なアプリケーション プログラムから共有する形で呼び出すことができることにつきます。そこで、今回は2つの役立ちそうな機能(関数)をDLL化してみたいと思います。 ・GetFileDlg … OPENFILENAME構造体の初期化、GetOpenFileName/GetSaveFileName関数の呼び出し ・GetFolderDlg … GetFileDlgにちなんで、フォルダ(ディレクトリ)パスを取得するためのダイアログボックスを表示するプログラムをまとめる まずは、プロジェクトの作成から。プロジェクト名を "FileDlg" などとし、タイプを "DLL" にします。プロジェクト オプションなどの設定は特に必要ありません。 プロジェクトの作成はできたでしょうか?ここから皆さんが扱うファイルは、FileDlg.sbp のみになります。このファイルに関数郡を定義していくのですが、なにやら、初期状態ですでにDllMainといった関数が定義されています。これはDLLのロードやスレッド開始、終了などの処理を記述するための特別な関数ですが、めったなことではいじりませんので、ほっときましょう。そのDllMain関数の下に独自の関数を定義していきます。 エクスポート関数 "GetFileDlg" を作る この関数では、「ファイルを開く」「ファイルの保存」ダイアログボックスを表示します。OPENFILENAME構造体の内容を共有する形で、GetOpenFileName関数、GetSaveFileName関数を呼び出します。ユーザーがファイルを選択すると1が、キャンセルすると0が返るようにします。 Function Export GetFileDlg(hWnd As Long, lpBuf As BytePtr, lpFilter As BytePtr, bOpen As Long) As Long Dim ofn As OPENFILENAME 'OPENFILENAME構造体の初期化 FillMemory(VarPtr(ofn),Len(ofn),0) ofn.lStructSize=Len(ofn) ofn.hwndOwner=hWnd SetDWord(VarPtr(ofn.lpstrFilter),lpFilter) ofn.nFilterIndex=1 SetDWord(VarPtr(ofn.lpstrFile),lpBuf) ofn.nMaxFile=MAX_PATH ofn.Flags=OFN_FILEMUSTEXIST or OFN_HIDEREADONLY or OFN_PATHMUSTEXIST ofn.lpstrDefExt="*" If bOpen Then ofn.lpstrTitle="ファイルを開く" '「ファイルを開く」ダイアログ ボックスを表示 If GetOpenFileName(ofn)=0 Then GetFileDlg=0 Exit Sub End If Else ofn.lpstrTitle="ファイルの保存" '「ファイルの保存」ダイアログ ボックスを表示 If GetSaveFileName(ofn)=0 Then GetFileDlg=0 Exit Sub End If End If GetFileDlg=1 End Function エクスポート関数 "GetFolderDlg" を作る SHBrowseForFolder関数、SHGetPathFromIDList関数を初めて目にした方がほとんどでしょう。SHBrowseForFolder関数で「フォルダの参照」ダイアログボックスを表示し、ユーザーがOKボタンを押すとSHGetPathFromIDList関数でフォルダへのパスを取得する流れになっています。ユーザーがフォルダを選択すると1が、キャンセルボタンを押すと0が返るようにします。 Function Export GetFolderDlg(hWnd As Long, lpFolder As BytePtr) As Long Dim bi As BROWSEINFO Dim pidlBrowse As VoidPtr 'BROWSEINFO構造体の初期化 FillMemory(VarPtr(bi),Len(bi),0) bi.hwndOwner=hWnd bi.lpszTitle="フォルダの選択" bi.ulFlags=BIF_RETURNONLYFSDIRS '「フォルダの参照」ダイアログボックスを表示 pidlBrowse=SHBrowseForFolder(bi) If pidlBrowse Then 'フォルダへのパスを取得(lpFolderポインタが示すバッファにコピー) SHGetPathFromIDList(pidlBrowse, lpFolder) GetFolderDlg=1 Else GetFolderDlg=0 End If End Function DLL内のプログラムはこれですべてです。コンパイルが正常に行われると、"FileDlg.dll" というファイルが生成されるはずです。 "FileDlg.dll" を作ったはいいが、どうやって使うの? ということで、DLL呼び出しのサンプル プログラムを作ってみましょう。ProjectEditorの新規作成でBasicプログラムを選択し、以下のソースコードを入力します。コンパイル前に、"test.abp" などというファイル名でFileDlgプロジェクトのディレクトリに保存しておきましょう。 Declare Function GetFileDlg Lib "FileDlg" ( hWnd As Long, lpBuf As BytePtr, lpFilter As BytePtr, bOpen As Long) As Long Declare Function GetFolderDlg Lib "FileDlg" ( hWnd As Long, lpFolder As BytePtr) As Long Dim i As Long Dim buf As String Dim FileFilter As String buf=ZeroString(MAX_PATH) FileFilter="すべてのファイル(*.*)" + Chr$(0) + "*" + Chr$(0) '開くダイアログを表示 i=GetFileDlg(0, _ StrPtr(buf), _ StrPtr(FileFilter), _ 1) If i Then MessageBox(0,buf,"「ファイルを開く」で選択されたファイル",MB_OK) Else MessageBox(0,"ファイルは選択されませんでした","エラー",MB_OK) End If '保存ダイアログを表示 i=GetFileDlg(0, _ StrPtr(buf), _ StrPtr(FileFilter), _ 0) If i Then MessageBox(0,buf,"「ファイルの保存」で選択されたファイル",MB_OK) Else MessageBox(0,"ファイルは選択されませんでした","エラー",MB_OK) End If '「フォルダの参照」ダイアログを表示 i=GetFolderDlg(0,StrPtr(buf)) If i Then MessageBox(0,buf,"「ファイルの参照」で選択されたフォルダ",MB_OK) Else MessageBox(0,"フォルダは選択されませんでした","エラー",MB_OK) End If ExitProcess(0) 上のプログラムでわかるとおり、Win32APIの関数を定義したことがある方なら、自作DLL内の関数の定義、呼び出しは朝飯前ですね!? DLL作成は初めてだったというかたはどうだったでしょうか?今回作成したFileDlg.dllは、意外と便利なDLLなので、テキスト エディタ プログラムなどで採用してみるのも良いかもしれません。
Basic言語でDLLを作るだって?冗談言うなよ! それが、ActiveBasicでは自然な形で作れてしまいます。ネイティブ コードにコンパイルされるため、DLLプログラムとして要求されるだけの実行速度、プログラム サイズが期待できます。 作り方はとてもシンプル 通常のEXEプログラムと違う点は以下の2つだけ。 ① プロジェクト作成時に「DLL」を選択する ② エクスポートする関数には "Export" 指定をする ①は画面の説明に従うだけなので解説の必要はありませんね。②に関してですが、今までは関数を定義するというと、 Sub func1(parm...) ... End Sub Function func2(oarm...) As Long ... End Sub という感じに定義するのに対し、エクスポートする関数に関しては、 Sub Export func1(parm...) ... End Sub Function Export func2(oarm...) As Long ... End Sub などと、"Sub/Function" の後に "Export" という指定をしましょうということです。エクスポートとは、外部プログラムから呼び出すことができる関数のことです。例えば、func1という関数をエクスポートし、test.dllを作成すると、 Declare Sub func1 Lib "test.dll" (parm...) というように、外部プログラム(EXEやDLL)からの呼び出しが可能になります。 実際にDLLを作ってみよう DLLの利点は、なんといっても汎用性の高いプログラムを様々なアプリケーション プログラムから共有する形で呼び出すことができることにつきます。そこで、今回は2つの役立ちそうな機能(関数)をDLL化してみたいと思います。 ・GetFileDlg … OPENFILENAME構造体の初期化、GetOpenFileName/GetSaveFileName関数の呼び出し ・GetFolderDlg … GetFileDlgにちなんで、フォルダ(ディレクトリ)パスを取得するためのダイアログボックスを表示するプログラムをまとめる まずは、プロジェクトの作成から。プロジェクト名を "FileDlg" などとし、タイプを "DLL" にします。プロジェクト オプションなどの設定は特に必要ありません。 プロジェクトの作成はできたでしょうか?ここから皆さんが扱うファイルは、FileDlg.sbp のみになります。このファイルに関数郡を定義していくのですが、なにやら、初期状態ですでにDllMainといった関数が定義されています。これはDLLのロードやスレッド開始、終了などの処理を記述するための特別な関数ですが、めったなことではいじりませんので、ほっときましょう。そのDllMain関数の下に独自の関数を定義していきます。 エクスポート関数 "GetFileDlg" を作る この関数では、「ファイルを開く」「ファイルの保存」ダイアログボックスを表示します。OPENFILENAME構造体の内容を共有する形で、GetOpenFileName関数、GetSaveFileName関数を呼び出します。ユーザーがファイルを選択すると1が、キャンセルすると0が返るようにします。 #asciiart(blockquote){ Function Export GetFileDlg(hWnd As Long, lpBuf As BytePtr, lpFilter As BytePtr, bOpen As Long) As Long Dim ofn As OPENFILENAME 'OPENFILENAME構造体の初期化 FillMemory(VarPtr(ofn),Len(ofn),0) ofn.lStructSize=Len(ofn) ofn.hwndOwner=hWnd SetDWord(VarPtr(ofn.lpstrFilter),lpFilter) ofn.nFilterIndex=1 SetDWord(VarPtr(ofn.lpstrFile),lpBuf) ofn.nMaxFile=MAX_PATH ofn.Flags=OFN_FILEMUSTEXIST or OFN_HIDEREADONLY or OFN_PATHMUSTEXIST ofn.lpstrDefExt="*" If bOpen Then ofn.lpstrTitle="ファイルを開く" '「ファイルを開く」ダイアログ ボックスを表示 If GetOpenFileName(ofn)=0 Then GetFileDlg=0 Exit Sub End If Else ofn.lpstrTitle="ファイルの保存" '「ファイルの保存」ダイアログ ボックスを表示 If GetSaveFileName(ofn)=0 Then GetFileDlg=0 Exit Sub End If End If GetFileDlg=1 End Function } エクスポート関数 "GetFolderDlg" を作る SHBrowseForFolder関数、SHGetPathFromIDList関数を初めて目にした方がほとんどでしょう。SHBrowseForFolder関数で「フォルダの参照」ダイアログボックスを表示し、ユーザーがOKボタンを押すとSHGetPathFromIDList関数でフォルダへのパスを取得する流れになっています。ユーザーがフォルダを選択すると1が、キャンセルボタンを押すと0が返るようにします。 #asciiart(blockquote){ Function Export GetFolderDlg(hWnd As Long, lpFolder As BytePtr) As Long Dim bi As BROWSEINFO Dim pidlBrowse As VoidPtr 'BROWSEINFO構造体の初期化 FillMemory(VarPtr(bi),Len(bi),0) bi.hwndOwner=hWnd bi.lpszTitle="フォルダの選択" bi.ulFlags=BIF_RETURNONLYFSDIRS '「フォルダの参照」ダイアログボックスを表示 pidlBrowse=SHBrowseForFolder(bi) If pidlBrowse Then 'フォルダへのパスを取得(lpFolderポインタが示すバッファにコピー) SHGetPathFromIDList(pidlBrowse, lpFolder) GetFolderDlg=1 Else GetFolderDlg=0 End If End Function } DLL内のプログラムはこれですべてです。コンパイルが正常に行われると、"FileDlg.dll" というファイルが生成されるはずです。 "FileDlg.dll" を作ったはいいが、どうやって使うの? ということで、DLL呼び出しのサンプル プログラムを作ってみましょう。ProjectEditorの新規作成でBasicプログラムを選択し、以下のソースコードを入力します。コンパイル前に、"test.abp" などというファイル名でFileDlgプロジェクトのディレクトリに保存しておきましょう。 #asciiart(blockquote){ Declare Function GetFileDlg Lib "FileDlg" ( hWnd As Long, lpBuf As BytePtr, lpFilter As BytePtr, bOpen As Long) As Long Declare Function GetFolderDlg Lib "FileDlg" ( hWnd As Long, lpFolder As BytePtr) As Long Dim i As Long Dim buf As String Dim FileFilter As String buf=ZeroString(MAX_PATH) FileFilter="すべてのファイル(*.*)" + Chr$(0) + "*" + Chr$(0) '開くダイアログを表示 i=GetFileDlg(0, _ StrPtr(buf), _ StrPtr(FileFilter), _ 1) If i Then MessageBox(0,buf,"「ファイルを開く」で選択されたファイル",MB_OK) Else MessageBox(0,"ファイルは選択されませんでした","エラー",MB_OK) End If '保存ダイアログを表示 i=GetFileDlg(0, _ StrPtr(buf), _ StrPtr(FileFilter), _ 0) If i Then MessageBox(0,buf,"「ファイルの保存」で選択されたファイル",MB_OK) Else MessageBox(0,"ファイルは選択されませんでした","エラー",MB_OK) End If '「フォルダの参照」ダイアログを表示 i=GetFolderDlg(0,StrPtr(buf)) If i Then MessageBox(0,buf,"「ファイルの参照」で選択されたフォルダ",MB_OK) Else MessageBox(0,"フォルダは選択されませんでした","エラー",MB_OK) End If ExitProcess(0) } 上のプログラムでわかるとおり、Win32APIの関数を定義したことがある方なら、自作DLL内の関数の定義、呼び出しは朝飯前ですね!? DLL作成は初めてだったというかたはどうだったでしょうか?今回作成したFileDlg.dllは、意外と便利なDLLなので、テキスト エディタ プログラムなどで採用してみるのも良いかもしれません。

表示オプション

横に並べて表示:
変化行の前後のみ表示: