Применение Windows API
Шрифт:
Оконная процедура вызывается с указанием дескриптора к окна, к которому направлено данное сообщение. Этот дескриптор однозначно идентифицирует внутреннюю структуру данных Windows, которая соответствует экземпляру окна. Это так часто случОконная процедура вызывается с указанием дескриптора к окна, к которому направлено данное сообщение. Этот дескриптор однозначно идентифицирует внутреннюю структуру данных Windows, которая соответствует экземпляру окна. Это так часто случается, что мы можем обращаться к этой структуре данных и использовать ее, чтобы сохранить некоторые специфические для экземпляра данные. Имеется типовой безопасный способ доступа к этой структуре. Между прочим, элемент GWL_USERDATA этой структуры гарантированно присутствует во всех окнах, включая окна сообщения, диалоговые окна и даже кнопки.
Каждый раз, когда Windows вызывает нашу оконную процедуру, мы хотим сначала восстановить ее контроллер. Вспомните, что может быть несколько окон, совместно использующих ту же самую оконную процедуру, и мы хотим иметь отдельный контроллер для каждого окна. Как мы узнаем, какой из контроллеров используетсять, когда произходит обратный вызов оконной процедуры? Мы можем выяснить это, рассмотрев дескриптор окна. В этом дескрипторе мы сохраняем указатель на контроллер данного окна, используя функцию Win[Set/Get]Long.
Оконная процедура сначала вызывается с сообщением WM_CREATE. В этот момент мы создаем экземпляр контроллера, нициализируем его дескриптором окна и специальной структурой данных по имени CREATESTRUCT, которая передана нам от Windows. Если же мы уже имеем контроллер, то сохраняем указатель на его в соответствующей внутренней Windows-структуре данных помеченной текущим hwnd. В следующий раз оконная процедура вызывается с сообщением, отличным от WM_CREATE, и мы просто восстанавливаем (отыскиваем) указатель на наш контроллер, используя hwnd.
Остальное просто. Оконная процедура интерпретирует параметры сообщения и вызывает соответствующие методы контроллера.
Ниже представлены примеры простых реализаций нескольких методов построения контроллеров. Конструктор должен помнить дескриптор окна для более позднего использования, деструктор должен посылать сообщение выхода (quit), метод Size передает его параметр Просмотру (Экрану), и т.д. Мы будем говорить о рисовании в окне немного позже. Теперь, обратите внимание, что контроллер готовит поверхность "Холста" для работы "Вида".
Когда пользователь выбирает один из пунктов меню, оконная процедура вызывается с сообщением WM_COMMAND. Соответствующий метод контроллера посылает команду, основанную на id команды. Когда Вы создаете меню, используя редактор ресурса, Вы выбираете эти идентификаторы команд для каждого пункта меню. Они сохранены в соответствующем заголовочном файле ("resource.h" в нашем случае), который должен быть включен в исходный файл контроллера.