Home | Projekte | Javascript-Debugger | Delphi-Tipp(1) | Delphi(2) | Delphi(3) | Pascal → Javascript | Lazarus | Kontakt

Herzlich Willkommen auf der Homepage von Jörg Siebrands

Hier finden einige Tipps und Scripte die für den einen oder andern nützlich sein könnten

Delphi - Komponenten verschwinden nach Betätigung der <ALT>-Taste

In älteren Delphi-Versionen (vermutlich bis Delphi 2007) verschwinden einige Komponenten während der Laufzeit beim Betätigen der <ALT>- oder <ALT-GR>-Taste. Der Fehler ist seit längeren bekannt und es gibt einige Lösungen dazu im Internet (Google-Suche...).
Der Fehler tritt bei folgenden Komponenten auf: TButton, TCheckBox, TRadioButton und TRadioGroup.

Für TButton kann man den Fehler beseitigen indem man die statt TButton eine andere Button-Komponente wie z. B. TBitBtn oder TSpeedButton benutzt. Bei diesen beiden Komponenten tritt der Fehler nicht auf.

Für die anderen Komponenten wird nachfolgend eine einfache Lösung vorgestellt um den Fehler zu beheben. Diese hat den Vorteil dass keine Komponente zusätzlich installiert werden muss und keine sehr aufwendigen Änderungen nötig sind.

Zunächst wird für das betreffende Formular KeyPreview auf true gesetzt. Dies kann entweder im Objektinspektor eingestellt werden oder im OnCreate-Ereignis des Formulars:

procedure Form1.FormCreateWebsite.FormCreate(Sender: TObject); 
begin 
  KeyPreview := true;
end; 

Wenn man den Quelltext später ohne Änderung für neuere Delphi-Versionen verwenden möchte kann man noch eine Compiler-Direktive zur Abfrage der Delphi-Version hinzufügen, so dass die Änderung nur für die definierte Delphi-Version gilt. Nachfolgend wird dies für Delphi 7 eingestellt. Unter http://docwiki.embarcadero.com/RADStudio/Tokyo/de/Compiler-Versionen findet man die Versionsnummer aller relevanten Delphi-Versionen.

procedure Form1.FormCreateWebsite.FormCreate(Sender: TObject); 
  {$ifdef VER150} // nur für Fehler in Delphi 7 (Elemente verschwinden bei ALT-Taste)
KeyPreview := true;
{$endif} end;

Nun wird im OnKeyDown-Ereignis des Formulars für alle betreffenden Komponenten bei der Betätigung der <ALT>- und <ALT-GR>-Taste ein RePaint() zum Neuzeichnen der Komponente ausgelöst.

procedure Form1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
{$ifdef VER150} // nur für Fehler in Delphi 7 (Elemente verschwinden bei ALT-Taste)
if (Key = VK_MENU) then begin // Alt-Taste
CheckBox1.Repaint; // Beispiele
RadioButton1.Repaint;
RadioGroup1.Repaint;
end;
{$endif}
end;

Wird nun die <ALT> bzw. <ALT-GR>-Taste gedrückt wird die Komponente neugezeichnet. Dies führt zu einem kurzen Flackern da die Komponente zunächst verschwindet. Das dürfte aber weniger gravierend sein wie das komplette Verschwinden der komponente.

Ein Problem gibt es nun aber noch: Drückt man relativ schnell nacheinander die <ALT>- und die <TAB>-Taste um zu einer anderen Anwendung zu wechseln, wird die Komponente nicht wieder neu gezeichnet. Wechselt man zurück zum Delphi-Programm bleibt die Komponente verschwunden.
Dies kann man dadurch verhindern, dass man beim (Wieder-)Aktivieren des Delphi-Programms ein Neu-Zeichnen vornimmt. Dazu kann man eine TApplication-Komponente auf das Hauptformular setzen und im OnActivate-Ereignis ein Neuzeichnen der betreffenden Komponenten auslösen.

procedure Form1.ApplicationEvents1Activate(Sender: TObject);
var
i, j: integer;
begin
{$ifdef VER150} // nur für Fehler in Delphi 7 (Elemente verschwinden bei ALT-Taste)
for i := 0 to Application.ComponentCount-1 do begin
for j := 0 to Application.Components[i].ComponentCount-1 do begin
if (Application.Components[i].Components[j] is TCheckBox) then begin
TCheckBox(Application.Components[i].Components[j]).Repaint;
// end else if (Application.Components[i].Components[j] is TButton) then begin // nur wenn TButton vorhanden ist
// TButton(Application.Components[i].Components[j]).Repaint; // nur wenn TButton vorhanden ist
end else if (Application.Components[i].Components[j] is TRadioButton) then begin
TRadioButton(Application.Components[i].Components[j]).Repaint;
end else if (Application.Components[i].Components[j] is TRadioGroup) then begin
TRadioGroup(Application.Components[i].Components[j]).Repaint;
end;
end;
end;
{$endif}
end;

Wenn man TButton-Komponenten nicht durch andere Button-Komponenten ersetzt hat muss man noch die Kommentar-Striche für das Repaint() für TButton entfernen.

In den meisten Fällen dürfte diess Lösung ausreichend sein. Mir ist aufgefallen das im folgenden - allerdings eher selten vorkommenden - Fall der Fehler noch auftritt:
Wird zunächst mit <ALT> + <TAB> ein schneller Wechsel zu einer anderen Anwendung durchgeführt und wird diese andere Anwendung anschließend minimiert durch Klick auf das Minimieren-Symbol oben rechts im Anwendungsfenster, dann wird die Delphi-Anwendung wieder sichtbar und beim Betätigen der <TAB>-Taste verschwinden die Komponenten wieder.

Wenn jemand hierfür eine einfache Lösung hat würde ich mich um einen kurzen Hinweis freuen um diese Seite entsprechend zu ergänzen.

Jörg Siebrands, Lünebuerger Schanze 1, 21614 Buxtehude