Wciskanie dwóch hotkeyów na zmianę.

0

Witam.

Jak zrobić w delphi, by dwa hoetkeye były wciskiwane w odstępach np. 100 milisekund?
Chodzi mi o takie coś:

Timer
begin
SendMessage(h, WM_KEYdown, 38, 0);
SendMessage(h, WM_KEYup, 38, 0);
//czekanie 100 milisekund
SendMessage(h, WM_KEYdown, 40, 0);
SendMessage(h, WM_KEYUP, 40, 0);
end;

Chciałbym by nie była to funkcja sleep, bo ona zacina cały program.
Dzięki

0

Uruchamiając ten fragment kodu w odrębnym wątku będziesz mógł wykorzystać sleep.

0

Mam jakieś problemy w tym wątku:

unit Unit8;

interface

uses
  System.Classes, Unit1;


type
  Trunning = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
  end;

implementation

{
  Important: Methods and properties of objects in visual components can only be
  used in a method called using Synchronize, for example,

      Synchronize(UpdateCaption);  

  and UpdateCaption could look like,

    procedure Trunning.UpdateCaption;
    begin
      Form1.Caption := 'Updated in a thread';
    end; 
    
    or 
    
    Synchronize( 
      procedure
      begin
        Form1.Caption := 'Updated in thread via an anonymous method' 
      end
      )
    );

  where an anonymous method is passed.

  Similarly, the developer can call the Queue method with similar parameters as
  above, instead passing another TThread class as the first parameter, putting
  the calling thread in a queue with the other thread.
    
}

{ Trunning }

procedure Trunning.Execute;
begin
  FreeOnTerminate := True;
begin
SendMessage(h, WM_KEYdown, 38, 0);
SendMessage(h, WM_KEYup, 38, 0);
sleep(Form1.SpinEdit9.value);
SendMessage(h, WM_KEYdown, 40, 0);
SendMessage(h, WM_KEYUP, 40, 0);
end;
end;
end.

Sorry, ale nigdy tego nie robiłem wcześniej.

0

Jaaaaaakie problemy. Konkretnie.

0

Jak masz problem z wątkami to użyj zwykłego TTimer - ustaw mu Interval na 100, a swój kod wykorzystujący Sleep wrzuć do zdarzenia OnTimer. Tworzenia i obsługi wątków pobocznych możesz się poczuczyć kiedy indziej.

0

Powiedzmy że to działa. W jaki sposób mogę tym operować w moim programie?

0

Co chcesz konkretnie robić?

0

Wykorzystać procedure Trunning.Execute;.

0

No a co piszą w poradniku? :)

1

Masz złą budowę metody Execute wątku.
Twoje rozwiązanie zapewnia tylko jednokrotne wykonanie kodu wątku. Aby kod był wykonywany cyklicznie musisz umieścić kod w pętli.
tak na szybko, pisząc z głowy, to tak to mogło by wyglądać

procedure Trunning.Execute;
begin
  FreeOnTerminate := true;
  while not self.terminated do
  begin
    SendMessage(h, WM_KEYdown, 38, 0);
    SendMessage(h, WM_KEYup, 38, 0);
    SendMessage(h, WM_KEYdown, 40, 0);
    SendMessage(h, WM_KEYup, 40, 0);
    sleep(100);
  end;
end;

w Twoim kodzie bardzo brzydko wygląda pobieranie w wątku wartości procedury sleep z obiektu klasy SpinEdit tak się nie robi

sleep(Form1.SpinEdit9.value);
0

No i mi to nie działa.

procedure TForm1.CheckBox7Click(Sender: TObject);
var
  Running : TRunning;
begin
if Checkbox6.Checked then
begin
Running.Resume;
end
Else
begin
Running.Suspend;
end;
end;
0

tak chyba lepiej wygląda ..

procedure TForm1.CheckBox7Click(Sender: TObject);
var
  Running: TRunning;
begin
  if Checkbox6.Checked then
  begin
    Running.Resume;
  end
  Else
  begin
    Running.Suspend;
  end;
end;

nie działa .. ale co nie działa ???

0

Nie wiem, po prostu wyskakuje napis "nieprawidłowe dojście".

0

wklej cały kod, bo nikt nie będzie zgadywał czym jest np. klasa albo typ Trunning

0
procedure TForm1.CheckBox7Click(Sender: TObject);
var
  Running: TRunning;
begin
  if Checkbox6.Checked then
  begin
    Running.Resume;
  end
  Else
  begin
    Running.Suspend;
  end;
end;

Running to zmienna lokalna w procedurze, nigdzie nie zainicjowana, ani przez podstawienie, ani metodą Create, ale wywołujesz jej metody Resume, Suspend
nic dziwnego że dostajesz wyjątek
Running jest NIL, nie istnieje ...!!!

0

Okej, zrobione. Jak zatem mogę dodac przerwę pomiędzy wciśnięciami 2 hotkeyów, skoro nie mogę po prostu tak wstawić sleep(form1.spiedit9.value)?

0

Dlaczego nie możesz? ;p

0

do odczytu form1.spiedit9.value użyj metody synchronize z klasy TThread

2
procedure TRunning.Execute();
begin
  FreeOnTerminate := True;
  
  while not Self.Terminated do
  begin
    SendMessage(h, WM_KEYDOWN, 38, 0);
    SendMessage(h, WM_KEYUP, 38, 0);
    
    Synchronize(
      procedure
      begin
        Sleep(Form1.SpinEdit9.Value);
      end
    );
    
    SendMessage(h, WM_KEYDOWN, 40, 0);
    SendMessage(h, WM_KEYUP, 40, 0);
  end;
end;

Pisane z głowy.

1 użytkowników online, w tym zalogowanych: 0, gości: 1