显示组件的模态形式

问题描述 投票:-1回答:3

我在自定义组件中显示模态表单时遇到问题。在应用程序启动期间,CustomComponent创建一个对用户不可见的自定义表单(CreateMenu)。当用户单击组件时(在运行时),将显示自定义表单(MouseClick),这是一个带按钮的表单 - 命令。

当我使用ShowModal方法显示组件的菜单表单时父表单被阻止,并且所显示的菜单表单也被阻止。下面是用于创建自定义表单(在自定义组件中)并显示它的代码。

procedure TCustomComponent.MouseClick(Sender: TObject; Button: TMouseButton;         Shift: TShiftState; X: integer; Y: integer);
begin
self.Repaint;
  self.PMenuForm.Left := self.Left; // p.x;
  self.PMenuForm.Top := self.Top + self.Height + 5; // p.Y+self.Height+5;
  PMenuForm.ShowModal;
end;


procedure TCustomComponent.CreateMenu(title: string);
begin

  if PMenuForm = nil then
  begin
    PMenuForm := TForm.Create(self.Parent);
    PMenuForm.Parent := self.Parent;
    PMenuForm.ParentWindow := self.Parent.Handle;
    PMenuForm.FormStyle := fsStayOnTop;
    PMenuForm.Enabled := true;
    PMenuForm.Visible := false;
    PMenuForm.BorderWidth := 2;
    PMenuForm.BorderStyle := bsNone;
    PMenuForm.BorderIcons := [];
    PMenuForm.caption := title;
    PMenuFormTitle := TLabel.Create(PMenuForm);
    PMenuFormTitle.Left := 0;
    PMenuFormTitle.Top := 0;
    PMenuFormTitle.Margins.Left := 5;
    PMenuFormTitle.AutoSize := true;
    PMenuFormTitle.Visible := true;
    PMenuFormTitle.Parent := PMenuForm;
    PMenuFormTitle.Font.Color := MakeColor($FFFFFF);
    PMenuFormTitle.Font.Size := 10;
    PMenuFormTitle.Font.Style := [fsBold];
    PMenuFormTitle.Color := MakeColor($0000CC);
    PMenuFormTitle.Transparent := false;
    PMenuFormTitle.caption := title;
    PMenuFormTitle.Layout := tlCenter;
    PMenuFormTitle.Alignment := taLeftJustify;
    PMenuFormTitle.AutoSize := false;
    if PMenuFormTitle.Width < 55 then
      PMenuFormTitle.Width := 65;
    if PMenuFormTitle.Height < 10 then
      PMenuFormTitle.Width := 10;

    PMenuFormItems[0] := TBitBtn.Create(PMenuForm);
    PMenuFormItems[0].Parent := PMenuForm;
    PMenuFormItems[0].ParentWindow := PMenuForm.ClientHandle;
    PMenuFormItems[0].tag := 0;
    PMenuFormItems[0].Enabled := true;
    PMenuFormItems[0].Visible := true;
    PMenuFormItems[0].Top := 0;
    PMenuFormItems[0].Left := PMenuFormTitle.Width - 22;
    PMenuFormItems[0].caption := 'X';
    PMenuFormItems[0].Font.Style := [fsBold];
    PMenuFormItems[0].Width := 20;
    PMenuFormItems[0].Height := PMenuFormTitle.Height;
    PMenuFormItems[0].OnClick := self.MenuItemClick;
    PMenuForm.AutoSize := true;
    self.PMenuFormItemsCount := 0;

    self.OnMouseDown := self.MouseClick;
    self.Cursor := crHandPoint;
  end;
end;

谢谢你的任何建议。

澄清:1。被阻止意味着父表单和显示的菜单表单都没有响应,未启用。此外,菜单表格上的每个按钮都没有响应,即。没有响应鼠标胡佛,并且无法点击(它没有变灰,虽然只是没有对点击和其他任何反应)

  1. 父表单是“阻止”/无响应但这也会影响显示的菜单表单 - 它也没有响应(按钮)。
delphi delphi-10.2-tokyo
3个回答
0
投票

这是故意的,从Delphi的第一个版本开始。最古老的在线html文档来自Delphi 2007,其中ShowModal文档:

使用ShowModal将表单显示为模态形式。模式表单是在表单关闭之前应用程序无法继续运行的表单。因此,ShowModal在表单关闭之前不会返回。当表单关闭时,它返回ModalResult属性的值。

如果您的问题实际上是关于如何解决菜单也被阻止:

  • 不要使用ShowModal,而是使用Show,并准备好表单现在不再是模态,因此用户可以在表单和其余应用程序之间来回切换
  • 以模态形式显示菜单

0
投票

这一行:PMenuFormItems[0].OnClick := self.MenuItemClick;self(CustomComponent)有一个方法MenuItemClick。它实施了吗?它有什么作用?

这就是点击bitbutton PMenuFormItems[0]最终的结果。如果这不会导致设置PMenuForm.ModalResult或特别关闭PMenuForm,则无响应继续。

您的代码中有两个设置

//    PMenuForm.ParentWindow := self.Parent.Handle;
//    PMenuFormItems[0].ParentWindow := PMenuForm.ClientHandle;

我不得不退出。他们引起了AV:s

它们在你的代码中没用,就像documented一样:

如果Parent不是nil(Delphi)或NULL(C ++),则设置ParentWindow无效。

对于两者,您正在设置Parent属性 -


0
投票

你的PMenuForm被阻止的原因是因为你的父亲已经在另一个表单上设置了一个控件,这意味着你的表单窗口实际上是另一个表单的子窗口。

因此,当该表单被ShowModal调用阻止时,您的PMenuForm无法接收OnClick消息,因为为了这样做,必须从父表单或组件转发此类消息,在这种情况下,此时将禁用该表单或组件。

因此,我担心你必须使用不同的方法来实现你想要的。这就是我要做的。

正常显示您的PMenuForm但禁用表单上的其他控件。您可以通过将控件放在面板上然后简单地禁用面板来轻松完成此操作,这些面板又会禁用放置在面板上的所有子控件。如果您的应用程序有多个表单,您也可以禁用其他表单,因此使用模式表单的效果相似。

© www.soinside.com 2019 - 2024. All rights reserved.