将TEdit聚焦在动态加载的嵌入式Form Firemonkey上

时间:2014-06-30 00:16:25

标签: delphi firemonkey delphi-xe6 firemonkey-fm3

我有一个应用程序,它加载了bpls形式的插件。每个插件都包含一个要嵌入到另一个名为CoreInf的包中的表单(表单名称为ManageF),它只是包含称为MTabcontrol1的TTabcontrol的应用程序的基本gui。这基本上发生了什么

插件列表在运行时按顺序动态加载,以布局界面。它基于接口IPluginFrame(Shared.bpl)加载插件。如果它包含接口,则它会尝试在MTabcontrol1中创建一个新选项卡并嵌入表单。我想要做的是在动态创建的速度按钮onClick焦点特定的ebedded表单上的TEdit框,但它会不断出现访问冲突错误。

包含界面的Shared.bpl

unit PluginIntf;

interface

uses
  FMX.Types, FMX.Controls;

type
  IPluginFrame = interface
  ['{3B4943DB-951B-411B-8726-03BF1688542F}']
    function GetBaseControl: TControl;
  end;


implementation

end.

要嵌入界面的表单和按钮

InventoryInf.pas具有要嵌入的表单

    var
      InventoryF: TInventoryF;

    implementation

    {$R *.fmx}

    function TInventoryF.GetBaseControl: TControl;
    begin
      Result := InvenLayout;  //<---- This is a a TLayout which align 
                              //to client this is the parent of every item on form
    end;

    //Below is the on click event for the TSpeedButton invBtn 
    //Which looks for the embedded form that is embedded
   //in MTabcontrol1 as a TTabitem that has the name InventoryF 

    procedure TInventoryF.Look4Tabitem(Sender: TObject);
    var
     o : TTabitem;
     s :TEdit;
    begin
     o  := TTabitem(ManageF.MTabcontrol1.FindComponent('InventoryF'));

     ManageF.MTabcontrol1.ActiveTab := o;

    s  := TEdit(ManageF.MTabcontrol1.FindComponent('VendorF').FindComponent('SearchEdit1')); <-- Dont  think it actually found the TEdit                               

    s.Setfocus;  <------------------ Not focusing giving access violtaion error

      with DataConModule1.InventoryQuery do
      ...   


    end;

注入Panel的TSpeedButton invBtn

unit InjectedInvBtn;
interface
implementation
uses
  FMX.Types, InventoryInf, FMX.Controls, FMX.Forms, InjectedControlsHelper, FMX.StdCtrls,
  ManageInf;
var
  SysBtn: TSpeedButton;
initialization
  SysBtn := TInjectedControl<TSpeedButton>.Create;
  SysBtn.Align := TAlignLayout.Top;
  SysBtn.Name := 'invBtn';
  SysBtn.Text := 'INVENTORY';
  ManageF.MenuPanel.AddObject(SysBtn);
  SysBtn.OnClick := InventoryF.Look4Tabitem;
end.

** ManageF显示如何将表单加载到选项卡MTabControl1 **

uses Shared;


function IsPluginFrameClass(AType: TRttiType; var AFormClass: TCustomFormClass): Boolean;
var
  LClass: TClass;
begin
  if not (AType is TRttiInstanceType) then Exit(False);
  LClass := TRttiInstanceType(AType).MetaclassType;
  Result := LClass.InheritsFrom(TCustomForm) and Supports(LClass, IPluginFrame);
  if Result then
    AFormClass := TCustomFormClass(LClass);
end;


function TSettingsF.LoadPluginTabs(const AFileName: string): HMODULE;
var
  Context: TRttiContext;
  Frame: TCustomForm;
  FrameClass: TCustomFormClass;
  LType: TRttiType;
  Package: TRttiPackage;
  Tab: TTabItem;
 // Statusbar: TTabItem;
  //Butz: TButton;
begin
  Result := LoadPlugin(AFileName);
  try
    { Cycle through the RTTI system's packages list to find the one we've just loaded. }
    for Package in Context.GetPackages do
      if Package.Handle = Result then
      begin
        { Cycle through the package's types looking for implementors of the
          IPluginFrameinterface defined in the shared package. }
        for LType in Package.GetTypes do
    if IsPluginFrameClass(LType, FrameClass) then
          begin
            { For each frame, create a new tab to host its contents. In the case of
              a VCL application, we could require an actual TFrame object, or failing
              that, embed the form directly. FireMonkey has neither frames proper nor
              supports embedded forms, so instead we ask the implementing form to
              nominate a base control that will get embedded. }
            Tab := TTabItem.Create(ManageF.MTabcontrol1);
            Frame := FrameClass.Create(Tab);
            Tab.Text := ' ' + Frame.Caption;
            Tab.Name := Frame.Name;

            MyTablist.Add(Tab);


            (Frame as IPluginFrame).GetBaseControl.Parent := Tab;
            { Associate the tab with the plugin - since it owns the 'frame' form,
              and that form owns its own components, freeing the tab will have the
              effect of freeing all the actual plugin objects too. }
            RegisterPluginComponent(Result, Tab);
            ManageF.MTabcontrol1.AddObject(Tab);
            Tab.Width := Tab.Canvas.TextWidth(Tab.Text + 'w');

          end;

           if IsStatusFrameClass(LType, FrameClass) then

           begin

           ....

            { Associate the tab with the plugin - since it owns the 'frame' form,
              and that form owns its own components, freeing the tab will have the
              effect of freeing all the` actual plugin objects too. }
           // RegisterPluginComponent(Result, Statusbar);
          //  ManageF.StatusMenuPanel1.AddObject(Statusbar);
            //Statusbar.Width := Statusbar.Canvas.TextWidth(Statusbar.Name + 'w');



           end;
        Break;

     end;
  except
    UnloadPlugin(Result);
    raise;
  end;
end;

希望我能正确说明问题。请帮助=(

1 个答案:

答案 0 :(得分:0)

通过循环嵌入Tcustomform的组件找到了解决方法。这就是我做的。

而不是TEdit,我使用了tms编辑框TTMSFMXSearchEdit

procedure TVendorF.focuscheck;
var
  i: integer;
  j: integer;
  Fieldname: string;
  o : TTabitem;
  e : TTMSFMXSearchEdit;
begin
  if ManageF.MTabcontrol1.FindComponent('VendorF').Name = 'VendorF' then
    begin
    o  := TTabitem(ManageF.MTabcontrol1.FindComponent('VendorF'));

   //ShowMessage(IntToStr(o.ComponentCount)) ;
   // ShowMessage((o.Components[0].tostring));

      for i := 0 to ManageF.MTabcontrol1.ActiveTab.ComponentCount - 1 do
        if (ManageF.MTabcontrol1.ActiveTab.Components[i]) is TCustomForm then
          begin
         // ShowMessage('TCustomForm Recognized gonna look for child components now');
         // ShowMessage(IntToStr(ManageF.MTabcontrol1.ActiveTab.Components[i].ComponentCount));

        for j := 0 to ManageF.MTabcontrol1.ActiveTab.Components[i].ComponentCount - 1 do
                if (ManageF.MTabcontrol1.ActiveTab.Components[i].Components[j]) is TTMSFMXSearchEdit then
                   begin
                   // ShowMessage('Edit box found =)')
                        if (ManageF.MTabcontrol1.ActiveTab.Components[i].Components[j].Name = 'VenSearchEdit1') then
                           begin
                           //ShowMessage('Edit1 box found =)');
                           //ShowMessage('See if we can focus it');
                           e := TTMSFMXSearchEdit(ManageF.MTabcontrol1.ActiveTab.Components[i].Components[j]) ;
                           e.SetFocus;
                           end;

                end;
        end;
   end;
end;

它有点草率但它的工作原理=)。如果其他人有更好的方式让我知道