Форум: "WinAPI";
Текущий архив: 2005.12.11;
Скачать: [xml.tar.bz2];
ВнизСервис и RegisterHotKey Найти похожие ветки
← →
Angel[Saint] (2005-10-06 07:52) [0]Доброго времени суток!
Пишу сервис и нужно чтобы он отлавливал определенные сочетания клавиш.
Проблема такая - не хочет региться ХотКей. Делаю так:procedure TService.ServiceStart(Sender: TService; var Started: Boolean);
begin
if RegisterHotKey(ServiceThread.Handle, MOD_SHIFT+MOD_CONTROL+VK_F6, MOD_SHIFT+MOD_CONTROL, VK_F6)
then Service.LogMessage("Reg OK",EVENTLOG_INFORMATION_TYPE)
else Service.LogMessage("Reg NOT OK",EVENTLOG_INFORMATION_TYPE)
end;
и на остановку сервиса Унрегю хоткей. Пробовал данный код на обычной форме - все работает прекрасно, а вот в сервисе ни в какую... На каком-то форуме встречал упоминание что такое делалось и работало... что делаю не так? и как нужно делать?
← →
Digitman © (2005-10-06 08:19) [1]Parameters
hWnd
Identifies the window that will receive WM_HOTKEY messages generated by the hot key. If this parameter is NULL, WM_HOTKEY messages are posted to the message queue of the calling thread and must be processed in the message loop.
а ты вместо хэндла окна почему-то подставляешь хэндл трэда, который не имеет ничего общего ни с какими окнами ..
← →
Leonid Troyanovsky © (2005-10-06 08:40) [2]
> Angel[Saint] (06.10.05 07:52)
> Пишу сервис и нужно чтобы он отлавливал определенные сочетания
> клавиш.
Сервису негоже взаимодействовать с десктопом юзера.
Ему нужен клиента, который будет запускаться, скажем,
в startup, и передавать уловленное.
--
Regards, LVT.
← →
Angel[Saint] (2005-10-06 09:16) [3]я пробовал делать иначе... создавал свой класс на основе TForm, делал у него процедуру обработки сообщения и передавал его хендл в процедуру регистрации... это не помогло, регистрация хоткеев также не проходила...
← →
Digitman © (2005-10-06 10:19) [4]
> Angel[Saint] (06.10.05 09:16) [3]
> не помогло, регистрация хоткеев также не проходила
ты справку-то вообще читать собираешься ?
или так и будешь слепо экспериментировать ?
справка-то не для Пушкина писана Борландом, а для тебя)
ведь черным же по белому сказано там:
This function cannot associate a hot key with a window created by another thread
т.е. если сы создал форму в одном код.потоке, а регистрируешь хоткей (с указанием хэндла окна этой формы) совсем в другом код.потоке, то система, как тебя и предупреждает справка, заведомо даст тебе отлуп.
← →
Angel[Saint] (2005-10-06 10:23) [5]тогда остается только глобальный хук... но вот вопрос, хуком отлавливается каждое нажатие клавиши, а как мне нужно определить что нажаты были к примеру Ctrl+Shift+F6
← →
xShadow © (2005-10-06 10:35) [6]
> хуком отлавливается каждое нажатие клавиши, а как мне нужно
> определить что нажаты были к примеру Ctrl+Shift+F6
Кнопка имеет 2 состояния нажата и отжата.
← →
Digitman © (2005-10-06 10:58) [7]
> Angel[Saint] (06.10.05 10:23) [5]
чтой-то вдруг сразу "глобальный хук" ?
достаточно просто соблюсти условия, указанные в справке
форму можно создать только в осн.потоке сервис-процесса, там же следует и зарегистрировать хоткей ... для этого существуют события OnCreate/OnDestroy - их обработчики вызываются как раз в осн.код.потоке сервис-процесса ... любые прочие же события, в т.ч. OnStart, вызываются в отдельном (ассоциированном с конкретным данным сервисом) доп.код.потоке, поэтому визуальную форму там создать не удастся (невизуальную можно, но при этом теряется смысл затеи)
можно поступить иначе - прямо в OnCreate средствами WinAPI создать окно и передать его хендл в регистрирующую хоткей ф-цию ... или вообще никаких окон не создавать, а в регистрирующую хоткей ф-цию в кач-ве хэндла передать 0 ...но тогда в OnExecute в любом случае придется организовывать цикл ожидания/выборки/диспетчеризации/обработки сообщений для того чтобы можно было реагировать в т.ч. и на WM_HOTKEY
← →
Angel[Saint] (2005-10-06 13:10) [8]блин, при создании формы сервис виснет намертво. спасает только снятие его из диспетчера процессов..
вот как делаю....
TMessHook = class (TCustomForm)
private
{ Private declarations }
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure WMHotKey(var Mess:TWMHotKey);message WM_HOTKEY;
end;
TService1 = class(TService)
procedure ServiceCreate(Sender: TObject);
procedure ServiceDestroy(Sender: TObject);
procedure ServiceExecute(Sender: TService);
private
{ Private declarations }
public
function GetServiceController: TServiceController; override;
{ Public declarations }
end;
....
procedure TService1.ServiceCreate(Sender: TObject);
begin
LogMessage("-==!!!CREATE FORM",EVENTLOG_INFORMATION_TYPE);
//MessHook:=TMessHook.CreateNew(Self);
Service1.LogMessage("-==!!!CREATION FORM COMPLETE",EVENTLOG_INFORMATION_TYPE);
// MessHook.Visible:=false;
end;
← →
Angel[Saint] (2005-10-06 13:14) [9]опс, ошибочка...
строчка MessHook:=TMessHook.CreateNew(Self); в коде не закоменчена...
← →
Digitman © (2005-10-06 13:31) [10]procedure TService1.ServiceCreate(Sender: TObject);
begin
LogMessage("-==!!!CREATE FORM",EVENTLOG_INFORMATION_TYPE);
try
MessHook:=TMessHook.CreateNew(Self);
LogMessage("-==!!!CREATION FORM COMPLETE",EVENTLOG_INFORMATION_TYPE);
except
on e:exception do
LogMessage("Вот такая беда приключилась при констуировании формы : " + e.Classname + " " + e.Message, EVENTLOG_INFORMATION_TYPE);
end;
end;
← →
Angel[Saint] (2005-10-06 14:02) [11]-==!!!CREATION FORM COMPLETE в лог попадает (значить форма создается?), но при попытке обратиться к MessHook возникает Access violation....
← →
Digitman © (2005-10-06 14:08) [12]
> -==!!!CREATION FORM COMPLETE в лог попадает (значить форма
> создается?),
ну, надо понимать, так и есть ...
> при попытке обратиться к MessHook возникает Access violation
а где в приведенном тобой коде есть такое обращение ? я не вижу ...
или ты, успешно создав форму в осн.потоке, тут же ринулся управлять ей в дополнительном ?
с этим надо быть крайне осторожным - не всякое обращение к объекту формы потокобезопасно ..
← →
Angel[Saint] (2005-10-06 14:22) [13]
procedure TService1.ServiceCreate(Sender: TObject);
begin
LogMessage("-==!!!CREATE FORM",EVENTLOG_INFORMATION_TYPE);
try
MessHook:=TMessHook.CreateNew(Self);
LogMessage("-==!!!CREATION FORM COMPLETE",EVENTLOG_INFORMATION_TYPE);
except
on e:exception do
LogMessage("Вот такая беда приключилась при констуировании формы : " + e.Classname + " " + e.Message, EVENTLOG_INFORMATION_TYPE);
end;
try
if RegisterHotKey(MessHook.Handle, 700, MOD_SHIFT, VK_F6)
then Service1.LogMessage("-==!!!KEY REG",EVENTLOG_INFORMATION_TYPE)
else Service1.LogMessage("-==!!!KEY NOT REG",EVENTLOG_INFORMATION_TYPE);
except
on e:exception do
LogMessage("Вот такая беда приключилась при регистрации сочетания клавиш : " + e.Classname + " " + e.Message, EVENTLOG_INFORMATION_TYPE);
end;
end;
вот если сделать так, то в лог пишет
Вот такая беда приключилась при констуировании формы : EResNotFound Resource TMessHook not found.
и
Вот такая беда приключилась при регистрации сочетания клавиш : EAccessViolation Access violation at address 0043978B in module "Service.exe". Read of address 00000180.
теперь и форма не создается... может она и не создавалась
← →
Digitman © (2005-10-06 15:53) [14]
> может она и не создавалась
судя по "EResNotFound Resource TMessHook not found" не создавалась.
а ты понимаешь принципиальные различия между CreateNew() и Create() ?
или от балды констр.метод выбрал ?)
← →
Angel[Saint] (2005-10-07 07:33) [15]CreateNew() создает класс фармы без чтения DFM зашитого в экзешник (а мне то как раз и не нужна сама форма, а только хэндл)... я глюканул и создавал форму с помощью Create().... поэтому была ошибка EResNotFound... после использования CreateNew() EResNotFound исчезла... но вот врорая осталась, т.е. к форме по прежнемиу нельзя обратиться - выдается Access violation
← →
Digitman © (2005-10-07 08:03) [16]
> мне то как раз и не нужна сама форма, а только хэндл
да тебе и хэндл даже не нужен ..вчитайся в [1] ..
а если таки нужен, то для этого совершенно необязательно создавать какие-то формы и городить прочий огород) ... достаточно вызвать AllocateHWnd() - одним махом получишь и окно и его хэндл ..
← →
Angel[Saint] (2005-10-07 08:49) [17]когда я описан TMessageHook и там определил метож обработки сообщения (procedure WMHotKey), то это мне понятно...
а с помощью AllocateHWnd()? посмотрел пример с таймером и что-то не врубаюсь... мне же нужно выполнить RegisterHorKey и передать ей хэндл...
а если объявить:
1. procedure WMHotKey(var Mess:TWMHotKey);message WM_HOTKEY;
2. Handle: HWND;
то Handle:=AllocateHWnd(WMHotKey); не проходит
[Error] Unit1.pas(48): Incompatible types: "TMessage" and "TWMHotKey"
← →
Digitman © (2005-10-07 10:12) [18]
> Angel[Saint] (07.10.05 08:49) [17]
ты справку когда-нибудь будешь читать ?)
или так и будешь гадать на кофейной гуще ?)
там ведь даже ПРИМЕР есть использования ф-ции AllocateHWnd() !
TMyService = class(TService)
..
procedure WndProc(var Message: TMessage);
..
end;
procedure TMyService.WndProc(var Message: TMessage);
begin
case Message.Msg of
WM_HOTKEY: ProcessHotKeyMessage(..);
end;
end;
..
procedure TMyService.MyServiceStart(..);
begin
WndHandle:=AllocateHWnd(WndProc);
Started := (WndHandle <> 0) and RegisterHorKey(WndHandle, ..);
end;
procedure TMyService.MyServiceExecute(..);
var
Msg: TMsg;
begin
while not Terminated do
ServiceThread.ProcessRequests(True);
end;
← →
Angel[Saint] (2005-10-07 13:07) [19]я читал, но хотелось чтобы у процедуры параметр был TWMHotKey, а не TMessage... ладно, сойдет...
спасибо за помощь Digitman :)
← →
Leonid Troyanovsky © (2005-10-07 13:11) [20]
> Angel[Saint] (07.10.05 13:07) [19]
> я читал, но хотелось чтобы у процедуры параметр был TWMHotKey,
> а не TMessage... ладно, сойдет...
case Message.Msg of
WM_HOTKEY: ProcessHotKeyMessage(TWMHotKey(Message));
--
Regards, LVT.
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2005.12.11;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.038 c