Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > Потоки в формах и службах


Автор: boobie 14.1.2014, 08:04
Добрый день!
Чем отличается поведение потока (простого, объекта класса THread), если его создает не окно, а служба.
Есть такой простенький поток:
Код

unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.SvcMgr, Vcl.Dialogs,
  Vcl.ExtCtrls;

type
  mypot = class(TThread)
  private
    { Private declarations }
  protected
    s,s2:string;
    i:integer;
    procedure Execute; override;
  end;

implementation

uses Unit1;

{ mypot }


procedure mypot.Execute;
begin
  { Place thread code here }
  i:=0;
  while terminated=false do
  begin
  Synchronize(
      procedure
      begin
        inc(i);
        s2:=s2+inttostr(i)+' ';

        if getasynckeystate($8)<>0 then
        begin
        s:=s+'BACKSPACE';
        end;

        if getasynckeystate($0d)<>0 then
        begin
       s:=s+'enter';
        end;
      end
      );
    sleep(100);
  end;
end;

end.



Так вот, если я его запускаю в оконном приложении, то все работает как надо - поток работает, getasynckeystate - перехватывает клавиши, (перехват идет всегда: свернуто приложение или развернуто, в фокусе оно или невидимо).
А если я этот поток запускаю из службы, то перехват не работает. Работает только счетчик
Код

inc(i);
        s2:=s2+inttostr(i)+' ';

Что не так?
Т.е. создаю службу и с параметрами
ServiceType - stWin32
StartType - stAuto
Код

procedure TMySluzhba.ServiceExecute(Sender: TService);
begin

  timer1.Enabled:=true;
  p1:=mypot.Create(true);
  p1.Priority:=tpnormal;
  p1.Start;
  repeat
  sleep(1);
  until (terminated=true);
end;

П.С. В потоке, на самом деле, я использую переменные из MySluzhba, но работает только счетчик, энтер с бэкспэйсом не ловятся. Еще есть таймер, который заканчивает выполнение потока через 100 секунд и записывает все строки в файл.

Автор: Illusion Dolphin 14.1.2014, 08:44
Из доков:
Цитата

Windows NT/2000/XP: The return value is zero for the following cases:

    The current desktop is not the active desktop
    The foreground thread belongs to another process and the desktop does not allow the hook or the journal record.

Автор: kami 14.1.2014, 09:13
Цитата(boobie @  14.1.2014,  08:04 Найти цитируемый пост)
Есть такой простенький поток:

Выбросьте его и юзайте таймер. Зачем нужен поток, если всё, что он выполняет - это вызывает Synchronize?

Автор: boobie 14.1.2014, 10:00
Illusion Dolphin, 
Т.е. если рабочий стол не активен или приоритета не хватает и рабочий стол блокирует?

Так почему с обычным приложением проходит, т.е. я сворачиваю его (или вообще делаю невидимым), набираю в блокноте, а getasynckeystate в потоке все видит... А тут? Это из-за того, что служба стартует вместе с системой? 

Как это обойти? Хуки помогут?

Автор: Illusion Dolphin 14.1.2014, 12:21
Цитата

Так почему с обычным приложением проходит, т.е. я сворачиваю его (или вообще делаю невидимым), набираю в блокноте, а getasynckeystate в потоке все видит... 

Вы всё равно в активном десктопе.

Цитата

Как это обойти? Хуки помогут?

Легально начиная с Vista никак вроде, в любом случае дожно быть приложение в вашем активном десктопе. 

Автор: boobie 14.1.2014, 13:15
Получатся, что голые службы вообще не могут использовать 
Код

getasynckeystate
?
А хуками могут пользоваться?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)