Пятница, 27.06.2025
Королевство Delphi
Главное меню
Статьи
Наш опрос
Нравится раздел статьи?
Всего ответов: 68
Статистика
Онлайн всего: 1
Гостей: 1
Пользователей: 0
Форма входа
Главная » Статьи » Система » Разное

Использование НООК в Delphi

Что такое НООК?

НООК - это механизм перехвата сообщений, предоставляемый системой Microsoft Windows. Программист пишет специального вида функцию (НООК-функция), которая затем при помощи функции SetWindowsHookEx вставляется на верх стека НООК-функций системы. Ваша НООК-функция сама решает, передать ли ей сообщение в следующую НООК-функцию при помощи CallNextHookEx или нет.

Какие бывает НООК'и?

НООК бывают глобальные, контролирующие всю систему, так и локальные, ориентированные на какой-либо поток (Thread). Кроме того НООК различаются по типу перехватываемых сообщений (подробнее об этом - ниже). НООК несколько подтормаживают систему, поэтому ставить их рекомендуется только при необходимости, и кактолько необходимость в них отпадает - удалять.

Как создавать НООК?

НООК устанавливается в систему при помощи функции SetWindowsHookEx, вот её заголовок:

function SetWindowsHookEx(idHook: Integer; lpfn: TFNHookProc; hmod: HINST; dwThreadId: DWORD): HHOOK;
idHook
константа, определяющая тип вставляемого НООК'а, должна быть одна из нижеследующих констант:
WH_CALLWNDPROC
вставляемая НООК-функция следит за всеми сообщения перед их отпралением в соответствующую оконную функцию
WH_CALLWNDPROCRET
вставляемая НООК-функция следит за всеми сообщениями после их отправления в оконную функцию
WH_CBT
вставляемая НООК-функция следит за окнами, а именно: за созданием, активацией, уничтожением, сменой размера; перед завершением системной команды меню, перед извлечением события мыши или клавиатуры из очереди сообщений, перед установкой фокуса и т.д.
WH_DEBUG
вставляемая НООК-функция следит за другими НООК-функциями.
WH_GETMESSAGE
вставляемая НООК-функция следит за сообщениями, посылаемыми в очередь сообщений.
WH_JOURNALPLAYBACK
вставляемая НООК-функция посылает сообщения, записанные до этого WH_JOURNALRECORD НООК'ом.
WH_JOURNALRECORD
эта НООК-функция записывает все сообщения куда-либо в специальном формате, причем позже они могут быть "воспроизведены" при помощи НООК'а WH_JOURNALPLAYBACK. Это в некотором роде аналог магнитофонной записи сообщений.
WH_KEYBOARD
вставляемая НООК-функция следит за сообщениями клавиатуры
WH_MOUSE
вставляемая НООК-функция следит за сообщениями мыши
WH_MSGFILTER
 
WH_SHELL
 
WH_SYSMSGFILTER
 
lpfn
указатель на непосредственно функцию. Обратите внимание, что если Вы ставите глобальный НООК, то НООК-функция обязательно должна находиться в некоторой DLL!!!
hmod
описатель DLL, в которой находится код функции.
dwThreadId
идентификатор потока, в который вставляется НООК

Подробнее о НООК-функциях сотри справку по Win32API.

Как удалять НООК?

НООК удаляется при помощи функции UnHookWindowsEx.

Пример использования НООК.

Ставим НООК, следящий за мышью (WH_MOUSE). Программа следит за нажатием средней кнопки мыши, и когда она нажимается, делает окно, находящееся непосредственно под указателем, поверх всех остальных (TopMost). Код самой НООК-функции помещен в библиотеку lib2.dll, туда же помещены и функции Start - для установки НООК, и Remove - для удаления НООК.

Файл sticker.dpr
program sticker;

uses windows, messages;


var wc : TWndClassEx;
 MainWnd : THandle;
 Mesg : TMsg;
//экспортируем две функции из библиотеки с НООК'ами
procedure Start; external 'lib2.dll' name 'Start';
procedure Remove; external 'lib2.dll' name 'Remove';

function WindowProc(wnd:HWND; Msg : Integer; Wparam:Wparam; Lparam:Lparam):Lresult; stdcall;
var nCode, ctrlID : word;
Begin
case msg of
wm_destroy :
 Begin
 Remove;//удаляем НООК
 postquitmessage(0); exit;
 Result:=0;
 End;

 else Result:=DefWindowProc(wnd,msg,wparam,lparam);
end;
End;


begin

wc.cbSize:=sizeof(wc);
wc.style:=cs_hredraw or cs_vredraw;
wc.lpfnWndProc:=@WindowProc;
wc.cbClsExtra:=0;
wc.cbWndExtra:=0;
wc.hInstance:=HInstance;
wc.hIcon:=LoadIcon(0,idi_application);
wc.hCursor:=LoadCursor(0,idc_arrow);
wc.hbrBackground:=COLOR_BTNFACE+1;
wc.lpszMenuName:=nil;
wc.lpszClassName:='WndClass1';

RegisterClassEx(wc);


MainWnd:=CreateWindowEx(0,'WndClass1',
'Caption',
ws_overlappedwindow,
cw_usedefault,cw_usedefault,cw_usedefault,cw_usedefault,0,0,
Hinstance,nil);


ShowWindow(MainWnd,CmdShow);

Start;//вставляем НООК

While GetMessage(Mesg,0,0,0) do
 begin
 TranslateMessage(Mesg);
 DispatchMessage(Mesg);
 end;

end.
Файл lib2.dpr
library lib2;


uses
 windows, messages;
var
 pt : TPoint;
 theHook : THandle;

function MouseHook(nCode, wParam, lParam : integer) : Lresult; stdcall;
var
 msg : PMouseHookStruct;
 w : THandle;
 style : integer;

Begin
 if nCode<0 then begin
 result := CallNextHookEx(theHook, nCode, wParam, lParam);
 exit;
 end;
 msg := PMouseHookStruct(lParam);

 case wParam of
 WM_MBUTTONDOWN : pt := msg^.pt;
 WM_MBUTTONUP : begin
 w := WindowFromPoint(pt);
 style := GetWindowLong(w, GWL_EXSTYLE);
 if (style and WS_EX_TOPMOST) <> 0 then begin
 //уже поверх всех - сделать обычным
 ShowWindow(w, sw_hide);
 SetWindowPos(w, HWND_NOTOPMOST, 0,0,0,0, SWP_NOMOVE or SWP_NOSIZE OR SWP_SHOWWINDOW);
 end
 else begin
 //сделать поверх остальных 
 ShowWindow(w, sw_hide);
 SetWindowPos(w, HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE OR SWP_NOSIZE OR SWP_SHOWWINDOW);
 end;

 end;
 end;


 result := CallNextHookEx(theHook, nCode, wParam, lParam);
End;


procedure Start;
begin

 theHook := SetWindowsHookEx(wh_mouse, @mouseHook, hInstance, 0);
 if theHook = 0 then messageBox(0,'Error!','Error!',mb_ok);
end;

procedure Remove;
begin
 UnhookWindowsHookEx(theHook);
end;



exports
Start index 1 name 'Start',
Remove index 2 name 'Remove';


end.

Всё.

Автор: Sergey Stolyarov

Получить ссылку на материал

Категория: Разное | Добавил: Барон (09.12.2011)
Просмотров: 633 | Теги: НООК, Delphi | Рейтинг: 0.0/0
[ Пожертвования для сайта ] [ Пожаловаться на материал ]

Если вам помог материал сайта кликните по оплаченной рекламе размещенной в центре

Поиск
Категории раздела
ActiveX [10]
CORBA и COM [16]
Kol и MCK [23]
WinAPI [28]
Компоненты [27]
Работа с Bluetooth [4]
Железо [8]
Текст [18]
Разное [98]
Королевство Delphi © 2010-2025
Яндекс цитирования