いつもお世話になっております。
今回の質問なんですが、PaintBoxに描画する線の幅をあげると
psDash 破線
psDot 点線
psDashDot 一点鎖線
psDashDotDot 二点鎖線
が、実線になってしまいます。どうにかしてスタイルを維持できないでしょうか?
方法がありましたらご教授願います。
できないと思います。
自前でコーディングするしかないかと。
単に、私が知らないだけかもしれませんが。
そうですか、わかりました!!
ありがとうございます。
PaintBoxは使ったことがないので、通用するかは解りませんが
TImage, TCanvas上での描画経験があります。
中村拓男さんのホームページ「中村の里」にある
TPathクラスを使うとあっけなく簡単に実現できます。
私は、同氏の著書「Delphi Graphic Secrets」で知りました。
記憶では、描画速度がやや落ちたように思います。
昨日は急いでいたのできちんと調べられませんでした。
補足をさせていただきます。
中村の里の該当ページ
http://www.asahi-net.or.jp/~HA3T-NKMR/DGS/DownLoad.htm
このぺーじより DHGL 1.2 (dhgl1.2.lzh, 3.63MB) 2002/9/26 版
をダウンロード
TPathはCommonフォルダのPathUtils.pasをusesして使います。
TPathの使い方は、
Chapter6\6-2\WideDashedLin\のデモプロジェクトにあります。
ありがとうございます!!
やってみますね!!
sadoyamaさん、ありがとうございます。
今、サンプルのソースを見ているのですが私のレベルでは、何がどうなっているのか分かりませんので、もしよろしければご教授願いたいのですが・・・
> PaintBoxは使ったことがないので、通用するかは解りませんが
> TImage, TCanvas上での描画経験があります。
私がやっているのは、TPaintBoxのTCanvas上での描画です^^;
説明不足ですいませんでした。
現在、PolyLineを使ってPointで座標を指定し点と点と結ぶグラフを描画しているのですが^^;ソースは下記の様なものです。
//******************************************************************************
// CanvasPaint : グラフ描画
// 罫線を描画する
// 引数 : ACanvas : ペイントボックス.キャンバス
// ARect : ペイントボックス領域
// 戻り値 : なし
//
//******************************************************************************
procedure TFm31RmsMain.CanvasPaint(ARect: TRect;p_PrintDataAry: PRMSItem;
p_Property: TGraphPaint);
var
iLoopCnt: Integer;
iZoom: Integer;
// グラフ描画関連
pDataAry : array[0..15] of TPoint; // 座標変換配列
pStart : TPoint; // 基準開始座標
pEnd : TPoint; // 基準終了座標
eGraphDmax : Extended; // 環境設定画面 グラフDMAX
eMeasureX : Extended; // 1マスの幅
eMeasureY : Extended; // 1マスの高さ
begin
// 画像を表示するCanvasを設定
Case Pctl01.ActivePageIndex of
0 : ActiveCanvas := Ptbo01RmsVsDen;
1 : ActiveCanvas := Ptbo02RmsVsLog;
2 : ActiveCanvas := Ptbo03Wiener;
3 : ActiveCanvas := Ptbo04CTF01;
4 : ActiveCanvas := Ptbo05CTF02;
end;
// ---------------------------------------------------------------------------
// 初期設定
// ---------------------------------------------------------------------------
// グラフ縦軸の最大値
// eGraphDmax := m_objSensitManager.m_objIniFile.m_eRangeDMax;
eGraphDmax := StrToFloat(EdtMax.Text);
// 横軸の間隔を設定
eMeasureX := (ARect.Right - ARect.Left) / 16; // 「描画領域 / 16」
// 縦軸の間隔を設定
eMeasureY := (ARect.Bottom - ARect.Top) / eGraphDmax;
// 基準座標設定
pStart.X := ARect.Left; // 基準開始 X座標
pStart.Y := ARect.Top; // 基準開始 Y座標
pEnd.X := ARect.Right; // 基準終了 X座標
pEnd.Y := ARect.Bottom; // 基準終了 Y座標
// ---------------------------------------------------------------------------
// Zoom・シフト有無判定
// ---------------------------------------------------------------------------
iZoom := 1; // 簡易増構造にはズーム機能はないので1に指定
// ---------------------------------------------------------------------------
// X座標,Y座標取得
// ---------------------------------------------------------------------------
for iLoopCnt := 0 to p_Property.iDotNum -1 do
begin
// X座標設定
pDataAry[iLoopCnt].X := pStart.X + Ceil(eMeasureX * iLoopCnt * iZoom);
// Y座標設定
pDataAry[iLoopCnt].Y := pEnd.Y - Ceil(eMeasureY * (p_PrintDataAry[iLoopCnt] / 1000) * iZoom);
end;
// ---------------------------------------------------------------------------
// グラフ描画
// ---------------------------------------------------------------------------
with ActiveCanvas.Canvas do
begin
// 描画線書式設定
Pen.Style := p_Property.tStyle; // 線種設定
Pen.Color := p_Property.tColor; // 線色設定
Pen.Width := p_Property.iWidth; // 線幅設定
// 描画
polyLine(pDataAry);
end;
end;
この場合、TPenのWidthが一定以下だと実践になります。この値を少し増やしてみてはいかがですか?
BeginPathとEndPathにはさんで描画し、その後、多角形化、Path情報を取得、描画、という具合にします。
単純なMoveTo, LineToでは、DrawPathでうまく行かなかったのですが、polyLineならたぶんうまく行きます。
2点間の場合、PathUtilsの、DrawPathを、次のように変更すれば一応動きました。
// 図形情報を取り出す
FirstIndex := LastIndex;
if FirstIndex + 1 < Path.Count-1 then
begin
を、
// 図形情報を取り出す
FirstIndex := LastIndex;
if FirstIndex + 0 < Path.Count-1 then
begin
に。
その上で、
procedure TMainForm.PaintBox1Paint(Sender: TObject);
var
Path: TPath;
begin
Path := TPath.Create;
try
BeginPath(PaintBox1.Canvas.Handle);
PaintBox1.Canvas.MoveTo(20,20);
PaintBox1.Canvas.LineTo(PaintBox1.Width-20, PaintBox1.Height-20);
EndPath(PaintBox1.Canvas.Handle);
FlattenPath(PaintBox1.Canvas.Handle);
Path.LoadFromCanvas(PaintBox1.Canvas);
DrawPath(Path, PaintBox1.Canvas, clRed, 8, [1, 1]); // 点線で描く
finally
Path.Free;
end;
end;
こんな感じで出来ました。
> 単純なMoveTo, LineToでは、DrawPathでうまく行かなかったのですが
http://www.asahi-net.or.jp/~HA3T-NKMR/DGS/AfterCare.htm#Aftercare10
ここに出てましたね。
こちらに差し替えてください。私の修正だと抜けがあると思いますので。
> DrawPath(Path, PaintBox1.Canvas, clRed, 8, [1, 1]); // 点線で描く
のPathとは何でしょうか?
HelpでTPathで調べても出てこないので分からないのですが^^;
[1,1]も何なのでしょう?TCapStyle???
DrawPath(???,描画する場所,描画色,ペン幅,???); // 点線で描く
一点鎖線、二点鎖線の場合はどうなりますか?
DHGL 1.2のChapter6を参照してください。
サンプルがあります。
鎖線も、DrawPathの第5引数で指定できます。
詳細は、DHGL 1.2に含まれるヘルプに出ています。
できました!!
sadoyamaさん、にしのさん、HOtaさん
ありがとうございました!!
ツイート | ![]() |