МегаПредмет

ПОЗНАВАТЕЛЬНОЕ

Сила воли ведет к действию, а позитивные действия формируют позитивное отношение


Как определить диапазон голоса - ваш вокал


Игровые автоматы с быстрым выводом


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


Целительная привычка


Как самому избавиться от обидчивости


Противоречивые взгляды на качества, присущие мужчинам


Тренинг уверенности в себе


Вкуснейший "Салат из свеклы с чесноком"


Натюрморт и его изобразительные возможности


Применение, как принимать мумие? Мумие для волос, лица, при переломах, при кровотечении и т.д.


Как научиться брать на себя ответственность


Зачем нужны границы в отношениях с детьми?


Световозвращающие элементы на детской одежде


Как победить свой возраст? Восемь уникальных способов, которые помогут достичь долголетия


Как слышать голос Бога


Классификация ожирения по ИМТ (ВОЗ)


Глава 3. Завет мужчины с женщиной


Оси и плоскости тела человека


Оси и плоскости тела человека - Тело человека состоит из определенных топографических частей и участков, в которых расположены органы, мышцы, сосуды, нервы и т.д.


Отёска стен и прирубка косяков Отёска стен и прирубка косяков - Когда на доме не достаёт окон и дверей, красивое высокое крыльцо ещё только в воображении, приходится подниматься с улицы в дом по трапу.


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

Обробка подій від клавіатури





I.Емуляція натиснення клавіші.

Всередині програми це виконується досить просто за допомогою виклику функції Windows API SendMessage () (можна скористатися і методом Perform того об'єкта (або форми), кому надсилається повідомлення про самій клавіші).

Код

Memo1.Perform (WM_CHAR, Ord ('A'), 0);

або SendMessage (Memo1.Handle, WM_CHAR, Ord ('A'), 0);

призведе до друку символу "A" в об'єкті Memo 1.

II.Перехоплення натисків клавіші всередині програми.

Завдання вирішується дуже просто. Можна у форми встановити властивість KeyPreview в True і обробляти подія OnKeyPress. Другий спосіб - перехоплювати подія OnMessage для об'єкта Application.

III.Перехоплення натиснутийия клавіші в Windows.

Існують програми, яким необхідно перехоплювати всі натиснення клавіш в Windows, навіть якщо в даний момент активно інший додаток. Це може бути, наприклад, програма, що перемикає розкладку клавіатури, резидентний словник або програма, виконує інші дії після натискання "гарячої" комбінації клавіш.

Перехоплення всіх подій в Windows (у тому числі і подій від клавіатури) виконується за допомогою виклику функції SetWindowsHook (). Ця функція реєструє в системі Windows пастку (hook) для певного типу подій / повідомлень. Пастка - це призначена для користувача процедура, яка буде обробляти вказану подію.

Основне тут те, що ця процедура повинна завжди бути присутнім в пам'яті Windows. Тому пастку поміщають в DLL і завантажують цю DLL з програми. Поки хоч одна програма використовує DLL, та не може бути вивантажено з пам'яті. Наведемо приклад такої DLL і програми, її використовує. У прикладі пастка перехоплює натиснення клавіш на клавіатурі, перевіряє їх і, якщо це клавіші "+" або "-", посилає відповідне повідомлення в конкретний додаток (вікно). Вікно шукається по імені його класу ("TForm 1") і заголовку (caption, "XXX").

{Текст бібліотеки}

library SendKey;

uses

WinTypes, WinProcs, Messages;

const

{Користувальницькі повідомлення}

wm_NextShow_Event = wm_User + 133;

wm_PrevShow_Event = wm_User + 134;

{Handle для пастки}

HookHandle: hHook = 0;

var

SaveExitProc: Pointer;

{Власне пастка}

function Key_Hook (Code: integer; wParam: word; lParam: Longint): Longint; export;

var

H: HWND;

begin

{Якщо Code> = 0, то пастка може обробити подію}

if Code> = 0 then

begin

{Це ті клавіші?}

if ((wParam = VK_ADD) or (wParam = VK_SUBTRACT)) and

(LParam and $ 40000000 = 0) then

begin

{Шукаємо вікно по імені класу і по заголовку}

H: = FindWindow ('TForm 1', 'XXX');

{Посилаємо повідомлення}

if wParam = VK_ADD then

SendMessage (H, wm_NextShow_Event, 0, 0)

else

SendMessage (H, wm_PrevShow_Event, 0, 0);

end;

{Якщо 0, то система повинна далі обробити цю подію}

{Якщо 1 - немає}

Result: = 0;

end

else

{Якщо Code <0, то потрібно викликати наступну пастку}

Result: = CallNextHookEx (HookHandle, Code, wParam, lParam);

end;

{При розвантаженні DLL треба зняти пастку}

procedure LocalExitProc; far;

begin

if HookHandle <> 0 then

begin

UnhookWindowsHookEx (HookHandle);

ExitProc: = SaveExitProc;

end;

end;

{Ініціалізація DLL при завантаженні її в пам'ять}

begin

{Встановлюємо пастку}

HookHandle: = SetWindowsHookEx (wh _ Keyboard, Key _ Hook,

hInstance, 0);

if HookHandle = 0 then

MessageBox (0, 'Unable to set hook!', 'Error', mb_Ok)

else begin

SaveExitProc: = ExitProc;

ExitProc: = @ LocalExitProc;

end;

end.

Розмір такої DLL в скомпільованому вигляді буде близько 3Кб, оскільки в ній не використовуються об'єкти з VCL.

Далі приведений код модуля в Delphi, який завантажує DLL і обробляє повідомлення від пастки, просто відображаючи їх в Label1.

unit Unit1;

interface

uses

SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;

{Повідомлення користувача}

const

wm_NextShow_Event = wm_User + 133;

wm_PrevShow_Event = wm_User + 134;

type

TForm1 = class (TForm)

Label1: TLabel;

procedure FormCreate (Sender: TObject);

private

{Обробники повідомлень}

procedure WM_NextMSG (Var M: TMessage);

message wm_NextShow_Event;

procedure WM_PrevMSG (Var M: TMessage);

message wm_PrevShow_Event;

end;

 

var

Form1: TForm1;

P: Pointer;

implementation

{$ R *. DFM}

{Завантаження DLL}

function Key_Hook: Longint; far; external 'SendKey';

procedure TForm1.WM_NextMSG (Var M: TMessage);

begin

Label1.Caption: = 'Next message';

end;

procedure TForm1.WM_PrevMSG (Var M: TMessage);

begin

Label1.Caption: = 'Previous message';

end;

procedure TForm1.FormCreate (Sender: TObject);

begin

{Якщо не використовувати виклик процедури з DLL в програмі,

то компілятор видалить завантаження DLL з програми}

P: = @ K e y_Hook;

end;

end.

Звичайно, властивість Caption у цій формі має бути встановлено в "XXX".

Зміна виду вікна програми

В розділ private напишіть наступне:

private

{Private declarations}

FormRgn, EllipseRgn: HRGN;

Тепер для головної форми створи подія "OnCreate". Для цього досить двічі клацнути по головній формі і Delphi створить процедуру FormCreate. У ній напишіть наступне:

procedure TForm1.FormCreate (Sender: TObject);

begin

FormRgn: = CreateEllipticRgn (0,0, Width, Height);

SetWindowRgn (Handle, FormRgn, True);

end;

У Вас повинен вийти ось такий текст:

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics,

Controls, Forms, Dialogs, StdCtrls;

type

TForm1 = class (TForm)

Button1: TButton;

procedure FormCreate (Sender: TObject);

procedure Button1Click (Sender: TObject);

private

{Private declarations}

FormRgn, EllipseRgn: HRGN;

public

{Public declarations}

end;

var

Form1: TForm1;

 

implementation

{$ R *. DFM}

procedure TForm1.FormCreate (Sender: TObject);

begin

FormRgn: = CreateEllipticRgn (0,0, Width, Height);

SetWindowRgn (Handle, FormRgn, True);

end;

procedure TForm1.Button1Click (Sender: TObject);

begin

Close;

end;

 

end.

Тепер розглянемо детальніше:

CreateEllipticRgn (

NLeftRect: Integer, / / Ліва позиція

nTopRect: Integer, / / Верхня

nRightRect: Integer, / / Права

nBottomRect: Integer / / Нижня

): HRGN;

Ця процедура створює регіон у вигляді еліпса.

SetWindowRgn (

HWnd: HWND, / / Покажчик на нашу форму

HRgn: HRGN, / / Попередньо створений регіон

BRedraw: Boolean / / Прапор перемальовування вікна

): Integer;

Ця процедура прив'язує створений нами регіон з нашою формою. Прапор bRedraw повинен бути true, інакше регіон ну буде промальований.

Розглянемо ще дві функції.

CreateRectRgn (

nLeftRect: Integer, / / Ліва позиція

nTopRect: Integer, / / Верхня

nRightRect: Integer, / / Права

nBottomRect: Integer / / Нижня

): HRGN;

Ця функція схожа на CreateEllipticRgn. Вона також створює регіон, але вже квадратний.

CombineRgn (

HrgnDest: HRGN, / / Покажчик на результуючий регіон

hrgnSrc1: HRGN, / / Покажчик на регіон 1

hrgnSrc2: HRGN, / / Покажчик на регіон 2

fnCombineMode: Integer / / Метод об'єднання

): Integer;

Ця функція комбінує два регіони з hrgnSrc1 і hrgnSrc2 і поміщає результат в HrgnDest. FnCombineMode - метод комбінування, який може бути: RGN_AND, RGN_COPY, RGN_DIFF, RGN_OR або RGN_XOR.

Тепер підправимо нашу програму з урахуванням нових функцій. Для цього, потрібно змінити процедуру FormCreate.

procedure TForm1.FormCreate (Sender: TObject);

begin

FormRgn: = CreateEllipticRgn (0,0, Width, Height);

EllipseRgn: = CreateRectRgn (round (Width / 4), round (Height / 4),

round (3 * Width / 4), round (3 * Height / 4));

CombineRgn (FormRgn, FormRgn, EllipseRgn, RGN_DIFF);

SetWindowRgn (Handle, FormRgn, True);

end;






©2015 www.megapredmet.ru Все права принадлежат авторам размещенных материалов.