Delpi在MDI窗口中显示图形控件及指定背景的解决方案

原创 2001年05月29日 13:33:00


    在使用MDI介面时,有时候需要在MDI客户窗口中显示一些图形或软件封面,使得软件介面不会显得空旷,软件功能也能一目了然。然而在Delphi中并没有直接给出这些接口。在MDI窗体中放入任何图形控件在运行时都不能显示。因此需要对MDI窗体进行改造。
申明:
    本方案仅针对MDI窗体,如果应用在非MDI窗体中,后果难说,你自已试试吧。
    记住,窗体的FormStyle属性要设置为:fsMDIForm。
解决方案:
    1.    在MDI主窗体中无法接收到MDI客户窗口的消息(Message),因此,需要自已定义客户窗口的处理过程(Window Procedure),并接管MDI客户窗口(需在重载的CreateWnd过程中实现):
        procedure TMDIForm.CreateWnd;
        begin
          inherited;
          FNewWndProc := MakeObjectInstance(ClientWndProc);
          FOldWndProc := Pointer(GetWindowLong(ClientHandle, GWL_WNDPROC));
          SetWindowLong(ClientHandle, GWL_WNDPROC, Longint(FNewWndProc));
        end;
        其中,ClientWndProc为自定义的窗口过程:    procedure ClientWndProc(var Message: TMessage);
        FOldWndProc用来存放旧的窗口过程的指针。
    2.    实现自已的客户窗口过程:
        procedure TMDIForm.ClientWndProc(var Message: TMessage);
        var
          R: TRECT;
       
          procedure Default;
          begin
            with Message do
              Result := CallWindowProc(FOldWndProc, ClientHandle, Msg, wParam, lParam);
          end;
        var
          PS: TPaintStruct;
        begin
          R := ClientRect;
          case Message.Msg of
          WM_PAINT:
            begin
              BeginPaint(ClientHandle,PS);
              try
                Canvas.Lock;
                try
                  Canvas.Handle := PS.hdc;
                  try
                    Paint;
                    if ControlCount > 0 then
                      PaintControls(PS.hdc,Controls[0]);
                  finally
                    Canvas.Handle := 0;
                  end;
                finally
                  Canvas.Unlock;
                end;
              finally
                EndPaint(ClientHandle,PS);
              end;
            end;
          WM_ERASEBKGND:
            begin
              DrawBG(TWMEraseBkGnd(Message).DC);
              Message.Result := 1;
            end;
          WM_VSCROLL,WM_HSCROLL:
            begin
              InvalidateRect(ClientHandle,@R,true);
              Default;
            end;
          WM_SIZE:
            begin
              InvalidateRect(ClientHandle,@R,true);
              Default;
            end;
          else
            Default;
          end;
        end;
        上面的DrawBG是用于画窗口背景的。
    3.    实现窗口背景。
        为了可以让继承者也能定义自已的背景,故此过程说明为virtual:
          protected
            procedure DrawBG(DC: HDC); virtual;
        在此,DrawBG过程只是简单的填充窗口背景:
        procedure TMDIForm.DrawBG(DC: HDC);
        begin
          if Brush.Color <> clNone then
            FillRect(DC, ClientRect, Brush.Handle);
        end;
    4.    综上所述,总结TMDIFrom类定义如下:
          TMDIForm = class(TForm)
          private
            FOldWndProc: TFarProc;
            FNewWndProc: TFarProc;
            procedure ClientWndProc(var Message: TMessage);
          protected
            procedure DrawBG(DC: HDC);virtual;
            procedure CreateWnd; override;
          end;
    5.    经过以上改造后,就可以在DrawBG中画出指定的背景(需直接调用Windows 的GUI接口),或者直接使用图形控件,或者实现窗体的OnPaint事件,MDI窗口从此多姿多彩。

MFC中MDI方式下如何自由生成自定义的子窗口

本文介绍如何删除由MFC AppWinzard工程中产生的文档/视图结构,同时根据自己的实际需要创建子窗口界面。 Visual C++ 开发系统中应用程序向导的标准设置允许应用程序开发者方便简单...
  • dearm23
  • dearm23
  • 2015年10月28日 23:54
  • 1261

VB6给MDI窗口(父窗口)动态绘制背景的种种方法

VB6就不说了,要快速写一个程序,.NET(C#)可能还更好更强大,但是要说安全,VB6反到强过他们 有时候两者就是一种矛盾,所以越是用户友好,越是易维护和扩展的程序,越容易被破解. ...
  • prsniper
  • prsniper
  • 2013年08月18日 06:12
  • 2012

自绘控件背景透明

从CWnd派生的自绘控件,想要做背景透明的话,采用的方案是复制父窗口背景。 即在绘制函数中,先将父窗口的背景图贴到控件的背景上。 实际操作中,发生了一个问题,就是不断绘制、刷新的过程中,发现有叠加现象...
  • jiratao
  • jiratao
  • 2013年08月27日 14:55
  • 2599

C# Winform MDI窗体,父窗体控件覆盖子窗体的解决办法

问题:MDI窗体中,父窗体控件会覆盖子窗体,网上很多解决方案表面上解决了问题,但失去了MDI窗体的基本特性,并不实用。比较赞成使用子窗体“代替”父窗体控件的方案。思路:不将控件放置在父窗体上,而是放在...
  • lj22377
  • lj22377
  • 2015年09月14日 15:37
  • 2222

C#中Form窗口中的控件不显示

C#中Form窗口中的控件不显示 转自http://www.debugease.com/csharp/1710.html 先前在C#中设计的Form界面,后来再打开时界面中的控件都不显...
  • itiswangwang
  • itiswangwang
  • 2017年06月13日 11:41
  • 190

VC拖放窗口中的控件

我一直想要自己做一个资源编辑器,要做到这个
  • aasmfox
  • aasmfox
  • 2014年11月21日 00:42
  • 663

[OpenCV]在显示窗口中截图

介绍使用OpenCV实现简单的截图功能。首先阐述实现此功能的基本步骤,然后给出实现代码,最后贴出实验结果和一点点评。...
  • bendanban
  • bendanban
  • 2015年03月08日 13:29
  • 6070

【VS开发】动态创建ActiveX控件

bool CCollectDataDlgDlg::CreateMyCtrl(LPRECT lpRect, UINT nID, CWnd *pParent) {  CLSID clsid;  ws...
  • LG1259156776
  • LG1259156776
  • 2016年07月23日 12:52
  • 673

OpenCV在一个窗口中显示多个视频子窗口

在一个窗口中显示多个视频,并在每个子窗口左上角显示系统时间,函数cvShowManyImages是改写的#include #include #include #include #includ...
  • Augusdi
  • Augusdi
  • 2013年05月05日 17:38
  • 2759

在PowerDesigner的PDM图形窗口中显示数据列的中文注释

 '****************************************************************************** '* File:     co...
  • bear_79
  • bear_79
  • 2015年11月04日 00:15
  • 208
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Delpi在MDI窗口中显示图形控件及指定背景的解决方案
举报原因:
原因补充:

(最多只允许输入30个字)