Aplikacja wielowątkowa lub inne rozwiązanie

Aplikacja wielowątkowa lub inne rozwiązanie
SE
  • Rejestracja:prawie 17 lat
  • Ostatnio:ponad 6 lat
0

Witam !

Mam problem z wzajemnym wywoływaniem się procedur.

W poniższym przykładzie są 2 przyciski i 2 Labele, Procedura Button2 zlicza licznikiem Licznik2 do 40 ale zajmuje mu to 4 sek, Button1 zlicza Licznikiem1 ale wywołuje również click-nięcie Buttona2, przez co musi czekać aż miną te 4 sekundy zanim doda do licznika1.

Teraz pytania:

  • czy jest jakiś sposób by wywołana procedura robiła się w tle, lub by program Buttona1 nie czekał aż się skończy wykonywać procedura Buttona2 ?(czytałem na forum coś o wątkach ale sprawa wygląda dość skomplikowanie, może jest jakiś prostszy sposób)
  • zakładając ze pierwszy problem uda się rozwiązać, czy da się zrobić tak by procedura Buttona1 nie wywoływała ponownie procedury Buttona2 dopóki się ona nie zakończy ale robiła swoje czyli dodawała do licznika1, a jak się procedura Button2 skoczy to znowu ja wywoływała ?

Poniżej kod przykładu, przykład jest tylko zobrazowaniem problemu wiec proszę się nie skupiać nad przyciskami, Labelami czy innymi szczegółami.

Kopiuj
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Label1: TLabel;
    Label2: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

  Licznik1, Licznik2 : Integer;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Button2.Click;
  Licznik1 := Licznik1 +1;
  Label1.Caption := InttoStr(Licznik1)
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  a : Integer;
begin
  for a :=1 to 40 do
  begin
    Licznik2 := Licznik2 +1;
    Label2.Caption := InttoStr(Licznik2);
    sleep(100);
    Application.ProcessMessages;
    if Application.Terminated then Break
  end;
end;

end.

Pozdrawiam Szymon

KA
  • Rejestracja:prawie 20 lat
  • Ostatnio:około 4 godziny
  • Lokalizacja:Gorlice
1

Button2 powinien tworzyć wątek. O wątkach poczytaj http://4programmers.net/Delphi/ARtyku%C5%82y/W%C4%85tki a drugi problem to prosta sprawa użyj jakieś zmiennej i sprawdzaj jej stan czyli np if Active = False then Button2.Click;


Nie odpowiadam na PW w sprawie pomocy programistycznej.
Pytania zadawaj na forum, bo:
od tego ono jest ;) | celowo nie zawracasz gitary | przeczyta to więcej osób a więc większe szanse że ktoś pomoże.
0

Button2 powinien tworzyć wątek.

Czyli: Jak przekombinować coś banalnego.

Jest tylko jeden wypadek gdy musisz użyć wątków: Twoja procedura nie wraca a nie masz możliwości jej zmiany.

Podany kod można przebudować tak aby nie wymagał wątków poprzez mądre zarządzanie powrotami oraz bez użycia sleep który właśnie powoduje że ta procedura nie wraca.
Jeżeli pytacz by powiedział co chce osiągnąć w rzeczywistości, to może znalazłbym jakieś konkretne rozwiązanie, bo na tak wymyślnych nazwach jak Button1 czy Licznik1 bardzo łatwo się nie myśli.

Widzę @kAzek ,że jak ja napisałem klasę serwera na Synapse w 100 liniach z metodą LoopStep którą się wykonywało 'co łaska' z głównego loopa i która robiła potrzebne rzeczy w stylu przyjmowanie klientów etc., tak ty byś to napisał w 200 liniach z wątkiem (a może oddzielny na dodawanie, rozłączanie klientów, odbieranie i wysyłanie?) oraz z masą blokad i innych porąbanych rzeczy które obniżałyby wydajność na rzecz bardziej skomplikowanego rozwiązania.

babubabu
Uhhh ja miałem zamiar coś takiego napisać...
KA
  • Rejestracja:prawie 20 lat
  • Ostatnio:około 4 godziny
  • Lokalizacja:Gorlice
0
szymon-ek napisał(a):

W poniższym przykładzie są 2 przyciski i 2 Labele, Procedura Button2 zlicza licznikiem Licznik2 do 40 ale zajmuje mu to 4 sek, Button1 zlicza Licznikiem1 ale wywołuje również click-nięcie Buttona2, przez co musi czekać aż miną te 4 sekundy zanim doda do licznika1.

Teraz pytania:

  • czy jest jakiś sposób by wywołana procedura robiła się w tle, lub by program Buttona1 nie czekał aż się skończy wykonywać procedura Buttona2 ?(czytałem na forum coś o wątkach ale sprawa wygląda dość skomplikowanie, może jest jakiś prostszy sposób)
  • zakładając ze pierwszy problem uda się rozwiązać, czy da się zrobić tak by procedura Buttona1 nie wywoływała ponownie procedury Buttona2 dopóki się ona nie zakończy ale robiła swoje czyli dodawała do licznika1, a jak się procedura Button2 skoczy to znowu ja wywoływała ?
efgegs napisał(a):

Button2 powinien tworzyć wątek.

Czyli: Jak przekombinować coś banalnego.

Jest tylko jeden wypadek gdy musisz użyć wątków: Twoja procedura nie wraca a nie masz możliwości jej zmiany.

Podany kod można przebudować tak aby nie wymagał wątków poprzez mądre zarządzanie powrotami oraz bez użycia sleep który właśnie powoduje że ta procedura nie wraca.
Jeżeli pytacz by powiedział co chce osiągnąć w rzeczywistości, to może znalazłbym jakieś konkretne rozwiązanie, bo na tak wymyślnych nazwach jak Button1 czy Licznik1 bardzo łatwo się nie myśli.

To możne znasz inny sposób aby program jednocześnie wykonywał się w 2 miejscach? Ten program jest przykładem czytaj ze zrozumieniem.

Co do reszty szkoda odpisywać geniuszu.


Nie odpowiadam na PW w sprawie pomocy programistycznej.
Pytania zadawaj na forum, bo:
od tego ono jest ;) | celowo nie zawracasz gitary | przeczyta to więcej osób a więc większe szanse że ktoś pomoże.
SE
  • Rejestracja:prawie 17 lat
  • Ostatnio:ponad 6 lat
0

Witam !

Dziękuje za szybka odpowiedź.

Co do programu, to trochę więcej informacji o realnym problemie dla efgegs żeby łatwiej się myślało ;-)

Button 2 to długa procedura robienia testów, zajmuje więcej niż 2 minuty, woła ze 30 innych procedur liczących, komunikacyjnych się po portach USB, RS232 i wszystkim co można sobie wymyślić. Ta procedura wywoływana jest buttonem2, i spoko , robię Enable := False i nie da się go drugi raz kliknąć, to samo mogę użyć do zapobiegania drugiemu uruchomieniu z zewnątrz. Procedura ma w sobie jakieś sleepy szczególnie w protokołach komunikacyjnych ale nie wiele się z nimi da zrobić, a nawet jeśli to strasznie dużo pracy by to zajęło i testów po tym.

Button1 to symulacja zdarzenia wywoływanego przez rozkaz z portu rs232, ma on symulować tak jak by użytkownik zdalnie naciskał Button2, ale nie morze czkać aż się zakończy Button2 bo w międzyczasie ten sam port jest wykorzystywany przez procedury z buttona2.

Tak wiec jak na razie spróbuje pokombinować w kierunku odpowiedzi kAzek i zobaczymy co się uda zrobić ;-)

Jeśli ktoś ma jakieś prostsze rozwiązania chętnie posłucham ;-)

Pozdrawiam Szymon

edytowany 1x, ostatnio: szymon-ek
0

Jedź na wątkach, nie po to się ludzkość parę dekad męczyła by stworzyć systemy zaprojektowane pod pracę wielowątkową by się teraz uwsteczniać i robić wsadowo.

Pamiętaj tylko żeby użyć synchronizacji tam gdzie trzeba (głównie przy zmianach w GUI, ale też tam gdzie dwa wątki grzebią w jednej zmiennej).

0

To możne znasz inny sposób aby program jednocześnie wykonywał się w 2 miejscach?

Problem w tym że tutaj nie ma takiej potrzeby. Tylko ty jej szukasz.

Ten program jest przykładem czytaj ze zrozumieniem.

Jeżeli dla ciebie sleep jest dobrym przykładem funkcji blokującej, to gratuluje. To jest raczej tworzenie sztucznego problemu.

Co do reszty szkoda odpisywać geniuszu.

Owym 'geniuszem' (tj. domniemanym idiotą) jesteś Ty, mój 'drogi' rozmówco. Nie mam zamiaru pozwalać sobie dmuchać w kaszę. Ja oczekuję rozmowy na poziomie, bez twoich kryptowyzwisk.

Button 2 to długa procedura robienia testów, zajmuje więcej niż 2 minuty, woła ze 30 innych procedur liczących, komunikacyjnych się po portach USB, RS232 i wszystkim co można sobie wymyślić.

No to to jest przykład funkcji blokującej. Do wątku.
Mimo że zapewne można to zaprogramować bez wątków to tutaj wątki się przydadzą żeby nie tracić liniowości tego kodu.

morze

Srsly?!

ma on symulować tak jak by użytkownik zdalnie naciskał Button2, ale nie morze może czkać aż się zakończy Button2 bo w międzyczasie ten sam port jest wykorzystywany przez procedury z buttona2.

No tego to nie rozumiem. Chcesz mieć parę testów wykonywanych na raz? Jakieś 'naciskanie zdalne', wtf. Chcesz dwa razy wykonywać to co sam stwierdziłeś że nie możesz robić bo 'port jest w użyciu'. Jakaś magia.

nie po to się ludzkość parę dekad męczyła by stworzyć systemy zaprojektowane pod pracę wielowątkową by się teraz uwsteczniać i robić wsadowo.

Systemy zaprojektowane pod pracę wielowątkową wymagają blokad i innych pierdół.
W przypadku prostych zadań łatwiej jest wykorzystać wsadowość. Tak można robić gdy np. masz jedną dużą procedurę a reszta to jakieś mniejsze obsługi GUI, a jest to częsty wariant.

KA
  • Rejestracja:prawie 20 lat
  • Ostatnio:około 4 godziny
  • Lokalizacja:Gorlice
0
szymon-ek napisał(a):

Teraz pytania:

  • czy jest jakiś sposób by wywołana procedura robiła się w tle, lub by program Buttona1 nie czekał aż się skończy wykonywać procedura Buttona2 ?

No jasne że nie ma potrzeby a to jak miało być zrealizowane? Musi być wątek skoro coś ma się wykonywać w tle.

Co do owych jak to określiłeś "kryptowyzwisk" sam się pochwaliłeś jaki to świetny projekt zrealizowałeś tylko nie wiem kogo to obchodzi i co on ma wspólnego z tematem a tym bardziej skąd zgadywanki w jaki sposób ja bym go napisał więc to raczej wymagając pewnego poziomu rozmowy sam go zachowaj.


Nie odpowiadam na PW w sprawie pomocy programistycznej.
Pytania zadawaj na forum, bo:
od tego ono jest ;) | celowo nie zawracasz gitary | przeczyta to więcej osób a więc większe szanse że ktoś pomoże.
0

tylko nie wiem kogo to obchodzi i co on ma wspólnego z tematem

Z tematem ma tyle wspólnego że nie wszędzie gdzie trzeba robić parę rzeczy na raz potrzebne jest użycie wątków. Widać że masz problem ze zrozumieniem morału mojego przykładu.

a tym bardziej skąd zgadywanki w jaki sposób ja bym go napisał

Cóż, jak widać masz problem ze zrozumieniem mojego przykładu który ma na celu pokazanie że wszędzie (nawet tam gdzie to jest niepotrzebne) chcesz zastosować wątki.

Co do owych jak to określiłeś "kryptowyzwisk"

Nie odwołujesz się do tego pojęcia a jedynie usiłujesz uczepić się tego co pisałem.

raczej wymagając pewnego poziomu rozmowy sam go zachowaj.

Pokazuj mi jak nie zachowuje poziomu wypowiedzi waląc jedno superfajnedługiemiłeiprzyjemne zdanie które nawet ma kropkę na końcu ale żadnej interpunkcji, czy większego składu.

Musi być wątek skoro coś ma się wykonywać w tle.

Czyżbym nie mówił o wsadowości? Można wykonywać rzeczy w tle bez wątków jeżeli się umie, tylko że tutaj zakładam że się to nie opłaca bo ta procedura 'testująca' zapewne jest bardzo liniowa i ciężko by się ją rozbijało.
W ogóle to pojęcie 'w tle' to pojęcie bardzo zwodnicze, bo jest coś takiego jak task switching, i szansa ze akurat będą się wykonywać oba wątki twojego programu jest bardzo niska. Więc w ogóle mówienie o tym jest bez sensu, zwłaszcza że jeszcze są komputery z jednym rdzeniem. Więc wiele wątków jest zazwyczaj praktycznie tym samym co wsadowość tylko że należy pamiętać o blokadach i innych wtfach.

KA
  • Rejestracja:prawie 20 lat
  • Ostatnio:około 4 godziny
  • Lokalizacja:Gorlice
0

Widzę ze dyskusja z Tobą nie ma sensu bo obrastasz w piórka i wydaje Ci się, że wszystko wiesz najlepiej. Przypominam że do tej pory nie podałeś autorowi tematu lepszego (czyli poza użyciem wątku) sposobu zrealizowania tego aby kod, który w przykładzie jest pod przyciskiem button2 był wykonywany w tle nawet gdyby to była bardzo długo wykonująca się procedura a jednocześnie można było w dowolnym momencie kliknąć na przycisk button1 tak aby wykonał się jego kod. Jak już krytykujesz rób to konstruktywnie czekam na rozwiązanie.


Nie odpowiadam na PW w sprawie pomocy programistycznej.
Pytania zadawaj na forum, bo:
od tego ono jest ;) | celowo nie zawracasz gitary | przeczyta to więcej osób a więc większe szanse że ktoś pomoże.
ŁF
Moderator
  • Rejestracja:ponad 22 lata
  • Ostatnio:około 12 godzin
3

grzeczniej, bo was porozsadzam


0

Widzę ze dyskusja z Tobą nie ma sensu bo obrastasz w piórka i wydaje Ci się, że wszystko wiesz najlepiej.

Widzę że nie jestem odosobniony w pleceniu przypuszczeń które to tak krytykujesz, hipokryto?

Przypominam że do tej pory nie podałeś autorowi tematu lepszego (czyli poza użyciem wątku) sposobu zrealizowania tego aby kod, który w przykładzie jest pod przyciskiem button2 był wykonywany w tle nawet gdyby to była bardzo długo wykonująca się procedura

I nigdy nie mówiłem że to zrobię. Doskonale wiem że jeżeli procedura jest blokująca to nie ma po co się bawić, bo można kombinować dla sportu, ale po co. Natomiast w przykładzie procedura blokująca sleep wyłącznie sztucznie blokuje.

Jak już krytykujesz rób to konstruktywnie czekam na rozwiązanie.

Krytykuję, bo w przykładzie wcale nie ma potrzeby używania wątku i ty doskonale o tym wiesz. Bah, można by napisać kod który spełniałby podane przez ciebie założenia, ale co z tego? Nie będę pisać kodu aby tobie coś pokazać bo nie jestem na tej fazie rozwoju. Można, ale to nie jest opłacalne gdy pytacz wyjaśnił po co w rzeczywistości mu ten kod i że jest on raczej blokujący (rzeczywistego kodu brak, więc brak realnej oceny), co wyraźnie powiedziałem, natomiast ty wciąż pytasz o pytania na które już odpowiedziałem. Wcześniej udzieliłem wyraźnych odpowiedzi na pytania które wciąż zadajesz. Zmień zestaw, bo na ten odpowiedziałem już parokrotnie. No chyba że twoje zarzuty kończą się na urojonych. Natomiast moje stanowisko jest jasne: Pierwszy kod nie był blokujący, można go przerobić bez wątków natomiast ty od razu odsyłasz każdego do wątków co jest bez sensu. Zapewne kod pytacza również nie wymagałby wątków gdyby był odpowiednio napisany. Ale zazwyczaj kod łatwiej jest robić liniowo, stąd te założenie blokowania.

grzeczniej, bo was porozsadzam

Cóż, na to można co najwyżej odpowiedzieć: Idź trzymaj waszą bazę danych żeby się (znowu) nie wysypała a nie bawisz się w szeryfa bez rewolwera.

ŁF
o, zobacz, mam dwa naboje. i rewolwer.
SE
  • Rejestracja:prawie 17 lat
  • Ostatnio:ponad 6 lat
0

Witam Ponownie !

Panowie po pierwsze się nie kłóćcie bo nie o to chodzi. Obu dziękuje za pomoc i odmienne punkty widzenia.

Co do mojej drogi to wybrałem wątki bo linki kAzek były proste łopatologiczne i czytelne, bez 100 linij kodu do zrobienia jednej rzeczy. Tak wiec kod wynikowy zamieszczam poniżej, działa ale miałem jeden problem, ale to tym później.

Co do sposobu efgegs, to jedyny komentarz jaki mi się nasuwa to to, by słowa poprzeć przykładami, samo rozpisywanie może coś daje zawodowcom, ale mnie zielonemu jak szczypiorek na wiosnę nie wiele mówi. Dlatego też zamieszczam kod wynikowy nie po to by się pochwalić, tylko by ułatwić życie innym użytkownikom tego forum bo nie ma jak to stare dobre CTRL C i CTRL V ;-))) Tak wiec przykłady na działanie bez wątków mile widziane.

Co do problemu, to odpaliłem kod poniżej i ni z gruch ni z pietruchy po naciśnięciu Buttona2 program doliczył do 5 i zwis czy co nie wiem bo button1 chodził ok. Dwie kompilacje potem znowu doliczył do 37 i koniec ???? Teraz nie potrafię już powtórzyć tego problemu, wiec nie wiem czy źle się skompilowało, błąd windy czy promieniowanie kosmiczne, niemniej teraz działa OK.

Obiecany kod:

Kopiuj
 
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Label1: TLabel;
    Label2: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
type
  TTest = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
  end;
 
var
  Form1: TForm1;
 
  Licznik1, Licznik2 : Integer;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  if Button2.Enabled = True Then Button2.Click;
  Licznik1 := Licznik1 +1;
  Label1.Caption := InttoStr(Licznik1)
end;
 
procedure TForm1.Button2Click(Sender: TObject);
var
  Test : TTest;
begin
  Button2.Enabled := False;
  Test := TTest.Create(False);
end;
 
procedure TTest.Execute;
var
  a : Integer;
begin
  FreeOnTerminate := True; // zakoncz watek po zaknczeniu tej procedury
  for a :=1 to 40 do
  begin
    Licznik2 := Licznik2 +1;
    Form1.Label2.Caption := InttoStr(Licznik2);
    sleep(100);
    Application.ProcessMessages;
    if Application.Terminated then Break
  end;
  Form1.Button2.Enabled := True;
end;
 
end.
 

Pozdrawiam i dziękuje za pomoc

Szymon

babubabu
Ten kod jest źle napisany.
babubabu
  • Rejestracja:około 13 lat
  • Ostatnio:2 miesiące
  • Lokalizacja:Łódź
  • Postów:648
0
Kopiuj
type
  TTest = class(TThread)
  private
    { Private declarations }
    procedure EnableButton;
    procedure UpdateCaption;
  protected
    procedure Execute; override;
  end;

procedure TTest.UpdateCaption;
begin
  Form1.Label2.Caption := InttoStr(Licznik2);  
end;

procedure TTest.EnableButton;
begin
  Form1.Button2.Enabled := True;  
end;

procedure TTest.Execute;
var
  a : Integer;
begin
  FreeOnTerminate := True; // zakoncz watek po zaknczeniu tej procedury
  for a :=1 to 40 do
  begin
    Licznik2 := Licznik2 +1;
    Sleep(100); // WTF?!?!?!?
    Synchronize(@UpdateCaption);
  end;
  Synchronize(@EnableButton);
end;

Poczytaj o synchronizacji kodu. Jeśli zmiennej Licznik2 używasz tylko w wątku to przenieś ją jako pole klasy TTest. A jeśli jeszcze gdzieś indziej w kodzie to poczytaj o CriticalSection.

edytowany 2x, ostatnio: babubabu
WL
Będę zgadywał; to Sleep jest po to, aby zmienił się Caption - szymon-ek ma nadzieję, że to się uda, bo inaczej kod wykonywał się tak szybko że user nie był w stanie zauważyć zmiany tekstu w Caption. Metoda UpdateCaption powinna mieć jeszcze dołożone wywołanie Application.ProcessMessages, ale! Owo zsynchronizowane (z głównym wątkiem aplikacji) wywołanie UpdateCaption nie powinno być wołane po każdej iteracji pętli, tylko co n powtórzeń. Inaczej może się okazać, że cały zysk na wątku poszedł w gwizdek, bo aktualizacja UI (tu zmiana tekstu w Caption) jest czasochłonna...
babubabu
no masz rację coś w stylu if a mod 5 = 0 then Synchronize(@UpdateCaption);
vpiotr
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 3 lata
0
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:3 miesiące
0

Patrząc na ten kod wydaje mi się że tu zupełnie nie są potrzebne wątki. Zamiast tagów można użyć trzy zmienne.

Kopiuj
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    Button1: TButton;
    Button2: TButton;
    Label1: TLabel;
    Label2: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
  if Button2.Enabled then Button2.Click;
  Label1.Tag:=Label1.Tag+1;
  Label1.Caption:=IntToStr(Label1.Tag);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Button2.Enabled:=false;
  Timer1.Enabled:=true;
  Timer1.Tag:=Timer1.Tag+40;
  Timer1.Interval:=100; // to można ustalić we wlaciwociach
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if Timer1.Tag>0 then
  begin
    Timer1.Tag:=Timer1.Tag-1;
    Label2.Tag:=Label2.Tag+1;
    Label2.Caption:=IntToStr(Label2.Tag);
  end
  else
  begin
    Timer1.Enabled:=false;
    Button2.Enabled:=true;
  end;
end;

end.

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
SE
  • Rejestracja:prawie 17 lat
  • Ostatnio:ponad 6 lat
0

Witam Ponownie

Nawiązując do pomysłów bez użycia wątków znalazłem sposób jaki daje jakieś rezultaty ale nie rozwiązuje wszystkich problemów:

Kopiuj
SendMessage(Handle, WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(ColorButton3.Handle),BN_CLICKED), ColorButton3.Handle);

Ta linia powoduje wywołanie przycisku ColorButton3 tak jak by był naciśnięty przez myszkę, ale z jakiegoś powodu przycisk tak naciśnięty zachowuje się inaczej niż rzeczywiście nacieknięty przez mysz w aplikacji przez operatora.

Jak już pisałem celem tej zabawy jest zdalne naciśniecie przycisku po tym jak z portu szeregowego przyjdzie komenda naciśnij przycisk, przycisk jest naciskany ale kolejna komenda ulokowana już w ColorButton3 zadaje pytanie przez ten sam port szeregowy, i czeka na odpowiedz, i o ile zapytanie wychodzi przez port to odpowiedz zostaje w buforze aż do chwili dopóki alkilacja nie wywoła jakiegoś systemowego MessageBox i ten nie zostanie kliknięty.

Tak wiec proste pytanie czy możliwe jest całkowite za-symulowanie kliknięcia ColorButton3 tak jak by przycisnął to operator ?? lub jaka jest przyczyna ze ComDataPacket1Packet nie odbiera danych po tym jak wywoła SendMessage uruchamiającego ColorButton3 aż do naciśnięcia OK luk czegokolwiek na najbliższym pojawieniu się MessageBox ?? mimo ze port wykonuje transmisje wychodzącą ?

Pozdrawiam
Szymon

_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:3 miesiące
0

ColorButton3.Click;


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
SE
  • Rejestracja:prawie 17 lat
  • Ostatnio:ponad 6 lat
0

No niestety zupełnie nie o to chodzi, dodam ze PostMessage też próbowałem z tm samym skutkiem.

w przypadku ColorButton1.Click jest jeszcze gorzej, bo ComDataPacket1Packet czeka na wykonanie ColorButton1 (ponad 2 minuty) zanim wykona resztę własnego kodu, a tu chodzi o to by ComDataPacket1Packet odebrała pakiet zanalizowała i wykonała naciśniecie ColorButton1.Click i zakończyła się. Procedura ColorButton1 która to ponownie zadaje pytanie przez port i oczekuje kolejnej odpowiedzi, analizy wykonanej ComDataPacket1Packet i która tego nie robi bo z jakiegoś powodu wisi, albo czeka na coś, nie mam pojęcia na co.

Pozdrawiam
Szymon

_13th_Dragon
Jeżeli pod ColorButton1 coś wykonuje się 2 minuty to zrób tam odpalenie wątku.
SE
  • Rejestracja:prawie 17 lat
  • Ostatnio:ponad 6 lat
2

Witam !

Jednak zamiana Send na Post zmieniła sytuacje, i port szeregowy nie czeka już na nic tylko się wykonuje ;-)

Kopiuj
PostMessage (Handle, WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(ColorButton3.Handle),BN_CLICKED), ColorButton3.Handle);

Wim ze metoda pokręcona, podobnie jak strzelać z armaty do muchy (nie mylić z Anną M ;-) ) ale działa symuluje ładnie naciśniecie myszki i to to chodziło.

Pozdrawiam i dziękuje za pomoc.
Szymon

dodanie znaczników <code class="delphi"> - fp

edytowany 1x, ostatnio: flowCRANE
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)