ダイアログボックスにリストボックスを付ける

リストボックス

今回は、ダイアログボックスにリストボックスを付けます。 リストボックスにフォルダとファイルを表示させ、ダブルクリックでサブフォルダに移動できるようにします。

テキストの表示 - インコのWindowsSDK で作成したソースを修正します。

ここでは、Reseditで作成する方法も説明します。

流れ

WM_INITDIALOG

WM_INITDIALOGは、ダイアログが作成されたときに一度だけ実行されます。

DlgDirList()で、指定されたリストボックスに、指定されたディレクトリ内のファイル名とサブディレクトリ名を表示します。

int DlgDirList(
    HWND hDlg,          // リストボックスを保持しているダイアログボックスのハンドル
    LPTSTR lpPathSpec,  // パス名やファイル名を格納するバッファ
    int nIDListBox,     // リストボックスのID
    int nIDStaticPath,  // 静的コントロールのID
    UINT uFileType      // 表示対象のファイルの属性
);

uFileTypeの値説明
DDL_ARCHIVEアーカイブファイルを表示
DDL_DIRECTORYサブディレクトリを角かっこ([ ])つきで、表示
DDL_DRIVESドライブ名を[-x-] という形式で表示
DDL_HIDDEN隠しファイルを表示
DDL_READONLY読み取り専用ファイルを表示
DDL_SYSTEMシステムファイルを表示

WM_COMMAND

リストボックス上でダブルクリック[LBN_DBLCLK]されたときの処理を追加

1.DlgDirSelectEx() で、リストボックスから、現在選択されている項目を取得します。

BOOL DlgDirSelectEx(
    HWND hDlg,       // リストボックスを保持しているダイアログボックスのハンドル
    LPTSTR lpString, // パスを格納するバッファ
    int nCount,      // パスを格納するバッファの文字数
    int nIDListBox   // リストボックスのID
);

戻り値は、フォルダまたはドライブが選択されている場合、0以外の値が返ります。
ファイルが選択されているときは、0が返ります。

2._tcscat_s()は、文字列をコピーする関数です。

_tcscpy_s(a, MAX_SIZE, b)

文字列a に文字列b をコピーします。MAX_SIZE は、文字列a が確保するバッファのサイズです。
strcpy()と同じ意味ですが、_tcscat_s()は、Unicode対応で、セキュリティ強化版になります。

リソースファイル

リストボックス[LISTBOX]

LISTBOX  id, x0, y0, width, height, type

idリストボックスのID
x0リストボックス左上のx座標
y0リストボックス左上のy座標
widthリストボックスの幅
heightリストボックスの高さ
styleリストボックスのスタイル
ウインドウスタイルと、リストボックスのスタイルが指定可能

・Visual Studioのリソース ビュー、ResEditでの設定
ツールボックス(Toolbox)ウインドウのListboxを選択

VCwin32アプリケーション2

ソースコードの入力

ソースコードは下記のように入れてください。

test.cpp
#include <windows.h>
#include <tchar.h>
#include "resource.h"

// このコード モジュールに含まれる関数の宣言を転送します:
BOOL CALLBACK DialogProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
          PSTR lpCmdLine, int nCmdShow )
{
    DialogBox(hInstance, TEXT("DIALOG_BOX"), NULL, DialogProc);
    return 0;
}

BOOL CALLBACK DialogProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    static TCHAR  szTmp[1024] = TEXT("C:\\*.*");
    UINT wmId;
    switch (msg)
    {
        case WM_CLOSE:
            EndDialog(hWnd, IDOK);
            break;
        case WM_INITDIALOG:
            DlgDirList(hWnd, szTmp, IDC_LIST1, IDC_EDIT1, DDL_DIRECTORY | DDL_DRIVES);
            break;
        case WM_COMMAND:
            wmId = LOWORD(wParam);
            switch (wmId)
            {
                case IDC_LIST1:
                    if (HIWORD(wParam) == LBN_DBLCLK)
                    {
                        if (DlgDirSelectEx(hWnd,szTmp,sizeof(szTmp),IDC_LIST1))
                        {
                            _tcscat_s(szTmp,1024,TEXT("*.*"));
                            DlgDirList(hWnd, szTmp, IDC_LIST1, IDC_EDIT1,
                              DDL_DIRECTORY | DDL_DRIVES);
                        }
                    }
                    break;
            }
        default:
            break;
    }
    return FALSE;
}

resource.h

#define IDC_LIST1 400
#define IDC_EDIT1 200
#ifndef IDC_STATIC
#define IDC_STATIC -1
#endif

Reseditで作成した場合は、これとは異なるソースコードになります。
上記の太線で示している箇所のみ追加です。

test.rc
#include <windows.h>
#include "resource.h"

/////////////////////////////////////////////////////////////////////////////
//
// ダイアログ
//

DIALOG_BOX DIALOG 0, 0, 138, 140
FONT 12, "MS UI Gothic"
CAPTION "Dialog"
BEGIN
    LISTBOX  IDC_LIST1, 5, 25, 128, 104, WS_TABSTOP | WS_VSCROLL | LBS_NOINTEGRALHEIGHT | LBS_SORT
    EDITTEXT IDC_EDIT1, 5, 6, 128, 14, ES_AUTOHSCROLL
END

Reseditで作成した場合は、これとは異なるソースコードになります。
上記の太線で示している箇所のみ追加です。