by ゲスト » 2008年2月17日(日) 02:50
コンソールの作成・破棄とコンソールに対する入出力を行うクラスです。
ウィンドウプログラムでコンソールを使いたかったので、調べて作ってみました。
「#console」を指定したときにでてくるコンソールと同じですが、
個人的にString型(クラス)は好きではないのでBytePtr型で入出力を行っています。
また、AB5(CP3)では「#console」指定ができない(エラーになる)ため、
このクラスを使うことでAB5でもコンソールプログラムを書く事ができます。
コード: 全て選択
/******** WIN32API定義 ********/
' 必要に応じてコメントアウトしてください
Declare Function AllocConsole Lib "kernel32" () As Long
Declare Function FreeConsole Lib "kernel32" () As Long
Declare Function ReadConsole Lib "kernel32" Alias "ReadConsoleA" ( _
hConsoleInput As HANDLE, lpBuffer As BytePtr, nNumberOfCharsToRead As Long, _
ByRef lpNumberOfCharsRead As DWord, lpReserved As Long) As Long
Declare Function WriteConsole Lib "kernel32" Alias "WriteConsoleA" (
hConOut As HANDLE, lpszText As BytePtr, lpcText As Long, ByRef NumWrite As DWord, NotUsed As Long) As Long
Const STD_INPUT_HANDLE = -10 ' 標準入力のハンドルを取得
Const STD_OUTPUT_HANDLE = -11 ' 標準出力のハンドルを取得
Const STD_ERROR_HANDLE = -12 ' 標準エラーのハンドル取得
/******** コンソール処理クラス ********/
Const CONSOLE_BUFSIZE = 1023
Class Console
Private: StdIn As HANDLE '標準入力ハンドル
Private: StdOut As HANDLE '標準出力ハンドル
Private: buf[CONSOLE_BUFSIZE] As Byte '入力バッファ(文字列用固定長)
Private: _mem As VoidPtr '入力バッファ(数値用可変長)
Public '//////// コンストラクタ ////////
Sub Console()
'AllocConsole() 'コンソールを割り当てる
StdIn = GetStdHandle(STD_INPUT_HANDLE) '標準入力ハンドルを取得
StdOut = GetStdHandle(STD_OUTPUT_HANDLE) '標準出力ハンドルを取得
_mem = 0 '可変長入力バッファの初期化
End Sub
Public '//////// デストラクタ ////////
Sub ~Console()
'FreeConsole() 'コンソールを解放する
free(_mem) '可変長入力バッファを解放する
End Sub
Public '//////// 文字列出力(改行なし) ////////
Sub PrintStr(lpString As BytePtr)
Dim length As DWord
WriteConsole(StdOut, lpString, lstrlen(lpString), length, 0)
End Sub
Public '//////// 文字列出力(改行あり) ////////
Sub PrintStrEx(lpString As BytePtr)
Dim length As DWord
WriteConsole(StdOut, lpString, lstrlen(lpString), length, 0)
WriteConsole(StdOut, Ex"\r\n", 2, length, 0)
End Sub
Public '//////// 整数値出力(改行なし) ////////
Sub PrintInt(Value As Long)
Dim buf[31] As Byte
wsprintf(buf, "%d", Value)
PrintStr(buf)
End Sub
Public '//////// 整数値出力(改行あり) ////////
Sub PrintIntEx(Value As Long)
Dim buf[31] As Byte
wsprintf(buf, Ex"%d\r\n", Value)
PrintStr(buf)
End Sub
Public '//////// 文字列入力 ////////
Function InputStr(lpOutputString As BytePtr) As BytePtr
Dim length As DWord
PrintStr(lpOutputString)
ReadConsole(StdIn, buf, CONSOLE_BUFSIZE, length, 0)
buf[length-2]=0 '改行コードを読み取らない
return buf
End Function
Public '//////// 整数値入力 ////////
Function InputInt(lpOutputString As BytePtr, item As Long) As *Long
'戻り値: item=0 -> 入力した値 item<>0 -> 入力した値が格納された配列へのポインタ
Dim ptr As *Long, str As BytePtr, ctr As Long
Dim offset As Long
'メモリバッファを更新
If 0<>item then ptr=MemUpdate(SizeOf(Long)*item)
Do
'文字列で入力
str = InputStr(lpOutputString)
'「item=0」なら値をそのまま返す
If 0=item then return Val(str) As Long
'カウンタ類の初期化
ctr = 0: offset = 0
Do
'整数値に変換して格納
ptr[ctr] = Val(str+offset) As Long
ctr += 1
'指定された個数の入力が終われば配列へのポインタを返す
If item = ctr then return ptr
'入力の区切りを見つける
offset = InStr(offset+1, str, ",")
If 0 = offset then Exit Do
Loop
'入力されたデータの個数が足らなければ再入力
PrintStrEx("データが足らないよ!")
Loop
End Function
Private '//////// メモリバッファを更新 ////////
Function MemUpdate(size As DWord) As VoidPtr
free(_mem)
_mem = calloc(size)
return _mem
End Function
End Class
コンストラクタ・デストラクタ内のコメントアウトを外すとオブジェクト生成時にコンソールが生成され、
オブジェクト破棄時にはコンソールも解放されます。
コメントアウトを付けたままの場合は、コンソールを使用する前に「AllocConsole」を呼び出してコンソールを割り当て、
その後にこのクラスのオブジェクトを生成してください。
一旦コンソールを破棄して再び生成した場合は、このオブジェクトも生成しなおす必要があります。
また、コンソール自体はプログラム終了時に自動で破棄されるので、「FreeConsole」は呼び出さなくても大丈夫です。
コンソールの作成・破棄とコンソールに対する入出力を行うクラスです。
ウィンドウプログラムでコンソールを使いたかったので、調べて作ってみました。
「#console」を指定したときにでてくるコンソールと同じですが、
個人的にString型(クラス)は好きではないのでBytePtr型で入出力を行っています。
また、AB5(CP3)では「#console」指定ができない(エラーになる)ため、
このクラスを使うことでAB5でもコンソールプログラムを書く事ができます。
[code]
/******** WIN32API定義 ********/
' 必要に応じてコメントアウトしてください
Declare Function AllocConsole Lib "kernel32" () As Long
Declare Function FreeConsole Lib "kernel32" () As Long
Declare Function ReadConsole Lib "kernel32" Alias "ReadConsoleA" ( _
hConsoleInput As HANDLE, lpBuffer As BytePtr, nNumberOfCharsToRead As Long, _
ByRef lpNumberOfCharsRead As DWord, lpReserved As Long) As Long
Declare Function WriteConsole Lib "kernel32" Alias "WriteConsoleA" (
hConOut As HANDLE, lpszText As BytePtr, lpcText As Long, ByRef NumWrite As DWord, NotUsed As Long) As Long
Const STD_INPUT_HANDLE = -10 ' 標準入力のハンドルを取得
Const STD_OUTPUT_HANDLE = -11 ' 標準出力のハンドルを取得
Const STD_ERROR_HANDLE = -12 ' 標準エラーのハンドル取得
/******** コンソール処理クラス ********/
Const CONSOLE_BUFSIZE = 1023
Class Console
Private: StdIn As HANDLE '標準入力ハンドル
Private: StdOut As HANDLE '標準出力ハンドル
Private: buf[CONSOLE_BUFSIZE] As Byte '入力バッファ(文字列用固定長)
Private: _mem As VoidPtr '入力バッファ(数値用可変長)
Public '//////// コンストラクタ ////////
Sub Console()
'AllocConsole() 'コンソールを割り当てる
StdIn = GetStdHandle(STD_INPUT_HANDLE) '標準入力ハンドルを取得
StdOut = GetStdHandle(STD_OUTPUT_HANDLE) '標準出力ハンドルを取得
_mem = 0 '可変長入力バッファの初期化
End Sub
Public '//////// デストラクタ ////////
Sub ~Console()
'FreeConsole() 'コンソールを解放する
free(_mem) '可変長入力バッファを解放する
End Sub
Public '//////// 文字列出力(改行なし) ////////
Sub PrintStr(lpString As BytePtr)
Dim length As DWord
WriteConsole(StdOut, lpString, lstrlen(lpString), length, 0)
End Sub
Public '//////// 文字列出力(改行あり) ////////
Sub PrintStrEx(lpString As BytePtr)
Dim length As DWord
WriteConsole(StdOut, lpString, lstrlen(lpString), length, 0)
WriteConsole(StdOut, Ex"\r\n", 2, length, 0)
End Sub
Public '//////// 整数値出力(改行なし) ////////
Sub PrintInt(Value As Long)
Dim buf[31] As Byte
wsprintf(buf, "%d", Value)
PrintStr(buf)
End Sub
Public '//////// 整数値出力(改行あり) ////////
Sub PrintIntEx(Value As Long)
Dim buf[31] As Byte
wsprintf(buf, Ex"%d\r\n", Value)
PrintStr(buf)
End Sub
Public '//////// 文字列入力 ////////
Function InputStr(lpOutputString As BytePtr) As BytePtr
Dim length As DWord
PrintStr(lpOutputString)
ReadConsole(StdIn, buf, CONSOLE_BUFSIZE, length, 0)
buf[length-2]=0 '改行コードを読み取らない
return buf
End Function
Public '//////// 整数値入力 ////////
Function InputInt(lpOutputString As BytePtr, item As Long) As *Long
'戻り値: item=0 -> 入力した値 item<>0 -> 入力した値が格納された配列へのポインタ
Dim ptr As *Long, str As BytePtr, ctr As Long
Dim offset As Long
'メモリバッファを更新
If 0<>item then ptr=MemUpdate(SizeOf(Long)*item)
Do
'文字列で入力
str = InputStr(lpOutputString)
'「item=0」なら値をそのまま返す
If 0=item then return Val(str) As Long
'カウンタ類の初期化
ctr = 0: offset = 0
Do
'整数値に変換して格納
ptr[ctr] = Val(str+offset) As Long
ctr += 1
'指定された個数の入力が終われば配列へのポインタを返す
If item = ctr then return ptr
'入力の区切りを見つける
offset = InStr(offset+1, str, ",")
If 0 = offset then Exit Do
Loop
'入力されたデータの個数が足らなければ再入力
PrintStrEx("データが足らないよ!")
Loop
End Function
Private '//////// メモリバッファを更新 ////////
Function MemUpdate(size As DWord) As VoidPtr
free(_mem)
_mem = calloc(size)
return _mem
End Function
End Class
[/code]
コンストラクタ・デストラクタ内のコメントアウトを外すとオブジェクト生成時にコンソールが生成され、
オブジェクト破棄時にはコンソールも解放されます。
コメントアウトを付けたままの場合は、コンソールを使用する前に「AllocConsole」を呼び出してコンソールを割り当て、
その後にこのクラスのオブジェクトを生成してください。
一旦コンソールを破棄して再び生成した場合は、このオブジェクトも生成しなおす必要があります。
また、コンソール自体はプログラム終了時に自動で破棄されるので、「FreeConsole」は呼び出さなくても大丈夫です。