![]() Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Инициализация списка и выбор элементов
Поскольку при создании список не содержит элементов, его необходимо инициализировать при первом отображении содержащего его диалога. Это довольно просто, поскольку при активизации диалога его оконная функция получает сообщение WM_INITDIALOG, так что в DialogFunc() нужно добавить обработку этого сообщения:
case WM_INITDIALOG: // Инициализация списка SendDlgItemMessage(hdwnd, ID_LB1, LB_ADDSTRING, 0, (LPARAM)" Яблоко"); SendDlgltemMessage(hdwnd, ID_LB1, LB_ADDSTRING, 0, (LPARAM)" Апельсин"); SendDlgltemMessage(hdwnd, ID_LB1, LB_ADDSTRING, 0, (LPARAM)" Груша"); SendDlgltemMessage(hdwnd, ID_LB1, LB_ADDSTRING, 0, (LPARAM)" Виноград"); return 1;
Этот фрагмент программы заносит в список элементы Яблоко, Апельсин, Груша и Виноград. Каждый вызов функции SendDlgItemMessage() добавляет новую строку в список. Функция SendDlgItemMessage() направляет списку команду LB_ADDSTRING. Указатель на добавляемую строку содержится в параметре lParam (тип указателя надо преобразовать к LPARAM). В данном случае строки добавляются в список в том порядке, в котором передаются. В зависимости от типа списка добавляемые элементы могут сортироваться в алфавитном порядке. Если количество включаемых в список элементов превышает число элементов, которые можно отобразить в списке, к окну списка автоматически добавляется линейка прокрутки.
Выбор элементов списка. После инициализации список готов к работе с ним. Существует два способа эыбора элементов в списке. Во-первых, это можно сделать двойным щелчком мыши на выбираемом элементе. В этом случае оконной функции диалога будет направлено сообщение WM_COMMAND, в котором LOWORD(wParam) будет содержать идентификатор окна списка, a HIWORD(wParam) – сообщение LBN_DBLCLK. Двойной щелчок мыши обычно означает, что программа должна обработать выбор сразу же. Во-вторых, пользователь может просто изменить выбранный элемент списка, используя клавиатуру или мышь. В этом случае сообщение в программу не посылается, выбранный элемент запоминается, так что программа может запросить у списка номер этого элемента. Оба подхода иллюстрируются в приведенном ниже примере. Если выбран какой-нибудь элемент списка, можно определить его номер, послав списку сообщение LB_GETCURSEL. В ответ список возвратит номер выбранного элемента. Если никакой элемент не выбран, список возвращает LB_ERR(-1). Чтобы продемонстрировать процедуру обработки выбора элементов списка, добавьте во вложенный оператор switch в функции DialogFunc() следующий фрагмент.
case ID_LB1: // Обработка сообщения LBN_DBLCLK списка // Если это, конечно, LBN_DBLCLK if(HIWORD(wParam) == LBN_DBLCLK) { // Получить индекс выбранного элемента i = SendDlgItemMessage(hdwnd, ID_LB1, LB_GETCURSEL, 0, 0L); sprintf(str, " Индекс выбранного элемента %d", i); MessageBox(hdwnd, str, " Сделан выбор", МВ_ОК); } return 1; case IDD_SELFRUIT: // Нажата кнопка " Выбери фрукт" { i = SendDlgItemMessage(hdwrtd, ID_LB1, LBJ3ETCURSEL, 0, 0L); if(i > -1) sprintf(str, " Индекс выбранного элемента %d", i); else sprintf(str, " Фрукт не выбран"); MessageBox(hdwnd, str, " Сделан выбор", МВ_ОК); return 1;
При двойном щелчке мыши на элементе списка будет появляться окно сообщения, отображающее индекс выбранного элемента. То же произойдет и при нажатии кнопки Выбери фрукт.
Пример 5-2. Для удобства приведем полный текст программы отображения диалога со списком. (Не забудьте внести соответствующие изменения а файлы Mydialog.h и Mydialog.rc).
// Демонстрация списка #include < Windows.h> #include < String.h> #include < Stdio.h> #include " Mydialog.h" LRESULT CALLBACK WindowFunc(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK DialogFunc(HWND, UINT, WPARAM, LPARAM); char szWinName[]=" МоеОкно"; // Имя класса окна HINSTANCE hInst; int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR lpszArgs, int nWinMode) { HWND hwnd; MSG msg; WNDCLASS wcl; HACCEL hAccel; // Определить класс окна wcl.hInstance=hThisInst; // Дескриптор приложения wcl.lpszClassName=szWinName; // Имя класса окна wcl.lpfnWndProc=WindowFunc; // функция окна wcl.style=0; // Стиль по умолчанию wcl.hIcon=LoadIcon(NULL, IDI_APPLICATION); // Иконка wcl.hCursor=LoadCursor(NULL, IDC_ARROW); // Курсор wcl.lpszMenuName=" MYMENU"; // Меню wcl.cbClsExtra=0; // Без дополнит. информации wcl.cbWndExtra=0; wcl.hbrBackground // Заполнение окна белым цветом =(HBRUSH)GetStockObject(WHITE_BRUSH); if(! RegisterClass(& wcl)) return 0; // Зарегистрировать класс окна // Создать окно: hwnd=CreateWindow(szWinName, // Имя класса " Демонстрация списка", // Заголовок WS_OVERLAPPEDWINDOW, // Стиль окна CW_USEDEFAULT, // Х-координата CW_USEDEFAULT, // Y-координата CW_USEDEFAULT, // Ширина по умолчанию CW_USEDEFAULT, // Высота по умолчанию HWND_DESKTOP, // Нет родительского окна NULL, // Нет меню hThisInst, // Дескриптор приложения NULL); // Без дополнительных аргументов hInst=hThisInst; // Сохранить дескриптор текущего // Загрузить акселераторы: hAccel=LoadAccelerators(hThisInst, " MYMENU"); // Показать окно и перерисовать содержимое: ShowWindow(hwnd, nWinMode); UpdateWindow(hwnd); // Запустить цикл обработки сообщений: while(GetMessage(& msg, NULL, 0, 0)) { if(! TranslateAccelerator(hwnd, hAccel, & msg)) { TranslateMessage(& msg); // Использ. клавиатуру DispatchMessage (& msg); // Вернуть управление } // к ОС Windows } return msg.wParam; }
// Следующая функция вызывается ОС Windows и получает // в качестве параметров сообщения из очереди // сообщений данного приложения
LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_COMMAND: switch(LOWORD(wParam)) { case IDM_DIALOG1: DialogBox(hInst, " MYDB", hwnd, DialogFunc); break; case IDM_DIALOG2: MessageBox(hwnd, " Этого диалога пока нет", " ", MB_OK); break; case IDM_HELP: MessageBox(hwnd, " Помощь", " Помощь", MB_OK); break; } break; case WM_DESTROY: /* завершение программы */ PostQuitMessage(0); break; default: // Все сообщения, не обрабатываемые // в данной функции, направляются // на обработку по умолчанию return DefWindowProc(hwnd, message, wParam, lParam); } return 0; }
// Простая функция диалога BOOL CALLBACK DialogFunc(HWND hdwnd, UINT message, WPARAM wParam, LPARAM lParam) { long i; char str[80]; switch(message) { case WM_COMMAND: switch(LOWORD(wParam)) { case IDCANCEL: EndDialog(hdwnd, 0); return 1; case IDD_RED: MessageBox(hdwnd, " Выбран Красный", " Красный", MB_OK); return 1; case IDD_GREEN: MessageBox(hdwnd, " Выбран Зеленый", " Зеленый", MB_OK); return 1; case ID_LB1: // Сообщение от списка, если // это, конечно, LBN_DBLCLK if(HIWORD(wParam) == LBN_DBLCLK) { // Получ. индекс выбран. элемента i=SendDlgItemMessage(hdwnd, ID_LB1, LB_GETCURSEL, 0, 0L); sprintf (str, " Индекс выбранного элемента %d", i); MessageBox(hdwnd, str, " Сделан выбор", MB_OK); } return 1; case IDD_SELFRUIT: //Кнопка " Выбери фрукт" i=SendDlgItemMessage(hdwnd, ID_LB1, LB_GETCURSEL, 0, 0L); if(i > -1) sprintf (str, " Индекс выбранного элемента %d", i); else sprintf(str, " Фрукт не выбран"); MessageBox(hdwnd, str, " Сделан выбор", MB_OK); return 1; } case WM_INITDIALOG: // Инициализация списка SendDlgItemMessage(hdwnd, ID_LB1, LB_ADDSTRING, 0, (LPARAM)" Яблоко"); SendDlgItemMessage(hdwnd, ID_LB1, LB_ADDSTRING, 0, (LPARAM)" Апельсин"); SendDlgItemMessage(hdwnd, ID_LB1, LB_ADDSTRING, 0, (LPARAM)" Груша"); SendDlgItemMessage(hdwnd, ID_LB1, LB_ADDSTRING, 0, (LPARAM)" Виноград"); return 1; } return 0; }
Пример работы этой программы показан на рис. 5.2.
|