List Box で名簿の削除と追加

VC++ で List Box に名簿を表示して EditControl と Button 操作で「削除と追加」を行います。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プロジェクトの設定

  1. 新規プロジェクトから空のプロジェクト(Dlglist)を作成します。
    ページ先頭の画像を参考にして DialogBoxを作成します。
    [ListBox]と[EditControl]と[Button]を配置して下さい。
    説明の画像
  2. 次の表に合わせて「キャプションとID」を設定して下さい。
    BOX キャプション ID
    DialogBox ダイアログ MYDIALOG
    ListBox IDC_LIST1
    EditControl IDC_EDIT1
    StaticText データ件数
    EditControl IDC_EDIT2
    Button 終了 IDCLOSE
    Button 削除 IDDELETE
    Button 追加 IDOK
  3. 私は my.lib に登録されている DATAFILE Object Class を使っています。
    my.lib を使うときは、メニューバーから [プロジェクト] [プロパティ] [リンカ] [入力] で追加する依存関係から my.lib を取り込みます。
    読者諸氏が作成するときは Object Class Library から次のファイルを取得してプロジェクトに組み込んで下さい。
    ファイル名 説明
    datafile.h DATAFILE Object Class のヘッダファイル
    datafile.cpp DATAFILE Object Class のプログラムファイル
  4. テスト用の名簿ファイルを name.txt の名前でフォルダーに格納して下さい。
    内容は何でも良いのですが改行コードを除いて18バイトでタイプして下さい。
    改行コード(CR/LF)を加えるとレコード長は20バイトになります。
  5. ビルドに続いて実行を行います。
    ListBox に名簿一覧が表示されたでしょうか?
    ListBox の名前をクリックして「削除」ボタンをクリックして下さい。
    削除確認のメッセージボックスが表示されて「OK」を応答するとデータが削除されてデータ件数が減ります。
    ListBox の下の EditControl に新しいデータをタイプして「追加」ボタンをクリックして下さい。
    選択されていた項目の直前に新しく追加されて、データ件数が増えます。
    「終了」をクリックすると現在表示されているデータが w.txt に保存されてプログラムが終了します。
    タイトルバー右端の「×」をクリックすると保存しないで終了します。

プログラムの説明

  1. DATAFILE Object を使うので my.h を取り込みます。
    g_buf はデータ入出力用のバッファで100件分の領域を確保しています。
    DATAFILE DataFile; で DATAFILE Object を定義します。
    edit_str は文字列を編集するためのワークエリアです。
    ListNo には ListBox のカレントアイテムを設定します。
        #include    <windows.h>
        #include    "my.h"
        #include    "resource.h"
    
        char        g_buf[100][20];
        DATAFILE    DataFile;
        char        edit_str[20];
        int         ListNo=0;
        
  2. WM_INITDIALOG: には DialogBox の初期化のときに制御が渡されます。
    InitDlgProc() で名簿データを入力して ListBox に登録します。
        switch (msg)
        {   case WM_INITDIALOG:
                ListNo= InitDlgProc(hDlg,"name.txt");
                break;
        
  3. IDOK: は名簿の追加処理です。
        case WM_COMMAND:
            switch (LOWORD(wParam))
            {   case IDOK:
                    AppData(hDlg);
                    break;
        
  4. IDDELETE: は名簿の削除処理です。
            case IDDELETE:
                DelData(hDlg);
                break;
        
  5. IDCLOSE では w.txt に修正済のデータを保存して終了します。
            case IDCLOSE:
                EndDlgProc(hDlg,"w.txt");
                EndDialog(hDlg,IDCLOSE);
                break;
        
  6. 名簿データを入力して ListBox に表示する処理です。
    DataFile.ReadData() でファイルから入力して g_buf に格納します。
    cnt に名簿の件数を求めて、一件ずつ ListBox に登録します。
    ListBox に登録するデータ形式は文字列で、文字列の終わりには '\0' を設定します。
    int InitDlgProc(HWND hDlg, char fname[])
    {   int     i,cnt;
    
        DataFile.ReadData(fname,g_buf[0],2000);
        cnt= DataFile.dwBytes/20;
        for(i=0; i<cnt; i++)
        {   g_buf[i][18]= '\0';
            SendMessage(GetDlgItem(hDlg,IDC_LIST1),LB_INSERTSTRING,(WPARAM)i,(LPARAM)g_buf[i]);
        }
        SendMessage(GetDlgItem(hDlg,IDC_LIST1),LB_SETCURSEL,(WPARAM)cnt,0L);
        wsprintf(edit_str,"%d",cnt);
        SetDlgItemText(hDlg,IDC_EDIT2,edit_str);
        DataCount(hDlg);
        return cnt;
    }
    
  7. ListBox から名簿データを取得してファイルに書き出す処理です。
    入力したデータ形式と同じになるようにレコードごとに改行コードを設定しています。
    int EndDlgProc(HWND hDlg, char fname[])
    {   int     i,cnt,len;
    
        cnt= SendMessage(GetDlgItem(hDlg,IDC_LIST1),LB_GETCOUNT,0,0L);
        for(i=0; i<cnt; i++)
        {   len= SendMessage(GetDlgItem(hDlg,IDC_LIST1),LB_GETTEXTLEN,(WPARAM)i,0L);
            if (len==LB_ERR)    break;
            SendMessage(GetDlgItem(hDlg,IDC_LIST1),LB_GETTEXT,(WPARAM)i,(LPARAM)g_buf[i]);
            g_buf[i][18]= '\r';
        }
        DataFile.WriteData(fname,g_buf[0],20*cnt);
        return(cnt);
    }
    

【NOTE】

ListBox は名簿一覧のようなデータを処理するのに適しています。
ListBox に関係する SendMessage を拾い出してみました。
関数 機能
SendMessage(GetDlgItem(hDlg,IDC_LIST1),LB_INSERTSTRING,(WPARAM)ListNo,(LPARAM)edit_str); データを登録する
SendMessage(GetDlgItem(hDlg,IDC_LIST1),LB_GETTEXT,(WPARAM)ListNo,(LPARAM)edit_str); アイテムからテキストを取得する
SendMessage(GetDlgItem(hDlg,IDC_LIST1),LB_DELETESTRING,(WPARAM)ListNo,0L); データを削除する
SendMessage(GetDlgItem(hDlg,IDC_LIST1),LB_GETCOUNT,0,0L); 登録されている件数を調べる
SendMessage(GetDlgItem(hDlg,IDC_LIST1),LB_SETCURSEL,(WPARAM)ListNo,0L); ListBox のフォーカスを設定する
SendMessage(GetDlgItem(hDlg,IDC_LIST1),LB_GETCURSEL,0L,0L); フォーカスが設定されている番号を調べる

前田稔(Maeda Minoru)の超初心者のプログラム入門