线程中怎么正确的释放Tbitmap 本帖最后由 u013962484 于 2014-03-07 18:46:43 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 http://bbs.csdn.net/topics/390259666这个帖子的作者,在最后说他解决问题了,但是,我没看懂,希望,大虾解救一下。 screenbmp 是啥玩意,代码没有交代 screenbmp 是啥玩意没角度,aimg 也没有free的代码 screenbmp.FreeImage; screenbmp.Free; screenbmp:=nil;这个是失误,复制的时候忘了检查一下。是 aimg.FreeImage; aimg.Free; aimg:=nil; 你每调用一次GEThdcimg就会创建一个Tbitmap对象,没有见到你Free的地方。 调用这个线程类的代码呢,在一个循环中不断创建pic线程? 上面的代码,复制的时候没注意。这个是改过的。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. 不是的,PIC线程只创建一次。是在PIC线程内,不断的截图某窗口,然后判断一些变化并操作。 按照下面改,改完你测试下看看,俺测试没啥问题 // 线程类 pic = class(TThread) private { Private declarations } protected procedure Execute; override; procedure SyncProc; // 同步过程 end;.....// 修改了下,确保对象的"谁创建谁销毁"的原则, 这里的对象是 TBitmapfunction 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; 因为处理的过程比较长,如果使用Synchronize同步,这样会不会影响性能? Synchronize 的同步处理是使用临界区的,可以在Synchronize 的实现源码里看到Canvs.Lock 同样也是用临界区的,上面代码可以不用Synchronize ,只要你自行做好同步就行了 经过测试,确实可以了。太感激了。当Tbitmap.create在循环外的时候,如果没有这句(aimg.Assign(nil);)的话,取得的图片,有可能是白色的,也有可能不变。反正,总之,哈哈,太感激了。 有没有人需要《Delphi组件参考大全》,换C++方面书或出售。 (高分请教)在文本编辑器显示特殊字符的算法问题 急求,如何通过web发布基于dll的activex?????????? 求多媒体网络监控解~~100分 我该怎么办?愁死了!! 4串口串行通信如何实现 如何提速画图效率? 错在什么地方! 如何对注册表进行操作??? 哪位大虾来解决DELPHI 5的DBLookupComboBox组件问题? 如何对比两个数据库中不同的字段 隐藏运行另一程序的代码。顶者有分
这个帖子的作者,在最后说他解决问题了,但是,我没看懂,希望,大虾解救一下。
screenbmp.Free;
screenbmp:=nil;
这个是失误,复制的时候忘了检查一下。
是 aimg.FreeImage;
aimg.Free;
aimg:=nil;
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.
不是的,PIC线程只创建一次。
是在PIC线程内,不断的截图某窗口,然后判断一些变化并操作。
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;
Canvs.Lock 同样也是用临界区的,上面代码可以不用Synchronize ,只要你自行做好同步就行了