1

bpls 形式のプラグインをロードするアプリケーションがあります。各プラグインには、MTabcontrol1 として知られる TTabcontrol を含むアプリケーションのベース GUI である CoreInf (フォーム名 ManageF) と呼ばれる別のパッケージに埋め込むフォームが含まれています。ここで基本的に何が起こるか

プラグインのリストは、インターフェイスをレイアウトするために、実行時に順番に動的にロードされます。インターフェイス IPluginFrame(Shared.bpl) に基づいてプラグインをロードします。インターフェイスが含まれている場合は、MTabcontrol1 に新しいタブを作成し、フォームを埋め込もうとします。私がやろうとしているのは、動的に作成されたスピードボタン onClick を特定の埋め込みフォームの 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;

問題を適切に説明したいと思います。助けてください =(

4

1 に答える 1

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;

少しずさんですが、動作します =)。他の誰かがより良い方法を知っているなら、私に知らせてください

于 2014-07-03T04:27:16.823 に答える