简体   繁体   English

Delphi 7,在表格上移动光标时,句柄无效:)

[英]Delphi 7, The handle is invalid, when moving cursor on the form :)

Here is small snippet of the code (ready to paste and run) which run one thread. 这是运行一个线程的代码的小片段(准备粘贴并运行)。 This thread get a list of the jpg files on disc, then do certain operations on it. 该线程获取光盘上jpg文件的列表,然后对其执行某些操作。

Normally it works okay. 通常情况下可以。 If I start moving the cursor on the form I get this error everytime :) 如果我开始在表格上移动光标,每次都会收到此错误:)

Any Idea? 任何想法? Thanks! 谢谢!

unit uTest;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, jpeg, gr32;

type
  TThreadSafeJpegImage = class(TJPEGImage)
  protected
    procedure Draw(ACanvas: TCanvas; const Rect: TRect); override;
  end;

  TForm1 = class(TForm)
    btn1: TButton;
    procedure btn1Click(Sender: TObject);
  private    
  public    
  end;

  TWatek = class(TThread)
  public
    procedure Execute;override;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.btn1Click(Sender: TObject);
var
  thr: TWatek;
begin
  thr := TWatek.Create(true);
  thr.FreeOnTerminate := true;
  thr.Resume;
end;

{ TWatek }

procedure TWatek.Execute;
var
  sciezka: string;
  Rec : TSearchRec;
  Path : string;
  I: Integer;

  function TestFile(path: string): WideString;
  var
    stream: TMemoryStream;
    jpg: TThreadSafeJpegImage;
    bmp32: TBitmap32;
    strStr: TStringStream;
    err: String;
  begin
    try
      stream := TMemoryStream.Create;
      jpg := TThreadSafeJpegImage.Create;

      try
        stream.LoadFromFile(path);
        jpg.LoadFromStream(stream);
      finally
        FreeAndNil(stream);
      end;

      bmp32 := TBitmap32.Create;
      try
        bmp32.Assign(jpg);
        strStr := TStringStream.Create('');
        bmp32.SaveToStream(strStr);
        strStr.Seek(0,soFromBeginning);
      finally
        FreeAndNil(jpg);
        FreeAndNil(bmp32);
      end;

      result := strStr.DataString;
      FreeAndNil(strStr);
    except
      on e: exception do
      begin
        err := e.Message;
        showmessage (err);
      end;
    end;
  end;

begin
  sciezka := 'd:\pictures\';

  for I := 1 to 100 do
  begin
    Path := IncludeTrailingPathDelimiter(sciezka) ;
    if FindFirst (Path + '*.jpg', faAnyFile - faDirectory, Rec) = 0 then
    begin
      try
        repeat
          TestFile (Path + Rec.Name);
        until FindNext(Rec) <> 0;
      finally
        FindClose(Rec) ;
      end;
    end;
  end;

end;

{ TThreadSafeJpegImage }

procedure TThreadSafeJpegImage.Draw(ACanvas: TCanvas; const Rect: TRect);
begin
  Bitmap.Canvas.Lock;
  try
    inherited Draw(ACanvas, Rect);
  finally
    Bitmap.Canvas.Unlock;
  end;
end;

end.

A guy from Graphics32 group found a solution for me. Graphics32小组的一个人为我找到了解决方案。 We have to amend some fixes to gr32 unit, as follows: 我们必须对gr32单元进行一些修复,如下所示:

1) In TBitmap32.AssignTo() replace

  DrawTo(Bmp.Canvas.Handle, 0, 0);

with

  Bmp.Canvas.Lock;
  try
    DrawTo(Bmp.Canvas.Handle, 0, 0);
  finally
    Bmp.Canvas.UnLock;
  end;

2) In TBitmap32.Assign() replace

  TGraphicAccess(Source).Draw(Canvas, MakeRect(0, 0, Width, Height));

with

  Canvas.Lock;
  try
    TGraphicAccess(Source).Draw(Canvas, MakeRect(0, 0, Width, Height));
  finally
    Canvas.UnLock;
  end;

Now it works!

not 100% sure, please vote me down if I'm delusional. 不确定100%,如果我有妄想,请拒绝我。

TThreadSafeJpegImage.Draw locks the Canvas. TThreadSafeJpegImage.Draw锁定画布。
When moving the mouse across the form you force a redraw, which the form cannot do (because you've already locked the canvas previously) and this causes the error to be returned. 当在表格上移动鼠标时,您将强制进行重绘,而表格无法执行此操作(因为您之前已经锁定了画布),这将导致返回错误。

Change the Draw code like so: 更改抽奖代码,如下所示:

procedure TThreadSafeJpegImage.Draw(ACanvas: TCanvas; const Rect: TRect);
var
  OKToDraw: boolean;
begin 
  OKToDraw:= Bitmap.Canvas.TryLock;
  if OKTODraw then try
    inherited Draw(ACanvas, Rect);
  finally
    Bitmap.Canvas.Unlock;
  end; {if try}
end;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在窗体上移动按钮时发生Delphi访问冲突 - Delphi Access Violation when moving button on form 在光标位置打开表格,Delphi - Open form at cursor position, Delphi 在 Delphi 7 的表格上显示动画.ani cursor - Showing an animated .ani cursor on a form in Delphi 7 Delphi 2010-线程错误:句柄无效(6) - Delphi 2010 - Thread error: The handle is invalid (6) 虚拟表编辑特定行而无需在 Delphi 中移动光标 - Virtual table edit specific row without moving the cursor in Delphi Delphi:除了移动光标之外,还有办法访问TClientDataset中的记录 - Delphi: Is there a way to access records in a TClientDataset besides moving the cursor 更改活动表单时,RichEdit需要两次单击才能更改光标(插入符号)位置(Delphi) - RichEdit needs two clicks to change cursor (caret) position when changing the active form (Delphi) Delphi Android应用程序-使用ShowModal表单处理mRCancel - Delphi Android application - handle mrCancel with ShowModal form Delphi - 如果通过方法从项目创建表单,TEdit 不显示光标 - Delphi - TEdit does not show cursor if form created from project by method Delphi 7,孩子如何对父窗体“移动”做出反应? - Delphi 7, How can a child react to the parent form Moving?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM