@grzegorz_so: z typami prostymi nie ma problemu, bo ich odczyt lub modyfikacja nie musi być synchronizowana. Poza tym, coś zbyt pesymistycznie podchodzisz do tego problemu :]
Z tego co widzę na zrzucie, dane przechowywane są w polu typu TEdit
, więc za pomocą funkcji Win32 API można się do nich bez problemu dobrać. Wystarczy znaleźć uchwyt okna, a następnie uchwyt kontrolki. Jeśli dobrze pamiętam, potem pozostanie jedynie obsługa komunikatu WM_GETTEXT
w celu pobrania tekstu.
Oczywiście można do tego wykorzystać standardowy timer, ale w nieco niestandardowy sposób. Przyda się ustawić mu Interval
na 1
, aby uzyskać zawsze minimum - czyli mniej więcej 16ms
. W zdarzeniu OnTimer
pobrać tekst z tego cudzego programu, wykonać swój kod. Aby timer poczekał sekundę i przy tym nie zamroził aplikacji, zdarzenie OnTimer
musi być wykonywane cyklicznie, bez opóźnień. Czyli trzeba sprawić, aby to zdarzenie nadal wywoływane było co te 16ms
, ale żeby przez ~60 wywołań (co da mniej więcej sekundę) żaden kod nie był wykonywany.
Mały przyklad:
const
WAIT_MS = 1000;
type
TMainForm = class(TForm)
{..}
private
FTimer: TTimer;
FWait: Boolean;
FWaitTo: Integer;
{..}
end;
constructor TMainForm.FormCreate(Sender: TObject);
begin
FWait := False;
end;
procedure TMainForm.FTimerTimer(Sender: TObject);
var
LTime, LValue: Integer;
begin
if FWait then
FWait := GetTickCount() <= FWaitTo;
if not FWait then
begin
LValue := GetValueFromExternalApp();
if LValue < SpinEdit.Value then
begin
DoMyStuff();
FWait := True;
FWaitTo := GetTickCount() + WAIT_MS;
end;
end;
end;
FWait
to zmienna logiczna, określająca czy timer ma oczekiwać, czy może działać normalnie. FWaitTo
zawiera licznik ticków, do którego timer ma nic nie robić. WAIT_MS
zawiera liczbę milisekund oczekiwania timera.
I teraz zdarzenie OnTimer
. Najpierw sprawdzane jest czy timer ma oczekiwać - domyślnie pole FWait
zawiera False
, więc timer nie znajduje się w stanie oczekiwania. Następnie sprawdzane jest czy timer oczekuje - jeśli tak to dalszy kod jest pomijany. Jeśli nie oczekuje to pobierana jest liczba z zewnętrznego programu, po czym jest porównywana z wartością ze SpinEdit
. Jeśli jest mniejsza to wykonywany jest odpowiedni kod (w miejscu hipotetycznej metody DoMyStuff
), a na koniec zostaje ustawiona flaga oczekiwania oraz stan licznika ticków na bieżący plus określona liczba milisekund.
W kolejnych wywołaniach tego zdarzenia, sprawdzane będzie czy timer ma czekać czy nie. Jeśli timer znajduje się w stanie oczekiwania to sprawdzane jest, czy już upłynął ten czas i jeśli tak - flaga zostaje ustawiona na False
. A jeśli nie upłynął to nadal zawiera wartość True
, dzięki czemu drugi warunek nie zostanie spełniony i timer nic więcej nie wykona.
Pisane z głowy, ale powinno działać.