关于在线程中操作Image的问题,200分急求解 我做了一个屏幕显示程序,使用线程在窗体的Image输出内容,但在输出的过程中,往往输出二三十屏后,Image就不显示了,调试可知Image的属性都正常,程序也未报任何错误。不知道是什么原因。希望有这方面经验的高手能帮个忙!在线等待 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 我感觉可能是因为线程和主进程对TImage操作时发生了冲突而造成的,我将所有对Image的操作改到主进程后,虽然程序能正常运行,但因为有多个线程进行这种操作,全部改过来后,对系统的影响比较大,其中一个线程还对串口进行操作,所以虽然能正常运行,但系统经常会没有响应,尤其是对串口进行通讯的时候(串口通讯的数据量很大) 是否可以用多个CANVAS去不停替换,CREATE,fREE,CREATE,FREE. 1、输出Image的时候用线程同步函数2、采用互斥量,保证操作的时候进入到了临界区。 建议不要在线程里操作VCL控件 unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls, Buttons;type TtestThread = class(TThread) private Fbuff: TBitmap; Fbuff2: TBitmap; Fimage: TImage; Fcount: integer; procedure updateimage; public constructor CreateThread(image: TImage); procedure Execute; override; destructor Destroy; override; end; TForm1 = class(TForm) Image1: TImage; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure FormActivate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private testThread: TtestThread; public end;var Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);var bmp: TBitmap;begin DoubleBuffered := true; bmp := TBitmap.Create; bmp.Width := ClientWidth; bmp.Height := ClientHeight; Image1.Left := 0; Image1.Top := 0; Image1.AutoSize := true; Image1.Picture.Assign(bmp); FreeAndNil(bmp); testThread := TtestThread.CreateThread(Image1);end;{ TtestThread }constructor TtestThread.CreateThread(image: TImage);begin Fcount := 0; Fimage := image; Fbuff := TBitmap.Create; Fbuff2 := TBitmap.Create; Fbuff.Width := image.Picture.Bitmap.Width; Fbuff.Height := image.Picture.Bitmap.Height; Fbuff2.Width := image.Picture.Bitmap.Width; Fbuff2.Height := image.Picture.Bitmap.Height; inherited Create(TRUE); Self.Priority := tpLower;end;destructor TtestThread.Destroy;begin FreeAndNil(Fbuff); FreeAndNil(Fbuff2); inherited;end;procedure TtestThread.Execute;begin while not Terminated do begin Sleep(1); Inc(Fcount); Synchronize(updateimage); end; Terminate;end;procedure TtestThread.updateimage;begin Fbuff2.Canvas.Draw(0, 0, Fbuff); Fbuff.Canvas.Draw(0, 20, Fbuff2); Fbuff.Canvas.TextOut(5, 3, '第' + IntToStr(Fcount) + '次'); BitBlt(Fimage.Canvas.Handle, 0, 0, Fbuff.Width, Fbuff.Height, Fbuff.Canvas.Handle, 0, 0, SRCCOPY); Fimage.Canvas.TextOut(100, 3, '第' + IntToStr(Fcount) + '次'); Fimage.Parent.Update;end;procedure TForm1.FormDestroy(Sender: TObject);begin if not testThread.Terminated then testThread.Terminate; testThread.Free;end;procedure TForm1.FormActivate(Sender: TObject);begin testThread.Resume;end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);begin if not testThread.Terminated then testThread.Terminate;end;end. 我测试了 10000 次刷新object Form1: TForm1 Left = 192 Top = 107 Width = 696 Height = 480 Caption = 'Form1' Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'MS Sans Serif' Font.Style = [] OldCreateOrder = False OnActivate = FormActivate OnClose = FormClose OnCreate = FormCreate OnDestroy = FormDestroy PixelsPerInch = 96 TextHeight = 13 object Image1: TImage Left = 176 Top = 96 Width = 105 Height = 105 endend 高手请进----------求一个复杂的字符串处理---------- delphi 2个程序冲突 急啊 在线等 如何设置昵称,去掉‘该用户很懒,没有设置昵称’ 帮忙看个简单的问题~~~ 新手请教问题。一个interbase 建表时用的语句 急 在线等。 如何从video中提取音频并保存? 关于消息问题! 高手指点:为什么用RESTORE恢复数据库后,数据库成Loading状态? mapx 控件怎样和SQLSERVER数据库连接? 关于网页和delphi窗口结合操作的问题?(高分求救参与者都给分) 使用Turbo Delphi的一个问题 有难度的捕捉异常问题
2、采用互斥量,保证操作的时候进入到了临界区。
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, Buttons;type
TtestThread = class(TThread)
private Fbuff: TBitmap;
Fbuff2: TBitmap; Fimage: TImage;
Fcount: integer;
procedure updateimage; public
constructor CreateThread(image: TImage);
procedure Execute; override;
destructor Destroy; override;
end;
TForm1 = class(TForm)
Image1: TImage;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormActivate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
testThread: TtestThread;
public end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);
var
bmp: TBitmap;
begin DoubleBuffered := true; bmp := TBitmap.Create;
bmp.Width := ClientWidth;
bmp.Height := ClientHeight;
Image1.Left := 0;
Image1.Top := 0;
Image1.AutoSize := true;
Image1.Picture.Assign(bmp); FreeAndNil(bmp);
testThread := TtestThread.CreateThread(Image1);
end;{ TtestThread }constructor TtestThread.CreateThread(image: TImage);
begin
Fcount := 0;
Fimage := image;
Fbuff := TBitmap.Create;
Fbuff2 := TBitmap.Create; Fbuff.Width := image.Picture.Bitmap.Width;
Fbuff.Height := image.Picture.Bitmap.Height; Fbuff2.Width := image.Picture.Bitmap.Width;
Fbuff2.Height := image.Picture.Bitmap.Height; inherited Create(TRUE);
Self.Priority := tpLower;
end;destructor TtestThread.Destroy;
begin
FreeAndNil(Fbuff);
FreeAndNil(Fbuff2);
inherited;
end;procedure TtestThread.Execute;
begin
while not Terminated do
begin
Sleep(1);
Inc(Fcount);
Synchronize(updateimage); end;
Terminate;
end;procedure TtestThread.updateimage;
begin Fbuff2.Canvas.Draw(0, 0, Fbuff);
Fbuff.Canvas.Draw(0, 20, Fbuff2);
Fbuff.Canvas.TextOut(5, 3, '第' + IntToStr(Fcount) + '次');
BitBlt(Fimage.Canvas.Handle, 0, 0, Fbuff.Width, Fbuff.Height, Fbuff.Canvas.Handle, 0, 0, SRCCOPY);
Fimage.Canvas.TextOut(100, 3, '第' + IntToStr(Fcount) + '次'); Fimage.Parent.Update;
end;procedure TForm1.FormDestroy(Sender: TObject);
begin
if not testThread.Terminated then
testThread.Terminate;
testThread.Free;
end;procedure TForm1.FormActivate(Sender: TObject);
begin
testThread.Resume;
end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if not testThread.Terminated then
testThread.Terminate;
end;end.
Left = 192
Top = 107
Width = 696
Height = 480
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
OnActivate = FormActivate
OnClose = FormClose
OnCreate = FormCreate
OnDestroy = FormDestroy
PixelsPerInch = 96
TextHeight = 13
object Image1: TImage
Left = 176
Top = 96
Width = 105
Height = 105
end
end