技術情報
[03] DLLの利用
ExcelVBA上でWindowsAPIなどを使いたい場合には、ダイナミックリンクライブラリ(DLL)への参照の宣言を記述する必要があります。
参照の宣言は、モジュールの先頭に記述しなければなりません。

[構文]
"キーワード1" Declare "キーワード2" Lib "DLL名(ライブラリ名)" "エイリアス" (引数,...]) "戻値型"
キーワード1
指定必須です。
"Public"または"Private"いずれかを指定します。
参照するDLLを他のモジュールからも共通利用する場合には、"Public"を指定します。
参照を宣言したモジュール内でのみ参照する場合には、"Private"を指定します。
基本的に他のモジュールから参照されても問題ありませんので、通常は"Public"で問題はありません。

キーワード2
指定必須です。
"Function"または"Sub"いずれかを指定します。
参照するDLL内から呼び出すものが関数の場合には"Function"を、サブルーチンの場合には"Sub"を指定します。
参照するDLLにどのように関数やサブルーチンが宣言されているかを調べて、それに従って適切にキーワード2を指定してください。

DLL名(ライブラリ名)
指定必須です。
参照するDLLファイル名を指定します。
(例) "user32.dll"

エイリアス
呼び出す関数やサブルーチンが別名を持っている場合には指定します。
指定する場合には、「Alias "別名"」と記述します。
例えば、user32.dllに宣言されている「GetWindowLong関数」は別名として「GetWindowLongA」を持っていますので、「Alias "GetWindowLongA"」と記述します。

引数
呼び出す関数やサブルーチンに引数がある場合には、必要なものを記述しておきます。

戻値型
呼び出すものが関数である場合には、戻り値がありますので、その戻り値のデータ型を宣言します。
指定する場合には、「As "データ型"」と記述します。

(Windowsディレクトリのパス名を取得する例)
Option Explicit
' DLLの参照宣言
Public Declare Function GetSystemDirectory Lib "kernel32.dll" Alias "GetSystemDirectoryA" (ByVal lpbuffer As String, ByVal nSize As Long) As Long

' APIを使うためのサンプルサブルーチン
' (これはDLLと無関係のVBA上のユーザ定義のサブルーチンです)
Sub Test()
' APIからの値を取得する変数
Dim LngSystemDirectoryLength As Long
Dim StrSystemDirectoryBuffer As String * MAX_PATH

' システムディレクトリのパス名を取得
' ※LngSystemDirectoryLength変数は、
' この例では戻り値受取以外には用いていません
LngSystemDirectoryLength = GetSystemDirectory(StrSystemDirectoryBuffer, VBA.Len(StrSystemDirectoryBuffer))

' 取得したシステムディレクトリのパスを表示します
VBA.MsgBox (VBA.Left(StrSystemDirectoryBuffer, VBA.InStr(StrSystemDirectoryBuffer, VBA.vbNullChar) - 1)
End Sub

(フォームの右上のボタンを操作する例)
Option Explicit
' API用定数の宣言
Public Const GWL_STYLE = (-16)
Public Const WS_THICKFRAME = &H40000
Public Const WS_MAXIMIZEBOX = &H10000
Public Const WS_MINIMIZEBOX = &H20000
Public Const MF_BYCOMMAND = &H0
Public Const MF_BYPOSITION = &H400
Public Const SC_CLOSE = &HF060

' DLLの参照宣言
Public Declare Function GetSystemMenu Lib "user32.dll" (ByVal hWnd As Long, ByVal bRevert As Long) As Long
Public Declare Function DeleteMenu Lib "user32.dll" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal uFlags As Long) As Long
Public Declare Function DrawMenuBar Lib "user32.dll" (ByVal hWnd As Long) As Long
Public Declare Function GetActiveWindow Lib "user32.dll" () As Long
Public Declare Function GetWindowLong Lib "user32.dll" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Public Declare Function SetWindowLong Lib "user32.dll" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

' 以下のユーザ定義関数を制御したいUserFormの
' Form_Activateイベントなどから呼び出すだけで制御できます
' ##### ユーザ定義関数 #####
' 最大化ボタンを表示するサブルーチン
Public Sub ShowWithMaximizeButton()
Dim LngMyRes As Long
Dim LngMyWindowHandle As Long
Dim LngMyWindowStyle As Long

LngMyWindowHandle = GetActiveWindow()
LngMyWindowStyle = GetWindowLong(LngMyWindowHandle, GWL_STYLE)
LngMyWindowStyle = LngMyWindowStyle Or WS_THICKFRAME Or WS_MAXIMIZEBOX Or WS_MINIMIZEBOX
LngMyRes = SetWindowLong(LngMyWindowHandle, GWL_style, LngMyWindowStyle)
LngMyRes = DrawMenuBar(LngMyWindowHandle)
End Sub

' 閉じるボタンを消去するサブルーチン
Public Sub _DeleteCloseMenu()
Dim LngMyWindowHandle As Long
Dim LngMySystemMenu As Long
Dim LngMyRes As Long
Dim StrMyClassName As String

LngMyWindowHandle = GetActiveWindow()
LngMySystemMenu = GetSystemMenu(LngMyWindowHandle, 0&)
LngMyRes = DeleteMenu(LngMySystemMenu, SC_CLOSE, MF_BYCOMMAND)
LngMyRes = DrawMenuBar(LngMyWindowHandle)
End Sub

' ボタンの表示をリセットするサブルーチン
Public Sub ResetMenu()
Dim LngMyWindowHandle As Long
Dim LngMySystemMenu As Long
Dim LngMyRes As Long
Dim StrMyClassName As String

LngMyWindowHandle = GetActiveWindow()
LngMySystemMenu = GetSystemMenu(LngMyWindowHandle, 1&)
LngMyRes = DrawMenuBar(LngMyWindowHandle)
End Sub