Einzelnen Beitrag anzeigen

to2

Registriert seit: 21. Aug 2009
3 Beiträge
 
#1

"Schleier" über Formbereiche legen

  Alt 28. Jul 2011, 12:57
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;
}
//---------------------------------------------------------------------------
Miniaturansicht angehängter Grafiken
blockingpanel.png  
  Mit Zitat antworten Zitat