概要

ローカルコンピューターの有効なディスクドライブとその種類をコンボボックスに表示し、選択します。

テスト環境

コンパイラ

Visual C++ 2008 Standard 32/64bit
Visual C++ 2013 Express 32/64bit

プロジェクトの作成

Win32プロジェクト

実行環境

Windows 8.1 Enterprise 64bit
Windows 7 EnterPrise Service Pack 1 64bit
Windows Vista Ultimate Service Pack 2 32bit
Windows XP Professional Service Pack 3 32bit

プログラムソースの概要

_tWinMain関数

ダイアログボックスを表示します。

DlgProc関数

ダイアログボックスプロシージャーです。
必要な時にWindowsから呼び出されます。
第2引数にメッセージの種類が格納されていますので、switchステートメントによりメッセージごとの処理を振り分けます。 コントロールダイアログボックスに張り付けられているエディットボックスやプッシュボタン等 コントロールと呼ぶ)を操作するには、コントロールのハンドルが必要です。 ダイアログボックスのコントロール(子ウィンドウ)のハンドルを取得するには、 GetDlgItem APIを呼び出し、ダイアログボックスのハンドルとコントロールのID番号よりハンドルを取得します。 自分で処理しないメッセージは、ダイアログボックスプロシージャー終了時にFALSEを渡せば、Windowsが標準的な処理を行ってくれます。

case WM_INITDIALOG:

ダイアログボックスの初期化時に発生するメッセージです。
GetLogicalDrives APIを呼び出しローカルコンピューターの有効なディスクドライブの一覧を取得します。
GetLogicalDrives APIの戻り値は、各ビットがドライブに対応しています。例えばビット0はAドライブ、ビット1がBドライブという風に割り付けられています。
変数bitに1をセットし、GetLogicalDrives APIの戻り値とのAND演算(論理積)を行い結果が0以外の場合、対応するビットが1であるため、そのドライブが有効であることを示します。
変数bitを1ビット左シフトし、またAND演算を行います。これを26下位繰り返すとA~Zドライブの検索ができます。
有効なドライブに対して、drv_type_info関数を実行しドライブの種類を示す文字列を取得しコンボボックスにCB_INSERTSTRINGメッセージを送信しコンボボックスにアイテムを登録します。
コンボボックスにCB_SETCURSELメッセージを送信し、アイテム0を選択状態にします。

case WM_COMMAND

ダイアログボックスの子ウィンドウ(ダイアログボックスに張り付けられているエディットボックスやプッシュボタン等)から発生したメッセージが届きます。
ダイアログボックスプロシージャーの第3引数であるWPARAMの下位16bitがコントロールのID番号、その上位16bitには通知内容が格納されています。 LOWORDマクロによりWPARAMの下位16bitを取り出し、switchステートメントによりコントロールごとに処理を振り分けます。
case IDOK:
OKプッシュボタンのID番号がIDOKです。
OKプッシュボタンをクリックするとこのメッセージが発生します。
コンボボックスにCB_GETCURSELメッセージを送信し選択されているコンボボックスのアイテム番号を取得します。
コンボボックスにCB_GETLBTEXTメッセージを送信し、アイテム番号に対応するアイテム文字列を取得します。
MessageBox APIでアイテム文字列を表示します。
EndDialog APIを呼び出し、ダイアログボックスを終了させます。 このAPIの第2引数は、ダイアログボックスが終了し、DialogBox APIが返す値となります。

drv_type_info関数

GetDriveType APIを呼び出し、戻り値に対応する文字列を返します。

プログラムソース

drvcombo.cpp

//    ドライブ名のコンボボックスサンプル
//      Visual C++ 2008/2013 32/64bit

#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include <tchar.h>
#include "resource.h"


//      ダイアログボックスプロシージャー
LRESULT CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);

//      ドライブの種類を返す
TCHAR* drv_type_info(int c);


int WINAPI _tWinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, TCHAR* lpsCmdLine, int nCmdShow){
        DialogBox(hCurInst, TEXT("DLG1"), 0, (DLGPROC)DlgProc);
        return (int)0;
}


//      ダイアログボックスプロシージャー

LRESULT CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam){
        TCHAR buf[32];
        int no;
    switch (msg) {
                case WM_INITDIALOG:{
                        DWORD dwDrive = GetLogicalDrives();
                        int i=0;
                        DWORD bit = 1;
                        for(int n=0;n<26;n++){
                                if(dwDrive & bit){
                                        _stprintf_s(buf,sizeof(buf)/sizeof(TCHAR),_TEXT("%c: %s"),_T('A')+n,drv_type_info(_T('A')+n));
                                        
                                        SendMessage(GetDlgItem(hDlg,IDC_COMBOBOX),CB_INSERTSTRING,i++,(LPARAM)buf);     //コンボボックスにアイテムの設定
                                }
                                bit = bit << 1;
                        }
                        SendMessage(GetDlgItem(hDlg,IDC_COMBOBOX),CB_SETCURSEL,0,(LPARAM)0);    //      初期時に選択されるアイテムを選択
                        return TRUE;
                }
        case WM_COMMAND:
            switch (LOWORD(wParam)) {
                                case IDOK:
                                        no=(int)SendMessage(GetDlgItem(hDlg,IDC_COMBOBOX),CB_GETCURSEL,0,0);
                                        SendMessage(GetDlgItem(hDlg,IDC_COMBOBOX),CB_GETLBTEXT,no,(LPARAM)buf);
                                        MessageBox(hDlg,buf,_TEXT("選択結果"),MB_OK);
                                        EndDialog(hDlg, TRUE);
                                        return TRUE;
                                case IDCANCEL:
                                        EndDialog(hDlg,FALSE);
                                        return FALSE;
                                default:
                                        return FALSE;
                        }
                default:
                        return FALSE;
        }
        return TRUE;
}

//      ドライブの種類を返す

TCHAR* drv_type_info(int c){
        TCHAR buf[4];
        buf[0] = c;
        buf[1] = _T(':');
        buf[2] = _T('\\');
        buf[3] = _T('\0');

        switch (GetDriveType(buf)){
        case DRIVE_UNKNOWN:     return _TEXT("不明");
        case DRIVE_NO_ROOT_DIR: return _TEXT("");
        case DRIVE_REMOVABLE:   return _TEXT("リムーバブル");
        case DRIVE_FIXED:       return _TEXT("HDD");
        case DRIVE_REMOTE:      return _TEXT("ネットワーク");
        case DRIVE_CDROM:       return _TEXT("CD又はDVD");
        case DRIVE_RAMDISK:     return _TEXT("RAMディスク");
        }
        return _TEXT("");
}

resource.h

#define IDC_COMBOBOX 100

resource.rc

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

DLG1 DIALOG DISCARDABLE 0, 0, 78, 77
EXSTYLE WS_EX_DLGMODALFRAME
STYLE WS_POPUP  | WS_CAPTION | WS_SYSMENU |  DS_SETFONT
CAPTION "ドライブ選択"
FONT 9, "MS Shell Dlg"
{
 CONTROL "", IDC_COMBOBOX, "COMBOBOX", WS_CHILD | WS_VISIBLE | WS_VSCROLL | CBS_DROPDOWNLIST , 7, 7, 64, 100

 CONTROL "OK", IDOK, "BUTTON", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 12, 56, 54, 14
}

ソースファイルのダウンロード

ダウンロード drvcombo.zip(41.1kByte)
ZIPファイルに含まれるファイル
drvcombo.cpp
resource.h
resource.rc
drvcombo.exe