PaintBoxのCanvasに図を描いています。
Rectangleを使用して図を描いていますが、そのPaintBoxの手前側にダイアログがある場合、図がうまくかけません。
PaintBox全体を描きたいのに、ダイアログの部分が描かれなかったり、ダイアログ部分以外のところが更新されなかったりします。
ダイアログがPaintBoxの枠の上に重なっていない場合は問題なくうまく描けます。
色々なやり方をしても、うまくできません。
この現象はしょうがないものなのでしょうか?
それはPaintBoxの仕様だったと記憶しています。
PaintBoxは使用メモリがとても少ない代わりに、
描画した内容を再描画する機能が無かったはずです。
その為、他のウインドウ等のダイアログにPaintBoxが隠れてしまうと、
その部分は保持されていないので、再描画された時に白紙になってしまいます。
これを回避するには、素直にImageコンポーネントを使うか、
PaintBoxを拡張して(自分でコンポーネントを作って)機能をつけるしか、
無いと思います。
自分が持っている古いDelphiのフリーコンポーネント集に、
そんなコンポーネントがあったと記憶してます。
因みに、Delphi1や2,3の頃の古い書籍なので、
現在のDelphiに対応している可能性は低いと思います。
Delphi5 のヘルプによると、
>PaintBox コンポーネントについて
>
>用途
>フォーム上での描画を PaintBox で囲まれた特定の長方形の領域に限定します。
>
>作業
>・PaintBox の描画にアクセスするには Canvas プロパティを使う
>・PaintBox のキャンバスに描画するには,OnPaint イベントのイベントハンドラに適切なコードを記述する
だそうです。
TPaintBoxのOnPaint で、図形を描いていますか?
それ以外のタイミングでPaintBoxに描画した内容は、他のウインドウなどで隠れたりすると、消えてしまいます。
回答ありがとうございます。
OnPaintでもその現象はおきます。
Delphi大好きさんの言っているようにImageを使えば、解決できました。
PaintBoxのOnPaint で PaintBoxのCanvasに対して描画していますか?
例えば、PaintBox1.Canvas.FrameRect(〜 ではなく Canvas.FrameRect(〜 にしていると
FormのCanvasに描画に行くので、OnPaintで描いても消えてしまいます。
こんにちは.
>それはPaintBoxの仕様だったと記憶しています。
ですね.
TPaintBoxはTWinContorlの派生コントロールです.
一方,TImageはTGraphicControlの派生コントロールです.
TGraphicContorlはウィンドウを持っていません.マウスやキーボードのイベントを受取れません.
もちろん,受取るようにすることも可能ですが,デフォルトではです.
TGraphiControlのCanvsで描画した内容は,他のフォームが重なっても消えません.
内部で自動処理してくれます.
TWinControlは従来からWindowsにあるコントロールで,これらはマウスやキーイベントを
受取ることができますが,描画内容は他のウィンドウに重なった場合,再描画が必要と
なります.つまり,再描画の際に発生するOnPaintイベント内で,Canvasに記述することに
なります.
これ以上は,長くなるので,ネットで調べてください.
>OnPaintでもその現象はおきます。
そういう現象を経験したことがありません.
具体的なコードがあれば,検討できますが,もし本当にそうであれば,そのTPaintBoxか
Delphiか,OSの一部が破損されているのかも知れません(笑).
説明変だぞ
TImage.Canvas は内部でもっている TPicutre の Canvas
それを Paint で描画しているだけ
Formの上にPaintBoxを置いて
Memo1.Lines.Add (IntToStr(PaintBox1.Canvas.Handle));
Memo1.Lines.Add (IntToStr(Form1.Canvas.Handle));
とやるとわかるけど ハンドルが同じ
つまり PaintBoxに描画しているわけではなく PaintBoxを置いている
フォームに直接描画しているわけ
つまり保存されていないので、消える
TBitmapをPaintBoxと同じサイズにして描画をTBitmapにして
PaintBox.Paint で Bitmap を Draw すれば Image と同じになる
その説明も正確じゃないですね。
PaintBoxのOnPaintの中で
PaintBox1.Canvas.TextOut(0, 0, IntToStr(PaintBox1.Canvas.Handle));
PaintBox1.Canvas.TextOut(0, 10, IntToStr(Form1.Canvas.Handle));
とやると、ちゃんと別々のハンドルが表示されます。
何故かというと、OnPaintを呼び出す前にBeginPaintして、そのDCを使うようにしているから。
(OnPaint以外の場所でCanvasを要求された時は、仕方がないので親のCanvasを借ります)
BeginPaintでもらった方のDCには、描画が必要な領域以外をクリップするよう設定がされています。
一方、FormのCanvasを使うとそのような設定はされていません。
両者を混ぜて使ったり、PaintBoxではなくFormの座標を使って描画したりすると
> ダイアログの部分が描かれなかったり、ダイアログ部分以外のところが更新されなかったり
といった現象が起こりえます。
ツイート | ![]() |