Отображение модальной формы из компонента - PullRequest
0 голосов
/ 31 августа 2018

У меня проблема с отображением модальной формы из пользовательского компонента. Во время запуска приложения 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. Предполагается, что родительская форма «заблокирована» / не отвечает, но это также влияет на отображаемую форму меню - она ​​также не отвечает (нажимает на нее).

Ответы [ 3 ]

0 голосов
/ 31 августа 2018

Эта строка: PMenuFormItems[0].OnClick := self.MenuItemClick; говорит о том, что self (CustomComponent) имеет метод MenuItemClick. Это реализовано? Что это делает?

Вот где щелкнет битовая кнопка PMenuFormItems[0]. Если это не приведет ни к установке PMenuForm.ModalResult, ни к конкретному закрытию PMenuForm, безответственность продолжается.

В вашем коде есть две настройки

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

что я должен был убить Они вызвали AV: s

Они бесполезны в вашем коде, так как задокументировано :

Настройка ParentWindow не действует, если Parent не равен nil (Delphi) или NULL (C ++).

Для обоих вы устанавливаете свойство Parent-

0 голосов
/ 01 сентября 2018

Причина, по которой ваш PMenuForm блокируется, заключается в том, что в качестве его родителя вы установили элемент управления для другой формы, что означает, что окно вашей формы фактически является дочерним окном другой формы.

Таким образом, когда эта форма блокируется вызовом ShowModal, ваш PMenuForm не может получить сообщение OnClick, потому что для этого такое сообщение должно быть перенаправлено из родительской формы или компонента, который в этом случае отключен в данный момент.

Поэтому я боюсь, что вам придется использовать другой подход для достижения того, что вы хотите. Вот что я бы сделал.

Показывайте свой PMenuForm нормально, но отключайте другие элементы управления в вашей форме. Это можно легко сделать, разместив элементы управления на панелях, а затем просто отключив панели, что, в свою очередь, отключит все дочерние элементы управления, размещенные на панелях. Если ваше приложение имеет несколько форм, вы также можете отключить эти другие формы и, таким образом, эффект, аналогичный использованию модальных форм.

0 голосов
/ 31 августа 2018

Это намеренно, начиная с первой версии Delphi. Самая старая онлайновая HTML-документация взята с Delphi 2007, где ShowModal документов:

Используйте ShowModal, чтобы отобразить форму в качестве модальной формы. Модальная форма - это та, в которой приложение не может продолжать работать, пока форма не будет закрыта. Таким образом, ShowModal не возвращается, пока форма не закроется. Когда форма закрывается, она возвращает значение свойства ModalResult.

Если ваш вопрос на самом деле о том, как обходить меню, которое также блокируется:

  • не используйте ShowModal, но Show, и будьте готовы к тому, что форма больше не является модальной, поэтому пользователь может переключаться между формой и остальной частью приложения
  • показать меню в модальной форме
...