Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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
2-1132769705
Plotnick
2005-11-23 21:15
2005.12.11
FormatFloat


4-1129201201
Виталий11111
2005-10-13 15:00
2005.12.11
Перехват сообщений от мыши


2-1132671744
Vladd
2005-11-22 18:02
2005.12.11
TWebBrowser


11-1113674934
Dot
2005-04-16 22:08
2005.12.11
VCL, KOLForm &amp; uses mirror


1-1131994208
Sam Stone
2005-11-14 21:50
2005.12.11
Метод при наследовании





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский