ドリル作成ツール VB6
前へ 目次へ 次へ 

 2.共通部分の処理

 

オブジェクト名 働き
@[出題数クリア]ボタン cmdSyutsuClear 設定した出題数(Aの部分)をすべて0にする。
A出題数設定 txtMonSuu
vsrMonSuu
テキストボックスと垂直スクロールバーをセットにして使用している。出題数が0以外の問題を出力する。
B次の問題番号 txtMNumber テキストボックスである。ここで問題の番号(【1】など)を管理している。
C[作成開始]ボタン cmdSakusei 問題と解答の作成を開始する。
D[クリア]ボタン cmdTextClear 問題と解答(F部分)のデータを消去する。
E[終了]ボタン cmdEnd このプログラムを終了する。
F問題出力領域 txtMondai テキストボックスである。ここに問題と解答が出力される。
G出力切り替えタブ TabStrip1 タブストリップである。問題と解答の出力形式を切り替える。
Hファイル名入力領域 txtFilename テキストボックスである。ファイル名を入力する。
I[保存]ボタン cmdFile ファイル名を付けて保存できるダイアログを表示する。
J[ヘルプ]ボタン cmdHelp 使用方法を表示する。
そのほかの処理 DisplayMondai … 問題と解答を追加表示する処理である。
InitComm … 共通の初期化処理である。
ダイアログ dlgHelp テキストボックス、ラベル、コマンドボタンを配置する。

・非標準コントロール
 実行中には表示されないコモンダイアログとタブストリップは標準では使うことができない。コンポーネントを追加して使えるようにする。(非標準コントロール参照
 追加するコンポーネントは次の2つである。
    Microsoft Common Dialog Control 6.0
    Microsoft Windows Common Controls 6.0

@[出題数クリア]ボタン

 出題数を0に設定する処理である。プログラムリストは次の通りである。

Private Sub cmdSyutsuClear_Click()
'出題数クリア(共通)
    Dim n As Integer

    For n = 0 To SYURUI - 1
        txtMonSuu(n).Text = "0"
    Next n
End Sub

 SYURUIは定数で問題の種類の数を定義している。基数変換では6種類あるので6と定義している。
    例 Const SYURUI = 6  または  Const SYURUI As Integer = 6

Top

A出題数設定

 テキストボックス(txtMonSuu)と垂直スクロールバー(vsrMonSuu)を連動させてカウンタのようにして使用している。複数個使用するのでコントロール配列としている。

Private Sub txtMonSuu_Change(Index As Integer)
'テキストボックスのデータをスクロールバーに設定(共通)
    Dim dat As Integer

    dat = Val(txtMonSuu(Index).Text)
    If dat < 0 Or dat > MONMAX Then
        MsgBox "出題数は0〜" & MONMAX & "の範囲で指定してください。", vbOKOnly, App.Title
        txtMonSuu(Index).Text = Str(vsrMonSuu(Index).Value)
    Else
        vsrMonSuu(Index).Value = Val(txtMonSuu(Index).Text)
        txtMonSuu(Index).SelStart = Len(txtMonSuu(Index).Text)  'カーソルを末尾に移動
    End If
End Sub

Private Sub vsrMonSuu_Change(Index As Integer)
'スクロールバーのデータをテキストボックスに設定(共通)
    txtMonSuu(Index).Text = Str(vsrMonSuu(Index).Value)
End Sub

 MONMAXは各種問題1回あたりに作成する最大の問題数である。定数として定義している。
 テキストボックスの値が変更されるとtxtMonSuu_Changeサブプロシージャが呼び出される。ここで値の範囲をチェックし、垂直スクロールバーに設定している。
 垂直スクロールバーがクリックされるとvsrMonSuuサブプロシージャが呼び出される。ここでテキストボックスに値を設定している。
 このように、どちらか変更されると、もう一方の値も変更(設定)されるようにプログラムしている。垂直スクロールバーでは値の範囲をチェックしていないが、プロパティMaxとMinで設定しているからである。

Private Sub txtMonSuu_GotFocus(Index As Integer)
'フォーカス時、範囲選択する(共通)
    txtMonSuu(Index).SelStart = 0
    txtMonSuu(Index).SelLength = Len(txtMonSuu(Index).Text)
End Sub

 txtMonSuu_GetFocusサブプロシージャはテキストボックス(txtMonSuu)にフォーカスが来たときに呼び出される。ここでは、入力されているデータを範囲選択するようにしている。キーを押したとき、そのデータと範囲選択されたデータが置き換えられるので、すでに入力されているデータを消してから入力する、という手間が省ける。

Top

B次の問題番号

 問題の番号(【1】など)を管理している。特別な処理は行っていない。

C[作成開始]ボタン

 問題と解答の作成を開始する。テーマ(ここでは基数変換)ごとに変わるので、後で説明する。

Top

D[クリア]ボタン

 表示されている問題と解答を消去する。プログラムリストは次の通りである。

Private Sub cmdTextClear_Click()
'問題消去(共通)
    Dim yn As Integer

    If TChangeF = True Then
        yn = MsgBox("ドリルが保存されていません。消去しますか?", vbYesNo + vbQuestion, App.Title)
        If yn = vbNo Then
            Exit Sub
        End If
    End If
    txtMondai.Text = ""
    TChangeF = False    'テキスト(問題)変更?
    BText = ""          'テキスト用
    txtMNumber.Text = "1"
End Sub

 保存の確認の後、txtMondai.Text(表示されているデータ)、TChangeF(変更されたかどうかを表すフラグ)、BText(オリジナルの問題と解答のデータ)、txtMNumber.Text(問題番号)を初期化する。

Top

E[終了]ボタン

 プログラムを終了する。プログラムリストは次の通りである。

Private Sub cmdEnd_Click()
'終了(共通)
    Unload Me
End Sub

 実際の終了処理はForm_QueryUnloadサブプロシージャで作成する。これは、[終了]ボタン以外で終了されたときに対応するためである。[終了]ボタン以外とは具体的にはウィンドウの閉じるのボタンのことである。プログラムリストは次の通りである。

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
'終了確認(共通)
    Dim yn As Integer

    iniFileWrite IniFile, "[WPATH]", sFolder
    If TChangeF = True Then
        yn = MsgBox("ドリルが保存されていません。終了しますか?", vbYesNo + vbQuestion, App.Title)
        If yn = vbNo Then    '終了しない
            Cancel = True
            Exit Sub
        End If
    End If
    End
End Sub

 サブプロシージャiniFileWriteは、*.iniファイル(設定ファイル)にデータを書き込むプロシージャである。プログラムは後で作成する。

Top

F問題出力領域

 問題と解答の表示データに変更があったかどうかを監視する。グローバル変数TChangeFで変更の有無がわかる。

Private Sub txtMondai_Change()
'テキスト問題変更(共通)
    TChangeF = True
End Sub

Top

G出力切り替えタブ

 問題と解答をタブに合わせて変更する。

Private Sub TabStrip1_Click()
'テキストをHTML化及び復元(共通)
    Dim sdat As String, smon As String, wk As String
    Dim pt As Long

    On Error GoTo ErrRe
    If TabStrip1.SelectedItem.Index = 1 Then
        txtMondai.Text = Text2Text(BText)   'Textデータを復元
        txtFilename.Text = BaseName(txtFilename.Text) & ".txt"
    ElseIf TabStrip1.SelectedItem.Index = 2 Then
        txtMondai.Text = Text2HTML(BText)   'HTML化
        txtFilename.Text = BaseName(txtFilename.Text) & ".htm"
    ElseIf TabStrip1.SelectedItem.Index = 3 Then
        txtMondai.Text = Text2HTMLjs(BText) 'HTML化JavaScript
        txtFilename.Text = BaseName(txtFilename.Text) & ".html"
    End If
    Exit Sub
ErrRe:
    If Err = 7 Then
        MsgBox "メモリが不足です。これ以上追加できません。" & vbCrLf & "データをクリアして新しく作成してください。", vbOKOnly, App.Title
    Else
        MsgBox "ERROR : TabStrip1_Click (Code=" & Str(Err) & ")", vbOKOnly, App.Title
    End If
End Sub

 オリジナルのデータはグローバル変数BTextに記憶している。このBTextのデータをテキストのときはText2Textファンクションプロシージャで、HTML(表示)のときはText2HTMLファンクションプロシージャで、HTML(自習)のときはText2HTMLjsファンクションプロシージャで変換して表示している。
 BaseNameファンクションプロシージャはファイルのパス名からファイル名だけを取り出すものである。
 これら4つのプログラムは後で作成する。

 エラー処理(On Error Goto)は、テキストボックスのTextプロパティには記憶できるデータが最大で約32KBまでなので、追加作成を繰り返してこれを超えたときのためのものである。

Top

Hファイル名入力領域

 ファイル名を入力、または、[保存]ボタンで保存したファイル名が表示される。特別な処理は行っていない。

Top

I[保存]ボタン

 ファイルを保存するためのダイアログを開く。このダイアログで保存する場所やファイル名を確認あるいは選択する。プログラムリストは次の通りである(ヘルプのサンプルプログラムをほぼそのまま利用している)。

Private Sub cmdFile_Click()
'ファイル名参照(共通)
'(ヘルプより)
    If txtMondai.Text = "" Then
        MsgBox "出力するデータがありません。", vbOKOnly, App.Title
        Exit Sub
    End If
    ' CancelError プロパティを真 (True) に設定します。
    CommonDialog1.CancelError = True
    On Error GoTo ErrHandler
    ' Flags プロパティを設定します。新規ファイル作成確認
    CommonDialog1.Flags = cdlOFNCreatePrompt
    'ファイルの場所の設定
    CommonDialog1.InitDir = sFolder
    ' リスト ボックスに表示されるフィルタを設定します。
    CommonDialog1.Filter = "テキスト ファイル (*.txt)|*.txt|" & _
        "HTML ファイル (*.htm *.html)|*.htm;*.html|" & _
        "すべてのファイル (*.*)|*.*|"
    CommonDialog1.FileName = txtFilename.Text   '現在のファイル名設定
    ' "テキスト ファイル" を既定のフィルタとして指定します。
    If TabStrip1.SelectedItem.Index = 1 Then
        CommonDialog1.FilterIndex = 1
    ElseIf TabStrip1.SelectedItem.Index = 2 Then
        CommonDialog1.FilterIndex = 2
    ElseIf TabStrip1.SelectedItem.Index = 3 Then
        CommonDialog1.FilterIndex = 2
    End If
    CommonDialog1.DialogTitle = App.Title & " - ファイル保存"
    ' ダイアログ ボックスを表示します。
    CommonDialog1.ShowSave
    ' ユーザーが選択したファイル名を表示します。
    txtFilename.Text = CommonDialog1.FileName
    sFolder = PathName(CommonDialog1.FileName)
    FileOutput
    Exit Sub
ErrHandler:
    ' ユーザーが [キャンセル] をクリックしました。
    Exit Sub
End Sub

 変数sFolderはグローバル変数で、ファイルの保存場所を記憶している。
 ファンクションプロシージャPathNameは、ファイル名(フルパス)からフォルダ名を取り出す関数である。プログラムは後で作成する。
 サブプロシージャFileOutputは、問題と解答のデータをファイルに出力する処理である。プログラムリストは次の通りである。

Private Sub FileOutput()
'ファイル出力処理(共通)
    Dim yn As Integer

    If txtFilename.Text = "" Then
        MsgBox "ファイル名を指定してください。", vbOKOnly, App.Title
        Exit Sub
    End If
    If isFile(txtFilename.Text) Then    '(DrillSub.bas)
        yn = MsgBox("すでにファイルがあります。上書きしますか?", vbYesNo + vbQuestion, App.Title)
        If yn = vbNo Then
            Exit Sub
        End If
    End If
    
    On Error GoTo ErrHandler
    Open txtFilename.Text For Output As #1
    Print #1, txtMondai.Text
    Close #1
    TChangeF = False
    MsgBox "ファイルへの出力を完了しました。", vbOKOnly, App.Title
    Exit Sub
ErrHandler:
    MsgBox "エラーが発生しました。", vbOKOnly, App.Title
End Sub

 ファンクションプロシージャisFileは、ファイルがディスク上にすでに存在しているかどうかを調べる関数である。存在すればTrue、存在しなければFalseを返却する。プログラムは後で作成する。

Top

J[ヘルプ]ボタン

 簡単な使用方法を表示するダイアログを開く。プログラムリストは次の通りである。

Private Sub cmdHelp_Click()
'説明用ダイアログを開く(共通)
    dlgHelp.Show 1
End Sub

 ダイアログのオブジェクト名(ここではdlgHelp)をShowメソッドで呼び出している。引数の1は開いたダイアログが閉じられるまで呼出し側をアクセスできないようにする設定である。モーダルという。
 使用方法のテキストデータはグローバル変数USAGEに記憶させておく。

Top

 そのほかの処理

 問題データと解答データを引数mondaiとkaitouにそれぞれ受け取り、問題と解答のでーたを作成する。
 問題と解答の区切りとして"#-----解答-----"の1行を追加している。また、解答の最後(データの最後)に"##"を追加している。このデータをグローバル変数BTextに記憶させ、タブストリップに応じて変形して表示している。
 すでに表示されているデータがあるときは追加される。

Private Sub DisplayMondai(mondai As String, kaitou As String)
'問題の追加・表示(共通)
    Dim pt As Long, wk As String

    On Error GoTo ErrRe
    wk = BText
    pt = InStr(wk, "#--")
    If pt = 0 Then      '新規
        wk = wk & mondai
        wk = wk & "#-----解答-----" & vbCrLf
    Else        '追加処理
        wk = Left(BText, pt - 1)
        wk = wk & mondai
        wk = wk & Mid(BText, pt)
        wk = Left(wk, Len(wk) - 6)  '解答末尾の##を削除
    End If
    BText = wk
    BText = BText & kaitou & "##" & vbCrLf & vbCrLf
    '表示(タブストリップに応じて)
    If TabStrip1.SelectedItem.Index = 1 Then
        txtMondai.Text = Text2Text(BText)
    ElseIf TabStrip1.SelectedItem.Index = 2 Then
        txtMondai.Text = Text2HTML(BText)   'HTML化
    ElseIf TabStrip1.SelectedItem.Index = 3 Then
        txtMondai.Text = Text2HTMLjs(BText) 'HTML化JavaScript
    End If
    txtMondai.SelStart = Len(txtMondai.Text)
    Exit Sub
ErrRe:
    If Err = 7 Then
        MsgBox "メモリが不足です。これ以上追加できません。" & vbCrLf & "データをクリアして新しく作成してください。", vbOKOnly, App.Title
    Else
        MsgBox "ERROR : DisplayMondai (Code=" & Str(Err) & ")", vbOKOnly, App.Title
    End If
End Sub

 オリジナルのデータはグローバル変数BTextに記憶している。このBTextのデータをテキストのときはText2Textファンクションプロシージャで、HTML(表示)のときはText2HTMLファンクションプロシージャで、HTML(自習)のときはText2HTMLjsファンクションプロシージャで変換して表示している。
 これら3つのプログラムは後で作成する。

 エラー処理(On Error Goto)は、テキストボックスのTextプロパティには記憶できるデータが最大で約32KBまでなので、追加作成を繰り返してこれを超えたときのためのものである。

Top

Private Sub InitComm()
'共通の初期化処理(共通)
    Dim pt As Integer

    aFolder = App.Path  'アプリのフォルダ
    Randomize           '乱数の初期化
    Set MainForm = Me   'メインフォームの設定
    BText = ""          'テキストクリア
    TChangeF = False    'テキスト変更なし
    txtMNumber.Text = "1"   '問題番号初期化
    ReadHTML            '設定ファイル(HTML部)読み込み
    '設定ファイル(作業フォルダ)読み込み
    IniFile = aFolder & "\" & App.Title & ".ini"    'アプリ用INIファイル
    sFolder = iniFileRead(IniFile, "[WPATH]")
    pt = InStr(sFolder, vbCrLf)
    If pt <> 0 Then
        sFolder = Left(sFolder, pt - 1)
    End If
    If sFolder = "" Then
        sFolder = App.Path
    End If
    If Left(sFolder, 1) <> "\" Then     'カレントパスの変更
        ChDrive sFolder
    End If
    ChDir sFolder
End Sub

 Meはこのフォーム自身を表すキーワードである。
 ReadHTMLサブプロシージャはHTML(表示)やHTML(自習)で使うHTMLタグやスクリプトを読み込む処理である。
 サブプロシージャiniFileReadは、*.iniファイル(設定ファイル)からデータを読み込むプロシージャである。
 プログラムは後で作成する。

Top

ダイアログ

 説明表示用である。フォーム(dlgHelp)にはテキストボックス(Text1)、ラベル(Label1, Label2)、コマンドボタン(OKButton)を配置している。

Option Explicit

Private Sub Form_Load()
    Me.Caption = App.Title
    Me.Icon = MainForm.Icon
    Label1.Caption = App.Title & "  Version " & App.Major & "," & App.Minor & "," & App.Revision
    Label2.Caption = COPYRIGHT
    Text1.Text = USAGE
End Sub

Private Sub OKButton_Click()
    Unload Me
End Sub

Private Sub Text1_Change()
    Text1.Text = USAGE
End Sub

 Meはこのフォーム自身を表すキーワードである。
 グローバル変数MainFormはメインのフォームのことである。InitCommサブプロシージャで設定している。
 App.Titleはこのプロジェクトのタイトル、App.Major, App.Minor, App.Revisionはこのプロジェクトのバージョン番号である。いずれもプロジェクトのプロパティ(メニューバー:[プロジェクト(P)] → [プロジェクトのプロパティ...(E)])で設定(変更)できる。
 グローバル変数USAGEは使い方を記憶した変数である。使い方はメインのフォームで設定している。

 [OK]ボタンがクリックされたときは、Unload Meでダイアログをメモリから消去する。Endまで実行するとプログラムが終了してしまう。

 説明を表示しているテキストボックスが変更されるとText1_Changeサブプロシージャが呼び出される。ここでは変更されないように、変更があれば元に戻す処理をしている。

 特定のデータ設定などがないので、テーマが変わったときもこのままで利用できる。
  ・使い方のデータはメインのフォームでUSAGEに記憶させておく。
  ・タイトルバーに表示されるアイコンやタイトルはメインのフォームのものを参照している。

Top


前へ 目次へ 次へ 
Copyright © 2003 Hiroshi Masuda 

 

 

inserted by FC2 system