Recent

Author Topic: How to create menu at runtime?  (Read 4984 times)

zamtmn

  • Sr. Member
  • ****
  • Posts: 365
How to create menu at runtime?
« on: June 12, 2013, 11:12:02 pm »
It is a bug or I doing something wrong? This code works in gtk2 and win, but in qt causes an error:
Code: [Select]
procedure TForm1._onCreateForm(Sender: TObject);
var
  MyItem:TMenuItem;
  MyMenu:TMainMenu;
begin
     MyMenu:=TMainMenu.Create(application);
     MyItem:=TMenuItem.Create(MyMenu);
     MyItem.Caption:='fail';
     MyMenu.items.Add(MyItem);
     self.Menu:=MyMenu;
end;
Lazarus&FPC from trunk

taazz

  • Hero Member
  • *****
  • Posts: 5363
Re: How to create menu at runtime?
« Reply #1 on: June 12, 2013, 11:27:28 pm »
change
Code: [Select]
     MyMenu:=TMainMenu.Create(application);
to
Code: [Select]
     MyMenu:=TMainMenu.Create(Self);

Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

zamtmn

  • Sr. Member
  • ****
  • Posts: 365
Re: How to create menu at runtime?
« Reply #2 on: June 13, 2013, 06:44:14 am »
Thank you, it works. But it should work with Application

zeljko

  • Hero Member
  • *****
  • Posts: 1079
    • http://wiki.lazarus.freepascal.org/User:Zeljan
Re: How to create menu at runtime?
« Reply #3 on: June 13, 2013, 08:00:25 am »
Thank you, it works. But it should work with Application

No it cannot work like that since WS.CreateHandle() expects TCustomForm as owner.

class function TQtWSMenu.CreateHandle(const AMenu: TMenu): HMENU;
var
  MenuBar: TQtMenuBar;
  Menu: TQtMenu;
begin
  { If the menu is a main menu, there is no need to create a handle for it.
    It's already created on the window }
 
  if (AMenu is TMainMenu) and (AMenu.Owner is TCustomForm) then <------------ See this
  begin
    MenuBar := TQtMainWindow(TCustomForm(AMenu.Owner).Handle).MenuBar; <------------- and then this

    Result := HMENU(MenuBar);
  end
  else if (AMenu is TPopUpMenu) then
  begin
    Menu := TQtMenu.Create(AMenu.Items);
    Menu.AttachEvents;
 
    Result := HMENU(Menu);
  end;

  {$ifdef VerboseQt}
    Write('[TQtWSMenu.CreateHandle] ');

    if (AMenu is TMainMenu) then Write('IsMainMenu ');

    WriteLn(' Handle: ', dbghex(Result), ' Name: ', AMenu.Name);
  {$endif}
end;

While creating menu handle parent is still unassigned, so owner is only solution.
Maybe I can add check for Application as owner, but in that case that menu should be treated only as TApplication.MainForm child.



zamtmn

  • Sr. Member
  • ****
  • Posts: 365
Re: How to create menu at runtime?
« Reply #4 on: June 13, 2013, 08:38:05 am »
Thans, if it's not a bug - I will not use Application