var
 FClientInstance,
 FPrevClientProc: TFarProc; 
-----(不懂)
//画背景
  FClientInstance := MakeObjectInstance(ClientWndProc); //这个函数查不到
  FPrevClientProc := Pointer(GetWindowLong(ClientHandle, GWL_WNDPROC));
  SetWindowLong(ClientHandle, GWL_WNDPROC, LongInt(FClientInstance));
-----procedure TMainForm.ClientWndProc(var Message: TMessage);
var
  MyDC: hDC;
  Ro, Co: Word;
begin
  with Message do
    case Msg of WM_ERASEBKGND:  //WM_ERASEBKGND是什么时候触发的
        begin
          MyDC := TWMEraseBkGnd(Message).DC;
          for Ro := 0 to ClientHeight div Image1.Picture.Height do
            for Co := 0 to ClientWIDTH div Image1.Picture.Width do
              BitBlt(MyDC, Co * Image1.Picture.Width, Ro * Image1.Picture.Height,
                Image1.Picture.Width, Image1.Picture.Height,
                Image1.Picture.Bitmap.Canvas.Handle, 0, 0, SRCCOPY);
          Result := 1;
        end;
    else
      Result := CallWindowProc(FPrevClientProc, ClientHandle, Msg, wParam, lParam);  //也不明白
    end;
end;

解决方案 »

  1.   

    也不懂,看字面好象是定义了个  客户端实例什么的~~~~~~````
    type 里面是怎么写的~~~~~查delphi帮助应该有CallWindowProc~~~~~觉得你应该比我行!
      

  2.   

    FPrevClientProc: TFarProc; 
    -----(不懂) -------------具体一个什么指针我也说不上
    //画背景
      FClientInstance := MakeObjectInstance(ClientWndProc); //这个函数查不到-不懂
      FPrevClientProc := Pointer(GetWindowLong(ClientHandle, GWL_WNDPROC));
      SetWindowLong(ClientHandle, GWL_WNDPROC, LongInt(FClientInstance));
    -----procedure TMainForm.ClientWndProc(var Message: TMessage);
    var
      MyDC: hDC;
      Ro, Co: Word;
    begin
      with Message do
        case Msg of WM_ERASEBKGND:  //WM_ERASEBKGND是什么时候触发的----当擦除背景时 触发
            begin
              MyDC := TWMEraseBkGnd(Message).DC;
              for Ro := 0 to ClientHeight div Image1.Picture.Height do
                for Co := 0 to ClientWIDTH div Image1.Picture.Width do
                  BitBlt(MyDC, Co * Image1.Picture.Width, Ro * Image1.Picture.Height,
                    Image1.Picture.Width, Image1.Picture.Height,
                    Image1.Picture.Bitmap.Canvas.Handle, 0, 0, SRCCOPY);
              Result := 1;
            end;
        else
          Result := CallWindowProc(FPrevClientProc, ClientHandle, Msg, wParam, lParam);  //也不明白------处理一些消息时系统要求有返回值因为用的         是with Message do所以这么写 正规是msg.result:=....                   
        end; 
    end;
      

  3.   

    WM_ERASEBKGND是什么时候触发的----当擦除背景时 触发
    就是譬如窗体paint的时候就会触发对不对。还有两个地方,大家提些看法。up没分
      

  4.   

    FClientInstance := MakeObjectInstance(ClientWndProc); //这个函数查不到-不懂
    我指的是MakeObjectInstance这个函数
      

  5.   

    MakeObjectInstance这个函数确实查不到
    俺关注吧
      

  6.   

    MakeObjectInstance函数创建一个可以作为窗口过程使用的方法,其返回值为一个指向该方法的指针
      

  7.   

    性性说的对,这是设置窗体背景的代码,有用到bitblt,作用知道,用法还要再多看看才了解
      

  8.   

    FClientInstance := MakeObjectInstance(ClientWndProc);  //好像返回窗口过程实例,是指
                                                             针类型
    //......
    SetWindowLong(ClientHandle, GWL_WNDPROC, LongInt(FClientInstance)); //把指定窗口赋
                                                                          新值
    CallWindowProc  //将消息传答窗口函数
      

  9.   

    var
     FClientInstance,
     FPrevClientProc: TFarProc; 
    -----(不懂)
    ^^^^过程指针  FClientInstance := MakeObjectInstance(ClientWndProc); //这个函数查不到
    //////////传出对象参数句柄,按地址赋值
      FPrevClientProc := Pointer(GetWindowLong(ClientHandle, GWL_WNDPROC));
      SetWindowLong(ClientHandle, GWL_WNDPROC, LongInt(FClientInstance));
    ////这里只影响一个对象,用新的处理过程替代以前的,并保存以前的过程指针,以将消息继续传递    case Msg of WM_ERASEBKGND:  //WM_ERASEBKGND是什么时候触发的----擦除背景时
          Result := CallWindowProc(FPrevClientProc, ClientHandle, Msg, wParam, lParam);  //也不明白--这句话,将消息继续往下传递,作用相当与inherited,调用以前的处理过程
        end;
    end;
      

  10.   

    MakeObjectInstance(ClientWndProc);
    作用将一个对象的方法转化成一个标准的窗口过程、
    FPrevClientProc := Pointer(GetWindowLong(ClientHandle, GWL_WNDPROC));
      SetWindowLong(ClientHandle, GWL_WNDPROC, LongInt(FClientInstance));
    作用将一个窗口的窗口处理函数替换掉,也就是用自己的窗口函数来处理消息with Message do
        case Msg of WM_ERASEBKGND:  //WM_ERASEBKGND是什么时候触发的----当擦除背景时 触发,是由OS来发消息,这个地方加入处理程序可以对这个消息进行处理
    CallWindowProc(FPrevClientProc, ClientHandle, Msg, wParam, lParam);  //调用原来的窗口函数来处理消息
            
      

  11.   

    仔细看过了风焱兄和zjybestzjybest(zjybestzjybest)的注释,还有些不懂的:
    两位关于MakeObjectInstance的论述不太一样
    FClientInstance := MakeObjectInstance(ClientWndProc); 
    //////////传出对象参数句柄,按地址赋值 (风焱兄的)
    ////作用将一个对象的方法转化成一个标准的窗口过程 (zjybestzjybest的)delphi里面:
    { Allocate an object instance }function MakeObjectInstance(Method: TWndMethod): Pointer;
    begin
      Result := Classes.MakeObjectInstance(Method);
    end;看delphi里的注释像是创建一个对象实例(Allocate an object instance ),我觉的:在不创建方法所属类的实例的情况下返回该方法的指针,引用该方法不知道说的对否谢谢大家继续关注还发现一问题:MyDC := TWMEraseBkGnd(Message).DC;    // ??
    怎么这样写呢,它是不是等价于Self.Canvas.Handle
      

  12.   

    我最后写完的注释
     //画背景
       //GetWindowLong和CallWindowProc
       //将image平铺到form的整个client区域,用aligh= alclient是不可以的。
      FClientInstance := MakeObjectInstance(ClientWndProc);  //Allocate an object instance
      FPrevClientProc := Pointer(GetWindowLong(ClientHandle, GWL_WNDPROC));//pointer to previous procedure
       //这里只影响一个对象,用新的处理过程替代以前的,并保存以前的过程指针,以将消息继续传递
      SetWindowLong(ClientHandle, GWL_WNDPROC, LongInt(FClientInstance)); //
    procedure TMainForm.ClientWndProc(var Message: TMessage);
    var
      MyDC: hDC;              //An application sends the WM_ERASEBKGND message when
      Ro, Co: Word;           //the window background must be erased (for example,
    begin                     //when a window is resized). The message is sent to
      with Message do         //prepare an invalidated portion of a window for painting.
        case Msg of WM_ERASEBKGND:         //窗体重绘时激发这个消息
            begin
              MyDC := TWMEraseBkGnd(Message).DC;    //消息中的参数-〉结构指针-〉里面包含了现在的dc封装后的访问形式
            //  MyDC := Self.Canvas.Handle;     和这个不等价?
              for Ro := 0 to ClientHeight div Image1.Picture.Height do
                for Co := 0 to ClientWIDTH div Image1.Picture.Width do     //放大倍数
                  BitBlt(MyDC, Co * Image1.Picture.Width, Ro * Image1.Picture.Height,
                    Image1.Picture.Width, Image1.Picture.Height,
                    Image1.Picture.Bitmap.Canvas.Handle, 0, 0, SRCCOPY);
              Result := 1;
            end;
        else
          Result := CallWindowProc(FPrevClientProc, ClientHandle, Msg, wParam, lParam);
    //将消息继续往下传递,作用相当与inherited,调用以前的处理过程
        end;
    end;谢谢大家