zoukankan      html  css  js  c++  java
  • Delphi非应用程序主窗口创建MDI

    对Delphi很熟悉的人,都知道MDI窗口的创建方式,是将主窗口的formstyle设置成MDIForm,然后将各个要设置成MDI的窗口的FormStyle都设置成MDIChild,运行就可以看到效果了嘿。

       但是,如果MDI子窗口的依附窗口不是主窗口呢?此时是否依然能够建立MDI应用程序呢?事实证明是不行的,通过看Forms单元的源码中的CreateWindowHandle这个我们可以看到这样几句代码

    if (FormStyle = fsMDIChild) and not (csDesigning in ComponentState) then
      begin
        if (Application.MainForm = nil) or
          (Application.MainForm.ClientHandle = 0) then
          raise EInvalidOperation.Create(SNoMDIForm);

    如果窗口样式为MDIChild的,先查看MainForm的ClientHandle是否为0,也就是说被局限在了

    Application.MainForm上了,此时如果MainForm不是MDIForm样式,那么ClientHandle就为0了,所以就会报出一个异常 EInvalidOperation.Create(SNoMDIForm);

    既然这样,那我们就需要绕过Application.Mainform这个砍,让子窗口创建的时候MainForm的 ClientHandle<>0,设置MDIForm自然就不是我们需要的了,我们是要非主窗口创建MDI应用程序,于是俺想到一个办法修改 Application.MainForm这个属性,修改成窗口样式为MDIFOrm的非主窗口,此时不就可以过了吗?

    于是写下

    Application.MainForm := MyMdiForm;

    很明显这个是会报错误的,因为Application.MainForm为只读属性声明为:

    Property MainForm: TForm read FMainForm;

    那么是否就无策了呢?细心的同志们仔细观察一下应该是可以发现的MainForm指向的是FMainForm,也就是说MainForm就是FMainForm的地址映射,那么我们就可以通过指针来达到这个修改的目的了哈哈

    那么就可以这样

    var
      p: PInteger;

    begin

       p := @Application.MainForm;
       p^ := Integer(form3);//这里就修改了Application的Mainform的属性了哈。

    end;

    然后我们就可以创建MDI子窗口了,呵呵

    具体如下:

    procedure TForm2.BitBtn1Click(Sender: TObject);
    var
      p: PInteger;
      f: TForm;
    begin
       f := Application.MainForm;
       f.Hide;
       form3 := Tform3.Create(nil);
       p := @Application.MainForm;
       p^ := Integer(form3);
       Form3.Show;
       f.Close;
    end;

    仅供研究,使用请慎重。没做任何测试。

  • 相关阅读:
    序列、元组、列表(基本的增、删、改、查)
    Python基础运算符(算数、比较、赋值、逻辑、成员)
    2015年9月14日记事
    2014年3月31日梦
    华为S5700系列交换机配置文件导出、导入
    C语言单链表简单实现(简单程序复杂化)
    北邮《大学英语2》第三次阶段作业带答案
    C++走向远洋——30(六周,项目一1.0)
    C++走向远洋——29(长方柱类)
    C++走向远洋——28(项目三,时间类,2)
  • 原文地址:https://www.cnblogs.com/DxSoft/p/1637659.html
Copyright © 2011-2022 走看看