本帖最后由 u013962484 于 2014-03-07 18:46:43 编辑

解决方案 »

  1.   

    http://bbs.csdn.net/topics/390259666
    这个帖子的作者,在最后说他解决问题了,但是,我没看懂,希望,大虾解救一下。
      

  2.   

    screenbmp 是啥玩意,代码没有交代
      

  3.   

    screenbmp 是啥玩意没角度,aimg 也没有free的代码
      

  4.   

             screenbmp.FreeImage;
             screenbmp.Free;
             screenbmp:=nil;
    这个是失误,复制的时候忘了检查一下。
    是          aimg.FreeImage;
             aimg.Free;
             aimg:=nil;
      

  5.   

    你每调用一次GEThdcimg就会创建一个Tbitmap对象,没有见到你Free的地方。
      

  6.   

    调用这个线程类的代码呢,在一个循环中不断创建pic线程?
      

  7.   

    上面的代码,复制的时候没注意。这个是改过的。unit Unit2;
     
    interface
     
    uses
      Classes;其它
     
    type
      pic = class(TThread)
      private
        { Private declarations }
      protected
        procedure Execute; override;
      end;
     
    implementation
     
     
     
    procedure pic.Execute;
    var
       aimg:Tbitmap;
    begin
      while true do begin
         if assigned(aimg) then begin
             aimg.FreeImage;
             aimg.Free;
             aimg:=nil;
         end;
         aimg:=GEThdcimg(指定窗口);
         ****************
         处理过程....
         ****************
         sleep(300);
      end;
    end;
     
    end.
      

  8.   


    不是的,PIC线程只创建一次。
    是在PIC线程内,不断的截图某窗口,然后判断一些变化并操作。
      

  9.   

    按照下面改,改完你测试下看看,俺测试没啥问题 // 线程类
      pic = class(TThread)
      private
        { Private declarations }
      protected
        procedure Execute; override;
        procedure SyncProc;  // 同步过程
      end;
    .....// 修改了下,确保对象的"谁创建谁销毁"的原则, 这里的对象是 TBitmap
    function GetHDCIMG(out aim: TBitmap; SCRhWnd: hWnd): Boolean; //截取指定窗口
    var
      ScrCanvas: TCanvas;
      scrHDC: HDC;
      R: TRect;
    begin
      Result := True;
      scrcanvas := Tcanvas.Create;
      try
        try
          scrhdc := GetWindowDC(scrhwnd);
          scrcanvas.Handle := scrhdc;
          Getwindowrect(scrhwnd, r);
          aim.Canvas.Lock;
          aim.Width := r.Right - r.Left;
          aim.Height := r.Bottom - r.Top;
          aim.Canvas.CopyRect(rect(0, 0, aim.Width, aim.Height), scrcanvas, rect(0,
            0,
            aim.Width, aim.Height));
          releasedc(0, scrhdc);
        except
          Result := False;
        end;
      finally
        aim.Canvas.Unlock;
        scrcanvas.Free;
      end;
    end;{ pic 实现}
    procedure pic.SyncProc;
    var
      aimg: Tbitmap;
    begin
      aimg := TBitmap.Create;
      while not Terminated do
      begin
        aimg.Assign(nil);
        if GEThdcimg(aimg, 窗口句柄) then
        begin
          // * * * * * * * * * * * * * * * *
          // 处理过程....
          // * * * * * * * * * * * * * * * *
          sleep(300);
        end;
      end;
      FreeAndNil(aimg); 
    end;procedure pic.Execute;
    begin
      Synchronize(SyncProc);
    end;
    // 调用
    procedure TForm1.btn1Click(Sender: TObject);
    var
      picThread: pic;
    begin
      picThread := pic.Create(True);
      picThread.FreeOnTerminate := True;
      picThread.Resume;
    end;
      

  10.   

    因为处理的过程比较长,如果使用Synchronize同步,这样会不会影响性能?
      

  11.   

    Synchronize 的同步处理是使用临界区的,可以在Synchronize 的实现源码里看到
    Canvs.Lock 同样也是用临界区的,上面代码可以不用Synchronize ,只要你自行做好同步就行了
      

  12.   

    经过测试,确实可以了。太感激了。当Tbitmap.create在循环外的时候,如果没有这句(aimg.Assign(nil);)的话,取得的图片,有可能是白色的,也有可能不变。反正,总之,哈哈,太感激了。