Autor Beitrag
Martin1966
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1068

Win 2000, Win XP
Delphi 7, Delphi 2005
BeitragVerfasst: 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. ;-)

ausblenden volle Höhe mainform.pas
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
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

Uses
  ThreadForm;

procedure TForm1.Button1Click(Sender: TObject);
begin
  TThreadTest.Create (False);
end;

end.


ausblenden volle Höhe ThreadForm.pas
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
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

implementation

{$R *.dfm}

Procedure TThreadTest.Execute;
Begin
  With TForm2.Create (nilDo
    ShowModal;
End;

end.


vielen dank schon mal für die hilfe!!!

lg martin
maxk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1696
Erhaltene Danke: 1

Win XP, Debian Lenny
Delphi 6 Personal
BeitragVerfasst: Mi 15.06.05 13:00 
user profile iconMartin1966 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1068

Win 2000, Win XP
Delphi 7, Delphi 2005
BeitragVerfasst: Mi 15.06.05 13:43 
hallo!

danke für deine antwort.

user profile iconmaxk 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.

user profile iconmaxk 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... :gruebel:

noch mal danke für deine hilfe!!

lg Martin
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1696
Erhaltene Danke: 1

Win XP, Debian Lenny
Delphi 6 Personal
BeitragVerfasst: Mi 15.06.05 21:44 
user profile iconMartin1966 hat folgendes geschrieben:
user profile iconmaxk 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 user profile iconLossy 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1068

Win 2000, Win XP
Delphi 7, Delphi 2005
BeitragVerfasst: 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. :nixweiss:

lg Martin
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1068

Win 2000, Win XP
Delphi 7, Delphi 2005
BeitragVerfasst: 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