- •История 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
7.Какие диалоговые окна предоставляют собой интерфейс, посредством которого пользователь может ввести текстовую строку для поиска и, если необходимо, строку для замены?
8.Какие стандартные диалоги являются модальными, а какие нет? К чему приводит это различие?
Динамически подключаемые библиотеки
Динамически подключаемые библиотеки (dynamic-link libraries, DLLs) — краеугольный камень операционной системы Windows, начиная с самой первой ее версии. В DLL содержатся все функции интерфейса Win32 API. Три самых важных DLL-библиотеки: KERNEL32.DLL (управление памятью, процессами и потоками), USER32.DLL (поддержка пользовательского интерфейса, в том числе функции, связанные с созданием окон и передачей сообщений) и GDI32.DLL (графика и вывод текста).
•В Windows есть и другие DLL, функции которых предназначены для более специализированных задач. Например, в ADVAPI32.DLL содержатся функции для
защиты объектов, работы с реестром и регистрации событий, в COMDLG32.DLL
— стандартные диалоговые окна, a LZ32.DLL поддерживает декомпрессию файлов.
Создание DLL
DLL является набором автономных функций, пригодных для использования любой программой, причем в DLL обычно отсутствует код, предназначенный для обработки циклов выборки сообщений или создания окон. Функции DLL пишутся в расчете на то, что их будет вызывать какое-то приложение (ЕХЕфайл) или другая DLL.
•Создавая DLL, надо указывать компоновщику ключ /DLL. Он заставляет компоновщика записывать в конечный файл информацию, по которой загрузчик операционной системы определит, что данный файл — DLL, а не приложение.
Чтобы приложение (или другая DLL) могло вызывать функции из DLL,
исполняемый файл нужно сначала спроецировать на адресное пространство вызывающего процесса.
•Это делается либо неявной компоновкой при загрузке, либо явной — в период выполнения.
Как только DLL спроецирована на адресное пространство вызывающего процесса,
еефункции доступны всем потокам этого процесса.
•Когда поток вызывает из DLL какую-то функцию, та считывает свои параметры из стека потока и размещает в этом стеке собственные локальные переменные.
Кроме того, любые созданные кодом DLL объекты принадлежат вызывающему потоку или процессу — DLL в Win32 ничем не владеет.
Например, если функция из DLL вызывает VirtualAlloc, резервируется регион в адресном пространстве того процесса, которому принадлежит поток, обратившийся к функции
из DLL. Если DLL будет выгружена из адресного пространства процесса, зарезервированный регион не освободится, так как система не фиксирует того, что регион выделен библиотечной функцией. Считается, что он принадлежит процессу и поэтому освободится, только если поток этого процесса вызовет VirtualFree или завершится сам процесс.
Глобальные и статические переменные DLL-библиотеки обрабатываются точно так, как
переменные ЕХЕ – файла, т.е. не разделяются его параллельно выполняемыми экземплярами.
•Когда процесс проецирует образ DLL файла на свое адресное пространство, система создает также экземпляры глобальных и статических переменных.
В 16-разрядной Windows DLL-библиотеки обрабатываются иначе, чем в Win32.
•В первой DLL-библиотека при загрузке становится в некотором смысле частью операционной системы. Все приложения, выполняемые в данный момент, получают доступ к DLL и всем содержащимся в ней функциям.
•В Win32-cpeдe DLL нужно спроецировать на адресное пространство процесса, прежде чем тот сможет вызывать ее функции.
Глобальные и статические данные DLL-библиотек в 16-разрядной Windows и Win32 тоже обрабатываются по-разному.
•В первой каждая DLL имеет свой сегмент данных. В нем находятся все глобальные и статические переменные DLL, a также ее закрытая локальная куча. При вызове из DLL функции LocalAlloc соответствующая область памяти выделяется из сегмента данных DLL, размер которого, как и размер всех других сегментов, ограничен 64 Кб.
|
Вот пример использования DLL для разделения данных между двумя приложениями: |
||||
HGLOBAL g_hData = NULL; |
|
|
|
||
void SetData(LPVOID IpvData, |
int nSize) { LPVOID Ipv; |
|
|||
g_hData |
= |
LocalAlloc(LMEM_MOVEABLE, |
nSize); |
||
Ipv |
|
|
= |
|
LocalLock(g_hData); |
memcpy(lpv, |
|
|
IpvData, |
nSize); |
|
LocalUnlock(g_hData); |
|
|
|
|
|
} |
|
|
|
|
|
void GetData(LPVOID IpvData, int nSize) |
{ |
|
|||
LPVOID Ipv = LocalLock(g_hData); |
|
|
|||
memcpy(IpvData, Ipv, nSize); |
|
|
|
LocalUnlock(g_hData);
}
•Вызов SetData приводит к выделению блока памяти из сегмента данных DLL, копированию в него данных, на которые указывает параметр IpvData, и сохранению описателя блока в глобальной переменной g_hData. Теперь другое при-
ложение может вызвать GetData. Та, используя глобальную переменную g_hData, блокирует выделенную область локальной памяти, копирует данные из нее в буфер, идентифицируемый параметром IpvData, и возвращает управление.
•В Win32: во-первых, у DLL в Win32 нет собственных локальных куч. Во-вторых,
глобальные и статические переменные не разделяются между разными проек-
циями одной DLL; система создает отдельный экземпляр глобальной переменной g_hData для каждого процесса, и значения, хранящиеся в разных экземплярах переменной, не обязательно одинаковы.
Проецирование DLL на адресное пространство процесса
Чтобы поток мог вызвать функцию из DLL-библиотеки, последнюю нужно, сначала спроецировать на адресное пространство процесса, которому принадлежит вызывающий поток. Сделать это можно следующими способами:
Неявная компоновка
Неявная компоновка (implicit linking). При сборке приложения компоновщику нужно указать набор LIB-файлов. Каждый такой файл содержит список функций данной
DLL. Обнаружив, что приложение ссылается на функции, упомянутые в LIB-файле для DLL, компоновщик внедряет имя этой DLL в конечный исполняемый файл.
Поиск DLL осуществляется в :
•каталоге, содержащем ЕХЕ - файл;
•текущем каталоге процесса;
•системном каталоге Windows;
•основном каталоге Windows;
•каталогах, указанных в переменной окружения PATH.
Явная компоновка
Образ DLL-файла можно спроецировать на адресное пространство процесса явным образом для чего один из потоков должен вызвать либо LoadLibrary, либо LoadLibraryEx: HINSTANCE LoadLibrary(LPCTSTR IpszLibFile);
HINSTANCE LoadLibraryEx(LPCTSTR IpszLibFile, HANDLE hFile, DWORD dwFlags);
Обе функции ищут образ DLL-файла и пытаются спроецировать его на адресное пространство вызывающего процесса. Значение типа HINSTANCE, возвращаемое обеими
функциями, сообщает адрес виртуальной памяти, по которому спроецирован образ файла. Если спроецировать DLL на адрес пространство процесса не удалось, функции возвращают NULL.
Обратим внимание на 2 дополнительных параметра функции LoаdLibraryEx: hFile и dwFlags. Первый зарезервирован и должен быть NULL. Во втором можно передать либо 0,
либо комбинацию флагов DONT_RESOLVE_DLL_REFERENCES, LOAD_LIВRARY_AS_DATAFILE и LOAD_WITH_ALTERED_SEARCH_PATH.
Рассмотрим эти параметры:
•DONT_RESOLVE_DLL_REFERENCES. Данный флаг заставляет систему
проецировать DLL, не обращаясь к DllMain и с ее помощью инициализирует библиотеку. При загрузке библиотеки система проверяет, используются ли ею другие DLL; если да, то загружает и их. При установке флага
DONT_RESOLVE_DLL_REFERENCES дополнительные DLL автоматически не загружаются.
•LOAD_LIBRARY_AS_DATAFILE. DLL проецирует на адресное пространство процесса так, будто это файл данных. При этом система не тратит дополнительного времени на подготовку к исполнению какого-либо кода из данного файл. Этот флаг
стоит указать, если DLL содержит только ресурсы и никаких функций. Также флаг может потребоваться, если Вам нужны ресурсы, содержащиеся в какомнибудь ЕХЕ – файле.
•LOAD_WITH_ALTERED_SEARCH_PATH. Изменяет алгоритм, используемый
LoadLibraryEx при поиске DLL-файла. Однако, если данный флаг установлен, функция ищет файл, просматривая каталоги в таком порядке:
1.Каталог, заданный в параметре IpszLibFile.
2.Текущий каталог процесса.
3.Системный каталог Windows.
4.Основной каталог Windows.
5.Каталоги, перечисленные в переменной окружения PATH.
И еще один фактор может повлиять на то, где система ищет файлы DLL. В реестре есть раздел:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs
Здесь может содержаться набор параметров, имена которых совпадают с именами некоторых DLL-файлов. Значения параметров представляют собой строки, идентичные именам параметров, только дополненные расширением “.DLL.”.
•Когда Вы вызываете LoadLibrary или LoadLibraryEx, каждая из них сначала
проверяет, указано ли имя DLL вместе с расширением “.DLL”. Если нет, поиск DLL ведется по уже знакомым Вам правилам.
•Если же расширение “.DLL” указано, функция его отбрасывает и ищет в разделе реестра KnownDLLs параметр с идентичным именем. Если его нет, вновь применяются описанные ранее правила. Есть — система обращается к значению, связанному с параметром, и пытается загрузить определенную в нем DLL. При этом система ищет DLL в каталоге, на который указывает значение, связанное с параметром реестра DllDirectory.
Если DLL загружается явно, ее можно отключить от адресного пространства процесса функцией FreeLibrary.
BOOL FreeLibrary(HINSTANCE hinstDll);
При вызове FreeLibrary, Вы должны передать значение типа HINSTANCE, которое идентифицирует выгружаемую DLL. Это значение Вы получите, предварительно вызвав
LoadLibran или LoadLibraryEx.