[Delphi] Vlákno+Canvas - pří ztrátě handle vlákno padá.

C++, C#, Visual Basic, Delphi, Perl a ostatní

Moderátor: Moderátoři Živě.cz

Odeslat příspěvekod miking 24. 10. 2017 22:08

Zdravím přátelé, Potřeboval bych pomoct vyřešit docela zásadní problém.
Mám aplikaci, která "fotí okna" jiných aplikací a vytvářím si tak náhledy.
Všecko běží parádně až do doby, kdy se jedna z aplikací zavře. Pak program sice pracuje dal, ale to vlákno už nefotí, nejspíš vůbec nejede -breakpoint vůbec nezabírá, jako by tam program už nechodil).

tady je obrazek jak to vypada když to funguje
http://prntscr.com/h1j92s

Díky všem za přečtení, snad sem to sepsal srozumitelně. Trvalo mi to hodinu určitě to sem dát.
Je to tím, že vůbec nevím kde je chyba a dělá to můj program nepoužitelnej.
Ale rád bych to s Váma nějak vyřešil a proto sem se sem snažil narvat co nejvíce informací v co nejpřehlednější formě.
Díky za Váš čas i zkušenosti a rady.


Zdrojak zjednodusene.
0)mám seznam handle aplikaci který chci skenovat
1)vemu jedno handle
2)udelam screen - tady je asi ta chyba
3)vemu další handle
I když se to okno cizí aplikace zavře, já ho v seznamu pořád mám a nemažu ho. Tím by se mi vznikaly díry v polích a já bych to musel nějak složitě řešit. Radši bych přeskakoval ty neplatný handle, to je jednodušší řešení.
proto tam mam ty if is window exist.



1)vemu jedno handle
1)v proceduře TCaryVlakno.Execute
inc(vlakno.cislo_stolu); //vemem dalsi stul
if vlakno.cislo_stolu>vlakno.celkem_stolu then vlakno.cislo_stolu:=0; //ošetřime preteceni a acnem zase prvnim stolem
if vlakno.cislo_stolu<0 then vlakno.cislo_stolu:=0; // toto je pro prvni pouziti kdyz je tam nahodna hodnota
cislo_obrazku:=vlakno.cislo_stolu; //sem linej to prepisovat

2)udelam screen
2)v proceduře TCaryVlakno.ObnovImage tady je ta chyba někde - něco dělam špatně ale nevim co.

if IsWindow(handle_stolu) then Canavas[cislo] := TCanvas.Create;
if IsWindow(handle_stolu) then Canavas[cislo].Handle := GetWindowDC(handle_stolu);
//ted to tam valim ty obrazky
if IsWindow(handle_stolu) then form2.Canvas.CopyRect(cil,Canavas[cislo],ctverec_kopiruj); //zkopiruju cast obrazku do image
//vymazu promenou
if IsWindow(handle_stolu) then ReleaseDC(handle_stolu, Canavas[cislo].Handle); //nevim
if IsWindow(handle_stolu) then Canavas[cislo].Free;



zdrojaky - original:
Kód: Vybrat vše
type
  TCaryVlakno = class(TThread)
  private
  obrazek_nahled_stolu: TMemoryStream;
  cislo_stolu:integer;
  celkem_stolu:integer;
  ctverec_kopiruj,cil:Trect;
  Muj_Canavas_vlakno:array [0..30] of TCanvas;  // sledovat třicet oken mi stačí bohatě

  protected
    procedure Execute; override;  //tady se nachysta obrazek
   procedure ObnovImage; //a tady se nakreslí
   procedure zjisti_info_listbox;
  end;

procedure TCaryVlakno.Execute; //tak tady to budu připravovat nahled
var
x,y,sidicka:integer;
vaha,hotovo,rozmer_rozdil_posun:integer;
vypis,tisk_pomoc:string;
cislo_obrazku:integer;
breakpoint:integer;
begin
  repeat
Synchronize(vlakno.zjisti_info_listbox); //nějak se to musí dělat synchronizovaně když se pracuje s komponentama


inc(vlakno.cislo_stolu); //vemem dalsi stul
if vlakno.cislo_stolu>vlakno.celkem_stolu then vlakno.cislo_stolu:=0; //ošetřime preteceni a acnem zase prvnim stolem
if vlakno.cislo_stolu<0 then vlakno.cislo_stolu:=0; // toto je pro prvni pouziti kdyz je tam nahodna hodnota
cislo_obrazku:=vlakno.cislo_stolu; //sem linej to prepisovat

if not IsWindow(multi_stoly[cislo_obrazku].handle_stolu) then exit;

sleep(300);

if not IsWindow(multi_stoly[cislo_obrazku].handle_stolu) then
                              begin
                              breakpoint:=cil.Top;
                              breakpoint:=breakpoint+1;
                              cislo_obrazku:=cislo_obrazku+0;  //tady vleti kdyz okno neexistuje, udela to jednou a pak uz ne.
                              end;

if not vlakno.Terminated then Synchronize(ObnovImage);


  until (Terminated = True);
end;  // konec vlakno priprava dat



procedure TCaryVlakno.ObnovImage; //a tady to nakreslim
var
cislo_obrazku:integer;
radek,sloupec,sidicka:integer;
tisk_text:string;
begin
cislo_obrazku:=vlakno.cislo_stolu;

//nastavim barvu ramecku podle podminek
Form2.Canvas.Pen.Color:=CLnavy;
if (multi_stoly[cislo_obrazku].Vaha>0) then Form2.Canvas.Pen.Color:=RGB(255,215,0);//CLYellow;  //zpracovavam stul
//if handle=handlicek then Form2.Canvas.Pen.Color:=RGB(0, 255, 0); //CLgreen;

//Form2.Canvas.Pen.Width:=6;
Form2.Canvas.Pen.Width:=(HUD_vyska div 20)+2;
Form2.Canvas.Brush.Color:=CLwhite;
Form2.Canvas.Rectangle(cil);


//navalim tam obrazek pokud okno existuje. Tady mi to dost padalo když sem zavčel okno.
//narychtuju promenou
if IsWindow(multi_stoly[cislo_obrazku].handle_stolu) then  Muj_Canavas_vlakno[cislo_obrazku] := TCanvas.Create; //vytvorim si svoje platno
if IsWindow(multi_stoly[cislo_obrazku].handle_stolu) then  Muj_Canavas_vlakno[cislo_obrazku].Handle := GetWindowDC(multi_stoly[cislo_obrazku].handle_stolu);   //nalepim svoje platno na aplikaci
//ted to tam valim ty obrazky
if IsWindow(multi_stoly[cislo_obrazku].handle_stolu) then form2.Canvas.CopyRect(cil,Muj_Canavas_vlakno[cislo_obrazku],ctverec_kopiruj); //zkopiruju cast obrazku do image
//vymazu promenou
if IsWindow(multi_stoly[cislo_obrazku].handle_stolu) then ReleaseDC(multi_stoly[cislo_obrazku].handle_stolu, Muj_Canavas_vlakno[cislo_obrazku].Handle); //nevim
if IsWindow(multi_stoly[cislo_obrazku].handle_stolu) then Muj_Canavas_vlakno[cislo_obrazku].Free;
end;
miking
Kolemjdoucí

Odeslat příspěvekod miking 24. 10. 2017 23:36

tak už sem to vymyslel asi
if not IsWindow(multi_stoly[cislo_obrazku].handle_stolu) then exit;
tenhle funguje jinak než sem si myslel. Chtěl sem aby ukončil provaděnou praci a začal znova, ale on vypina běh vlakna. Po vymyazani toho příkazu, to zatim jede stabilně.
miking
Kolemjdoucí


Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 0 návštevníků