| Autor |
Beitrag |
Martin1966
      
Beiträge: 1068
Win 2000, Win XP
Delphi 7, Delphi 2005
|
Verfasst: Mi 15.06.05 11:12
hallo!
ich habe da ein kleines problem was ich nicht lösen kann. ich habe ein delphi projekt mit einem hauptform (Unit mainform.pas) und einen zweiten Form (threadform.pas). das hauptform besitzt nur einen button. das zweite fenster besitzt nur ein timage mit einem bild.
über den button des hauptfesters starte ich einen Thread, dieser ist in threadform.pas implementiert, der nichts anderes macht als das zweite Form mit showmodal anzuzeigen.
klicke ich öfters auf den button so wird auch mehrmals das zweite form angezeigt. und jetzt kommt das problem: wenn ich z. B. drei forms geöffnet habe, diese dann hin und her verschiebe und diese sich überlagern so kommt es vor, dass das Image nicht mehr neugezeichnet wird. Wie kommt das? Ich hab auch schon das ShowModal durch Show ersetzt aber das hat auch nicht geholfen.
Hier mal der Sourcecode... vielleicht könnt ihr mir dann besser helfen.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34:
| unit MainForm;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private public end;
var Form1: TForm1;
implementation
{$R *.dfm}
Uses ThreadForm;
procedure TForm1.Button1Click(Sender: TObject); begin TThreadTest.Create (False); end;
end. |
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33:
| unit ThreadForm;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls;
type TThreadTest = Class (TThread) Public Procedure Execute; override; End;
TForm2 = class(TForm) Image1: TImage; private public end;
implementation
{$R *.dfm}
Procedure TThreadTest.Execute; Begin With TForm2.Create (nil) Do ShowModal; End;
end. |
vielen dank schon mal für die hilfe!!!
lg martin
|
|
maxk
      
Beiträge: 1696
Erhaltene Danke: 1
Win XP, Debian Lenny
Delphi 6 Personal
|
Verfasst: Mi 15.06.05 13:00
Martin1966 hat folgendes geschrieben: | | klicke ich öfters auf den button so wird auch mehrmals das zweite form angezeigt. und jetzt kommt das problem: wenn ich z. B. drei forms geöffnet habe, diese dann hin und her verschiebe und diese sich überlagern so kommt es vor, dass das Image nicht mehr neugezeichnet wird. |
Hast du das Problem immer erst bei drei Fenster, oder ist das Problem auch bei einem Fenster schon erkennbar? Eine richtige Lösung kann ich dir nicht vorschlagen, aber vllt. kann ich dir ja helfen die Ursache des Problems einzugrenzen: Pack mal auf das Form des Threads noch einen Buttons, der ein Invalidate; bzw. Image1.Invalidate; (falls es das gibt) ausführt, wenn es dann immernoch nicht geht, probiere mal ein Repaint; (für beide). Ich vermute, dass die Windowsnachricht nicht richtig an das Form übertragen wird.
Gruß,
maxk
_________________ Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
|
|
Martin1966 
      
Beiträge: 1068
Win 2000, Win XP
Delphi 7, Delphi 2005
|
Verfasst: Mi 15.06.05 13:43
hallo!
danke für deine antwort.
maxk hat folgendes geschrieben: | | Hast du das Problem immer erst bei drei Fenster, oder ist das Problem auch bei einem Fenster schon erkennbar? |
Das Problem ist ab zwei Fenstern zu erkennen. Bei einem Fenster geht alles ohne Probleme. Nur soblad sich zwei oder mehrere Fenster (ThreadForm.pas) gegenseitig überlagern werden diese nicht neugezeichnet.
maxk hat folgendes geschrieben: | | Pack mal auf das Form des Threads noch einen Buttons, der ein Invalidate; bzw. Image1.Invalidate; (falls es das gibt) ausführt, wenn es dann immernoch nicht geht, probiere mal ein Repaint; (für beide). |
Das habe ich mal ausprobiert. Alle Varianten (jeweils die Aufrufe invalidate und repaint jeweils bei Form und Image) zeigen keine Wirkung.
Hm... weiß einfach keinen Rat mehr...
noch mal danke für deine hilfe!!
lg Martin
|
|
Lossy eX
      
Beiträge: 1048
Erhaltene Danke: 4
|
Verfasst: Mi 15.06.05 14:35
Doch sie werden wahrscheinlich neu gezeichnet. Zu mindest wird es versucht. Aber ich glaube, dass deine Bilder kaputt sind. Ich habe derzeit ein sehr sehr (erschreckend) ähnliches Problem. Allerdings kommen bei mir die Fenster aus einer DLL. Habe es aber auch ohne DLLs ausprobiert.
Ich vermute, dass es daran liegt, dass der erstellte Thread und der VCL Thread auf ein und das selbe Applicationobjekt zugreifen. Beide arbeiten zur gleichen Zeit die einkommenden Messages ab und zeichnen dann neu. Das kann dazu führen, dass beide gleichzeitig neuzeichnen oder die gleiche message abarbeiten. Und anscheind geht dabei dann das Bild kaputt. (warum auch imer).
Eine Lösung dafür suche ich derzeit allerdings auch noch. Das einfachste ist du startest die Fenster aus dem Haupthread heraus und rufst lediglich Show auf. Alle anderen Lösungen dürften wohl ein wenig verzwickter werden, da es anscheind so ist, dass jedes Fenster dann anscheinend ein eigenes Applicationobjekt benötigt.
_________________ Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
|
|
maxk
      
Beiträge: 1696
Erhaltene Danke: 1
Win XP, Debian Lenny
Delphi 6 Personal
|
Verfasst: Mi 15.06.05 21:44
Martin1966 hat folgendes geschrieben: | maxk hat folgendes geschrieben: | | Pack mal auf das Form des Threads noch einen Buttons, der ein Invalidate; bzw. Image1.Invalidate; (falls es das gibt) ausführt, wenn es dann immernoch nicht geht, probiere mal ein Repaint; (für beide). |
Das habe ich mal ausprobiert. Alle Varianten (jeweils die Aufrufe invalidate und repaint jeweils bei Form und Image) zeigen keine Wirkung. |
Von Lossy eX inspiriert könntest du mal versuchen den Aufruf in einer CriticalSection zu machen, dann kann man Probleme beim gleichzeitigen Zugriff auf das Applicationobjekt ausschließen.
_________________ Ein Computer wird das tun, was Du programmierst - nicht das, was Du willst.
|
|
Martin1966 
      
Beiträge: 1068
Win 2000, Win XP
Delphi 7, Delphi 2005
|
Verfasst: Mo 20.06.05 16:14
Hallo!
danke für eure hilfe!!!
Aber worum soll ich denn dann die Criticalsection packen? denn schließlich passiert dieser "fehler" ja schon beim simplen verschieben von Fenstern? ich kann ja schlecht auf das verschieben von fentern reagieren und dann in invalidate in einer criticalsection aufrufen.
ist das ein fehler in der vcl? denn schließlich mache ich ja nichts anderes als zwei threads zu starten in denen ein modales fenster geöffent wird. da kann man doch kaum was falsch machen.
lg Martin
|
|
Lossy eX
      
Beiträge: 1048
Erhaltene Danke: 4
|
Verfasst: Mo 20.06.05 16:55
Weder die VCL noch GDI sind wohl Threadsave. Das hat zur Folge, dass wenn zwei Threads jeweils ShowModal aufrufen diese sich ein und das selbe ApplicationObjekt teilen. Und damit die selben Messages abarbeiten. Was wiederum zu leichten Problemen führen kann. Das einzige was halbwegs etwas bringen würde ist wenn man es schaft das jeder Thread ein eigenes Applicationobjekt bekommt. Dummerweise traten bei mir immer noch unerklärliche Fehler auf. Accessviolations an den wildesten Stellen. Das kann man unmöglich mit CriticalSections etc sichern.
_________________ Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
|
|
Martin1966 
      
Beiträge: 1068
Win 2000, Win XP
Delphi 7, Delphi 2005
|
Verfasst: Mi 22.06.05 09:09
hm... schade das ich keinen fehler gemacht habe und dadurch Problem leichter zu lösen wäre
danke auf jeden fall für deine/eure hilfe!!!
lg martin
|
|
|