Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ch-08.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
645.12 Кб
Скачать

Получение сообщений от окон списка

Когда пользователь щелкает мышью над окном списка, окно списка получает фокус ввода. Родительское окно может предоставить управляющему (listbox control) окну списка фокус ввода с помощью вызова функции:

SetFocus (hwndList);

Если окно списка имеет фокус ввода, то для выбора пунктов списка также могут использоваться клавиши управления курсором, буквенные клавиши и клавиша <Spacebar>.

Управляющее окно списка посылает сообщения WM_COMMAND своему родительскому окну. Значение параметров сообщения lParam и wParam то же, что и для кнопок управления и управляющих окон редактирования:

LOWORD (wParam)

Идентификатор дочернего окна

HIWORD (wParam)

Код уведомления

lParam

Описатель дочернего окна

Ниже перечисляются коды уведомления и их значения:

LBN_ERRSPACE

—2

LBN_SELCHANGE

1

LBN_DBLCLK

2

LBN_SELCANCEL

3

LBN_SELFOCUS

4

LBN_KILLFOCUS

5

Окно списка посылает своему родительскому окну коды LBN_SELCHANGE и LBN_DBLCLK только в том случае, если в стиль дочернего окна включен идентификатор LBS_NOTIFY.

Код LBN_ERRSPACE показывает, что превышен размер памяти, отведенный для списка. Код LBN_SELCHANGE показывает, что был изменен текущий выбор; эти сообщения имеют место, когда пользователь перемещает подсветку по списку, изменяет состояние выборки с помощью клавиши <Spacebar> или выбирает нужный элемент списка с помощью щелчка мыши. Код LBN_DBLCLK показывает, что на данном пункте списка имел место двойной щелчок мыши. (Значение кодов уведомления для LBN_SELCHANGE и LBN_DBLCLK соответствует количеству щелчков мыши.)

В зависимости от вашего приложения, вы можете использовать либо сообщения LBN_SELCHANGE, либо сообщения LBN_DBLCLK, либо оба вместе. Ваша программа будет получать много сообщений LBN_SELCHANGE, что же касается сообщений LBN_DBLCLK, то они будут случаться только при двойных щелчках мышью. Если в вашей программе используются двойные щелчки мышью, то вам понадобиться обеспечить соответствующий интерфейс клавиатуры для дублирования сообщений LBN_DBLCLK.

Простое приложение, использующее окно списка

Теперь, когда вы знаете как создать список, как заполнить его текстовыми элементами, как получать сообщения от окна списка и как извлекать строки, самое время создать приложение, использующее список. Программа ENVIRON, представленная на рис. 8.8, использует окно списка в рабочей области окна для вывода имен текущих переменных окружения MS-DOS (таких, как PATH, COMSPEC и PROMPT). При выборе переменной, имя и строка окружения выводятся в верхней части рабочей области.

ENVIRON.MAK

#-----------------------

# ENVIRON.MAK make file

#-----------------------

environ.exe : environ.obj

$(LINKER) $(GUIFLAGS) -OUT:environ.exe environ.obj $(GUILIBS)

environ.obj : environ.c

$(CC) $(CFLAGS) environ.c

ENVIRON.C

/*----------------------------------------

ENVIRON.C -- Environment List Box

(c) Charles Petzold, 1996

----------------------------------------*/

#include <windows.h>

#include <stdlib.h>

#include <string.h>

#define MAXENV 4096

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

PSTR szCmdLine, int iCmdShow)

{

static char szAppName[] = "Environ" ;

HWND hwnd ;

MSG msg ;

WNDCLASSEX wndclass ;

wndclass.cbSize = sizeof (wndclass) ;

wndclass.style = CS_HREDRAW | CS_VREDRAW ;

wndclass.lpfnWndProc = WndProc ;

wndclass.cbClsExtra = 0 ;

wndclass.cbWndExtra = 0 ;

wndclass.hInstance = hInstance ;

wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;

wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;

wndclass.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1) ;

wndclass.lpszMenuName = NULL ;

wndclass.lpszClassName = szAppName ;

wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION) ;

RegisterClassEx (&wndclass) ;

hwnd = CreateWindow (szAppName, "Environment List Box",

WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT, CW_USEDEFAULT,

CW_USEDEFAULT, CW_USEDEFAULT,

NULL, NULL, hInstance, NULL) ;

ShowWindow (hwnd, iCmdShow) ;

UpdateWindow (hwnd) ;

while (GetMessage (&msg, NULL, 0, 0))

{

TranslateMessage (&msg) ;

DispatchMessage (&msg) ;

}

return msg.wParam ;

}

LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)

{

static char szBuffer[MAXENV + 1] ;

static HWND hwndList, hwndText ;

HDC hdc ;

int i ;

TEXTMETRIC tm ;

switch (iMsg)

{

case WM_CREATE :

hdc = GetDC (hwnd) ;

GetTextMetrics (hdc, &tm) ;

ReleaseDC (hwnd, hdc) ;

hwndList = CreateWindow ("listbox", NULL,

WS_CHILD | WS_VISIBLE | LBS_STANDARD,

tm.tmAveCharWidth, tm.tmHeight * 3,

tm.tmAveCharWidth * 16 +

GetSystemMetrics (SM_CXVSCROLL),

tm.tmHeight * 5,

hwnd, (HMENU) 1,

(HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE),

NULL) ;

hwndText = CreateWindow ("static", NULL,

WS_CHILD | WS_VISIBLE | SS_LEFT,

tm.tmAveCharWidth, tm.tmHeight,

tm.tmAveCharWidth * MAXENV, tm.tmHeight,

hwnd, (HMENU) 2,

(HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE),

NULL) ;

for (i = 0 ; environ[i] ; i++)

{

if (strlen (environ [i]) > MAXENV)

continue ;

*strchr (strcpy (szBuffer, environ [i]), '=') = '\0' ;

SendMessage (hwndList, LB_ADDSTRING, 0, (LPARAM) szBuffer) ;

}

return 0 ;

case WM_SETFOCUS :

SetFocus (hwndList) ;

return 0 ;

case WM_COMMAND :

if (LOWORD (wParam) == 1 && HIWORD (wParam) == LBN_SELCHANGE)

{

i = SendMessage (hwndList, LB_GETCURSEL, 0, 0) ;

i = SendMessage (hwndList, LB_GETTEXT, i,

(LPARAM) szBuffer) ;

strcpy (szBuffer + i + 1, getenv (szBuffer)) ;

*(szBuffer + i) = '=' ;

SetWindowText (hwndText, szBuffer) ;

}

return 0 ;

case WM_DESTROY :

PostQuitMessage (0) ;

return 0 ;

}

return DefWindowProc (hwnd, iMsg, wParam, lParam) ;

}

Рис. 8.8. Программа ENVIRON

В программе ENVIRON создается два дочерних окна: окно списка стиля LBS_STANDART и статическое окно стиля SS_LEFT (текст с выравниванием по левому краю). В программе ENVIRON для получения списка строк окружения используется переменная environ (объявленная как внешняя в STDLIB.H). Программа использует сообщение LB_ADDSTRING для размещения каждой строки в окне списка.

Когда вы запускаете программу ENVIRON, то с помощью мыши или клавиатуры можете выбрать переменную окружения. Каждый раз, когда вы изменяете выбор, окно списка посылает своему родительскому окну сообщение WM_COMMAND, которое попадает в процедуру WndProc. Когда WndProc получает сообщение WM_COMMAND, она проверяет равно ли младшее слово параметра lParam (идентификатор дочернего окна) единице, и равно ли старшее слово параметра wParam (код уведомления) величине LBN_SELCHANGE. При наличии соответствующих значений она, с помощью сообщения LB_GETCURSEL, получает индекс выбранного элемента, а с помощью сообщения LB_GETTEXT — сам текст выбранного элемента, т. е. имя переменной окружения. Для получения строки, соответствующей этой переменной окружения, в программе ENVIRON используется функция языка С getenv, а функция SetWindowText используется для передачи этой строки статическому дочернему окну управления, в котором собственно и выводится на экран содержимое строки.

Обратите внимание, что в программе ENVIRON для индексирования переменной environ и получения строки нельзя использовать индекс, возвращаемый сообщением LB_GETCURSEL. Поскольку окно списка имеет стиль LBS_SORT (являющийся частью стиля LBS_STANDART), индексы не совпадают.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]