- •Содержание
- •Управление памятью: хорошо, плохо и ужасно
- •Сегментированная память
- •Промежуточные решения
- •И, наконец, 32 бита
- •Выделение памяти
- •Библиотечные функции C
- •Фундаментальное выделение памяти в Windows 95
- •Перемещаемая память
- •Удаляемая память
- •Другие функции и флаги
- •Хорошо ли это?
- •Функции работы с "кучей"
- •Файловый ввод/вывод
- •Старый путь
- •Отличия Windows 95
- •Ввод/вывод с использованием файлов, проецируемых в память
- •Режимы многозадачности
- •Многозадачность в DOS
- •Невытесняющая многозадачность
- •Решения, использующие многопоточность
- •Многопоточная архитектура
- •Коллизии, возникающие при использовании потоков
- •Преимущества Windows
- •Новая программа! Усовершенствованная программа! Многопоточная!
- •Многопоточность в Windows 95
- •И снова случайные прямоугольники
- •Задание на конкурсе программистов
- •Решение с использованием многопоточности
- •О пользе использования функции Sleep
- •Синхронизация потоков
- •Критический раздел
- •Объект Mutex
- •Программа BIGJOB1
- •Объект Event
- •Локальная память потока
- •Печать, буферизация и функции печати
- •Контекст принтера
- •Формирование параметров для функции CreateDC
- •Измененная программа DEVCAPS
- •Вызов функции PrinterProperties
- •Проверка возможности работы с битовыми блоками (BitBlt)
- •Программа FORMFEED
- •Печать графики и текста
- •Каркас программы печати
- •Прерывание печати с помощью процедуры Abort
- •Реализация процедуры прерывания
- •Добавление диалогового окна печати
- •Добавление печати к программе POPPAD
- •Обработка кодов ошибок
- •Техника разбиения на полосы
- •Разбиение на полосы
- •Реализация разбиения страницы на полосы
- •Принтер и шрифты
- •Глава 16 Буфер обмена
- •Простое использование буфера обмена
- •Стандартные форматы данных буфера обмена
- •Передача текста в буфер обмена
- •Получение текста из буфера обмена
- •Открытие и закрытие буфера обмена
- •Использование буфера обмена с битовыми образами
- •Метафайл и картина метафайла
- •Более сложное использование буфера обмена
- •Использование нескольких элементов данных
- •Отложенное исполнение
- •Нестандартные форматы данных
- •Соответствующая программа просмотра буфера обмена
- •Цепочка программ просмотра буфера обмена
- •Функции и сообщения программы просмотра буфера обмена
- •Простая программа просмотра буфера обмена
- •Основные концепции
- •Приложение, раздел и элемент
- •Типы диалогов
- •Символьные строки и атомы
- •Программа сервер DDE
- •Программа DDEPOP1
- •Сообщение WM_DDE_INITIATE
- •Оконная процедура ServerProc
- •Функция PostDataMessage программы DDEPOP1
- •Сообщение WM_DDE_ADVISE
- •Обновление элементов данных
- •Сообщение WM_DDE_UNADVISE
- •Сообщение WM_DDE_TERMINATE
- •Программа-клиент DDE
- •Инициирование диалога DDE
- •Сообщение WM_DDE_DATA
- •Сообщение WM_DDE_TERMINATE
- •Управляющая библиотека DDE
- •Концептуальные различия
- •Реализация DDE с помощью DDEML
- •Элементы MDI
- •Windows 95 и MDI
- •Пример программы
- •Три меню
- •Инициализация программы
- •Создание дочерних окон
- •Дополнительная информация об обработке сообщений в главном окне
- •Дочерние окна документов
- •Освобождение захваченных ресурсов
- •Сила оконной процедуры
- •Основы библиотек
- •Библиотека: одно слово, множество значений
- •Пример простой DLL
- •Разделяемая память в DLL
- •Библиотека STRLIB
- •Точка входа/выхода библиотеки
- •Программа STRPROG
- •Работа программы STRPROG
- •Разделение данных между экземплярами программы STRPROG
- •Некоторые ограничения библиотек
- •Динамическое связывание без импорта
- •Библиотеки, содержащие только ресурсы
- •Глава 20 Что такое OLE?
- •Основы OLE
- •Связь с библиотеками OLE
- •Расшифровка кода результата
- •Интерфейсы модели составного объекта (COM-интерфейсы)
- •Услуги интерфейса IUnknown
- •Является ли OLE спецификацией клиент/сервер?
- •Сервер закрытого компонента
- •IMALLOC.DLL
- •Теперь о макросах
- •Услуги, предоставляемые интерфейсом IUnknown
- •Клиент закрытого компонента
- •Сервер открытого компонента
- •Назначение реестра
- •Способы генерации и использования идентификаторов CLSID
- •Компонент фабрика классов
- •Управление временем жизни сервера
- •Клиент открытого компонента
- •Заключение
169
Три меню
Начнем анализ программы с файла описания ресурсов MDIDEMO.RC. В нем определяются три шаблона меню, используемые в программе.
Программа выводит на экран меню MdiMenuInit при отсутствии окон документов. Это меню просто позволяет создать новый документ или завершить программу.
Меню MdiMenuHello связано с окном документа, в котором выводится фраза "Hello, World!". Подменю File позволяет открыть новый документ любого типа, закрыть активный документ и завершить программу. Подменю Color позволяет задать цвет символов. В подменю Window имеются опции для упорядочивания окон документов в каскадном или мозаичном виде, упорядочивания значков документов и закрытия всех окон. В этом подменю также имеется список всех открытых окон документов.
Меню MdiMenuRect связано с документом со случайными прямоугольниками. Оно аналогично меню MdiMenuHello, за исключением того, что в нем нет подменю Color.
В заголовочном файле MDIDEMO.Н все идентификаторы меню определяются как три константы:
#define INIT_MENU_POS |
0 |
#define HELLO_MENU_POS |
2 |
#define RECT_MENU_POS |
1 |
Эти идентификаторы задают положение подменю Window в каждом из трех шаблонов меню. Эта информация необходима программе, чтобы информировать окно-администратор о том, когда должен появиться список документов. Конечно, в меню MdiMenuInit нет подменю Window, поэтому в файле обозначено, что список должен быть присоединен к первому подменю (положение 0). Однако, фактически здесь список никогда не появится. (Зачем он нужен станет ясно при дальнейшем анализе программы.)
Идентификатор IDM_FIRSTCHILD не соответствует ни одному пункту меню. Этот идентификатор будет связан с первым окном документа в списке, который появляется в подменю Window. Значение этого идентификатора должно быть больше, чем значение всех остальных идентификаторов меню.
Инициализация программы
В файле MDIDEMO.С WinMain начинается с регистрации классов окна для главного окна и двух дочерних окон. Их оконные процедуры называются FrameWndProc, HelloWndProc и RectWndProc. Как правило, с каждым из этих трех классов связан свой значок. Для простоты в программе и для главного и для дочерних окон использован стандартный значок IDI_APPLICATION.
Обратите внимание, что в поле hbrBackground структуры WNDCLASSEX для класса главного окна задан системный цвет COLOR_APPWORKSPACE. Это необязательно, поскольку рабочая область главного окна полностью занята окном-администратором, а окно-администратор имеет тот же самый цвет. Однако, когда главное окно появляется на экране первым, одинаковый цвет смотрится несколько лучше.
В поле lpszMenuName заносится значение NULL для каждого из трех классов окна. Для классов окна дочерних окон Hello и Rect это нормально. Для главного окна это сделано для того чтобы указать описатель меню при создании главного окна в функции CreateWindow.
Классы окна дочерних окон Hello и Rect для каждого окна резервируют дополнительную область памяти путем указания ненулевого значения в поле cbWndExtra структуры WNDCLASSEX. Эта область будет использоваться для хранения указателя на блок памяти (размером со структуру HELLODATA или RECTDATA, которые определены в начале файла MDIDEMO.С), необходимый для хранения информации, уникальной для каждого окна документа.
Далее WinMain использует функцию LoadMenu для загрузки трех меню и сохраняет их описатели в глобальных переменных. Три вызова функции GetSubMenu позволяют получить описатели подменю Window, в которому будет добавлен список окон документов. Они также запоминаются в глобальных переменных. Функция LoadAccelerators загружает таблицу быстрых клавиш.
Вызов функции CreateWindow в WinMain создает главное окно. При обработке в FrameWndProc сообщения WM_CREATE главное окно создает окно-администратор. При этом еще раз вызывается функция CreateWindow. Класс окна задается как MDICLIENT, который представляет собой уже зарегистрированный в системе класс для окна-администратора MDI. Последний параметр функции CreateWindow должен быть указателем на структуру типа CLIENTCREATESTRUCT. В этой структуре имеется два поля:
•hWindowMenu является описателем подменю, в котором появится список документов. В программе MDIDEMO это описатель hMenuInitWindow, полученный в WinMain. Позже мы узнаем, как изменить меню.