Autor Beitrag
Björn karpenstein
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 96

Windows XP, Linux
D7, K3
BeitragVerfasst: Mi 21.09.05 20:18 
Hallo! Ich habe ein MDIForm und mehrere MDIChilds. Jedes MDIChild darf nur einmal geöffnet werden. Also habe ich Aktionen für das Menü und die Toolbuttons hinterlegt um die Fenster zu öffnen:

ausblenden Delphi-Quelltext
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:
procedure TFormular_Hauptfenster.oeffne_adressbuchExecute(Sender: TObject);
var frm : TFormular_Adressbuch;
var i : Integer;
var open : Boolean;
begin
  open := false;

  // Fenster schon offen??? Dann nach vorne holen!!!!
  for i:=0 to self.MDIChildCount -1 do
  begin
    if (self.MDIChildren[i] is TFormular_Adressbuch) then
    begin
      open := true;
      self.MDIChildren[i].BringToFront;
      self.MDIChildren[i].SetFocus;
    end;
  end;

  // Fenster noch nicht offen?? Sofort öffnen!!!
  if open = false then
  begin
    frm := TFormular_Adressbuch.Create(self);
    frm.Show;
  end;
end;


Das Öffnen funktioniert einwandfrei, allerdings bringt er meistens die falschen MDI-Fenster nach vorne - manchmal passiert auch gar nichts.Ich nehme dann auch manchmal ein Repaint war (die Fenster flackern kurz), aber irgendwie klappt das aufwählen den MDI-Fensters nicht so richtig. Ich meine das hätte schonmal funktioniert.

Was mache ich falsch?
Björn karpenstein Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 96

Windows XP, Linux
D7, K3
BeitragVerfasst: Do 22.09.05 20:15 
Ähm also ich hab zwar keine Ahnung warum, aber ich habe folgenden Code geschrieben und jetzt gehts:

ausblenden volle Höhe Delphi-Quelltext
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:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
type 
    { Array of form references } 
    A_TForm = Array [0 .. (($fff0 div SizeOf(TForm)) - 1)] 
        of TForm; 

procedure TFormular_Hauptfenster.hole_mailsExecute(Sender: TObject);
var frm : TFormular_Posteingang;
var i : Integer;
var open : Boolean;

var
    ChildCount: Integer;
    CurrentMDIChildCount: Integer;
    CurrentMDIChildren: ^A_TForm;

begin

  open := false;

  CurrentMDIChildCount := MDIChildCount;
  CurrentMDIChildren := AllocMem(CurrentMDIChildCount * SizeOf(CurrentMDIChildren^[0]));

  try
    for ChildCount := 0 to CurrentMDIChildCount - 1 do
    CurrentMDIChildren^[ChildCount] := MDIChildren[ChildCount];

    for ChildCount := CurrentMDIChildCount - 1 downto 0 do
    begin
      if (CurrentMDIChildren^[ChildCount] is TFormular_Posteingang) then
      begin
        open := true;
        CurrentMDIChildren^[ChildCount].BringToFront;
        if CurrentMDIChildren^[ChildCount].CanFocus then CurrentMDIChildren^[ChildCount].SetFocus;
      end;
    end;

  finally
    FreeMem(CurrentMDIChildren, CurrentMDIChildCount * SizeOf(CurrentMDIChildren^[0]));
  end;


  if open = false then
  begin
    frm := TFormular_Posteingang.Create(nil);
    frm.Show;
  end;
end;


Den hatte ich hierher:

www.delphipraxis.net/post56053.html

Scheint irgendwie ein Standard-Problem von Delphi 7 zu sein???
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6393
Erhaltene Danke: 147

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Do 22.09.05 20:45 
Ich habe das mal irgendwann so gelöst:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
Function TForm1.MDIChildExist (frm : TForm) : Boolean;
var
  cnt : Word;
begin
  Result := False;
  Application.ProcessMessages;
  if TForm(Owner).MDIChildCount > 0 then 
  begin
    cnt := 0;
    while (cnt < MDIChildCount) and (not Result) do 
    begin
      Result := (MDIChildren[cnt] = frm);
      inc(cnt);
    end;
  end;
end;

Die Funktion habe ich dann an der notwendigen Stelle aufgerufen.
Hat bei mir bisher gut funktioniert.
Achtung! Habe den Source ein wenig angepasst. Ich hoffe, dass ich keine Fehler gemacht habe.
Björn karpenstein Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 96

Windows XP, Linux
D7, K3
BeitragVerfasst: Do 22.09.05 21:22 
Hallo!

Das Problem war aber eigentlich, dass Delphi7 aus irgendwelchen Gründen das MDIChildren-Array auseinander bringt. Löst Du damit dieses Problem?

Aus dem anderen Forum:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
      For some reason Delphi messes around with the MDIChildren array 
      when child forms are repositioned in code, causing the routine to 
      suddenly start accessing the wrong form in the middle of an 
      iteration! To get around this problem, allocate some memory to 
      make copies of the main form's MDIChildren array and use this 
      copy throughout the rest of the routine


Gruß Björn
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6393
Erhaltene Danke: 147

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Fr 23.09.05 08:12 
Nein. Nicht so, wie es dort beschrieben ist.
Allerdings habe ich das damals in D5 programmiert.
In D2005 funktioniert es bisher auch ohne Fehler.
Ist das vielleicht wirklich nur eine "Spezialität" von D7? Kann ich mir fast nicht vorstellen.
Björn karpenstein Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 96

Windows XP, Linux
D7, K3
BeitragVerfasst: Fr 23.09.05 13:42 
Also damit ihr nicht mit dem gleichen Problem kämpfen müsst:

Es gibt ein Update von Delphi 7 auf Delphi 7.1 von Borland. Ich habe es installiert und jetzt ist das Problem behoben. Delphi bringt die MDIChildren nicht mehr durcheinander.