Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Modales Fenster mit Möglichkeit anderes Fenster anzuclicken.


mtm - Di 25.09.12 16:40
Titel: Modales Fenster mit Möglichkeit anderes Fenster anzuclicken.
Hallo zusammen,

die Überschrift ist vielleicht etwas verwirrend, aber mit viel keine bessere ein.

Ich habe da nämlcih ein kleines Problem. Ich möchte aus einem Grid heraus, einen Kalender als Datumsauswahl öffnen. Dieser Kalender soll unterhalb der geclickten Zelle stehen und, falls nötig, über den Rand des Fensters hinausgehen.
Es soll aber, abgesehen von der Datumsauswahl, auch die Möglichkeit geben erneut auf das Grid oder ein anderes Control zu clicken, so daß der Kalender beim Verlust des Fokusses automatisch verschwindet ohne den Eintrag im Grid zu ändern.

Dazu habe ich ein extra Fenster mit einem Kalender erstellt (ohne Rand und in der Größe des Kalenders) das folgende Prozeduren enthält :


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:
// TfrmPopKal = Fenster
// Kalender = Kalender-Komponente

// wenn Fenster Focus verliert, Fenster schließen
procedure TfrmPopKal.FormDeactivate(Sender: TObject);
begin
  Self.Close;
end;

// bei Resize Fenster immer auf Kalendergröße setzen
procedure TfrmPopKal.FormResize(Sender: TObject);
begin
  Width := Kalender.Width;
  Height := Kalender.Height;
end;

// bei Anzeige Fenster auf Kalendergröße setzen
procedure TfrmPopKal.FormShow(Sender: TObject);
begin
  Width := Kalender.Width;
  Height := Kalender.Height;
end;

function TfrmPopKal.getDatum(def: TDate):TDate;
begin
  pDatum := def;

  Kalender.Visible := True;
  Self.Show;

  Result := pDatum;
end;

procedure TfrmPopKal.KalenderDateClick(Sender: TObject; Datum: TDate);
begin
  // Wenn auf Datum geclickt wurde, soll das Datum zurückgegeben werden und
  // das Fenster geschlossen werden.
  pDatum := Datum;
  Self.Close;
end;

// wenn Kalender Fokus verliert, Fenster schließen
procedure TfrmPopKal.KalenderExit(Sender: TObject);
begin
  Kalender.Visible := False;
  Self.Close;
end;


Dieses Fenster soll also an einer bestimmten Position geöffnet werden. Das habe ich durch einen Aufruf der Funktion getDatum versucht.


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:
// grd = StringGrid
procedure TfrmMain.grdMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  Row, Col: Integer;
  datum: TDate;
begin
  grd.MouseToCell(x,y,Col,Row);
  if (Col = 2AND (Button = mbRight) then begin
    with frmPopKal do begin

      // Positionierung des Kalender-Fensters
      Top := x;
      Left := y;

      datum := Date;

      // Öffnen des Kalender-Fensters
      datum := getDatum(datum);

      grd.Cells[Col,Row] := DateToStr(datum);
    end;
  end;
end;


Das Fenster wird zwar geöffnet, aber es wird (selbstverständlich) direkt ein Wert ausgegeben, da ja die Funktion nach dem Self.Show direkt weiterläuft. Das möchte ich aber verhindern.
Ich könnte natürlich statt Self.Show auch Self.ShowModal benutzen, dann kann ich aber nicht mehr auf das aufrufende Fenster clicken, was ich aber ermöglichen will.

Irgendwie komme ich da nicht weiter. Vielleicht hat von Euch einer eine Idee, wie ich das Problem lösen kann.

Danke im Voraus
Gruß uss Kölle
mtm


jaenicke - Di 25.09.12 18:04

Das ist ein typisches Beispiel für ein Event. Du zeigst das neue Fenster an und reagierst darauf, dass dieses geschlossen wird. Dafür kannst du z.B. ein eigenes Event erfinden. OnSecondWindowFinished z.B.

Warten / Pollen war unter DOS üblich, aber heutzutage bei Windows macht das meistens keinen Sinn mehr. Mehr noch, bei Windows RT ist dies gar nicht mehr möglich, da läuft im Grunde alles asnchron und du bekommst das Ergebnis hinterher (vom Prinzip her zumindest).