DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: herinspace
今日帖子: 15
在线用户: 12
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 changfenglee (葫芦老四) ★☆☆☆☆ -
普通会员
2023/6/14 20:25:33
标题:
关于FMX嵌入式窗体问题请教 浏览:1129
加入我的收藏
楼主: 各位大佬,小弟又来请教了

问题描述:我将子窗体显示在主窗体的Layout里面,但子窗体的权限控制失效了,非嵌入的窗体权限正常

我将代码贴上,求高手指点一下看如何修改代码,或是有其它的改善案例也行,在此先行谢过了

【主窗体调用子窗体代码】:
   Layout3.RemoveObject(0);
   Layout3.AddObject(FrmUserInf.LayUserInf);


【权限代码】:
procedure LevelLoadItems(MyForm:TForm;MyAdoQuery:TClientDataSet);
var
  MMItems:string;
  cx:Integer;
  Obj:TComponent;
begin
  MyAdoQuery.Close;
  MyAdoQuery.CommandText:='select * from LevelInf where GroupName= '''+ Trim(FrmMain.Label8.Text) +'''';
  MyAdoQuery.Open;

  MyAdoQuery.First;
  while not MyAdoQuery.Eof do
  begin
    MMItems:=MyAdoQuery.fieldbyname('SysName').AsString;
    for cx:=0 to MyForm.ComponentCount - 1 do
    begin
      Obj:=TComponent(MyForm.Components[cx]);

      if Obj.Name=MMItems then
      begin
        if Obj is TButton then
        begin
          TButton(Obj).Visible:=True;
        end;

       if Obj is TMenuItem then
       begin
         TMenuItem(Obj).Visible:=True;
       end;

       if Obj is TComboBox then
       begin
         TComboBox(Obj).Visible:=True;
       end;

       if Obj is TMemo then
       begin
         TMemo(Obj).Visible:=True;
       end;

       if Obj is TPanel then
       begin
         TPanel(Obj).Visible:=True;
       end;

       if Obj is TTreeViewItem then
       begin
         TTreeViewItem(Obj).Visible:=True;
       end;

      end;
    end;
    MyAdoQuery.Next;
  end;
end;
----------------------------------------------
【个人签名】:玩了多年DELPHI,终于从菜鸟升级成老菜鸟
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2023/6/15 0:23:12
1楼: @changfenglee you can try some like this:

implementation

{$R *.fmx}

uses
  Unit2;

function funcShowOnlyControlsAuthorized(AControlsAuthorized: TArray<string>; AControl: TControl): boolean;
begin
  result := false;
  //
  if (length(AControlsAuthorized) = 0) or (AControl = nil) then
    exit;
  //
  for var C in AControlsAuthorized do
    if (C = AControl.ClassName) then
      exit(true);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  LFoundControlsOnLayout2OnForm2: boolean;
  LObjectOnLayout2          : TArray<TControl>;
begin
  LFoundControlsOnLayout2OnForm2 := false;
  //
  if (Form2 = nil) then
    Form2 := TForm2.Create(nil);
  //
  try
    // if dont exists a "Layout" on Form2 = exception!!!
    LFoundControlsOnLayout2OnForm2 := (Form2.LayoutMainForm2.ControlsCount > 0);
    //
    LayoutMainOfForm1.DeleteChildren;
    //
    // Because when using "xxxx.ADDObject()", the object will be "removed from source" and "added on target"!!!
    for var i: integer := 0 to (Form2.LayoutMainForm2.ControlsCount - 1) do
      LObjectOnLayout2 := LObjectOnLayout2 + [Form2.LayoutMainForm2.Controls[i]];
    //
    for var i: integer := 0 to high(LObjectOnLayout2) do
      begin
        if funcShowOnlyControlsAuthorized(['TEdit', 'TListBox', 'TLabel'], LObjectOnLayout2[i]) then
          LayoutMainOfForm1.AddObject(LObjectOnLayout2[i]); // WARNING: "this will remove automatically any object from Form2"
      end;
  finally
    if not LFoundControlsOnLayout2OnForm2 then
      FreeAndNil(Form2);
  end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FreeAndNil(Form2);
end;

initialization

ReportMemoryLeaksOnShutdown := true;

end.
此帖子包含附件:
PNG 图像
大小:8.0K
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 changfenglee (葫芦老四) ★☆☆☆☆ -
普通会员
2023/6/15 10:50:07
2楼: To:emailx45

首先非常感谢您的回复与指导。

按您的代码所写,我如果没有理解错误,是在我原来一次导入的基础上,修改为遍历控件并加入判断条件导入,其中可以在这中间的过程加入权限控制的代码,是这意思吗?

这种方式在我这里将存在一些问题,我的权限控制的逻辑在这种方式中实现起来比较困难,这跟最开始设计的方式有关,因为当前我是从VCL转成FMX,数据库内的数据需要引用
----------------------------------------------
【个人签名】:玩了多年DELPHI,终于从菜鸟升级成老菜鸟
作者:
男 changfenglee (葫芦老四) ★☆☆☆☆ -
普通会员
2023/6/15 11:06:56
3楼: 可能我对问题的描述还存在一些问题,这里我再详细说明一下:

我是从VCL转到FMX,数据库的内容不能变,只是更换软件客户端界面而已,是为了跨平台使用。

在VCL的时候,我采用的是选项卡显示窗体的模式,即每打开一个窗体就在PageControl上增加一个选项卡,窗体上控件的权限也在这时候导入。

换成FMX以后,选项卡模式没有再采用,而是接受了emailx45的方法,使用Layout.AddObject方法,但这种方式导致了权限控制的失效

所以我现在想重归问题本身:
1.还是继续研究选项卡方式打开窗体?
2.或者是如何解决Layout.AddObject权限问题?
3.有其它方式实现?

下面我将VCL的代码贴上,请各位给点意见,谢谢

【VCL模式下选项卡窗体代码】
procedure TFrmMain.OpenForm(FrmName, FrmCaption: string; MyFormCls: TFormClass);
var
    MyTabSheet:TRzTabSheet;
    MyForm:TForm;
 begin
    MyTabSheet := TRzTabSheet(self.FindComponent(FrmName));
    if MyTabSheet = nil then
    begin
      try
        MyTabSheet :=  TRzTabSheet.Create(self);
        MyTabSheet.Name := FrmName;
        MyTabSheet.PageControl := RzPageControl1;
        MyTabSheet.Caption := FrmCaption;
        MyTabSheet.Align := alClient;
          try
          MyForm:=MyFormCls.Create(Self);
          MyForm.Parent:=MyTabSheet;
          MyForm.BorderStyle:=bsNone;
          MyForm.Align:=alClient;
          LevelLoadItems(MyForm,FDQuery2); //导入权限控制
          MyForm.Show;
          except
          FreeAndNil(MyForm);
          Abort;
          end;
      except
         FreeAndNil(MyTabSheet);
         Exit;
      end;
    end;
     RzPageControl1.ActivePage:=MyTabSheet;
end;

【权限控制代码】
procedure LevelLoadItems(MyForm:TWinControl;MyAdoQuery:TFDQuery);
var
  MMItems:string;
  cx:Integer;
  Obj:TComponent;
begin
  MyAdoQuery.Close;
  MyAdoQuery.SQL.Clear;
  MyAdoQuery.SQL.Add('select * from LevelInf where GroupName= '''+ FrmMain.GroupName +'''');
  MyAdoQuery.Open;

  MyAdoQuery.First;
  while not MyAdoQuery.Eof do
  begin
    MMItems:=MyAdoQuery.fieldbyname('SysName').AsString;
    for cx:=0 to MyForm.ComponentCount - 1 do
    begin
      Obj:=TComponent(MyForm.Components[cx]);

      if Obj.Name=MMItems then
      begin
        if Obj is TButton then
        begin
        //  TWinControl(Obj as TButton).Enabled:=True;
          TButton(Obj).Enabled:=True;
        end;

       if Obj is TMenuItem then
       begin
         TMenuItem(Obj).Enabled:=True;
       end;

       if Obj is TComboBox then
       begin
         TComboBox(Obj).Enabled:=True;
       end;

       if Obj is TMemo then
       begin
         TMemo(Obj).Enabled:=True;
       end;

       if Obj is TPanel then
       begin
         TPanel(Obj).Enabled:=True;
       end;

      end;
    end;
    MyAdoQuery.Next;
  end;
end;
----------------------------------------------
【个人签名】:玩了多年DELPHI,终于从菜鸟升级成老菜鸟
作者:
男 denis (Denis) ★☆☆☆☆ -
盒子活跃会员
2023/6/15 17:31:51
4楼: for cx:=0 to MyForm.ComponentCount - 1 do
这个地方有问题 找不到你要的component
没有完整源码,不方便测试
----------------------------------------------
-
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2023/6/16 5:12:48
5楼: try this
此帖子包含附件:
GIF 图像
大小:166.8K
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2023/6/16 5:13:14
6楼: project ... FMX
此帖子包含附件:emailx45_202361651314.zip 大小:11.2K
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 zhyhero (zhyhero) ★☆☆☆☆ -
盒子活跃会员
2023/6/16 8:09:32
7楼:  Layout3.AddObject(FrmUserInf.LayUserInf);
改成 Layout3.AddObject(FrmUserInf.LayUserInf( {SetupCodeObjectOrVar} ));
不知道怎么样?
----------------------------------------------
z@S7
作者:
男 changfenglee (葫芦老四) ★☆☆☆☆ -
普通会员
2023/6/16 15:10:02
8楼: To:emailx45

先谢谢您的指点,您使用的是Frame模式,不知道窗体模式如何实现,因为Frame模式对于我来说,改动实在太大。

我主要解决的问题只要针对窗体进行嵌入就好,无论是嵌入在Panel还是Layout,或是其它控件内
----------------------------------------------
【个人签名】:玩了多年DELPHI,终于从菜鸟升级成老菜鸟
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2023/6/17 2:55:50
9楼: @changfenglee

“框架”类似于“窗体”,主要区别在于“框架”必须嵌入某个“容器”内,即窗体、面板、布局等......任何其他接受的控件!

这样,您只需创建一个新的“框架”(就像您创建一个“表单”,并添​​加您的控件和代码一样)
之后,只需将您的“框架”添加到任何您想要的地方,次数不限。 例如,它比在面板中嵌入“表单”更容易!
此帖子包含附件:
GIF 图像
大小:1.25M
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 denis (Denis) ★☆☆☆☆ -
盒子活跃会员
2023/6/17 8:07:40
10楼: @changfenglee
你弄一个简单的能运行的demo出来,这样可以测试
你放出的主窗体2行代码太少
权限代码是在哪里调用
这样的问题,没有demo,别人没法帮到你,是你的代码问题,还是传参的问题
----------------------------------------------
-
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2023/6/17 19:05:34
11楼: 可以不用tframe和tform,考虑使用panel作为容器,在fmx里不像vcl,很多组件都是窗口,但使用fmx的窗口、tframe,可以牵涉到一些消息机制问题,不如使用panel好些。layout没试过,估计没panel好使。
----------------------------------------------
-
作者:
男 changfenglee (葫芦老四) ★☆☆☆☆ -
普通会员
2023/6/19 15:06:41
12楼: 非常感谢大家的指点,我综合大家的意见,查询了一些资料,现在问题解决了

还是使用的窗体嵌入的方式,权限问题也解决了,代码如下:

//打开窗体的涵数
procedure TFrmMain.OpenForm(AParent: TControl; AForm: TCustomForm);
begin
 while AForm.ChildrenCount>0 do
    AForm.Children[0].Parent:=AParent;
    LevelLoadItems(AForm,CDS); {此处是调用权限管理,代码在楼上}
end;

//调用打开窗体涵数,显示在主页面的Layout3里面
   Layout3.DeleteChildren;
   OpenForm(Layout3,TFrmWorkTask.Create(Self));

做以上两项就可以实现嵌入式窗体,权限管理问题也可以了,这个问题花了点时间解决,在此期间感谢大家的热情指点,特别是要感谢emailx45,因为你您的多次指点,我解决了很多的问题
----------------------------------------------
【个人签名】:玩了多年DELPHI,终于从菜鸟升级成老菜鸟
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2023/6/20 0:41:57
13楼: YAAAHOOOOOOO !!!
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2023/6/20 2:17:10
14楼: 楼主,你看看这个:

https://blog.csdn.net/pcplayer/article/details/126592420

我这个写的是 SkiaForDelphi 那个控件的例子代码。你直接去研究它的例子代码也可以。
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行1917.969毫秒 RSS