Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Toolfenster noch bedienbar trotz modalem Hauptfenster


matze - Fr 29.10.10 14:36
Titel: Toolfenster noch bedienbar trotz modalem Hauptfenster
Hi.

Ich stehe gerade vor dem Problem, dass ich eine Anwendung habe, in der der Benutzer Daten in modalen Fenstern bearbeiten kann. Diese werden ganz normal mit ShowModal; aufgerufen.
Nun gibt es in dem Programm aber noch ein kleines Tool-Fensterchen, das immer neben dran herum schwebt. Dieses ist natürlich nach dem modalen Aufruf eines anderen Fensters nicht mehr bedienbar.

Gibt es denn eine Möglichkeit, dass man das kleine Tool-Fenster trotz eines anderen aktiven modalen Fensters noch bedienbar machen kann?

Danke!
Matze


bummi - Fr 29.10.10 15:34

mhhh einen kleinen Fake könnte ich Dir anbieten, wenn Du die Vorlage Deiner Modalen Dialoge um ein Panel aufbohrst:
Form2 ist hier Dein Toolfenster, Form3 Deine Modalen, würde halt noch die ganze Assigned/Visible Prüfung fehlen....


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:
procedure TForm1.Button2Click(Sender: TObject);
begin
  With TForm3. Create(self) do
    begin
    ShowModal;
    Free;
    end;
end;



procedure TForm3.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin

   Form2.Align := alnone;
   Form2.BoundsRect := FBounds;
   Form2.Parent := FP;

end;

procedure TForm3.FormShow(Sender: TObject);
begin
   FP := Form2.Parent;
   FBounds := Form2.BoundsRect;
   Form2.Parent := Panel1;
   Form2.Align := alClient;
end;


Martok - Fr 29.10.10 17:04

Werden die anderen Fenster bei Showmodal nicht nur auf Enabled:= false gesetzt?

Dann müsste man doch eigentlich auch im OnShow des modalen Fensters eins selektiv wieder enablen können... mal so ins blaue geraten.


jaenicke - Fr 29.10.10 17:07

user profile iconMartok hat folgendes geschrieben Zum zitierten Posting springen:
Werden die anderen Fenster bei Showmodal nicht nur auf Enabled:= false gesetzt?
Nein, so einfach ist das dann doch nicht. ;-)

Es gibt dafür glaube ich Möglichkeiten, welche sinnvoll ist, hängt vom Projekt ab. Ich schreibe nachher zu Hause mehr dazu.


BenBE - Fr 29.10.10 23:03

@Martok: Jep. Modal setzt ein DisableControls für alle sichtbaren Toplevel-Fenster. Müsste aber auch erst den Source dazu rauskramen, wo das in TCustomForm gemacht wird.

Man kann da durchaus was hacken an der Stelle, aber inwiefern das praktikabel ist, hängt stark von der App ab.


delfiphan - Fr 29.10.10 23:18

Ist zwar eine unschöne Lösung aber, versuch mal procedure WMEnable(var Message: TMessage); message WM_ENABLE; + EnableWindow(Handle, True).


jaenicke - Sa 30.10.10 06:17

Das wird denke ich nicht gehen, denn Delphi fängt genau diese Messages ab während modal aktiv ist. ;-)
Dafür gibt es eine entsprechende Fensterliste.

// EDIT:
Nein, ich habe mich geirrt, EnableWindow klappt, nur WM_ENABLE wird abgefangen und funktioniert daher nicht. :zustimm:


matze - Sa 30.10.10 10:40

Puh. Sieht also danach aus, als gäbe es nicht wirklich eine saubere praktikable Lösung, sehe ich das richtig?
In diesem Fall stampfe ich dann das Tool-Window einfach ein und mache das irgendwie anders in meinem Programm :-)

Danke euch für die vielen Antworten!

Matze


delfiphan - Sa 30.10.10 10:48

Die Lösung verdient zwar keinen Schönheitspreis, funktioniert aber eigentlich gut. Was spricht dagegen?

Du kannst die Änderung ja in eine eigene Klasse verlegen. Solange der Code gut getestet ist und das ganze gekapselt ist, kann dir die Implementation praktisch egal sein. Falls es doch mal zu Problemen führen sollte, kannst du dann einfach die Implementation durch was besseres austauschen.

Irgendwie so könnte das aussehen:

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:
unit ModalOverrideForms;

interface

uses Windows, Messages, Classes, Controls, Forms;

type
  TModalOverrideForm = class(TForm)
  private
    FInternalChanging: Integer;
    procedure WMEnable(var Message: TWMEnable); message WM_ENABLE;
    procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
  end;

implementation

procedure TModalOverrideForm.CMEnabledChanged(var Message: TMessage);
begin
  Inc(FInternalChanging);
  try
    inherited;
  finally
    Dec(FInternalChanging);
  end;
end;

procedure TModalOverrideForm.WMEnable(var Message: TWMEnable);
begin
  inherited;
  if Enabled and not Message.Enabled and (FInternalChanging = 0then
    EnableWindow(Handle, True);
end;

end.


matze - Di 02.11.10 21:46

Vielen Dank an euch alle!