複数選択リスト


可変個数のアイテムの選択

前回の章で作成したようなリストボックスは
必ず、選択されている項目は1つだけでした

しかし、CreateWindow() 関数のスタイルで LBS_MULTIPLESEL を指定します
すると複数の項目を同時に選択できるリストボックスが生成されます

問題は、複数選択リストボックスにおいて
WM_SETCURSEL や WM_GETCURSEL、WM_SELECTSTRING など
単一項目の指定が原則となっているメッセージだけでは役不足です

そこで、項目の選択や解除には LB_SETSEL メッセージを使います
このメッセージは、フラグによって項目の選択や解除を行うことができます
WPARAM に TRUE を指定すれば選択、FALSE を指定すれば解除します
LPARAM には、対象となるリストのインデックスを指定します
失敗した時、戻り値は LB_ERR になります

同様に、項目の選択状態を調べるには LB_GETSEL を使いましょう
WPARAM には、調べるリストのインデックスを指定します。LPARAM は 0 です
戻り値は、選択されていれば 0 以外、選択されていなければ 0 が返り
失敗した場合は LB_ERR が返ります
#include <windows.h>

LPCTSTR strItem[] = {
	TEXT("Kitty on your lap") ,
	TEXT("Tokyo mew mew") ,
	TEXT("Magical nyan nyan TARUTO") ,
	TEXT("Di Gi Charat") ,
	TEXT("Nekoneko Zoo")
};

LRESULT CALLBACK WndProc(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp) {
	static HWND list , label;
	TCHAR strText[1024] , strBool[5][6];
	int i;

	switch (msg) {
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	case WM_CREATE:
		list = CreateWindow(
			TEXT("LISTBOX") , NULL , 
			WS_CHILD | WS_VISIBLE | LBS_STANDARD | LBS_MULTIPLESEL , 
			0 , 0 , 200 , 100 , hwnd , (HMENU)1 ,
			((LPCREATESTRUCT)(lp))->hInstance , NULL
		);
		for (i = 0 ; i < 5 ; i++)
			SendMessage(list , LB_ADDSTRING , 0 , (LPARAM)strItem[i]);

		label = CreateWindow(
			TEXT("STATIC") , NULL , 
			WS_CHILD | WS_VISIBLE , 
			200 , 0 , 100 , 90 , hwnd , (HMENU)2 ,
			((LPCREATESTRUCT)(lp))->hInstance , NULL
		);
		return 0;
	case WM_COMMAND:
		for (i = 0 ; i < 5 ; i++) {
			if (SendMessage(list , LB_GETSEL , i , 0)) 
				wsprintf(strBool[i] , TEXT("TRUE"));
			else wsprintf(strBool[i] , TEXT("FALSE"));
		}

		wsprintf(strText , TEXT("%s\n%s\n%s\n%s\n%s") ,
			strBool[0] , strBool[1] ,
			strBool[2] , strBool[3] , strBool[4]
		);
		SetWindowText(label , strText);
		return 0;
	}
	return DefWindowProc(hwnd , msg , wp , lp);
}

int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance ,
			PSTR lpCmdLine , int nCmdShow ) {
	HWND hwnd;
	MSG msg;
	WNDCLASS winc;

	winc.style		= CS_HREDRAW | CS_VREDRAW;
	winc.lpfnWndProc	= WndProc;
	winc.cbClsExtra	= winc.cbWndExtra	= 0;
	winc.hInstance		= hInstance;
	winc.hIcon		= LoadIcon(NULL , IDI_APPLICATION);
	winc.hCursor		= LoadCursor(NULL , IDC_ARROW);
	winc.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);
	winc.lpszMenuName	= NULL;
	winc.lpszClassName	= TEXT("KITTY");

	if (!RegisterClass(&winc)) return -1;

	hwnd = CreateWindow(
			TEXT("KITTY") , TEXT("Kitty on your lap") ,
			WS_OVERLAPPEDWINDOW | WS_VISIBLE ,
			CW_USEDEFAULT , CW_USEDEFAULT ,
			CW_USEDEFAULT , CW_USEDEFAULT ,
			NULL , NULL , hInstance , NULL
	);

	if (hwnd == NULL) return -1;

	while(GetMessage(&msg , NULL , 0 , 0)) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return msg.wParam;
}


右のスタティックコントロールに、リストの選択状況を表示するプログラムです
WM_COMMAND が発行されるたびに、全インデックスを LB_GETSEL で調べています



前のページへ戻る次のページへ