CRO_Tomislav 0 Posted November 5, 2020 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
CRO_Tomislav 0 Posted November 5, 2020 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 Posted November 15, 2020 (edited) 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 November 15, 2020 by Guest Share this post Link to post