概要

 EnumPrintersを用いてプリンタ名の一覧を取得しコンボボックスで表示します。ディフォルトプリンターを最初に選択されるようにしています。
 以下に動作例を示します。

テスト環境

コンパイラ

Visual C++ 2013 Express 32/64bit

プログラムソースの概要

_tWinMain

DialogBox APIを呼び出してモーダルダイアログボックスを表示します。

DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)

WM_INITDIALOG

 EnumPrinters APIでプリンタ名の列挙に必要なメモリのバイト数を求めるためにメモリサイズ0を指定してEnumPrinters APIを呼び出し、必要なメモリサイズを取得します。この環境では1000バイトが返されました。
 ここではローカルプリンタしか確認できない環境ですのでPRINTER_ENUM_LOCALを指定しています。
 LocalAlloc APIでメモリを確保しゼロクリアします。
 EnumPrinters APIに確保したメモリのアドレスとサイズを指定して呼び出すと、プリンタ情報の一覧が指定したメモリに複写されます。メモリはPRINTER_INFO_1の配列ですのでprnInfoポインタにキャストします。
 後は、プリンタの数だけprnInfo配列をアクセスしCB_INSERTSTRINGメッセージでリストボックスに登録します。
 LocalFree APIでLocalAlloc APIで確保したメモリを解放します。
 GetDefaultPrinter APIでディフォルトプリンターの名前を取得しリストボックスの初期の選択アイテムをCB_SETCURSELメッセージで設定します。

WM_COMMAND

IDC_COMBOBOX
 コンボボックスの選択項目が変更したときに発生するCBN_SELCHANGEメッセージを処理します。
 CB_GETCURSELメッセージにより選択されているアイテムのインデックスを取得します。
 CB_GETLETEXTメッセージによりインデックスで指定するアイテムの文字列を取得します。
 インデックスを元に配列より文字列を取り出しSetWindowText APIによりラベルに表示します。
IDOK
 OKプッシュボタンをクリックするとこのメッセージが発生します。
 CB_GETCURSELメッセージにより選択されているアイテムのインデックスを取得します。
 CB_GETLETEXTメッセージによりインデックスで指定するアイテムの文字列を取得します。
 MessageBox APIを呼び出し、取得した文字列を表示します。
 EndDialog APIを呼び出し、ダイアログボックスを終了させます。
IDCANCEL
 キャンセルプッシュボタンをクリックするとこのメッセージが発生します。
 EndDialog APIを呼び出し、ダイアログボックスを終了させます。

プログラムソース

prnsel.cpp

//      プリンタの選択
//      Visual C++ 2013 32/64bit

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

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

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){
	static TCHAR buf[MAX_PATH];
	int num;
	switch (msg) {
	case WM_INITDIALOG:{
			DWORD dwNeeded,dwRet,i;
			PRINTER_INFO_1 *prnInfo;
			LPBYTE pPrnEnum;
			//	プリンタの名前等に必要なバイト数を取得
			EnumPrinters(PRINTER_ENUM_LOCAL,//	←ローカルプリンタを対象
				NULL,1,NULL,0,&dwNeeded,&dwRet);
			pPrnEnum = (LPBYTE)LocalAlloc(LPTR, dwNeeded);// メモリを確保
			if (pPrnEnum == NULL){
				break;
			}
			//	プリンタの情報を取得
			EnumPrinters(PRINTER_ENUM_LOCAL,NULL,1,pPrnEnum,dwNeeded,&dwNeeded,	&dwRet);
			prnInfo = (PRINTER_INFO_1 *)pPrnEnum;
			int defNum=-1;
			DWORD size=sizeof(buf)/sizeof(buf[0]);
			GetDefaultPrinter(buf,&size);

			for (i = 0; i < dwRet; i++){
				if(_tcscmp(prnInfo[i].pName,buf)==0)
					defNum=i;
				SendMessage(GetDlgItem(hDlg,IDC_COMBOBOX),CB_INSERTSTRING,i,(LPARAM)prnInfo[i].pName);        //コンボボックスにアイテムの設定
			}
			LocalFree(pPrnEnum);	//	メモリを解放
			if(0<=defNum)
				SendMessage(GetDlgItem(hDlg,IDC_COMBOBOX),CB_SETCURSEL,defNum,(LPARAM)0);    //   ディフォルトプリンタを選択
		}
		return TRUE;
	case WM_COMMAND:
		switch (LOWORD(wParam)) {
			case IDC_COMBOBOX:
				if (HIWORD(wParam) == CBN_SELCHANGE){   //      コンボボックスのアイテムが選択されたときに呼び出される
					num = (int)SendMessage(GetDlgItem(hDlg, IDC_COMBOBOX), CB_GETCURSEL, 0, 0);     //      カーソル位置のアイテムを取得
					SendMessage(GetDlgItem(hDlg, IDC_COMBOBOX), CB_GETLBTEXT, num,(LPARAM)buf);
					SetWindowText(GetDlgItem(hDlg, IDC_LABEL), buf);
				}
				break;
			case IDOK:
				num=(int)SendMessage(GetDlgItem(hDlg,IDC_COMBOBOX),CB_GETCURSEL,0,0);   //      カーソル位置のアイテムを取得
				SendMessage(GetDlgItem(hDlg, IDC_COMBOBOX), CB_GETLBTEXT, num,(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;
}

resource.h

#define IDC_COMBOBOX 100
#define IDC_LABEL    110

resource.rc

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

DLG1 DIALOG DISCARDABLE 0, 0, 168, 85
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, 155, 100
 LTEXT                  "", IDC_LABEL, 7, 50, 155, 14

 CONTROL "OK", IDOK, "BUTTON", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,28, 64, 48, 14
 CONTROL "キャンセル", IDCANCEL, "BUTTON", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 92, 64, 48, 14
}

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

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