на тему рефераты Информационно-образоательный портал
Рефераты, курсовые, дипломы, научные работы,
на тему рефераты
на тему рефераты
МЕНЮ|
на тему рефераты
поиск
Окна приложений в среде Windows
p align="left">);

HINSTANCE описывает копию приложения.

в Windows 3.x этот хендл указывает на сегмент данных приложения, который содержит стек и локальную кучу. Для каждого запущенного приложения создается свой собственный сегмент данных, что позволяет однозначно определить конкретную копию приложения по его сегменту данных или организовать обмен данными между двумя копиями одного приложения. Так функция GetInstanceData позволяет скопировать данные, принадлежащие сегменту данных другой копии, в то-же самое место текущей копии.

int GetInstanceData( hInstance, pByte, cbData );

В функцию WinMain передается как хендл текущей копии приложения, так и хендл предыдущей копии, что позволяет организовать взаимодействие двух копий между собой, предотвратить запуск других копий, если это может привести к ошибке, или для выполнения действий, необходимых только в первой копии приложения.

В Win32 для каждого запущенного приложения (т.е. процесса) выделяется виртуальное адресное пространство в 4G в едином сегменте. Поэтому данный хендл описывает не сегмент данных (который описывает весь 4G сегмент), а адрес в виртуальном пространстве, с которого был загружен данный модуль. В адресном пространстве одного процесса никаких других приложений не существует, поэтому этот хендл не может применяться для обнаружения других копий приложения и тем более для обмена данными между разными копиями приложений. В приложениях Win32 hPrevInstance всегда равен NULL, а хендл текущей копии приложения в большинстве случаев совпадает. При необходимости обнаружения других копий приложения надо использовать какие-либо иные методы, например функцию:

HWND FindWindow( lpszClassName, lpszWindowTitle );

Хендл окна в Win32 является уникальным и может идентифицировать конкретное окно в любом приложении.

Для обмена данными между приложениями (процессами) приходится передавать данные из адресного пространства одного процесса в адресное пространство другого. Для выполнения этих операций предусмотрено сообщение WM_COPYDATA. Когда Вы посылаете это сообщение окну, созданному другим процессом, указанные Вами данные копируются в адресное пространство другого процесса и могут быть прочитаны оконной процедурой окна-получателя. Этот механизм может применяться и для обмена данными между 16-ти и 32-х битовыми приложениями, однако для этого необходимо определить номер сообщения WM_COPYDATA и специальную структуру COPYDATASTRUCT для 16-ти битовой платформы - так как файл windows.h не содержит этих определений:

#define WM_COPYDATA 0x004A

typedef struct tagCOPYDATASTRUCT {

DWORD dwData;

DWORD cbData;

LPVOID lpData;

} COPYDATASTRUCT, FAR* PCOPYDATASTRUCT;

HMODULE описывает отдельный модуль.

В Windows 3.x под модулем понимается отдельный выполняемый файл или библотека динамической компоновки. Для описания модуля создается специальный сегмент описания модуля, содержащий информацию о всех сегментах данного модуля и их атрибутах. Хендл модуля идентифицирует этот сегмент. Для любого приложения создается только один описывающий сегмент, который разделяется между всеми копиями этого приложения. Для получения хендла модуля Вы можете воспользоваться функциями:

HMODULE GetModuleHandle( lpszFileName );

int GetModuleFileName( hInstance, lpsBuffer, cbMaxSize );

В большинстве случаев, функции Windows API, работающие с хендлом модуля, корректно выполняются при передачи им хендла копии приложения, так что в документации возможен некоторый разнобой в используемых терминах.

В Win32 хендл модуля является синонимом хендла копии приложения. В документации встречаются оба термина, как они перекочевали из 16-ти битовых Windows, хотя они тождественны.

Сообщения. Посылка и передача сообщений

Ранее, на первых лекциях, мы рассматривали метод передачи сообщений, называемый “посылкой” сообщений (post). При использовании этого метода сообщение ставится в очередь приложения и позже извлекается из нее. Однако этот механизм не всегда удобен, так как не позволяет получить результата обработки сообщения, или дождаться его завершения. Точнее, позволяет, но очень громоздким способом.

Для решения этих задач вводится альтернативный механизм, называемый передачей сообщений. При этом сообщение в очередь не попадает и направляется непосредственно оконной функции. По сути его можно рассматривать как непосредственный вызов оконной функции с передачей ей указанных параметров. Это накладывает некоторые ограничения; так, например, нельзя передавать сообщение WM_QUIT - оно обязательно должно пройти через очередь сообщений, иные сообщения (скажем, клавиатуры) дополнительно обрабатываются в цикле обработки сообщений и их тоже надо посылать а не передавать и т.д.

Кроме того сложности возникают при использовании многопоточных приложений Win32 API - там принято, что сообщения, направленные окну, обязательно обрабатываются тем потоком, который это окно создал. Это существенно усложняет процесс передачи (не посылки) сообщений окну, созданному другим потоком - передающий сообщение поток помещает это сообщение в очередь принимающего потока с флагом `переданное сообщение' и приостанавливается до получения ответа. Принимающий поток, закончив обработку текущего сообщения, извлекает из очереди первыми сообщения, помеченные как переданные, обрабатывет их и после этого возобновляет работу пославшего потока. Однако при этом возможно зависание обеих потоков, если поток, принимающий сообщение, пытается передать вызывающему потоку подтверждение - тот находится в остановленном состоянии и не может обработать подтверждения, а принимающий в свою очередь останавливается, пока подверждение не будет обработано.

Для посылки и передачи сообщений могут применяться следующие функции:

BOOL PostMessage( hWnd, wMsg, wPar, lPar );

Посылает указанное сообщение окну (через очередь сообщений).

LONG SendMessage( hWnd, wMsg, wPar, lPar );

Передает сообщение окну (прямой вызов обработчика сообщений) и звращает управление в вызвавшую процедуру после обработки указанного сообщения. При этом она возвращает значение, возвращаемое оконной функцией. При использовании этой функции сообщение вообще не поступает в очередь приложения (кроме приложений Win32 API). То есть Вы можете воспользоваться этой функцией для обработки тех или иных сообщений до организации цикла обработки сообщений.

BOOL PostAppMessage( hTask, wMsg, wPar, lPar ); // Windows 3.x

BOOL PostAppMessage( dwProccessId, wMsg, wPar, lPar ); // Win32 API

BOOL PostThreadMessage( dwThreadId, wMsg, wPar, lPar ); // Win32 API

Посылает сообщение конкретной задаче. При этом в очередь соответствующего приложения помещается сообщение, имеющее нулевой хендл окна - получателя. Соответственно такое сообщение не диспетчеризуется никакому окну.

Хендл задачи hTask не является хендлом копии приложения. Вы можете использовать функцию GetCurrentTask для получения хендла задачи в среде Windows 3.x, а также функции GetCurrentThreadId и GetCurrentProcessId в Win32 API.

для получения этого хендла.

BOOL PostQuitMessage( wPar );

Посылает сообщение WM_QUIT с заданным параметром wPar вашему приложению. Сообщение WM_QUIT используется для завершения главного цикла обработки сообщений.

Типичные последовательности сообщений, получаемых окном.

Сейчас мы займемся изучением основных сообщений, используемых окном.
При этом мы рассмотрим несколько типичных последовательностей сообщений, получаемых окном. Так, например, мы рассмотрим последовательность сообщений, получаемых окном при его создании. При этом надо считать, что приводимые сообщения в последовательности являются как бы “скелетом”, а реальная последовательность может иметь большее число сообщений, или некоторые могут отсутствовать. Это определяется характеристиками окна, его свойствами и выполняемой дополнительной обработкой сообщений. (Так, например, последовательности сообщений, получаемых “скрытыми” окнами или окнами в минимизированном состоянии могут существенно отличаться).

В рассматриваемых нами последовательностях сообщений большинство сообщений не проходят через очередь сообщений, а передаются непосредственно оконной процедуре какой-либо функцией. Именно логика выполнения этой функции и определяет последовательность получения сообщений. Кроме того, некоторые сообщения в этих цепочках являются как бы “вложенными” - то есть они порождаются при обработке какого-либо иного сообщения.

Инициализация окна

Для создания окна используется функция CreateWindow(). Во время ее выполнения окно получает несколько сообщений:

WM_GETMINMAXINFO 0 &MINMAXINFO

Информация о допустимых размерах окна; данные в структуре MINMAXINFO задаются ДО передачи сообщения, так что вы можете их не изменять, а только прочитать при необходимости. (Для получения данных Вы можете вместо обработки этого сообщения воспользоваться функцией GetWindowPlacement()).

WM_NCCREATE 0 &CREATESTRUCT

Создание внешней (non-client) области окна. Обработка, предусмотренная процедурой DefWindowProc() инициализирует необходимые структуры и, в частности, выделяет пространство для хранения заголовка окна. Никакого рисования не выполняется. Возвращаемый процедурой 0 указывает на возникшую ошибку и окно не создается; не 0 указывает на успешное создание внешней области.

WM_NCCALCSIZE flag &NCCALCSIZE_PARAMS

Определение размера внутренней (client) части окна; кроме этого определяется часть окна, которая может быть скопирована без изменений при перемещении окна или изменении его размеров.

WM_CREATE 0 &CREATESTRUCT

Предусмотрено для выполнения Вами необходимых действий для создания внутренней (client) области окна. При этом Вы производите инициализацию связанных объектов, создание дочерних окон и пр. Как и WM_NCCREATE функция возвращает подтвержение о успешном выполнении нужных действий. Однако “успех” обозначается 0, а ошибка: -1 (!).

Активация приложения

Сейчас мы рассмотрим еще несколько последовательностей сообщений, получаемых главным окном приложения. Рассматривать мы их будем на примере создания и отображения главного окна приложения. Для начала мы выделим несколько сообщений в две обычных последовательности, которые можно назвать “активацией” и “деактивацией” приложения. Эти цепочки сообщений возникают при передаче активности (фокуса ввода) от одного приложения другому. За время работы одного приложения эти цепочки могут возникать многократно. Обычно сразу за созданием главного окна приложения следует активация этого приложения.

Активация приложения:

WM_ACTIVATEAPP TRUE hTask

сообщение, информирующее об активации приложения. Если приложение имеет несколько окон “верхнего уровня” (т.е. окон стиля WS_OVERLAPPED или WS_POPUP), то все они получают эти сообщения. Младшее слово lParam содержит хендл той задачи, которая была активна до этого момента.

WM_NCACTIVATE TRUE minimized & hWnd

активация (или деактивация, смотря по параметру wParam) внешней области окна. Обработка этого сообщения по умолчанию перерисовывает внешнюю область окна для выделения цветом активного/неактивного состояний. При этом активность или неактивность окна запоминается в структуре описания окна. Вы можете сами посылать WM_NCACTIVATE для изменения состояния окна. В документации параметр `lParam' не описывается, однако он может быть не 0, и содержать такие же данные, как и в сообщении WM_ACTIVATE (см. ниже). Это сообщение может быть получено не только главным окном приложения, так как информирует об активации окна, а не приложения.

Если окно активируется, то возвращаемое значение может быть любым, а если деактивируется то значение 0 запрещает его дальнейшую деактивацию. Дочерние не MDI окна (стиль WS_CHILD) часто этого сообщения не получают.

WM_GETTEXT bufsize &buffer

при обработке этого сообщения указанный буфер заполняется названием активируемого окна. В данном случае это сообщение порождается при перерисовке внешней области окна - WM_GETTEXT “вложено” в обработку WM_NCACTIVATE. Если окно не имеет заголовка (caption bar), то это сообщение не посылается.

WM_ACTIVATE 1 или 2 minimized & hWnd

активация внутренней области окна. Это сообщение может быть получено не только главным окном приложения, так как информирует об активации окна, а не приложения. Однако дочерние окна (например, управляющие элементы диалогов) могут этого сообщения не получать. Параметр wParam информирует о том, что окно активируется с помощью нажатия кнопки мыши (2) или иным путем (0). Параметр lParam содержит в старшем слове не 0, если окно минимизировано, а в младшем слове - хендл окна бывшего до этого активным.

<получение фокуса ввода>

сообщения получения/потери фокуса ввода окном см. ниже.

В этой цепочке можно выделить две фазы:

Страницы: 1, 2, 3



© 2003-2013
Рефераты бесплатно, курсовые, рефераты биология, большая бибилиотека рефератов, дипломы, научные работы, рефераты право, рефераты, рефераты скачать, рефераты литература, курсовые работы, реферат, доклады, рефераты медицина, рефераты на тему, сочинения, реферат бесплатно, рефераты авиация, рефераты психология, рефераты математика, рефераты кулинария, рефераты логистика, рефераты анатомия, рефераты маркетинг, рефераты релиния, рефераты социология, рефераты менеджемент.