在解决fsMDIChild窗口"闪"的问题后,又出现主窗口镂空(锁定过程中)的问题 
解决"闪"的过程如下: 
procedure   MDIChildshow(FrmName:   string;Frmmain:   TForm;   mForm:   TForm;fForm:   TFormClass;App:   TApplication); 
begin 
              Frmmain.Perform(WM_SETREDRAW,0,0); 
              if   Application.FindComponent(FrmName)=nil   then 
              try 
                      App.CreateForm(fForm,mForm); 
              except 
                      showmessage(FrmName+'创建不成功!'); 
              end; 
              mForm.Show; 
              Frmmain.Perform(WM_SETREDRAW,1,0); 
        RedrawWindow(Frmmain.Handle,nil,0,RDW_FRAME+RDW_INVALIDATE+RDW_ALLCHILDREN+RDW_NOINTERNALPAINT); 
end;

解决方案 »

  1.   

    http://img.blog.163.com/photo/zpFxmQcJQHV02kCnKQgVOA==/5149303223945357156.jpg
      

  2.   

    用LockWindowUpdate锁定屏幕后创建MDI子窗体时,子窗体依然闪烁(刷新),奇怪时间:2007-11-21 11:30:38  来源:论坛整理  翻译整理:IT者  :作者:xstdljj我做的一个MDI程序,一主窗体加上很多MDI子窗体,但是在子窗体的创建过程中会出现:创建(空白窗体)---> 组件创建并显示---> 窗体最大化这一过程,即所谓的窗体闪烁现象,在创建的过程中我已经锁定了屏幕,但还是没效果,创建子窗体的代码如下: 
    这是一个通用函数,我们公司的代码就是这样写的,它就不闪烁,而我做的这个例子就会出现这种情况,很迷惑!有没有碰到这个问题并解决的高人 
    procedure RunMDIChild( MDIChildFormClass: TFormClass ;var Reference); 
    var 
    MDIChildForm: TForm; 
    i:Integer; 
    begin 
    with Application.MainForm do 
    begin 
    for i:=0 to MDIChildCount-1 do 
    begin 
    //假如所调用的窗体存在,显示该窗体 
    if MDIChildren[i].ClassType = MDIChildFormClass then 
    begin 
    RestoreWindow(MDIChildren[i].Handle);//API IT 者 
    Exit; 
    end; 
    end; 
    try 
    LockWindowUpdate(GetDeskTopWindow);//锁定屏幕,API 
    Application.CreateForm(MDIChildFormClass,Reference);//创建子窗体 
    finally 
    Screen.Cursor:=crDefault; 
    end; 
    try 
    LockWindowUpdate(GetDeskTopWindow);//锁定屏幕 
    MDIChildForm:=TForm(Reference); 
    MainForm.AddToWindowList(MDIChildForm);//不用管这行代码 
    MDIChildForm.WindowState:= wsMaximized; 
    finally 
    LockWindowUpdate(0);//解除锁定API 
    end; 
    end; 
    end;
    网友回复:LockWindowUpdate似乎是指,锁定屏幕的数据刷新,并不是屏幕的图形不刷新
    网友回复://先禁止客户区更新,隐藏子窗口创建和显示细节,然后一次性更新客户区及其所有子窗口 www.itzhe.cn 
    SendMessage(ClientHandle,WM_SETREDRAW,0,0); 
    ……//创建窗口代码 
    SendMessage(ClientHandle,WM_SETREDRAW,1,0); 
    ReDrawWindow(ClientHandle,nil,0,RDW_INVALIDATE or RDW_ALLCHILDREN); 网友回复: 问题是我们公司的产品系统架构就是这样写的,却一点都不会发生闪烁,假如非要用ockWindowUpdate,问题出在哪里?
    网友回复:LockWindowUpdate不但闪烁,而且有可能引起桌面闪烁。因为LockWindowUpdate并不忽略消息,只是暂时不响应,所以有可能积聚多个重画消息,并在使用LockWindowUpdate(0)之后依次响应。 
    而使用SendMessage(ClientHandle,WM_SETREDRAW,0,0)之后,控件根本不接收重画消息,除非使用SendMessage(ClientHandle,WM_SETREDRAW,1,0)之后; LockWindowUpdate的意思是暂时禁止某控件或窗口所在的区域更新(这个区域可能有多个窗口),LockWindowUpdate(0)的意思是有更新消息就更新屏幕上所有该更新的窗口吧。所以LockWindowUpdate(0)之后,若此前有重画消息积聚,会马上重画。所以使用LockWindowUpdate会在不同的时候有不同的表现,比如屏幕上窗口多少、堆放情况等等,所以有时不闪有时却闪个不停。 
    itzhe.cn
    SendMessage(ClientHandle,WM_SETREDRAW,0,0)的意思是不接收任何重画消息; 
    SendMessage(ClientHandle,WM_SETREDRAW,1,0)的意思是可以接收并响应重画消息了,但并不立即重画,所以必须附加 ReDrawWindow(ClientHandle,nil,0,RDW_INVALIDATE or RDW_ALLCHILDREN); 
    本篇文章来源于 www.itzhe.cn 原文链接:http://www.itzhe.cn/html/Programme/Delphi/20071121/20934.html
      

  3.   

    用SendMeSSAGE()和ClientHandle参数就好了但 还是不完美 还是有点点"闪"
      

  4.   

    BOOL   RedrawWindow( 
        HWND   hWnd,                               //   handle   to   window 
        CONST   RECT   *lprcUpdate,     //   指定这个矩形区域 
        HRGN   hrgnUpdate,                   //   handle   to   update   region 
        UINT   flags                               //   重画的一些选项,你看MSDN上面吧,讲得很清楚CONST   RECT   *lprcUpdate,     //不用说了就是你要更新的矩形区域 第四个参数简单说下: 
    RDW_ERASE   擦除背景 
    RDW_FRAME   如果你的矩形包括了非客户区,会更新客户区即常用的nc消息 
    RDW_INTERNALPAINT   会强迫触发WM_PAINT消息,会走到OnPaint函数里如果你写了 
    RDW_INVALIDATE   如果你只是想更新部分区域,用这个参数,否则就会全都更新了,会闪的。 
    RDW_ALLCHILDREN   包括子窗口。 
    还有就是RDW_NOXXXX的和上面的意思基本相反。
      

  5.   

    设定fsMDIchild的画面在父画面中显示在中间位置,为什么不是紧挨着父窗体。