![]() |
Tastatureingabe an Formularen
Ich möchte auf dem Hauptformular des Programmes (Form1) ein zweites Formular (Form2) ohne sichtbaren Rahmen (BorderStyle = bsNone) anzeigen. Dabei soll Form2 auch sichtbar bleiben, wenn mit der Maus auf Form1 geklickt wird. Die Titelleiste von Form1 soll blau bleiben wenn Form2 angezeigt wird und Form2 soll im OnKeyDown-Ereignis auf die Tastatureingaben reagieren. Aber an einem dieser Punkte scheitert es immer.
Bei Form2.FormStyle = fsStayOnTop und Form2.KeyPreview = true lässt sich Form2 mit der Tastatur bedienen aber die Titelleiste von Form1 wird grau. Bei Form2.Parent:= Form1 wird Form2 angezeigt und die Titelzeile von Form1 bleibt blau aber Form2 lässt sich nicht mit der Tastatur bedienen. Wie kann man dieses Problem lösen? |
Re: Tastatureingabe an Formularen
Brauchst du vlt.
![]() |
Re: Tastatureingabe an Formularen
Soweit ich das sehe ist
Form2.SetParent(Form1); das gleiche wie Form2.Parent:= Form1; |
Re: Tastatureingabe an Formularen
I hab ja auch Windows.SetParent geschrieben und net FormX.Parent. Dann hast du 2 Argumente die du uebergeben musst.
Kann mich aber auch taeuschen! Ist schon spaet hier! |
Re: Tastatureingabe an Formularen
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo.
Wenn aus irgendeinem Grund Frames keine akzeptable Lösung sind, dann darf es natürlich auch eine embedded form sein. Ich habe ein Demo-Projekt dazu angehängt. Wenn man die beispielhaften Controls nebst dem event handler ButtonClick() aus der ChildForm entfernt, dann kann man diese ChildForm als Template ins Object Repository stellen. Grüße vom marabu |
Re: Tastatureingabe an Formularen
Ich habe mir das Beispiel von Marabu angeschaut und es entsprechend modifiziert. Wenn das ChildFrm aktiv ist werden trotzdem alle Tastatureingaben, die im OnKeyDown-Ereignis definiert sind, vom DemoFrm(Hauptformular) abgefangen. Die Befehle im OnKeyDown-Ereignis vom ChildFrm werden nicht ausgeführt.
Viele Grüße Tom |
Re: Tastatureingabe an Formularen
Hi Tom,
das liegt an der VCL. Ich habe mir an dem Problem auch schon die Zähne ausgebissen. Jetzt mach ich es so, dass ich über einen Keyboardhook das Form ermittle und eine eigene Nachricht sende. Dann gibt es noch die Möglichkeit, nicht mit Parent sondern wie schon beschrieben mit Windows.SetParent zu arbeiten. So hab ich mir mal ein FormPanel erstellt.
Delphi-Quellcode:
Vielleicht hilft es dir ja weiter.
unit RW_FormPanel;
interface uses Forms, Windows, Messages, Classes, Controls, ExtCtrls; type TRWFormPanel = class(TCustomPanel) private FForm: TCustomForm; FFormSaveParent: THandle; FFormSavePosition: TPosition; FFormSaveStyle: Integer; FFormSaveStyleEx: Integer; FFormSaveVisible: Boolean; FFormSaveWindowPlacement: TWindowPlacement; procedure SetForm(Value:TCustomForm); protected procedure Notification(AComponent : TComponent; Operation : TOperation); override; procedure SizeChanged; procedure WMSize(var Message:TMessage); message WM_SIZE; public constructor Create(AOwner:TComponent); override; property Form: TCustomForm read FForm write SetForm; published property Align; property Alignment; property Anchors; property AutoSize; property BevelInner; property BevelOuter default bvNone; property BevelWidth; property BiDiMode; property BorderStyle; property BorderWidth; property Caption; property Color; property Constraints; property Ctl3D; property DockSite; property DragCursor; property DragKind; property DragMode; property Enabled; property Font; property FullRepaint; property OnCanResize; property OnClick; property OnConstrainedResize; property OnDblClick; property OnDockDrop; property OnDockOver; property OnDragDrop; property OnDragOver; property OnEndDock; property OnEndDrag; property OnEnter; property OnExit; property OnGetSiteInfo; property OnMouseDown; property OnMouseMove; property OnMouseUp; property OnResize; property OnStartDock; property OnStartDrag; property OnUnDock; property ParentBiDiMode; property ParentColor; property ParentCtl3D; property ParentFont; property ParentShowHint; property PopupMenu; property ShowHint; property TabOrder; property TabStop; property UseDockManager default True; property Visible; end; implementation procedure TRWFormPanel.Notification(AComponent : TComponent; Operation : TOperation); begin inherited Notification( AComponent, Operation); if Assigned(FForm) then if (Operation = opRemove) and (AComponent = FForm) then begin // RemoveFreeNotification(AComponent); FForm := nil; end; end; procedure TRWFormPanel.SetForm(Value:TCustomForm); begin try if (FForm = Value) then Exit; if csDesigning in ComponentState then Exit; // hat schon ein Form, also wiederherstellen if (FForm<>nil) and FForm.HandleAllocated then begin FForm.Visible := False; if not FFormSaveVisible then FFormSaveWindowPlacement.showCmd:=SW_HIDE; Windows.SetParent(FForm.Handle,FFormSaveParent); SetWindowPlacement(FForm.Handle,@FFormSaveWindowPlacement); SetWindowLong(FForm.Handle,GWL_STYLE,FFormSaveStyle); SetWindowLong(FForm.Handle,GWL_EXSTYLE,FFormSaveStyleEx); SetWindowPos(FForm.Handle,HWND_BOTTOM,0,0,0,0,SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER or SWP_FRAMECHANGED or SWP_NOACTIVATE); FForm.Visible := FFormSaveVisible; TForm(FForm).Position := FFormSavePosition; end; FForm:=Value; if FForm<>nil then begin FFormSaveStyle := GetWindowLong(FForm.Handle,GWL_STYLE); FFormSaveStyleEx := GetWindowLong(FForm.Handle,GWL_EXSTYLE); FFormSaveVisible := FForm.Visible; FFormSaveParent := GetParent(FForm.Handle); FFormSavePosition := TForm(FForm).Position; TForm(FForm).Position := poDesigned; GetWindowPlacement(FForm.Handle,@FFormSaveWindowPlacement); SetWindowLong(FForm.Handle,GWL_STYLE,(FFormSaveStyle or WS_CHILD) and not WS_OVERLAPPED and not WS_OVERLAPPEDWINDOW and not WS_CAPTION); SetWindowLong(FForm.Handle,GWL_EXSTYLE,FFormSaveStyleEx and not WS_EX_MDICHILD); Windows.SetParent(FForm.Handle,self.Handle); SetWindowPos(FForm.Handle,HWND_BOTTOM,0,0,0,0,SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER or SWP_FRAMECHANGED or SWP_NOACTIVATE); FForm.Left:=0; FForm.Top:=0; SizeChanged; // FForm.Visible:=True; // FForm.SetFocus; // Application.ProcessMessages; FForm.FreeNotification(Self); end; except FForm := nil; if csLoading in ComponentState then Application.HandleException(Self) else raise; end; end; procedure TRWFormPanel.SizeChanged; begin FForm.Width := ClientWidth; FForm.Height := ClientHeight; end; procedure TRWFormPanel.WMSize(Var Message:TMessage); begin inherited; if FForm <> nil then SizeChanged; end; constructor TRWFormPanel.Create(AOwner:TComponent); begin inherited; // BevelOuter := bvNone; Caption := ''; end; end. Cu, Frank |
Re: Tastatureingabe an Formularen
@Dataspider
Vielen Dank für Deine Hilfe. Ich werde es testen. Viele Grüße Thomas |
Re: Tastatureingabe an Formularen
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo.
In meiner Demo bin ich aus Schusseligkeit nicht auf die Sache mit dem KeyPreview eingegangen. Hier eine erweiterte Demo, die etwas Licht auf dieses Problem wirft. Dazu muss man wissen, dass Borland die ParentForm eines Controls für die Überprüfung der Eigenschaft KeyPreview ermittelt, indem es den Top-Level-Parent des Controls sucht. Dadurch arbeitet KeyPreview bei ChildForms nicht auf die übliche Weise. KeyPreview muss bei der ParentForm von ChildForm gesetzt werden und nur dort wird die Eigenschaft von den VCL-Machern auch ausgewertet. Es gibt jetzt zwei Strategien zum Umgang mit der Misere - neben dem Ansatz von Frank, den ich mangels Zeit jetzt nicht nachvollzogen habe: Man berücksichtigt die Designschwäche und gestaltet die event handler OnKeyDown() etc. entsprechend (siehe Demo) oder man verkettet die event handler im Ereignis OnCreate() der ChildForm. Man beachte die von mir überschriebene Funktion GetParentForm():
Delphi-Quellcode:
So erkenne ich im event handler der DemoForm, ob ein Tastendruck auf einem eigenen Control oder einem Control der ChildForm ausgelöst wurde.
function GetParentForm(Control: TControl): TCustomForm;
begin Result := nil; while Assigned(Control.Parent) do begin Control := Control.Parent; if Control is TCustomForm then begin Result := TCustomForm(Control); Break; end; end; end; marabu |
Re: Tastatureingabe an Formularen
@ marabu
Vielen Dank für Deine Hilfe. Jetzt habe ich es verstanden. Grüße! Tom |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:37 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