Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   "Schleier" über Formbereiche legen (https://www.delphipraxis.net/161939-schleier-ueber-formbereiche-legen.html)

to2 28. Jul 2011 12:57

"Schleier" über Formbereiche legen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,

ich habe einen größeren Bereich mit Eingabeelementen (Checkboxen, RadioButtons, Editfelder usw.), in welchem ich in bestimmten Betriebszuständen Eingaben für Teilbereiche verhindern muss. Das Ganze soll so gestaltet sein, dass der Anwender sofort sieht, dass keine Eingaben möglich sind.

Aus diversen Gründen möchte ich das nicht durch das Setzen der Enabled Eigenschaft der einzelnen Controls erreichen.

Mir schwebt eine Art "Schleier" vor, welcher sich über Eingabebereiche legt, wenn sie nicht zugänglich sein sollen. Ich habe dazu mit den in diesem Forum enthaltenen Beispielen für transparente Controls experimentiert.

Als simples Arbeitsbeispiel ist eine Komponente BlockingPanel, abgeleitet von TCustomPanel entstanden, welche zunächst mal ein paar Streifen zeichnet.

Das funktioniert sehr gut für Controls, welche dem selben Parent untergeordnet sind, wie das BlockingPanels. Jedoch wirkt das BlockingPanel nicht zuverlässig auf Controls, welche eine Ebene tiefer liegen, d.h. wo der Parent in der selben Ebene liegt wie das BlockingPanel.

Ein Bild verdeutlich das. Links ist die Problemkonfiguration. Das BlockingPanel liegt über der GroupBox, deckt aber nicht die in der GroupBox enthaltene CheckBox ab. Rechts funktioniert es, hier hat das BlockingPanel die GroupBox als Parent.

Der Schleier wird in der überschriebenen Paint Methode erzeugt und wenn ich mit einem Fenster darüberwische, sieht auch alles i.O. aus. Es gibt aber genug Situationen, wo es aussieht wie links im Bild dargestellt.

Mich wundert das, denn sollten nicht zuerst die Constrols gezeichnet werden, die in der Z-Order unten liegen, d.h. die GroupBox mit ihrer Checkbox und dann das darüberliegende Control, das BlockingPanel?

Vielleicht hat jemand einen Tipp für mich.

Beiliegend der Code. Nicht wundern, ist C++ Builder. Die Delphi-Foren sind einfach besser besucht. Das Highlighting ist etwas irreführend, weil geschweifte Klammer in Delphi wohl Kommentar signalisiert, in C++ aber ein begin. Daher habe ich desöfteren mal // vor die öffnende, geschweifte Klammer gesetzt.

Delphi-Quellcode:
//---------------------------------------------------------------------------
// Konstruktor. Ruft nur den Konstruktor der Basisklasse auf.
__fastcall TBlockingPanel::TBlockingPanel(TComponent* Owner)
                          :inherited(Owner)
{}
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// Einstellungen zur Transparenz treffen.
void __fastcall TBlockingPanel::CreateParams(TCreateParams& Params)
//{
 inherited::CreateParams(Params);
 Params.ExStyle = Params.ExStyle + WS_EX_TRANSPARENT;

 // csOpaque braucht nicht abgeschaltet werden, Debug ergab: Es ist initial
 // nicht eingeschaltet
 // ControlStyle = ControlStyle >> csOpaque;
}
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// Zeichnen.
void __fastcall TBlockingPanel::Paint()
//{
 TRect rect = GetClientRect();

 // Waagerechte Linien im Abstand von 10 Pixeln zeichnen.
 Canvas->Pen->Color = clBlack;
 Canvas->Pen->Style = psSolid;
 int height = rect.Height();
 int width = rect.Width();
 for (int i = 0; i < height; i += 10)
  //{
   Canvas->MoveTo(0    , i);
   Canvas->LineTo(width, i);
  }
}
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// Message abfangen.
void __fastcall TBlockingPanel::WMEraseBkgnd(TWMEraseBkgnd& message)
//{
 message.Result = 1;
}
//---------------------------------------------------------------------------

uligerhardt 28. Jul 2011 13:06

AW: "Schleier" über Formbereiche legen
 
Schau doch mal hier: How to show a semi-transparent dimmed panel/image in Delphi?

to2 28. Jul 2011 13:54

AW: "Schleier" über Formbereiche legen
 
Zitat:

Zitat von uligerhardt (Beitrag 1113961)
Schau doch mal hier

Das sieht schon gut aus. Bei mir ist die Situation aber nicht ganz so statisch. Die Eingabeelemente sind in TCategoryPanels gruppiert und die sollen immer noch auf- und zuklappbar sein. Beim Aufklappen soll dann gleich sichtbar sein, was zugänglich ist und was nicht. Desweiteren soll das MainForm auch immer noch verschiebbar sein. Ich bin mir nicht sicher, ob das unter diesen Bedingungen immer noch gut mit den darübergelegten Forms funktioniert. Dann muss ich bei Bewegung des MainForms die DimmForms nachziehen - und ob das flimmer- und verzögerungsfrei funktioniert ...

Medium 28. Jul 2011 14:27

AW: "Schleier" über Formbereiche legen
 
Tut es, ich hab's in einem meiner letzten Projekte genau so gemacht. Du kannst ja auf Verschieben und Scrollen und Klappen entsprechend reagieren. Ist zwar nicht wirklich irrsinnig elegant, zumal man sich die jeweiligen Hanlder damit belegt und immer dran denken muss, dass da ja was war, bevor man da später mal was anderes zuweist, aber auf Basis der VCL bzw. WinAPI wird es keinen anderen vernünftig aussehenden Weg geben, ausser man fängt an sämtliche Controls zu subclassen und spendiert ihnen eigene selbst verwaltete Dimm-Forms - das ist aber auch nur eine spontane Idee und völlig ungetestet auf "geht das überhaupt?" und Machbarkeit.
Gemein ist u.a. auch, dass man bei Controls, die z.B. in einer Scrollbox liegen, deren ClientRect natürlich so bekommt, als wäre alles sichtbar, auch wenn das Control halb rausgescrollt ist. Man müsste also sogar noch in solchen Fallen die Lage des Controls in den Grenzen seines Parents beachten. Alles leider etwas fummelig in diesem unseren Delphischen GUI Framework.

to2 28. Jul 2011 15:45

AW: "Schleier" über Formbereiche legen
 
Zitat:

Zitat von Medium (Beitrag 1113968)
Ist zwar nicht wirklich irrsinnig elegant

Genau deswegen suche ich noch ein wenig herum.

stahli 28. Jul 2011 15:53

AW: "Schleier" über Formbereiche legen
 
Hier mal 3 Links, die etwas zum Thema enthalten:
- http://www.delphipraxis.net/160506-t...ml#post1111821 (ab #181)
- http://www.delphipraxis.net/158294-a...-controls.html
- http://www.delphipraxis.net/161720-l...on-texten.html

Ich finde das Thema zwar auch interessant, habe mich aber nicht detaillierter damit beschäftigt.
Vermutlich wird die aktuelle VCL eine solche Funktion nicht unterstützen. Es müssten sich die Controls ja gegenseitig informieren, wenn vor oder hinter ihnen etwas gezeichnet wird.
Der Hinweis von Rollstuhlfahrer auf SetLayeredWindowAttributes im letzten Link klingt zwar gut, scheint aber wohl in einem normalen Formular auch nicht zuzutreffen.

Falls Du etwas findest, dann gib mal bescheid...

PS: Und herzlich willkommen noch :-)


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:53 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz