|
Навигация
|
Главная » Delphi Сообщения Windows и их обработка (исходники)Источник: Русские Документы Арсентьев Александр Что же такое "Сообщение Windows"? Этот вопрос первым может возникнуть у начинающего программиста, тот же, кто когда-либо сталкивался с этим, хитро ухмыльнется и спрячет свои мысли в загадочную улыбку.Взаимодействие, как форма общенияВ своей повседневной жизни, мы постоянно общаемся. Общение может подразумевать разговор, совместную работу и еще много всего прочего, однако в любом случае это обмен разного рода информацией, выраженной различными формами взаимодействия. Так же происходит и в электронном мире, когда мы запускаем какую-нибудь программу, не важно игра это, текстовый редактор, или среда разработки Delphi. Программы, начинают, скрыто от нас общаться и обмениваться информацией, в простейшем виде это обмен информацией между операционной системой и приложением.Приложение может взаимодействовать, как со своими дочерними формами, так и с "посторонними" (внешними) приложениями. Виды взаимодействия с внешними приложениями могут быть следующими:
Обработка сообщений в приложениях WindowsИ все же что такое сообщение? Как оно выглядит? Как можно его послать? Немного терпения друзья мои, и Вы все узнаете.Итак! Настал момент выложить карты на стол. В свое время сообщения выглядели крайне не приветливо, и было довольно сложно для запоминания В новых версиях Windows, великая и могучая и всеми "любимая" Microsoft, видимо осознав все это значительно облегчила Нам жизнь, приведя сообщения к вполне "цивилизованному" виду (например WM_CLOSE). Рассмотрим некоторые виды сообщений: WM_CLOSE - сигнализирует, что окно или приложение закрывается. Это сообщение не имеет параметров. По умолчанию оно закрывает окно, которому послано. Если приложение обрабатывает это сообщение, то оно должно возвращать нуль. При обработке этого сообщение приложение может запросить пользователя о необходимости закрывать окно или вызвать функцию закрывания окна только при положительном ответе. WM_ACTIVATE - посылается, когда окно переводится в активное или неактивное состояние. Сначала сообщение посылается окну, переходящему в неактивное состояние, а потом - активируемому. Это сообщение имеет дополнительные параметры:
Параметр fActive показывает, как активизируется или деактивируется окно. Возможные значения этого параметра:
Параметр hwndPrevious - это дескриптор, который указывает на окно, из которого фокус переключился на данное окно, если оно активируется, или на окно, в которое передается управление, если данное окно деактивируется. По умолчанию, если активируемое окно не свернуто, то оно получает фокус. Если приложение обрабатывает это сообщение, то оно должно возвращать нуль. WM_GETMINMAXINFO - посылается при изменении размеров или положения окна. Обработчик события может использоваться для ограничения допустимых размеров и координат положения на экране. Определение: WM_GETMINMAXINFO lpmmi = (LPMINMAXINFO) lParam; // address of structure Параметр lpmmi указывает на структуру типа MINMAXINFO, содержащую принятые по умолчанию пределы изменения размеров и координат положения окна. Описание этой структуры: typedef struct tagMINMAXINFO { // mmi POINT ptReserved; POINT ptMaxSize; POINT ptMaxPosition; POINT ptMinTrackSize; POINT ptMaxTrackSize; } MINMAXINFO; Поля структуры означают следующее:
WM_COPYDATA - посылается, когда одно приложение передает данные другому приложению. Определение: WM_COPYDATA
Параметр hwnd идентифицирует окно, посылающее данные. Параметр pcds указывает на структуру типа COPYDATASTRUCT, содержащую пересылаемые данные. Описание этой структуры: typedef struct tagCOPYDATASTRUCT { cds DWORD dwData; до 32 бит данных, передаваемых приложению-получателю DWORD cbData; определяет размер (в байтах) даных, на которые указывает lpData PVOID lpData; указатель на данные, передаваемые приложению-получателю } COPYDATASTRUCT; Возвращаемое приложение-приемник обрабатывает сообщение, оно должно возвратить значение TRUE; в противном случае - FALSE. Замечания:
Посылка сообщенийФункция SendMessage посылает указанное в ней сообщение окну или множеству окон и не возвращается, пока это сообщение обрабатывается. Этим она отличается от функции PostMessage, которая возвращается сразу после передачи сообщения.Объявление функции: function SendMessage(HWND: hWnd, Msg,WPARAM: word,LPARAM: longint):longint; Параметр hWnd - дескриптор окна, которому передается сообщение. Параметр Msg определяет передаваемое сообщение. Параметры WPARAM и LPARAM могут содержать дополнительную информацию. Значение, возвращаемое функцией, зависит от вида сообщения. Функция PostMessage не годится для передачи срочных сообщений, но зато она не блокирует вызвавшее приложение на время обработки сообщения приемником. Объявление функции: function PostMessage(HWND: hWnd, Msg,WPARAM: word,LPARAM: longint):longint; Параметр hWnd - дескриптор окна, которому передается сообщение. Если этот параметр nil, то сообщение становится в очередь сообщений (если она есть) текущего процесса. Параметр Msg определяет передаваемое сообщение. Параметры WPARAM и LPARAM могут содержать дополнительную информацию. Функция возвращает ненулевое значение при успешном завершении и нуль в случае аварийного завершения. В этом случае причину ошибки можно установить вызовом функции GetLastError. Обратимся к программе, которая приведена в качестве примера для данной статьи и разберем кусок текста программы, чтобы лучше понять механизм работы сообщений. SendMessage (Form2.Handle, WM_CLOSE, 0, 0); В данной строке ясно видно, что мы работаем с дочерним окном своего приложения (Form2.Handle) и передаем ему "приказ" закрыться (WM_CLOSE). var CDS : TCopyDataStruct; dt : TDateTime; ms : TMemoryStatus; begin .... GlobalMemoryStatus(ms); CDS.dwData:=ms.dwAvailPageFile+ms.dwAvailPhys; CDS.cbData:=SizeOf(dt); CDS.lpData:=@dt; SendMessage(FindWindow (`TForm1`, `Form1`), WM_COPYDATA, 0, longint(@CDS)); .... end; Очевидно, что мы посылаем найденному окну внешней программы (в нашем случае заголовок окна будет иметь значение Caption = `Form1`) сообщение с дополнительными параметрами, опять же в нашем случае это адрес структуры CDS типа TcopyDataStruct (longint(@CDS)), в которую мы предварительно занесли информацию о текущем времени и объеме свободной памяти. Замечание: здесь стоит сразу оговориться, что если процедура FindWindow будет иметь вид FindWindow (`TForm1`, nil), то сообщение будет отослано всем приложениям, имеющим в своем составе класс TForm1, т.к эта запись предполагает любое значение свойства Caption в заголовке. Обработка сообщений Во всех оконных компонентах предусмотрены обработчики сообщений Windows по умолчанию. Можно определить свои собственные обработчики, заменив ими обработчики по умолчанию, или дополнив их. Объявление своего обработчика помещается в описание класса оконного компонента, как правило, в раздел private. Синтаксис объявления: procedure <имя>(var <параметр>:<тип параметра>);message <сообщение>; Здесь <имя> обозначает имя процедуры обработки сообщения. Имя может быть любым, но обычно принято делать его тождественным имени обрабатываемого сообщения, исключив из него символ подчеркивания. Передаваемый в обработчик параметр также может иметь любое имя. Этот параметр представляет собой запись, через которую в обработчик передаются параметры сообщения, а из обработчика возвращается значение поля Result, фиксирующее результат обработки. <тип параметра> - это тип структуры параметров сообщения. После ключевого слова message записывается тип сообщения. Снова обратимся к демонстрационной программе и посмотрим пример объявления своего обработчика сообщения WM_CLOSE: unit Unit2; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; private { Private declarations } procedure WMClose(var a : TWMClose);message WM_CLOSE; ..... implementation {$R *.dfm} ..... procedure TForm2.WMClose(var a:TWMClose); begin if MessageDlgPos(`Меня хотят закрыть. Согласны?`, mtConfirmation, [mbYes,mbNo],0,BoundsRect.Left,BoundsRect.Bottom)=mrYes then Close else Label1.Caption:=`Не закроюсь!`; end; Здесь мы объясняем программе, как нужно реагировать на сообщение операционной системы о том, что ей пора закрываться. При попытке ее закрыть, она будет оказывать сопротивление и спросит Вас действительно ли ей нужно закрыться, или нет. Определение собственных сообщений Можно описать свои собственные сообщения, и работать с ними так же, как и с предопределенными API Windows. Номера своих собственных сообщений необходимо отсчитывать от константы WM_USER, которая соответствует первому номеру сообщения пользователя. Например, можно определить в своем приложении константы Const WM_MyMess1=WM_USER; WM_MyMess2=WM_USER+1; и затем оперировать с сообщениями WM_MyMess1 и WM_MyMess2 как с предопределенными в Windows. Ниже представлен пример объявления своего сообщения: ... private { Private declarations } procedure WMin (var b : TMessage); message WM_USER ; .... procedure TForm2.WMin (var b : TMessage); begin Form2.WindowState := wsMinimized; end; Вместо заключения Вот и закончилось наше путешествие в мир сообщений Windows, как заканчивается очередная глава, понравившейся книги. В данной статье я постарался сообщить Вам по этой теме все, что знаю я, и буду рад, если хоть кому-то она пойдет впрок. Помните господа, Вы программисты! У вас особый склад ума и особый статус! И не важно, на каком Вы уровне и сколько на данный момент у Вас знаний; важно постоянно совершенствовать себя и давать для этого возможность другим, быть чуткими к близким и не размениваться по мелочам. Покорно благодарю всех, кто почтил внимаем сей скромный труд и дочитал до этих строк, растите в профессиональном плане и любите Linux. Как уменьшить приложение написанное на Delphi в 20 раз. Изменение размеров массивов. Нисходящие Б-деревья в Delphi. Embarcadero обеспечивает возможность создания приложений для Windows 8 и OS X на базе единого исходного кода. Типы данных в DELPHI. Главная » Delphi |
© 2024 Team.Furia.Ru.
Частичное копирование материалов разрешено. |