将一个Form融合到容器后,如何使Form的FormKeyDown响应? (100分)

  • 主题发起人 wuyaobin
  • 开始时间
W

wuyaobin

Unregistered / Unconfirmed
GUEST, unregistred user!
代码:
//用如下过程建立Form2后,如何使Form2的FormKeyDown响应?
//已设Form2.KeyPreview:=True
//**************Form1**************
procedure ShowForm(FormClass:TFormClass;Form:TForm;FParent:TPanel);//窗口融合
begin
  if Form=nil then
    Form:=FormClass.Create(nil);
  FParent.DockSite:=True;
  with Form do
 begin
    do
ckSite:=True;
    DragKind:=DkDock;
    Align:=alClient;
    HostDockSite:=FParent;
    Show;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ShowForm(TForm2,Form2,Panel1);//建立Form2
end;

//**************Form2**************
procedure TForm2.FormKeyDown(Sender: TObject;
var Key: Word;
  Shift: TShiftState);
begin
if key=VK_Return then
 
  ShowMessage('Form2 VK_Return');//没有响应
end;
 
将一个子窗体以设置parent的方式融合到主窗体中
其KeyPress就失效,受主窗体的KeyPress控制了
 
把Form2的keydown事件改成主窗体的Keydown
 
To 大富婆:
如何改法呢?可不可以给出具体的代码!
 
TChildForm = class(TParentForm)
private
FAsChild:Boolean;
//是否创建为子窗体
FTempParent:TWinControl;
//父组件
{ Private declarations }
protected
procedure CreateParams(var Params:TCreateParams);override;
procedure Loaded;override;
public
constructor Create(AOwner:TComponent);overload;override;
constructor Create(AOwner:TComponent;AParent:TWinControl);reintroduce;overload;
{ Public declarations }
end;

constructor TChildForm.Create(AOwner: TComponent);
begin
FAsChild:=false;
inherited Create(AOwner);
end;

constructor TChildForm.Create(AOwner: TComponent;
AParent: TWinControl);
begin
FAsChild:=true;
FTempParent:=aParent;
Inherited Create(AOwner);
end;

procedure TChildForm.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
if FAsChild then
Params.Style:=Params.Style or WS_CHILD;
end;

procedure TChildForm.Loaded;
begin
inherited;
if FAsChild then
begin
align:=alClient;
BorderStyle:=bsNone;
BorderIcons:=[];
Parent:=FTempParent;
Position:=poDefault;
end;
end;
把本来的from2的事件加到 form2就行了
 
例如主窗体的onkeydown为formkeydown,那么:
form2.onkeydown:=formkeydown
 
>>>>>你们都误会了我的意思。
我的意思是:有Form1(主窗口),Form2(或更多窗口),其它窗口都融合进Form1
的Panel1中,怎样使其它窗口在融合进Form1后能响应自身的FormKeyDown事件?谁知道?
 
上面已经说得很明白了,直接不行。
但是反过来,如果主Form维护子Form的表,就可以实现。就是在主Form的KeyDown事件主动
激发子Form的KeyDown。下面以一个子Form为例
procedure TForm1.FormKeyDown(Sender: TObject;
var Key: Word;
Shift: TShiftState);
begin
if Assigned(ChildForm.OnKeyDown) then
ChildForm.OnKeyDown(Sender,Key,Shift);
end;
 
不知怎么,ugvanxk 和 daiqingbo 的方法在Delphi6下调试总是出错。[:(]
有不会出错的方法吗?[:)]
 
不知怎么,ugvanxk 和 daiqingbo 的方法在Delphi6下调试总是出错。[:(]
有不会出错的方法吗?[:)]
 
的确是这样,你将一个窗体融合到别的容器中,此窗体的Keydown事件将不会再引发,
而由容器的KeyDown事件处理了,你只需要将容器的KeyDown事件指向此窗体的KeyDown事件
处理函数即可以
但是多个窗体融合到同一个容器,你只好判断谁是当前在最前面的窗体了.
 
To lynu,
对,有没有好的解决办法呢?[:(]
举个例子
 
首先建议你使用ugvanxk的方法,这个方法详细见“delphi5开发人员指南”,好经典的书哦。
你的问题可以这样解决。关键在于理解Key事件的处理过程,它总是发给活动窗口的活动
控件。窗体的ActiveControl属性。以下方法都是可以的:
A:添加TForm2的Mouse事件:
procedure TForm2.FormMouseMove(Sender: TObject;
Shift: TShiftState;
X,
Y: Integer);
begin
Form1.ActiveControl := self;
end;
B:删除 //Align:=alClient;
当你点击双横杠后,你的事件就可以发生了。
如果你要看清楚原理,再Form1中增加Label1和Timer:输入以下代码
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if assigned(form1.ActiveControl) then
label1.Caption := 'ff - ' + form1.ActiveControl.name
else
label1.Caption := 'ff';
end;
就知道Key事件当前是送给谁了。
如果Form2内有控件,问题就比较复杂了,所以我不建议你使用这样的方案。
 
大富婆是男是女阿
 
我原來做出同樣的程序,但所有融合到這個容器的其他窗體都是Align=alClient,也就是說
顯示其中一個窗體那么其他窗體就被遮擋了.
我是在每個窗體的OnPaint中處理中,在此用一個TForm全局變量指向當前前面的窗
體.OnPaint中 currform:=self;然后在容器的Keydown事件中根據currform來判斷當前最前
的窗體.我試過其他方法,都沒能解決我的這個問題
 
唉,使用TabControl做容器,把容器内窗体和标签联系起来不就完了。
 
我是希望能实现这个功能!
 
TPanel没有OnKeyDown事件,当然无法响应了,你用OnMouseDown就行了。
 
难道没有人可以解决这个问题吗?
 
不是已经给出答案了吗?
 
顶部