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

Создание элементов управления на панели инструментов

Существует несколько правил, используемых при создании дочерних окон на панели инструментов. Прежде всего, убедитесь, не забыли ли вы включить флаги стиля окна WS_VISIBLE и WS_CHILD. Без флага WS_VISIBLE вызов функции может оказаться успешным, однако окно на экране не появится. Флаг WS_CHILD используется для создания дочернего окна, которое должно иметь родителя, на поверхности которого будет расположено дочернее окно. Это вызывает появление проблемы, какое окно должно быть родительским для дочернего.

Очевидным выбором родительского окна для окон на панели инструментов является само окно панели инструментов, но это может привести к странным проявлениям. В частности, предопределенные элементы управления посылают уведомляющие сообщения (в виде сообщений WM_COMMAND) своему родителю, что может иметь неожиданный результат. Например, программа GADGETS постоянно сбивается в Windows 95, когда ее окно комбинированного списка панели инструментов создается с окном панели инструментов в роли родительского окна, а идентификатор окна комбинированного списка равен 101. (Заметим, что эта комбинация не вызывает никаких проблем в Windows NT 3.51. Это связано с отличающимися в этих операционных системах версиями библиотеки COMCTL32.DLL.) Изменение управляющего идентификатора — кажущееся решение этой проблемы, поскольку такой путь оставляет шанс (хоть и незначительный) на то, что в будущих версиях библиотеки элементов управления общего пользования будет использоваться идентификатор, который используем мы, и тогда указанная проблема возникнет вновь. И все же, панель инструментов должна быть родительским окном для того окна, которое хочет располагаться на ее поверхности.

Решение этого противоречия состоит в задании другого окна в качестве родительского в вызове функции CreateWindow — предпочтительнее одного из тех, которые имеют вашу собственную оконную процедуру. После того, как дочернее окно будет создано, оно помещается на панель инструментов путем вызова функции SetParent. Элементы управления диалогового окна лояльны к этому и посылают свои уведомляющие сообщения WM_COMMAND их первоначальному родительскому окну, что позволяет вам обрабатывать уведомляющие сообщения по своему усмотрению. Таким образом, уведомляющие сообщения посылаются одному окну, а дочернее окно физически располагается на другом окне — панели инструментов. Программа GADGETS делает эти два шага следующим образом:

hwndCombo = CreateWindow ("combobox",

NULL,

WS_CHILD | WS_VISIBLE |

CBS_DROPDOWN,

x, y, cx, cy,

hwndParent,

HMENU) 100,

hInst,

;

// Установление панели инструментов как родительского окна для комбинированного списка //

SetParent ( hwndCombo, hwndTB ) ;

Изменение размеров панели инструментов с дочерними окнами

Другая сложность, возникающая при использовании дочерних окон на панели инструментов состоит в том, что необходимо быть уверенным, что размеры самой панели инструментов достаточны для размещения дочерних окон. Между прочим, эта проблема актуальна для оболочек типа старой Windows, такой как Windows NT 3.51, а не для новейшей оболочки Windows 95. Но поскольку некоторые из пользователей вашей программы могут работать на указанной версии Windows NT, следует тестировать вашу программу в обеих средах.

Простейшее решение, для всех элементов управления кроме комбинированных списков, состоит в изменении размеров окна самим окном. Работа с комбинированным списком более трудоемка, поскольку он изменяет свои размеры в зависимости от текущего шрифта. Поэтому, вы можете косвенно воздействовать на размеры комбинированного списка, устанавливая его шрифт. Это делается путем создания шрифта необходимого размера и передачи его в комбинированный список путем посылки сообщения WM_SETFONT. Пока элемент управления короче, чем кнопки панели инструментов, обработка сообщения TB_AUTOSIZE будет выполнять всю хлопотливую работу по приведению размеров панели инструментов в соответствие с изменяющимися размерами ее родительского окна. (См. предшествующее обсуждение размещения и изменения размеров панели инструментов.)

Если вы не можете заставить дочернее окно быть меньше, необходимо сделать панель инструментов больше. Программа GADGETS демонстрирует этот подход и является основой для дальнейшего обсуждения.

Для получения полного контроля над размерами и местоположением панели инструментов создавайте панель инструментов с использованием флага стиля CCS_NORESIZE. Вопреки тому, что можно было бы подумать на основе имени, этот флаг не дает панели инструментов возможности самостоятельно изменять свои размеры и расположение. Если установлен этот флаг, то сообщение TB_AUTOSIZE не приводит ни к каким действиям. Поэтому, перемещение и установка местоположения панели инструментов целиком в вашей власти. Когда родительское окно получает сообщение WM_SIZE, вам следует рассчитать необходимые координаты местоположения (x, y) и размеры окна, а затем произвести необходимые изменения путем вызова функции типа MoveWindow.

Для приложений с простой панелью инструментов в верхней части родительского окна местоположение определяется просто — (0, 0 ). Ширина также определяется просто, поскольку сообщение WM_SIZE родительскому окну содержит в младшем слове параметра lParam ширину окна. Для изменения размеров панели инструментов в ответ на сообщение WM_SIZE необходим примерно такой код:

case WM_SIZE:

{

int cx = LOWORD (lParam) ;

MoveWindow (hwndToolBar, 0, 0, cx, cyToolBar, TRUE) ;

[другие строки программы]

return 0 ;

}

Остается пока непонятным, как определить высоту панели инструментов (cyToolBar). В программе GADGETS проблема решается в два этапа: сначала делается запрос определения размера комбинированного списка, затем запрос определения размера элемента панели инструментов, к которому добавляется дополнительная величина, равная 5 (величина поля, строго определенная в панели инструментов). Высота панели инструментов и есть максимум из этих двух значений:

// вычислить высоту панели инструментов

GetWindowRect (hwndCombo, &r) ;

cyToolBar = r.bottom — r.top + 1 ;

cyToolBar += y ;

cyToolBar += (2 * GetSystemMetrics (SM_CYBORDER)) ;

ToolBar_GetItemRect (hwndTB, 0, &r) ;

cyToolBar = max (cyToolBar, r.bottom + 5) ;

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