Delphi Change main form while application is running

后端 未结 8 1734
无人及你
无人及你 2020-12-03 06:07

I have this problem. When I hide my main form, then the taskbar icon of my application is also hidden. I saw a new question about this problem as well and the answers didn\'

相关标签:
8条回答
  • 2020-12-03 06:41

    You can change main form. Do a variable F: ^TForm, then set it to @Application.MainForm. After that you can set main form as via F^ := YourAnotherForm.

    0 讨论(0)
  • 2020-12-03 06:41

    I've had an additional issue working with Delphi XE2 MDI apps that are also COM servers. My main form Main calls a secondary form MenuForm which contains shared icons and popup menus for the whole app.

    In my example, the app works perfectly when run standalone.

    Main gets created, and then creates a MenuForm at the end of FormCreate. All good.

    But when called from a COM server, Main.FormCreate is called first, but somehow MenuForm gets assigned to Application.MainForm. There is a race condition in the underlying RTL. This causes havoc when trying to create the first SDI child, as Application.MainForm is not MDI.

    I tried working around this by Main.FormCreate posting a message back to itself, to delay creation of MenuForm until after Main.FormCreate has returned.

    But there is still a race condition here - MenuForm was still assigned to Application.MainForm.

    I was eventually able to work around this using code to poll Application.MainForm every 10ms, with a maximum of 10 seconds. I also had to remove any reference in Main to MenuForm's icon list (in the .dfm) until after MenuForm was created explicitly - otherwise MenuForm would get created implicitly at the end of MainForm.create.

    Hope this helps someone!

    const
      CM_INITIAL_EVENT = WM_APP + 400;
    
    
    TmainForm = class(TForm)
      ...
      procedure afterCreate(var Message: TMessage); message CM_INITIAL_EVENT;
      ...
    end;
    
    
    procedure TmainForm.FormCreate(Sender : TObject);
    begin
      ...
      ...standard init code
      ...
    
      postmessage( handle, CM_INITIAL_EVENT, 0, 0 );
    End;
    
    
    procedure TmainForm.AfterCreate(var Message: TMessage);
    var
      i: Integer;
    begin
    
      //must assign these AFTER menuform has been created
      if menuForm = nil then
      begin
        //wait for mainform to get assigned
        //wait up to 10*1000ms = 10 seconds
        for i := 0 to 1000 do
        begin
          if Application.Mainform = self then break;
          sleep(10);
        end;
    
        Application.CreateForm(TmenuForm, menuForm);
        menuForm.parent := self;
      end;
    
      //NOW we can assign the icons
      Linktothisfilterfile1.SubMenuImages := menuForm.treeIconList;
      ActionManager.Images := menuForm.treeIconList;
      allFilters.Images := menuForm.treeIconList;
      MainMenu.Images := menuForm.treeIconList;
      ...
    end;
    
    0 讨论(0)
提交回复
热议问题