http://www.discoversoft.net/wforum/wfor ... =past#1603
2005. 6/11編集
旧掲示板WebForumが閉鎖されたので、過去ログ集BackSearchABのトピック番号を書いておきます。
目次:1715-コマンドライン引数
タイトル:Re^6: コマンドライン引数
投稿時間:2004/05/03(Mon) 15:59
Iteratorパターンを使ったらわりとすっきりしたので、投稿してみます。
ついでにロジックの方も見直してみました。少し分かり易くなった...かな?
---以下ソース
コード: 全て選択
'コマンドライン引数を1つずつ切り出すクラス
Declare Function GetLongPathName Lib "kernel32" Alias "GetLongPathNameA" (lpszShortPath As BytePtr, lpszLongPath As BytePtr, cchBuffer As DWord) As DWord
TypeDef BOOL = Long
Class CommandLineArgumentsIterator
lpCmdLineArgs As BytePtr
lpCurrentPos As BytePtr
szCurrentArg[ELM(MAX_PATH)] As Byte
Protected
Function HasShortFileName() As BOOL
Dim osver As OSVERSIONINFO
osver.dwOSVersionInfoSize=SizeOf(OSVERSIONINFO)
GetVersionEx(osver)
If osver.dwPlatformId=VER_PLATFORM_WIN32_WINDOWS Then
HasShortFileName=TRUE
Else
HasShortFileName=FALSE
End If
End Function
Sub ConvertToLongFileName(lpArg As BytePtr)
Dim buffer[ELM(MAX_PATH)] As Byte
GetLongPathName(lpArg, buffer, MAX_PATH)
lstrcpy(lpArg, buffer)
End Sub
Public
Sub CommandLineArgumentsIterator(lpStr As BytePtr)
lpCmdLineArgs=lpStr
lpCurrentPos=lpCmdLineArgs
End Sub
Function HasNext() As BOOL
If lpCurrentPos[0]<>NULL Then
HasNext=TRUE
Else
HasNext=FALSE
End If
End Function
Function GetNext() As BytePtr
Dim i As Long, j As Long
Dim c As Byte
Dim bDqrt As BOOL
If lpCurrentPos[0]=Asc(Ex"\q") Then
bDqrt=TRUE
Else
bDqrt=FALSE
End If
'"の有無によって初期位置・終端文字を変更する
If bDqrt Then
i=1: c=Asc(Ex"\q")
Else
i=0: c=Asc(" ")
End If
'パラメータひとつ分を抽出する
j=0
While (lpCurrentPos<>c And lpCurrentPos<>NULL And j<MAX_PATH)
szCurrentArg[j]=lpCurrentPos
i=i+1: j=j+1
Wend
szCurrentArg[j]=NULL
'長いファイル名に変換する
If(HasShortFileName() And bDqrt=FALSE) Then
ConvertToLongFileName(szCurrentArg)
End If
'次のパラメータの位置を格納
Select Case lpCurrentPos
Case Asc(Ex"\q")
Select Case lpCurrentPos[i+1]
Case NULL
lpCurrentPos=lpCurrentPos+i+1 ' "Param1"\0
Case Asc(" ")
lpCurrentPos=lpCurrentPos+i+2 ' "Param1"_?Param2?...
End Select
Case Asc(" ")
lpCurrentPos=lpCurrentPos+i+1 ' Param1_?Param2?...
Case NULL
lpCurrentPos=lpCurrentPos+i ' Param1\0
End Select
GetNext=szCurrentArg
End Function
Sub Reset()
lpCurrentPos=lpCmdLineArgs
End Sub
End Class
---使用法
コード: 全て選択
Dim arg As CommandLineArgumentsIterator(GetCommandLine())
While arg.HasNext()
Dim buf As BytePtr
buf=arg.GetNext()
MessageBox(0, buf, "", MB_OK)
Wend