Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
каркас.doc
Скачиваний:
58
Добавлен:
03.06.2015
Размер:
1.6 Mб
Скачать

Типы сообщений

Сообщение

Назначение

1

LB_ADDSTRING

Добавление новой строки в список

2

LB_GETCURSEL

Запрос номера (индекс) выбранного элемента

LB_ADDSTRING является сообщением, представляющим собой команду, в соот­ветствии с которой заданная строка включается в список как новый элемент. Вскоре Вы увидите, как используется это сообщение. При получении сообщения LB_GETCURSEL список возвращает индекс элемента, выбранного пользователем. Индексы в списке всегда начинаются с 0. Чтобы направить сообщение списку (или любому другому элементу управления), нужно использовать функцию API SendDlgItemMessage(), имеющую прототип:

LONG SendDlgItemMessage(HWND hwnd, int ID,

UINT IDMsg, WPARAM wParam,

LPARAM lParam);

Функция SendDlgItemMessage() направляет элементу управления, идентификатор которого задается параметром ID, сообщение, задаваемое параметром IDMsg. Допол­нительная информация в сообщении задается параметрами wParam и lParam. Эта информация может изменяться от сообщения к сообщению. Если дополнительная информация не требуется, значения wParam и lParam должны быть равны 0. Значение, возвращаемое функцией SendDlgItemMessage(), содержит информацию, запрашивае­мую IDMsg.

5.7. Инициализация списка и выбор элементов

Поскольку при создании список не содержит элементов, его необходимо ини­циализировать при первом отображении содержащего его диалога. Это довольно просто, поскольку при активизации диалога его оконная функция получает сообще­ние 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.