- •История 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
Еще раз подчеркнем важный момент. На базе этого класса легко и удобно создавать фреймы окон. Для того чтобы существенно расширить эти возможности, в библиотеке реализованы специальные классы, базирующиеся на понятии "представление".
Создание главного окна SDI-приложения
В рассмотренной ранее программе First мы образовали класс нашего окна из базового CWnd. Это допустимый, но очень неэффективный путь. Пришло время познакомить вас с одним из возможных подходов для создания главного окна SDI-приложения.1
Прежде всего обратим внимание на базовый класс нашего главного окна:
class CMainFrame : public CFrameWnd
Почему CFrameWnd? Дело в том, что этот класс спроектирован таким образом, чтобы предоставить максимум удобств для работы с перекрывающимися и всплывающими окнами. А, как вы помните, в качестве главного окна приложения наиболее приемлемым является именно перекрывающееся окно. Рассмотрим теперь подробно функцию CStylesApp::InitInsnance где, собственно, и начинается создание главного окна:
BOOL CStylesApp::Initlnstance() { CMainFrame *pMainWnd = new CMainFrame; m_pMainWnd = pMainWnd;
1 Второй, еще более эффективный, подход будет представлен при знакомстве с архитектурой документ/представление.
pMainWnd->LoadFrame (IDR_MAINFRAME) ;
int ex = : :GetSystemMetrics (SM_CXSCREEN) /8; int cy = : :GetSystemMetrics (SM_CYSCREEN) /4;
pMainWnd->SetWindowPos (NULL, ex, cy,
6*cx, 2*cy, SWP_NOZORDER | SWP_SHOWWINDOW) ;
return TRUE;
Процесс создания окна состоит из трех шагов. Прежде всего необходимо создать объект "главное окно":
CMainFrame *pMainWnd = new CMainFrame;
Следующий шаг состоит в вызове специальной функции, которая создает окно Windows и присоединяет его к нашему объекту:
pMainWnd->LoadFrame (IDR_MA IN FRAME) ;
И, наконец, следует отобразить окно на экране, чтобы пользователь мог с ним взаимодействовать:
pMainWnd->SetWindowPos (NULL, ex, су, 6*сх, 2*су, SWP_NOZORDER | SWP_SHOWWINDOW) ;
Рассмотрим сначала процесс создания окна Windows, или, используя терминологию MFC, фрейма окна.
Из двух функций, реализованных в классе CFrameWnd, мы остановили свой выбор на виртуальной функции CFrameWnd::LoadFrame, которая берет на себя задачу регистрации оконного класса, используя для этого предопределенный шаблон, и извлекает из файла ресурсов, задаваемого идентификатором, остальные необходимые для создания окна Windows параметры:
virtual BOOL CFrameWnd::LoadFrame( UINT nIDResource,
DWORD dwDefaultStyle = WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, CWnd *pParentWnd = NULL, CCreateContext *pContext = NULL)
Функция возвращает значение TRUE, если создание фрейма прошло успешно, и FALSE в противном случае. Она имеет следующие параметры: nIDResource — идентификатор разделяемых ресурсов, ассоциированных с фреймом, который определяет меню, таблицу акселераторов,
пиктограмму и строку, помещаемую в заголовок окна; pParentWnd — указатель на родительское окно данного фрейма (необязательный параметр); pContext — указатель на структуру CCreateContex, которая определяет объекты, связанные с
данным фреймом; dwDefaultStyle — стиль фрейма (необязательный параметр), дополнительно к стандартным могут быть использованы следующие стили:
FWS_ADDTOTITLE в конец заголовка окна будет добавлена дополнительная текстоваястрока
FWS_PREFIXTITLE перед заголовком окна будет помещено имя документа
FWS_SNAPTOBAR позволяет подогнать размеры окна под размеры панели элементов управления
Основное назначение этой функции — максимальное упрощение процесса создания фрейма окна.1 Используя идентификатор ресурсов, функция извлекает из них необходимые параметры и ... вызывает функцию CFrameWnd::Create, к рассмотрению которой мы и переходим:
BOOL CFrameWnd::Create( LPCTSTR IpszClassName, LPCTSTR IpszWindowName, DWORD dwStyle = WS_OVERLAPPEDWINDOW, const RECT &rect = rectDefault, CWnd *pParentWnd = NULL, LPCTSTR IpszMenuName = NULL, DWORD dwExStyle = 0, CCreateContext *pContext = NULL)
Функция возвращает значение TRUE, если создание прошло успешно, и FALSE в противном случае. Многие из параметров, передаваемых в функцию, вам уже должны быть хорошо знакомы, поэтому мы их только перечислим, рассматривая только те, которые не совпадают с уже описанными для функции CFrameWnd::LoadFrame: IpszClassName — адрес символьной строки, содержащей зарегистрированное имя класса, если этот параметр равен NULL, то в качестве шаблона используются атрибуты предопределенного класса "AfxFrameOrView"; IpszWindowName — адрес символьной строки, содержащей имя конкретного окна, этот же текст помещается в заголовок окна; dwStyle — стиль окна (необязательный параметр); reel — ссылка на структуру, содержащую размеры и координаты окна относительно его родителя (необязательный параметр); IpszMenuName — адрес символьной строки, содержащей имя ресурса меню, используемого в окне, если меню задано числовым идентификатором, то для получения строки следует использовать макрос Windows MAKEINTRESOURCE (необязательный параметр); dwExStyle — определяет атрибуты расширенного стиля (необязательный параметр).
Функция загружает ресурс меню и вызывает функцию CWnd::CreateEx, которая регистрирует имя оконного класса, заполняя структуру WNDCLASS,1 (При использовании функции
CFrameWndr.LoadFrame единственным обязательным ресурсом является меню. Если его не определить, то программа будет выдавать сообщение об ошибке.)
и вызывает виртуальную функцию PreCreateWindow. В процессе выполнения функции Windows посылает в окно следующие сообщения: WM_GETMINMAXINFO, WM_NCCREATE, WM_NCCALKSIZE и WM_CREATE. Если при создании окна был определен стиль WSJVISIBLE, то в окно дополнительно посылаются все сообщения, необходимые для активизации и отображения окна на экране. Таким образом, переопределяя функцию PreCreateWindow и обработчик любого из представленных сообщений Windows, можно изменять параметры оконного класса и собственно окна, как до, так и после создания окна Windows.
Рассмотрим, как этот механизм реализован в нашей программе. Начнем с функции
CMainFrame::PreCreate Window.
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { cs.lpszName = "Главное окно приложения \"Стили\""; return CFrameWnd::PreCreateWindow(cs);
Единственный параметр, передаваемый в эту функцию, — ссылка на структуру CREATESTRUCT, которая определяет параметры инициализации, посылаемые в оконную процедуру, и содержит следующие поля:
typedef struct tagCREATESTRUCT{ LPVOID IpCreateParams; HANDLE hlnctance;
KMENU hMenu; HWND hwndParent; int cy;
int ex; int y; int x;
LONG style; LPCSTR IpszName; LPCSTR IpszClass;
DWORD dwExStyle; ) CREATESTRUCT;
Назначение полей этой структуры: IpCreateParams — указатель на данные, используемые при создании окна; hlnstance — дескриптор модуля, который владеет окном; hMenu — идентификатор меню, используемого окном; hwndParent — дескриптор окна-родителя, если этот параметр равен NULL, то новое окно является окном верхнего уровня; су, сх, у, х — целые числа, задающие соответственно ширину и высоту окна, а также его положение относительно своего владельца; IpszName — символьная строка, задающая имя окна; IpszClass — символьная строка, содержащая имя класса, которому принадлежит окно; dwExStyle — определяет атрибуты расширенного стиля окна.
Мы использовали эту функцию, чтобы не заниматься процедурой регистрации класса окна, возложив ее выполнение на библиотеку, поскольку принятые по умолчанию установки нас вполне устраивают. Единственное, что нас не устраивает, это заголовок окна, который мы и переопределили:
cs.lpszName = "Главное окно приложения \"Стили\"";
Это один из возможных способов присвоения имени окну.1
После того как окно Windows создано и присоединено к объекту фрейма окна, в ответ на сообщение WM_CREATE вызывается обработчик сообщения OnCreate (механизм вызова был нами подробно описан при обсуждении механизма работы с сообщениями в библиотеке MFC):
int CMainFrame: : OnCreate (LPCREATESTRUCT IpCreateStruct) { if (CFrameWnd: : OnCreate (IpCreateStruct) == -1) return -1; return 0;
Эта функция — одно из возможных мест, где создаются и присоединяются к окну произвольные элементы пользовательского интерфейса. Для правильного завершения процесса создания окна не забывайте вызывать перед какими-либо своими действиями обработчик базового класса С Frame Wnd:: On Create.
После того как фрейм создан, его необходимо вывести на экран. Библиотека предоставляет несколько функций для реализации этого процесса. Для отображения нашего главного окна мы остановились на одной из них — функции
CWnd::SetWindowPos:
BOOL CWnd::SetWindowPos( const CWnd *pWndlnsertAfter, int x, inty, int ex, int cy, UINT nFlags)
Вызов этой функции позволяет изменить как размеры, так и расположение дочерних и всплывающих окон относительно экрана и других окон. Она имеет следующие параметры: pWndlnsertAfter — указывает на объект CWnd, после которого будет расположено окно, вместо этого указателя можно использовать одно из следующих предопределенных значений, задающих расположение окна относительно других окон:1 (
Не забывайте вызывать функцию базового класса CFrame Wnd::PreCreate Window для проведения правильных
инициализирующих |
действий.) |
wndBott om
wndNoTopMost
wndTop
wndTop
Most
разместить WS_EX_TOPMOST |
|
||
окно |
подразместить |
окно над |
другими окнами (на |
другими |
(внизувершине стека Z-порядка) |
||
окнами |
|||
стека |
Z-разместить окно над всеми другими окнами, |
||
порядка); еслиимеющими статус wndTopMost; эта позиция |
|||
окно |
имелосохраняется |
(флаг |
расширенного стиля |
статус |
WS_EX_TOPMOST |
остается |
|
wndTopMost, установленным) даже когда окно находится
то |
этотв неактивном состоянии |
||
статус |
|
|
|
теряется —перемещает окно выше всех окон, имеющих |
|||
удаляется |
статус wndTop, но ниже окон, имеющих |
||
статус wndTopMost |
|||
флаг |
|
||
расширенного
стиля
х, у, сх, су — задают новые значения, соответственно, горизонтального и вертикального расположения окна, его ширины и высоты;
nFlags — определяет параметры размера и позиции окна и может принимать одно из следующих значений:
SWP_DRAWFR AME SWP_HIDEWIN DOW SWP_NOACTIV ATE SWP_NOMOVE
SWP_NOREDR
AW
SWP_NOSIZE
SWP_NOZORD
ER
SWP_SHOWWI NDOW
отображает окно
задает рамку вокруг окна, определенную в классе окна делает окно невидимым блокирует активизацию окна
предписывает окну сохранение текущей позиции; параметры х и у игнорируются
предписывает не перерисовывать окно; после перемещения приложение должно перерисовать окно самостоятельно
задает сохранение текущих размеров; параметры сх и су игнорируются
задает сохранение текущего расположения окна относительно других окон, при этом параметр pWndlnsertAfter игнорируется
