• Delphi MDI多文档架构几个问题解决


    1.关于登录窗口(Login):

    很多时候我们在做开发delphi的MDIform时,常常因为要做进去Login一个正常的登录窗口,平常做Login的project代码如下:
    只有Login登录成功了时候,才会建立起frm_Main窗体,这是正常不用MDI框架的正常登录与主窗体切换。

    Application.CreateForm(Tfrm_Login, frm_Login);
        if frm_Login.ShowModal = mrOK then //登录窗体关闭时返回了mrOK值,说明登录成功
        begin
          Application.CreateForm(Tfrm_Main, frm_Main);
          frm_Main.ShowModal;
        end;

    现在问题是frm_Main是MDI主窗体,而delphi会把第一个CreateForm认定为MDI主窗体,而frm_Login的FormsTyle是fsNormal正常窗体。

    如果按上面的代码的话,将导致“Cannot create form.No MDI forms are currently active."

    解决方案:

    既然delphi会把第一个CreateForm认定为MDI主窗体,那我们就把Application.CreateForm(Tfrm_Main,frm_Main);放在最前,project代码如下:

      Application.CreateForm(Tfrm_Main, frm_Main);
      Application.CreateForm(Tfrm_Login, frm_Login);

    这样的话执行后的第一个窗口不是Login 而是Main窗体,这时我们需要再Main窗体OnCreate事件中加进如下代码:

    procedure Tfrm_Main.FormCreate(Sender: TObject);
    begin
      with Tfrm_Login.Create(Self) do ShowModal;
    end;

    加上这句后的,执行后的第一个窗口就是Login,第一个问题解决。

    2.关于MDI子窗体最小化,与窗体恢复:

    在做MDI窗体的时候,点击菜单按钮呼出第一个MDI子窗体。对MDI子窗体最小化后,我们会看到窗体在主窗体的左下角。

    而当我们往往再次点击菜单那个按钮不是再次重新建立一个窗体,而是对原有窗体进行呼出选择并显示。(比如MDI子窗体最小化了,而我们点击菜单该子窗体按钮时,该子窗体应重新Restrore到中央)

    一开始,我试着对frm_UserDefine(我的一个MDI子窗体)进行控制。包括以下:

    showwindow(frm_UserDefine.handle, sw_restore);   // 显示子窗口

    SendMessage(frm_UserDefine.Handle,MY_SETSTATE_MSG,0,0);// 发送消息到子窗口 触发消息进行Restore

    都不管用,甚至以下代码,都会报内存错误

    procedure Tfrm_Main.N9Click(Sender: TObject);
    var
      frm_UserDefine: Tfrm_UserDefine;
    begin
      if not isInclude(Tfrm_UserDefine) then
      begin
        frm_UserDefine := Tfrm_UserDefine.Create(Application);
        frm_UserDefine.Show;
      end
      else
      begin
        frm_UserDefine.Show;
      end;
    end;

    当重新点击时 判断了frm_UserDefine已建立,重新show时就报错,最后跟踪查了下frm_UserDefine找不到,我也不太清楚什么原因。

    解决方案:

    我在判断子窗体是否存在时,若存在就对其进行Restore,就把这个功能实现了,代码如下:

    function Tfrm_Main.isInclude(Formclass: TFormClass): Boolean;
    var
      i: Integer;
      Form: TObject;
    begin
      Result := false;
      for i := 0 to frm_Main.MDIChildCount do
      begin
        Form := frm_Main.MDIChildren[i];
        if Form is Formclass then
        begin
          Result := true;
          SendMessage(MDIChildren[i].Handle, WM_SYSCOMMAND, SC_RESTORE, 0); //在这里对MDI窗口进行管理恢复
          MDIChildren[i].Enabled:=true;
          MDIChildren[i].Show;
          MDIChildren[i].SetFocus;
        end;
      end;
    end;
    procedure Tfrm_Main.N9Click(Sender: TObject);
    var
      frm_UserDefine: Tfrm_UserDefine;
    begin
      if not isInclude(Tfrm_UserDefine) then
      begin
        frm_UserDefine := Tfrm_UserDefine.Create(Application);
        frm_UserDefine.Show;
      end;
    end;

    这样就实现了重新点击就能使子窗体重新恢复的功能。不过大家有什么更好的解决方法也可以跟我留言。

    3.关于MDI子窗体被主窗体控件遮挡问题

    因为要在主窗体插入Falsh或者Webbrower控件,panel控件做总体导航时,因为MDI子窗体挡在后面而头疼。(Image控件刚好没有遮挡MDI子窗体,所以一般开发就是在MDI主窗体背后放个Image做背景),OK,现在问题是如何解决主窗体的控件不遮挡MDI子窗体,而且躲在底层还能点击。

    解决方案:

    这里我是把子窗体的父类指向MDI主窗体,代码如下:

    procedure Tfrm_Main.N9Click(Sender: TObject);
    var
      frm_UserDefine: Tfrm_UserDefine;
    begin
      if not isInclude(Tfrm_UserDefine) then
      begin
        frm_UserDefine := Tfrm_UserDefine.Create(Application);
        Winapi.Windows.SetParent(frm_UserDefine.Handle,frm_Main.Handle);
        frm_UserDefine.Show;
      end;
    end;

      这时呼出来的 子窗体界面就在控件前面了,还有个小Bug,就是对子窗体最小化后看不到子窗体,这时关闭窗体会报内存错误。

    其实最小化后是隐藏起来,鼠标还是可以点击到的。(这里怎么会隐藏起来,可能还需要研究,如果大神知道原因的话,可以留言告诉我,我觉得可能改变了框架导致MDI错乱了吧)

    这里可以在子窗体在最小化时show一下,且子窗体需要有控件(例如:panel)存在(没控件存在的form也会最小化隐藏),以下为子窗体代码

    procedure Tfrm_UserDefine.FormCanResize(Sender: TObject; var NewWidth,
      NewHeight: Integer; var Resize: Boolean);
    begin
      case WindowState of
        wsMinimized: Self.Show;
      end;
    end;

    问题解决!

    以上代码是泡泡航在Delphi XE5的开发,虽然微软说明多文档界面MDI存在问题,但是现在以MDI窗体作为系统开发的还是蛮多的。如果大家有什么更好的办法或者建议,可以多多留言交流。

  • 相关阅读:
    【网摘】sql 语句修改字段名称以及字段类型
    转:关于bugfree的一些不得不说的事
    excel打乱各行的顺序,实现无序随机排列
    易语言报错:无法定位链接器!请检查 toolslink.ini 中的配置是否正确。 静态连接失败
    关于a标签的onclick和href谁先执行的问题
    关于a标签的onclick和href谁先执行的问题
    关于a标签的onclick和href谁先执行的问题
    易语言-子程序的参数属性
    SQL 随机取出一条数据
    为梦想,每天坚持30分钟
  • 原文地址:https://www.cnblogs.com/jijm123/p/13804089.html
Copyright © 2020-2023  润新知