
- •Уп. 2. Органы управления в приложениях Win32
- •2.1. Кнопки
- •2.1.1. Создание кнопок
- •2.1.2. Кнопки и сообщения
- •2.1.3. Флажки и переключатели
- •2.2. Статический орган управления
- •2.3. Полоса прокрутки
- •2.3.1. Общие сведения
- •2.3.2. Создание полосы прокрутки
- •2.3.3. Простейшие полосы прокрутки
- •2.3.4. Сообщения от полосы прокрутки
- •2.3.5. Управление полосой прокрутки
- •2.3.6. Пример обработки сообщений от полос прокрутки
- •2.3.7. Новые функции управления полосами прокрутки
- •2.3.8. Пример окна приложения с полосой просмотра
- •2.4. Редактор текста
- •2.4.1. Создание редактора
- •2.4.2. Сообщения для редактора текста
- •2.4.3. Сообщения от редактора текста
- •2.4.4. Пример работы с однострочным редактором
- •2.5. Списки строк
- •2.5.1. Создание списка
- •2.5.2. Сообщения от списка
- •2.5.3. Сообщения для списка
- •2.5.4. Пример работы со списком
- •2.6. Комбинированный список
- •2.6.1. Создание комбинированного списка
- •2.6.2. Коды извещения
- •2.6.3. Сообщения для комбинированного списка
- •2.6.4. Пример работы с комбинированным списком
- •Контрольные вопросы
- •Упражнения
- •Приложение 2
2.5.4. Пример работы со списком
Задача. В окне приложения создать однострочный редактор, список и кнопку "Добавить". При нажатии на кнопку содержимое редактора записать в список. При двойном щелчке по строке списка сообщить о строке, которая была выбрана.
Решение этой задачи отображено в описании следующей функции окна (листинг 2.7).
При создании окна друг под другом создаются 4 органа управления с дескрипторами hStatic (статический орган), hEdit (однострочный редактор), hListBox (список) и hButton (кнопка).
Листинг 2.7. Работа со списком строк
#include <windows.h>
#define ID_EDIT 1000
#define ID_LISTBOX 1001
#define ID_BUTTON 1002
BOOL RegClass(WNDPROC, LPCTSTR, UINT);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE hInstance;
TCHAR szClassName[] = TEXT("ListDir");
TCHAR szTitle[] = TEXT("Работа со списком");
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpszCmdLine, int nCmdShow)
{
MSG msg;
HWND hwnd;
hInstance = hInst;
if (!RegClass(WndProc, szClassName, COLOR_WINDOW))
return FALSE;
if (!(hwnd = CreateWindow(szClassName, szTitle,
WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 50, 364, 360, 0, 0, hInstance, NULL)))
return FALSE;
while(GetMessage(&msg, 0, 0, 0))
{ TranslateMessage(&msg); DispatchMessage(&msg); }
return msg.wParam;
}
BOOL RegClass(WNDPROC Proc, LPCTSTR szName, UINT brBackground)
{
WNDCLASS wc;
wc.style=wc.cbClsExtra=wc.cbWndExtra=0;
wc.lpfnWndProc = Proc;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(brBackground + 1);
wc.lpszMenuName = (LPCTSTR)NULL;
wc.lpszClassName = szName;
return (RegisterClass(&wc) != 0);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HWND hListBox, hEdit, hButton, hStatic;
int uItem;
TCHAR Buf[80];
switch (msg)
{
case WM_CREATE:
{
hStatic=CreateWindow(TEXT("static"), TEXT("Введите строку для ввода в список"),
WS_CHILD | WS_VISIBLE | SS_CENTER,
30, 10, 300, 20, hwnd, (HMENU)0, hInstance, NULL);
hEdit = CreateWindow(TEXT("edit"), NULL,
WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT | ES_AUTOHSCROLL,
30, 40, 300, 30, hwnd, (HMENU)ID_EDIT, hInstance, NULL);
hListBox = CreateWindow(TEXT("listbox"), NULL,
WS_CHILD | WS_VISIBLE | LBS_STANDARD,
30, 80, 300, 200, hwnd, (HMENU)ID_LISTBOX, hInstance, NULL);
hButton = CreateWindow(TEXT("button"), TEXT("Добавить"),
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
130, 290, 100, 30, hwnd, (HMENU)ID_BUTTON, hInstance, NULL);
SetFocus(hEdit);
return 0;
}
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case ID_LISTBOX:
{
switch (HIWORD(wParam))
{
case LBN_ERRSPACE:
{
MessageBox(hwnd, TEXT("Мало памяти"), szTitle, MB_OK);
return 0;
}
case LBN_DBLCLK:
{
uItem = (int)SendMessage(hListBox, LB_GETCURSEL, 0, 0L);
if(uItem != LB_ERR)
{
SendMessage(hListBox, LB_GETTEXT, uItem, (LPARAM)Buf);
MessageBox(hwnd, Buf, szTitle, MB_OK);
}
return 0;
}
default: return 0;
}
return 0;
}
case ID_BUTTON:
{
//SendMessage(hEdit, EM_GETLINE, 0, (LPARAM)Buf);
SendMessage(hEdit, WM_GETTEXT, 80, (LPARAM)Buf);
SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM)Buf);
SetWindowText(hEdit, TEXT("\0"));
SetFocus(hEdit);
return 0;
}
default: return 0;
}
}
case WM_DESTROY: { PostQuitMessage(0); return 0; }
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
Если нажать на кнопку "Добавить", то в буфер с именем Buf выбирается содержимое (даже пустое) однострочного редактора и содержимое буфера Buf записывается в список:
SendMessage( hEdit, EM_GETLINE, 0, (LPARAM)Buf);
SendMessage( hListBox, LB_ADDSTRING, 0, (LPARAM)Buf);
Обратите внимание, что редактор в этом примере может содержать и очень длинную строку. В любом случае она записывается в список. Ограничение накладывает лишь длина буфера Buf.
При двойном щелчке по строке списка определяется номер выделенного элемента:
uItem=(int)SendMessage( hListBox, LB_GETCURSEL, 0, 0L);
Если код возврата uItem не равен ошибке (LB_ERR), то в буфер с именем Buf выбирается строка с номером uItem:
SendMessage( hListBox, LB_GETTEXT, uItem, (LPARAM)Buf);