Canvasへの線の再描画がTImageの再描画で消される?

解決


isi  2013-02-13 01:26:47  No: 43846

こんにちは。

TImageにJpeg画像を読み込んだ後、
  Canvas.Pen.Width :=2;
  Canvas.Pen.Color :=clBlue;
  MoveToEx(Canvas.Handle,10,20,nil);
  LineTo(Canvas.Handle,100,150);
として線を引いています。

最小化から復帰等を行う事を想定して、線の再描画が必要ですが、
FormのOnPaintにて上記同様に記述しても描画されません。

どうやら、Jpeg画像の再描画で消されているようです。
試しにJpeg画像の読み込みを行わずにおくと、線は再描画されます。
どうすれば、Jpegの再描画より後に、線の再描画をさせられるのでしょうか。

開発環境は、DelphiXE3、Windows7(x64)です。

よろしくお願いいたします。


deldel  2013-02-13 01:52:59  No: 43847

Delphi5,XPですが、
  TImageは再描画不要、TPaintBoxなら必要
  Jpegには描画できなかった・・・
  LineTo(Canvas.Handle,100,150); の後に、Refresh; と書くと描画された
でした。
XEなら色々と違うんですかねぇ??


isi  2013-02-13 03:28:22  No: 43848

deldel さん

タイトルが紛らわしかったです、すみません。
XE3でもTImageを任意に再描画する必要はないです。


isi  2013-02-13 03:31:22  No: 43849

色々試してみていますが、
良くわからなくなってきました。

>procedure TForm1.Button1Click(Sender: TObject);
>begin
>  Image1.Picture.LoadFromFile('test.jpg');
>  MoveToEx(Canvas.Handle,10,20,nil);
>  LineTo(Canvas.Handle,100,150);
>end;
とすると、Lineが描画されたあとに画像が描画されるようで、
Lineは画像により見えなくなります。

>procedure TForm1.Button1Click(Sender: TObject);
>begin
>  Image1.Picture.LoadFromFile('map.jpg');
>end;
>
>procedure TForm1.Button2Click(Sender: TObject);
>begin
>  MoveToEx(Canvas.Handle,10,20,nil);
>  LineTo(Canvas.Handle,100,150);
>end;
として、Button1、Button2の順にクリックすると、
画像の上にLineが描画されて、Lineは見えます。

しかし、最小化→元に戻す すると、もちろん、
Lineは描画されされません。

そこで、これに更に、
>procedure TForm1.FormPaint(Sender: TObject);
>begin
>  MoveToEx(Canvas.Handle,10,20,nil);
>  LineTo(Canvas.Handle,100,150);
>end;
を追加してみても、画像が後で描画されてる感じで、
Lineは見えません。


Mr.XRAY  2013-02-13 07:01:56  No: 43850

>とすると、Lineが描画されたあとに画像が描画されるようで、
>Lineは画像により見えなくなります。

当然そうなります.
また,そうなってもらわないと困ります.
下に描画したものが見えてしまったら,フォームに配置したコンポーネントの見え方が....  
ああっぁ,あぅ ! となってしまいます.
例えば,フォームに TPanel を配置して,

procedure TForm1.Button1Click(Sender: TObject);
begin
  MoveToEx(Canvas.Handle,10,20,nil);
  LineTo(Canvas.Handle,100,150);
end;

としても,TPanel の座標と重なる部分は,TPanelに隠れて見えなくなります.
何か文句あります ?


KHE00221  2013-02-13 07:15:37  No: 43851

>>procedure TForm1.Button1Click(Sender: TObject);
>>begin
>>  Image1.Picture.LoadFromFile('test.jpg');
>>  MoveToEx(Canvas.Handle,10,20,nil);
>>  LineTo(Canvas.Handle,100,150);
>>end;
>とすると、Lineが描画されたあとに画像が描画されるようで、
>Lineは画像により見えなくなります。

画像がロードされた時点で再描画が要求されるが、実際には Button1Click
が終わった時点で処理されるので

画像ロード -> 線描画 -> 画像描画  になるので  線が消える

ロードした後に Application.ProcessMessages すれば消えない

///

フォームを描画後に各コンポーネントを描画しにいくので

OnPaint でフォーム描画後にImageを再描画しに行くので
線が消える

なので WM_PAINT 後に描画するしかない

type
  TForm7 = class(TForm)
    Image1: TImage;
    procedure WMPAINT(var Message: TWMPAINT);message WM_PAINT;
  private
  public
  end;

var
  Form7: TForm7;

implementation

{$R *.dfm}

procedure TForm7.WMPAINT(var Message: TWMPAINT);
begin
    inherited;
    Canvas.Pen.Width := 2;
    Canvas.MoveTo(0,0);
    Canvas.LineTo(100,100);
end;


KHE00221  2013-02-13 07:25:47  No: 43852

ディスクトップに直接書けば消えない

procedure TForm7.Button2Click(Sender: TObject);
var
    H: HDC;
    L,T: Integer;
    P: TPoint;
begin
    Image2.Picture.LoadFromFile('C:\Users\Public\Pictures\Sample Pictures\Desert.jpg');
    H := GetWindowDC(0);
    P := ClientToScreen(Point(0,0));
    L := P.X;
    T := P.Y;
    MoveToEx(H,L,T,nil);
    LineTo(H,L+100,T+100);
end;


Sara  2013-02-13 10:16:43  No: 43853

なぜFormのCanvasに描画したいのかが不明ですが、Image2をImage1の上に
重ねておいてImage2に描画するのではダメなの?

   if OpenDialog1.Execute then begin
     Image1.Picture.LoadFromFile(OpenDialog1.FileName);
   end;
   Image2.Transparent := True;
   Image2.Picture.Bitmap.Canvas.Brush.Style := bsClear;
   Image2.Picture.Bitmap.SetSize(Image1.Width,Image1.Height);
   Image2.Picture.Bitmap.Canvas.Pen.Width :=2;
   Image2.Picture.Bitmap.Canvas.Pen.Color :=clBlue;
   MoveToEx(Image2.Picture.Bitmap.Canvas.Handle,10,20,nil);
   LineTo(Image2.Picture.Bitmap.Canvas.Handle,100,150);


isi  2013-02-13 19:15:30  No: 43854

>Mr.XRAY さん
ありがとうございました。
理解できました。
文句ありません(^^)

>KHE00221さん
ありがとうございました。
WMPAINTを検知させる、ということですね。
成功しました。勉強になりました。

>KHE00221さん
>デスクトップに直接
残念ながら線消えてしまいました。
(DelphiXE3、Windows7(x64))

>Sara さん
ありがとうございました。
TImageに描けば良い、という事に気付いていませんでした。
FormのCanvasに描画したい理由が無いので、この方法が妥当ですね。

皆様、この度はとても勉強になりました。
ありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加