我做的一个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
        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;

解决方案 »

  1.   

    LockWindowUpdate好像是指,锁定屏幕的数据刷新,并不是屏幕的图形不刷新
      

  2.   

    //先禁止客户区更新,隐藏子窗口创建和显示细节,然后一次性更新客户区及其所有子窗口
    SendMessage(ClientHandle,WM_SETREDRAW,0,0);
    ……//创建窗口代码
    SendMessage(ClientHandle,WM_SETREDRAW,1,0);
    ReDrawWindow(ClientHandle,nil,0,RDW_INVALIDATE or RDW_ALLCHILDREN);
      

  3.   

          问题是我们公司的产品系统架构就是这样写的,却一点都不会发生闪烁,如果非要用ockWindowUpdate,问题出在哪里?
      

  4.   

    LockWindowUpdate不但闪烁,而且有可能引起桌面闪烁。因为LockWindowUpdate并不忽略消息,只是暂时不响应,所以有可能积聚多个重画消息,并在使用LockWindowUpdate(0)之后依次响应。
    而使用SendMessage(ClientHandle,WM_SETREDRAW,0,0)之后,控件根本不接收重画消息,除非使用SendMessage(ClientHandle,WM_SETREDRAW,1,0)之后;LockWindowUpdate的意思是暂时禁止某控件或窗口所在的区域更新(这个区域可能有多个窗口),LockWindowUpdate(0)的意思是有更新消息就更新屏幕上所有该更新的窗口吧。所以LockWindowUpdate(0)之后,若此前有重画消息积聚,会立刻重画。所以使用LockWindowUpdate会在不同的时候有不同的表现,比如屏幕上窗口多少、堆放情况等等,所以有时不闪有时却闪个不停。SendMessage(ClientHandle,WM_SETREDRAW,0,0)的意思是不接收任何重画消息;
    SendMessage(ClientHandle,WM_SETREDRAW,1,0)的意思是可以接收并响应重画消息了,但并不立即重画,所以必须附加 ReDrawWindow(ClientHandle,nil,0,RDW_INVALIDATE   or   RDW_ALLCHILDREN);