Jump to content
CRO_Tomislav

FMX Show and Hide MainMenu from code

Recommended Posts

Dear all.

 

I am trying to migrate from Delphi VCL to Delphi Firemonky application.

In VCL I am using several ManiMenus.

 

In VCL form, on Show I have:

Form_main.Menu := nil;

Also in VCL, depending on which button is pressed I load certain MainMenu

Form_main.Menu := MainMenu_Parts;

 

I stuck in FMX with this because it handle MainMenu totally different. How I can do the same in FMX?

 

Thanks in advance

Tomislav

Share this post


Link to post

Hi.

 

I achieve the same effect by replacing MainMenu with MenuBar and set a Menubr.Visible := False and True.

 

Is this OK or there is some elegant non complicated solution? 8)

 

With best regards

Tomislav

 

Share this post


Link to post
Guest

in FMX, you can have just 1 MainMenu for all application!

a possibility is create all items and childrens for all forms, and set the "visible" only for menuitem necessary in each form used!
Then, that way, it's not necessary have a "clone" of old menu! Else, you can store this MainMenu for "when" close new form, re-create it or re-show the hide items!

 

some like this:

// main-form
var
  lMainMenuObj: TMainMenu = nil; // this will be our MainMenu for all app!
...
implementation
...

///----- prcMyLogMemo = my procedure to "Memo1.Lines.Add( xxxx );"

procedure TfrmFormMain.btnVerifyingOrAssigningAMainMenuToAppClick(Sender: TObject);
begin
  try
    if not(Self.MainMenu = nil) then
      prcMyLogMemo(Format('The MainMenu.Name is [%s]', [Self.MainMenu.Name]))
    else
    begin
      if (lMainMenuObj = nil) then
      begin
        lMainMenuObj      := TMainMenu.Create(Self); // owner! ... creating my MainMenu by code
        lMainMenuObj.Name := 'mmnuMyMainMenuForAppWhole';
        // *********************************************************************************
        // "parent" property, do the magic happens!
        // when defining the "parent" you are "attributing" your "MainMenu" for your form!
        // then, Self.MainMenu will be assigned!
        // remember: Only one MainMenu is accepted in your app!
        // *********************************************************************************
        //
        lMyMenuItem         := TMenuItem.Create(lMainMenuObj);
        lMyMenuItem.Name    := Format('MMItem%d', [TMainMenu(Self.MainMenu).ItemsCount + 1]);
        lMyMenuItem.Text    := lMyMenuItem.Name;
        lMyMenuItem.OnClick := prcMyMenuItemsClick;
        //
        lMainMenuObj.AddObject(lMyMenuItem); // adding the Items to MainMenu 
        //
        prcMyLogMemo(Format('MainMenu [%s] was created and first MenuItem = [%s] was added on MainMenu', { }
          [lMainMenuObj.Name, lMyMenuItem.Name]));
        //
        lMyMenuItem := nil; // maybe it's not necessary if it was "local" in this procedure!
		//
        lMainMenuObj.Parent := Self; // now, we are defining "who" will be our "MainMenu" // let it for last command-line! when all is defined ok?
      end
      else
        prcMyLogMemo('(lMainMenu=nil) and (lMainMenuObj.Name=' + lMainMenuObj.Name);
    end;
  except
    on e: exception do
      ShowMessage(e.Message);
  end;
end;

procedure TfrmFormMain.btnCreatingSecondFormClick(Sender: TObject);
var
  lMyFormSecond: TfrmFormSecondTests;
begin
  {
    a possibility is create all items and childres for all forms, and set the "visible" only for
    menuitem necessary in each form used!
    Then, that way, it's not necessary have a "clone" of old menu!
  }
  if not(lMainMenuObj = nil) then
  begin
    lBkpMainMenu := lMainMenuObj; // dont works like expected! It's just a "pointer", not a "copy of object"
    ShowMessage(lMainMenuObj.Name + ', entering in FormSecond');
  end;
  //
  lMyFormSecond := TfrmFormSecondTests.Create(nil);
  try
   // now, in FormSecond, I can destroy or hide the items not necessary or any other thing... in my sample, when I came back... the MainMenu was destroyed by FormSecond.destoy event
    lMyFormSecond.ShowModal;
  finally
    FreeAndNil(lMyFormSecond);
  end;
  //
  // as our MainMenu as "destroyed" in FormSecond, let's re-create again!
  // as the Items was not cleaned, then, it's not necessary recreat it!
  if not(lBkpMainMenu = nil) then
  begin
    ShowMessage('came back from FormSecond');
    //
    // lMainMenuObj        := TMainMenu.Create(Self); // owner!
    // lMainMenuObj.Parent := Self;
    ... recreating the MainMenu or just enable its hide "Items"
  end;
end;

 

var
  frmFormSecondTests: TfrmFormSecondTests;

implementation

{$R *.fmx}

uses
  // System.Generics.Collections,
  uFormMainTests;

var
  lBackupMainMenuObj: TMainMenu;
  lNewMainMenuObj   : TMainMenu;
  lMyMenuItem       : TMenuItem;
  //
  lMyMenuBarClone: TMenuBar;

procedure TfrmFormSecondTests.btnDestroyMainMenuAndCreateANewMainMenuClick(Sender: TObject);
begin
  if (not(lMainMenuObj = nil)) and (lMainMenuObj is TMainMenu) then
  begin
    ShowMessage((lMainMenuObj as TMainMenu).Name);
    //
    // If you needs create a new MainMenu, then, you need "destroy" older in use!
    // all items will be destroyed too!
    (lMainMenuObj as TMainMenu).Free;
    lMainMenuObj := nil;
    ShowMessage('menu main destruido');
    //
    //
    lNewMainMenuObj      := TMainMenu.Create(self); // owner!
    lNewMainMenuObj.Name := 'NewmmnuMyMainMenuForAppWhole';
    // *********************************************************************************
    // "parent" property, do the magic happens!
    // when defining the "parent" you are "attributing" your "MainMenu" for your form!
    // then, Self.MainMenu will be assigned!
    // remember: Only one MainMenu is accepted in your app!
    lNewMainMenuObj.Parent := self; // now, we are defining "who" will be our "MainMenu"
    // *********************************************************************************
    //
    lMyMenuItem      := TMenuItem.Create(lNewMainMenuObj);
    lMyMenuItem.Name := Format('NewMMItem%d', [TMainMenu(self.MainMenu).ItemsCount + 1]);
    lMyMenuItem.Text := lMyMenuItem.Name;
    //
    lNewMainMenuObj.AddObject(lMyMenuItem);

  end;
end;

procedure TfrmFormSecondTests.CloseThisFormClick(Sender: TObject);
begin
  if (not(lNewMainMenuObj = nil)) and (lNewMainMenuObj is TMainMenu) then
  begin
    ShowMessage((lNewMainMenuObj as TMainMenu).Name);
    //
    // if you need use older MainMenu, you need "destroy" the current MainMenu!
    (lNewMainMenuObj as TMainMenu).Free;
    lNewMainMenuObj := nil;
    //
    ShowMessage('menu main form2 destruido');
    //
    if not(lBkpMainMenu = nil) then
      ShowMessage(lBkpMainMenu.ItemsCount.ToString + ', voltando do formsecond');
    //
    close;
  end;
end;

procedure TfrmFormSecondTests.FormDestroy(Sender: TObject);
begin
  if not(lMyMenuBarClone = nil) then
    lMyMenuBarClone.Free;
end;

 

Edited by Guest

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×