ab.com コミュニティ

ActiveBasicを通したコミュニケーション
現在時刻 - 2017年9月22日(金) 11:34

All times are UTC+09:00




新しいトピックを投稿する  トピックへ返信する  [ 2 件の記事 ] 
作成者 メッセージ
投稿記事Posted: 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」は呼び出さなくても大丈夫です。


通報する
ページトップ
   
 記事の件名: 追加事項
投稿記事Posted: 2008年2月17日(日) 02:58 
オフライン

登録日時: 2006年10月14日(土) 10:52
記事: 22
住所: 愛知
入力処理中は処理が止まってしまうので、ウィンドウプログラムからコンソールを処理するときは
コンソール用にスレッドを1つ作らないと固まってしまいます。

また、「ReadConsole」、「WriteConsole」の代わりに「ReadFile」、「WriteFile」 でも処理することができます。

ps.
久しぶりの投稿なので失敗してしまいました;;
・「hide」タグの付け忘れ
・自動ログオフ(タイムアウト?)でログアウトされた。


通報する
ページトップ
期間内表示:  ソート  
新しいトピックを投稿する  トピックへ返信する  [ 2 件の記事 ] 

All times are UTC+09:00


オンラインデータ

このフォーラムを閲覧中のユーザー: なし & ゲスト[1人]


トピック投稿:  可
返信投稿:  可
記事編集: 不可
記事削除: 不可
ファイル添付: 不可

検索:
ページ移動:  
cron
Powered by phpBB® Forum Software © phpBB Limited
Japanese translation principally by KONISHI Yohsuke