- •История Windows
- •Windows 1.0
- •Windows 1.3
- •Windows 2.0
- •Windows 3.0
- •Windows 3.1
- •Windows for Workgroups версии 3.11
- •Windows NT
- •Windows 95
- •Windows NT Workstation 4.0 и Windows NT Server 4.0
- •Windows NT 4.0 Server Enterprise Edition
- •Windows 98
- •Windows 98 Second Edition (SE)
- •Windows 2000
- •Windows 98 Millenium Edition (ME)
- •Windows XP
- •Общая архитектура WINDOWS приложения.
- •Каркас приложения
- •Регистрация класса окна
- •Создание окна.
- •Отображение окна.
- •Цикл обработки очереди сообщений.
- •WndProc
- •Обработка сообщений типового приложения.
- •Контрольные вопросы
- •Сообщения
- •Типы сообщений
- •Обработка клавиатурных сообщений
- •Обработка сообщений от мыши
- •Сообщения таймера
- •Контрольные вопросы
- •Организация ввода
- •Разупорядоченный ввод
- •Разделение потоками виртуальных очередей ввода
- •Локальное состояние ввода
- •Ввод с клавиатуры и фокус
- •Управление курсором мыши
- •Контрольные вопросы
- •Окна
- •Окна Windows
- •Иерархия окон
- •Оконная процедура, стандартные оконные процедуры
- •Стиль класса окна
- •Стили окон, окна основных стилей
- •Перекрывающиеся окна
- •Временные окна
- •Дочерние окна
- •Сообщения управления окнами
- •Окна с полосами прокрутки
- •Системные метрики
- •Определение размера окна
- •Определение расположения окна
- •Контрольные вопросы
- •Графический интерфейс устройств(GDI).
- •Создание (получение) контекста устройств.
- •Сохранение контекста устройства.
- •Прямые (отрезки) и кривые
- •Закрашенные области
- •Битовые шаблоны (растровые шаблоны, растровые образы)
- •Текст и шрифты
- •Режимы масштабирования и преобразования
- •Метафайл
- •Регионы
- •Путь
- •Палитры
- •Контрольные вопросы
- •Объекты ядра
- •Что такое объект ядра
- •Учет пользователей объектов ядра
- •Защита
- •Таблица описателей объектов ядра
- •Создание объекта ядра
- •Закрытие объекта ядра
- •Синхронизация объектов
- •Именованные объекты
- •Дублирование описателей объектов
- •Изменение флагов описателя
- •Синхронизация потоков
- •Критическая секция
- •Мьютексы
- •Семафоры
- •События
- •Ожидаемые таймеры
- •Контрольные вопросы
- •Ресурсы Windows приложения
- •Файлы ресурсов приложения
- •Значки (пиктограммы)
- •Курсоры
- •Битовые образы
- •Символьные строки
- •Ресурсы, определяемые пользователем
- •Таблица акселераторов
- •Меню
- •Диалоговые окна
- •Контрольные вопросы
- •Элементы управления
- •Дочерние окна управления
- •Создание дочерних окон
- •Сообщения дочерних окон родительскому окну
- •Сообщения родительского окна дочерним окнам
- •Дочерние окна и фокус ввода
- •Дочерние окна управления и цвет
- •Кнопки различных стилей (класс BUTTON)
- •Нажимаемые кнопки
- •Флажки-переключатели
- •Переключатели
- •Окна групп
- •Кнопки, определяемые пользователем
- •Статические поля (класс static)
- •Текстовые редакторы (класс edit)
- •Списки разных стилей (класс listbox)
- •Комбинированные списки (класс combobox)
- •Полосы прокрутки (класс scrollbar)
- •Контрольные вопросы
- •Расширенные элементы управления
- •Основы общих элементов управления
- •Инициализация библиотеки элементов общего пользования
- •Создание элементов управления общего пользования
- •Посылка сообщений общим элементам управления
- •Уведомляющие сообщения от общих элементов управления
- •Контрольные вопросы
- •Стандартные диалоговые окна.
- •Окна сообщений
- •Диалоговые окна общего пользования
- •Контрольные вопросы
- •Динамически подключаемые библиотеки
- •Создание DLL
- •Проецирование DLL на адресное пространство процесса
- •Функция входа/выхода
- •Функция DllMain и стандартная библиотека С
- •Функция LibEntry
- •Функция LibMain
- •Функция WEP
- •Экспорт функций и переменных из DLL
- •Импорт функций и переменных из DLL
- •Заголовочный файл DLL
- •Разделы в ЕХЕ- и DLL-файлах
- •Контрольные вопросы
- •Файлы, проецируемые в память
- •Контрольные вопросы
- •Классы, определяющие архитектуру приложения
- •Классы приложения и поддержки потоков
- •Классы приложения и потоков
- •Классы фреймов окон
- •Получение информации о приложении
- •Соглашения об именах MFC
- •Включаемые файлы
- •Функция WinMain
- •Класс CWinApp
- •Класс CWnd
- •Класс CFrameWnd
- •Создание главного окна SDI-приложения
- •Примечание
- •Создание главного окна SDI-приложения
- •Создание дочерних окон
- •Ограничение размеров окна
- •Ограничение доступа к окну
- •Создание многодокументных приложений
- •Класс CMDIChildWnd
- •MDI — пример приложения
- •Категории сообщений
- •Карта сообщений
- •Компоненты карты сообщений
- •Класс CCmdTarget
- •Стандартный маршрут команды
- •Команды обновления и класс CCmdlll
- •Функции для работы с сообщениями
- •Основные положения
- •Класс CDocTemplate
- •Класс CSingleDocTemplate
- •Роль фреймов в архитектуре "документ/представление"
- •Документ и его представления
- •Документы
- •Класс CDocument
- •Класс CArchive
- •Представления
- •Класс CView
- •Панели элементов управления
- •Класс CStatusBar
- •Класс CStatusBarCtrl
- •Класс CDialogBar
- •ControlBars — пример приложения
- •НЕКОТОРЫЕ КЛАССЫ MFC
- •Класс CObject - основной класс MFC
- •Конструкторы класса
- •Оператор присваивания
- •Диагностика
- •Проверка целостности объектов класса
- •Получение дампа объекта класса
- •Сохранение и восстановление состояния объекта
- •Метод IsSerializable
- •Виртуальный метод Serialize
- •Информация о классе
- •Виртуальный метод GetRuntimeClass
- •Метод IsKindOf
- •Класс CPoint - точка на плоскости
- •Класс CSize - относительные координаты
- •Класс CString - текстовые строки
- •Конструктор класса
- •Коллекции
- •Массивы - шаблон CArray
- •Списки - шаблон CList
- •Словари - шаблон CMap
- •Класс CTime - дата и время
- •Файловая система - класс CFile
- •Открытие и создание файлов
- •Идентификатор открытого файла
- •Закрытие файлов
- •Чтение и запись файлов
- •Метод Flush
- •Операции с файлами
- •Блокировка
- •Позиционирование
- •Характеристики открытого файла
- •Файловая система - классы CMemFile и CStdioFile
- •Модификация класса CMemFile
- •Файловая система - класс CStdioFile
- •Запись и восстановление объектов
- •Запись в архивный файл
- •Чтение из архивного файла
- •Исключения - класс CException
- •Класс CException
- •Класс CMemoryException
- •Класс CFileException
- •Приложение Except
- •Класс CArchiveException
- •Класс CNotSupportedException
- •Класс CResourceException
- •Класс CUserException
BOOL CWnd:.EnableWindow(BOOL bEnable = TRUE)
которая разрешает (bEnable = TRUE) или запрещает (bEnable = FALSE) доступ к окну для мыши и клавиатуры. Если при вызове этой функции изменилось состояние окна, то до возврата из нее Windows посылает окну сообщение WM_ENABLE.
Для того чтобы узнать текущее состояние окна в смысле его доступности, можно использовать функцию
BOOL CWnd::lsWindowEnable()
которая возвращает значение TRUE, если окно доступно, и FALSE в противном случае.
Создание многодокументных приложений
Мы надеемся, что нет необходимости подробно представлять многодокументный интерфейс (MDI, Multiple Document Interface), который позволяет в одном приложении работать с несколькими документами или с разными представлениями одного и того же документа. Этот интерфейс описан в руководстве по разработке интерфейса пользователя System Application Architecture Common User Access Advanced Interface Design Guide (SAA/CUA), созданном фирмой IBM. В Windows интерфейс MDI
используется, начиная с версии 3.0, типичным примером приложения на базе MDI является хорошо всем знакомый текстовый процессор Microsoft Word для Windows.
Как и все приложения Windows, MDI-приложение имеет одно главное окно, которое управляет своими окнами "MDI child".1 Поведение окон "MDI child" напоминает поведение как дочерних, так и перекрывающихся окон. Так же, как и первые, их невозможно переместить за пределы главного окна приложения. И в то же время окна "MDI child" можно сделать активными, при этом их заголовок выделяется цветом. Кроме того, каждое окно "MDI child" имеет, как правило, системное меню и кнопки изменения размера. Если свернуть такое окно, то его пиктограмма расположится в нижней части главного окна приложения. При увеличении размеров окна до максимальных, пиктограмма системного меню окна "MDI child" помещается в левую часть основного меню, а в правой части расположатся кнопки изменения размера и закрытия окна.
Одним словом, можно, конечно, создать аналогичное приложение с использованием обычных окон, но для этого придется затратить немало усилий. Более того, достаточно серьезную работу надо проделать, чтобы создать полноценное MDI-приложение, используя функции библиотеки SDK (Software Development Kit). Для того чтобы в этом убедиться, достаточнорассмотреть исходные тексты приложения MULTIPAD, поставляемые в составе примеров приложений с системой разработки Microsoft Developer Studio Visual C++. Совсем другая картина предстанет перед вами, когда вы возьмете исходные тексты такого же приложения, но созданного с использованием библиотеки MFC. Мы попытаемся обойти эти две крайние позиции и рассмотреть интерфейс MDI одновременно с деталями его внутренних механизмов, знание которых позволит вам создавать приложения любой сложности наиболее эффективно и с наименьшими затратами на поиск ошибок, которые зачастую возникают изза непонимания происходящего.
Начнем с рассмотрения двух основных классов библиотеки MFC, разработанных специально для создания многодокументных приложений, — CMDIFrameWnd м CMDIChildWnd
CMDIFrameWnd — базовый класс для главного окна любого многодокументного приложения. Если быть более точными, то в данном случае следует говорить не об окне, а о фрейме, поскольку помимо него создается специальное окно, называемое окном MDICLIENT, которое управляет рабочей областью фрейма и является, собственно, родительским для окон "MDI child".
Уточним некоторые моменты, которые связаны с процессом создания MDI-окна. Как обычно, сначала создается объект нашего оконного класса. Далее, если вы сравните тексты функции Initlnstance для создания главных окон SDI- и MDT-приложений, то не увидите никакой разницы. И в том и в другом случае вызываются одни и те же функции. Однако, если при создании SDI-окна вызывается функция CFrameWnd::OnCreateClient, то при создании MDI-окна вызывается функция CMDIFrameWnd::OnCreateClient. Первая отвечает за создание (если необходимо) присоединяемого к окну представления, а вторая — за создание специального окна MDICLIENT, которое, как мы уже говорили, полностью управляет рабочей областью главного окна MDI-прило-жения и отвечает за работу с окнами "MDI child". На рис. 23 показаны все перечисленные окна MDI-прило-жения.
Нам осталось рассмотреть функциональные возможности, которые класс CMDI-
void CMDIFrameWnd::MDIActivate(CWnd *pWndActivate),
где pWndActivate — указатель на окно "MDI child", которое должно быть активизировано.
Эта функция посылает сообщение WM_MDIACTIVATE в два окна: сначала в то, которое активизируется, затем в то, которое теряет активность. То же самое сообщение посылается, если пользователь изменил фокус дочернего окна при помощи мыши или клавиатуры. Окна "MDI child" активизируются независимо от основного MDI-окна. Когда активизируется основное окно, то дочернее, которое было активно последним, посылает сообщение WM_NCACTIVATE, чтобы нарисовать его рамку и заголовок, но при этом не получает сообщения WM MDIACTIVATE.
CMDIChildWnd*CMDIFrameWnd::MDIGetActive( BOOL *pbMaximized = NULL) -
возвращает указатель на текущее активное окно "MDI child". Дополнительно, в параметре pbMaximized, возвращается информация о том, развернуто это окно илинет.
void CMDIFrameWnd::MDIIconArrange() —
упорядочивает все свернутые окна "MDi child", не затрагивая те, которые не свернуты.
void CMDIFrameWnd::MDIMaximize(CWnd *pWnd) -
разворачивает окно "MDI child". При этом Windows изменяет его размеры таким образом, чтобы оно заполнило всю рабочую область окна фрейма. Windows размещаетсистемноеменюдочернегоокнавполосе основногоменю, аегозаголовокдобавляетсякзаголовкуокнафрейма.1
void CMDIFrameWnd::MDINext() — активизирует следующее окно "MDI child".
void CMDIFrameWnd::MDIRestore(CWnd *pWnd) -
восстанавливает исходные размеры окна "MDI child", заданного параметром pWnd, если оно было развернуто или свернуто.
CMenu* CMDIFrameWnd::MDISetMenu( CMenu *pFrameMenu,
CMenu *pWindowMenu),
если pFrameMenu и/или pWindowMenu не равны NULL, то заменяет соответствующие текущие меню на переданныевкачествепараметров. Возвращаетвременныйуказательназамененноеменю.
После вызова этой функции следует вызвать функцию CWnd:: Draw Menu Bar для обновления полосы меню. Если функция изменяет раскрывающееся меню, то элементы меню окна "MDI child" удаляются из предыдущего меню окна и добавляются в раскрывающееся меню. Если вы используете фрейм для управления окнами "MDI child", то не следует вызывать эту функцию.
void CMDIFrameWnd::MDITile()
и
void CMDIFrameWnd::MDITile(int nType) -
располагают все окна "MDI child" без перекрытия. Первая версия функции располагает окна по вертикали, а вторая в качестве параметра пТуреможетприниматьодноизследующихзначений:
MDITILE_HORIZONTAL |
расположить окна по горизонтали |
MDITILE_VERTICAL |
расположить окна по вертикали |
MDITILE_SKIPDISABLED |
предотвращает отображение блокированных |
окон "MDI child" |
|
void CMDIFrameWnd::MDICascade()
и
void CMDIFrameWnd::MDICascade(int nType) -
располагают все окна "MDI child" каскадом. Первая версия функции отображает и блокированные окна, а вторая, которая может быть вызвана только с параметром MDITILE_SKIPDISABLED, — все, кроме блокированных.
virtual BOOL CMDIFrameWnd::CreateClient( LPCREATESTRUCT IpCreateStruct, Cmenu *pWindowMenu) —
создает для текущего объекта CMDIFrameWnd окно Windows MDICLIENT, которое управляет объектами CMDIChildWnd. Эта функция должна быть вызвана, если вы переопределили функцию CWnd::OnCreate.1
virtual HMENU CMD!FrameWnd::GetWindowMenuPopup( HMENU hMenuBar)
позволяет получить дескриптор раскрывающегося меню для элемента меню Window (Окно) основного меню, заданного параметром hMenuBar. Реализация заданная по умолчанию, ищет раскрывающееся меню, которое содержит стандартные команды элемента меню Window (Окно) основного меню типа ID_WINDOW_NEW и ID_WINDOW_TILE_HORZ. Если это раскрывающееся меню не содержит идентификаторов стандартных команд, то этуфункцию следует переопределить.
Как видите, всю основную работу по поддержанию работы MDI-прило-жений выполняет Windows