Повідомлення Windows та їх обробка (исходники), Різне, Програмування, статті

Що ж таке “Повідомлення Windows”? Це питання першим може виникнути у початківця програміста, той же, хто коли-небудь стикався з цим, хитро посміхнеться і сховає свої думки в загадкову посмішку.


Взаємодія, як форма спілкування


У своєму повсякденному житті, ми постійно спілкуємося. Спілкування може мати на увазі розмову, спільну роботу і ще багато всього іншого, проте в будь-якому випадку це обмін різного роду інформацією, вираженої різними формами взаємодії. Так само відбувається і в електронному світі, коли ми запускаємо якусь програму, не важливо гра це, текстовий редактор, або середу розробки Delphi. Програми, починають, приховано від нас спілкуватися і обмінюватися інформацією, в найпростішому вигляді це обмін інформацією між операційною системою та програмою.


Додаток може взаємодіяти, як зі своїми дочірніми формами, так і з “сторонніми” (зовнішніми) додатками. Види взаємодії із зовнішніми додатками можуть бути наступними:



У даній статті нам належить познайомитися з повідомленнями та способами їх обробки.


Обробка повідомлень в додатках Windows


І все ж що таке повідомлення? Як воно виглядає? Як можна його послати? Трохи терпіння друзі мої, і Ви все дізнаєтеся.


Отже! Настав момент викласти карти на стіл. Свого часу повідомлення виглядали вкрай не привітно, і було досить складно для запам’ятовування У нових версіях Windows, велика і могутня і всіма “улюблена” Microsoft, мабуть усвідомивши все це значно полегшила Нам життя, привівши повідомлення до цілком “цивілізованого” вигляду (наприклад WM_CLOSE).


Розглянемо деякі види повідомлень:


WM_CLOSE – Сигналізує, що вікно або додаток закривається. Це повідомлення не має параметрів. За замовчуванням воно закриває вікно, якому послано. Якщо додаток обробляє це повідомлення, то воно повинно повертати нуль. При обробці цього повідомлення додаток може запитати користувача про необхідність закривати вікно або викликати функцію закривання вікна тільки при позитивній відповіді.


WM_ACTIVATE – Надсилається, коли вікно переводиться в активну або неактивний стан. Спочатку повідомлення надсилається вікна, яке переходить у неактивний стан, а потім – активованого. Це повідомлення має додаткові параметри:













fActive = LOWORD(wParam); Прапор активації
fMinimized = (BOOL) HIWORD(wParam); Прапор мінімізації (1 – якщо вікно мінімізовано, 0 – якщо ні)
hwndPrevious = (HWND) lParam; Ідентифікатор вікна (Handle)


Параметр fActive показує, як активізується або деактивується вікно. Можливі значення цього параметра:













WA_ACTIVE вікно активізується не клацанням миші (наприклад, функцією SetActiveWindow або клавіатурою)
WA_CLICKACTIVE вікно активізується клацанням миші
WA_INACTIVE вікно деактивується


Параметр 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;


Поля структури означають наступне:


















ptReserved Зарезервовано і поки не використовується
ptMaxSize Поле типу Point визначає ширину (Point.x) і висоту (Point.y) розгорнутого вікна
ptMaxPosition Поле типу Point визначає положення лівого (Point.x) і верхнього (Point.y) країв розгорнутого вікна
ptMinTrackSize Поле типу Point визначає мінімальну ширину (Point.x) і мінімальну висоту (Point.y) вікна при зміні користувачем розмірів його рамки.
ptMaxTrackSize Поле типу Point визначає максимальну ширину (Point.x) і максимальну висоту (Point.y) вікна при зміні користувачем розмірів його рамки.

Якщо додаток обробляє це повідомлення, воно повинно повернути 0.


WM_COPYDATA – Надсилається, коли один додаток передає дані іншому додатку.
Визначення:
WM_COPYDATA










wParam = (WPARAM) (HWND) hwnd; Дескриптор посилаючої вікна
lParam = (LPARAM) (PCOPYDATASTRUCT) pcds; покажчик на структуру з даними


Параметр 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.


Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*