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;

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



本文转自 不得闲 博客园博客,原文链接: http://www.cnblogs.com/DxSoft/archive/2010/01/01/1637659.html  ,如需转载请自行联系原作者

相关文章
|
2月前
|
设计模式 程序员 C#
C# 使用 WinForm MDI 模式管理多个子窗体程序的详细步骤
WinForm MDI 模式就像是有超能力一般,让多个子窗体井然有序地排列在一个主窗体之下,既美观又实用。不过,也要小心管理好子窗体们的生命周期哦,否则一不小心就会出现一些意想不到的小bug
187 0
|
Python
PyQt5-基本控件| 主窗口的类型、创建以及代码如何实现?
PyQt5-基本控件| 主窗口的类型、创建以及代码如何实现?
79 1
|
6月前
Qt MainWindow 程序主窗口
Qt MainWindow 程序主窗口
|
7月前
MFC窗口创建机制
MFC窗口创建机制
36 0
|
API C# 数据安全/隐私保护
C#之二十一 创建MDI应用程序和组件开发
C#之二十一 创建MDI应用程序和组件开发
123 0
Windows编程基础,第一个Windows程序,注册窗口,创建窗口(下)
Windows编程基础,第一个Windows程序,注册窗口,创建窗口
|
编译器 API 开发工具
Windows编程基础,第一个Windows程序,注册窗口,创建窗口(上)
Windows编程基础,第一个Windows程序,注册窗口,创建窗口
|
容器
Qt5——主窗口
Qt5——主窗口
208 0
Qt5——主窗口
|
图形学 Windows
unity 实现调用Windows窗口/对话框交互
Unity调用Window窗口 本文提供全流程,中文翻译。 Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页缩放比例) Chinar ——...
1853 0
|
C# C++
获取当前进程(程序)主窗体句柄并设置wpf的父窗体为此句柄
原文:获取当前进程(程序)主窗体句柄并设置wpf的父窗体为此句柄 有时候在c++调用wpf控件的时候,wpf控件想自己显示窗体,但需要设置owner属性。迂回解决办法是设置wpf的window窗体的父窗体为进程的句柄。
3113 0