DelFusa Blog 総本山

プログラミングの話題とかです。

NEW | PAGE-SELECT | NEXT

≫ EDIT

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

| スポンサー広告 | --:-- | comments(-) | trackbacks(-) | TOP↑

≫ EDIT

テキストビューワー

ずんぐりと前の、12月あたまに
C++BuilderMLで、こんな質問がありました。

           _________
   ∧,,∧   / ずんぐり前だけど
  ミ,,゚Д゚彡 <  流量はそんなにないから
   ミ つ旦)~~ \ まあ、最近といえば最近だ。
 @ミ   ミ     ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
   ∪''∪


[cbuilder:39782] TMemo の表示で行間を空けたい
内容は転記はしませんが

質問された方は
利用許諾を表示するのにTMemoを使っているそうで
Memoは行間を変えられないから読みにくくて嫌だから
どうしようか、、、と考えたみたいです。

こんな素敵なテクニックを公開された方もおられました。
MiyaB ソフト Delphi Tips
TMemoでもできるんですね。


さてさて、漏れはTMemoとは関係ないので
MLで下手な回答などはできないのですが

一つのネタとして
うちのBarPanelというコンポーネントを使えば
テキストビューワは、意外と簡単につくれるので
ご紹介しておきます。

エディタを自作したい、という人には
文字描画についての、本当の入り口の入り口の
ヒントになんかなるかもね。

※カーソル点滅とかもAPIで出来るんだよね?
 発展させればTMemoみたいなのは自作できるのかな?

漏れの自作のBarPanelというのは外観的にはTScrollBoxです。
パネルにAPIでスクロールバーをくっつけてみました。

TScrollBarは内部のクライアント領域を大きくとれて
コントロールを配置しているとスクロールバーで領域をスクロールできるものです、
それと対比して
私自作のBarPanelは単にPanelの横にスクロールバーがついていて
内部の領域は全く変化しないけどスクロールバーを移動した値は
プロパティとして取得できるから
自前でパネルに文字描画するような時に便利につかえるものです。

はい、BarPanelのソースはこちら
http://delfusa.main.jp/delfusafloor/opensource/delfusalibrary/20070828160200/BarPanel/BarPanel.pas.txt
・・・いまみたら、OutputDebugStringとかがそのまま放置されてる・・・泣ける

さて、これを使ってBarPanelのキャンバスに文字を描画したり
描画をスクロールさせることでテキストビューワーを作る事ができます。

下記のようにします。ちょっとソースは長くてくどいので参考程度にどうぞ。
────────────────────
※FLinesはForm1のメンバーでStringListです。

{-------------------------------
//リサイズでScrollBarのPageSizeを変更
//------------------------------}
procedure TForm1.InitialBarParam;
begin
 BarPanel1.VertScrollBar.Min := 0;
 BarPanel1.VertScrollBar.Max := TextAllLineCount;
 TextShowLineCount;

 BarPanel1.HorzScrollBar.Min := 0;
 BarPanel1.HorzScrollBar.Max := TextAllWidth;
 TextShowTopRow;
end;

procedure TForm1.BarPanel1Resize(Sender: TObject);
begin
 InitialBarParam;
end;
//------------------------------

{-------------------------------
//テキストの行処理
//------------------------------}
function TForm1.TextAllLineCount: Integer;
begin
 Result := FLines.Count;
end;

function TForm1.TextShowLineCount: Integer;
begin
 Result := Abs(PaintBox1.Height div PaintBox1.Canvas.Font.Height);

 {全行数:画面表示可能行=Max:PageSize}
 {FontHeight*画面表示可能行=画面の高さ}

 BarPanel1.VertScrollBar.PageSize := Result;
end; //画面表示可能行

function TForm1.TextShowTopRow: Integer;
begin
 Result := BarPanel1.VertScrollBar.Position;
end;
//------------------------------

{-------------------------------
//テキストの列処理
//------------------------------}
function TForm1.TextAllWidth: Integer;
var
 i: Integer;
 TextWidth: Integer;
begin
 Result := 0;
 for i := 0 to FLines.Count-1 do
 begin
  TextWidth := PaintBox1.Canvas.TextWidth(FLines[i]);
  if Result < TextWidth then
  begin
   Result := TextWidth;
  end;
 end;
 Result := Result + 100;
end;

function TForm1.TextShowLeft: Integer;
begin
 Result := BarPanel1.HorzScrollBar.Position;
end;

function TForm1.TextShowWidth: Integer;
begin
 Result := PaintBox1.Width;
 BarPanel1.HorzScrollBar.PageSize := Result;
end;
//------------------------------

{-------------------------------
//テキストの行スクロール処理
//------------------------------}
procedure TForm1.BarPanel1VertScrolling(Sender: TObject; ScrollCode: TScrollCode;
 var ScrollPos: Integer);
begin
 FScrPreLinePos := BarPanel1.VertScrollBar.Position;
end;

procedure TForm1.BarPanel1VertScroll(Sender: TObject);
var
 LineScrCount: Integer;
 R: TRect;
begin
 LineScrCount := BarPanel1.VertScrollBar.Position - FScrPreLinePos;
 {上:スクロールした行数}

 R := PaintBox1.BoundsRect;

 ScrollWindow(BarPanel1.Handle, 0, -1*LineScrCount*Abs(PaintBox1.Canvas.Font.Height),
        @R, @R);

 PaintBox1.Update;
end;
//------------------------------

{-------------------------------
//テキストの列スクロール処理
//------------------------------}
procedure TForm1.BarPanel1HorzScrolling(Sender: TObject; ScrollCode: TScrollCode;
 var ScrollPos: Integer);
begin
 FScrPreLeftPos := BarPanel1.HorzScrollBar.Position;
end;

procedure TForm1.BarPanel1HorzScroll(Sender: TObject);
var
 LeftScrCount: Integer;
 R: TRect;
begin
 LeftScrCount := BarPanel1.HorzScrollBar.Position - FScrPreLeftPos;
 {上:スクロールした横幅}

 R := PaintBox1.BoundsRect;

 ScrollWindow(BarPanel1.Handle, -1*LeftScrCount, 0, @R, @R);

 PaintBox1.Update;
end;
//------------------------------

{-------------------------------
//テキストの表示処理
//------------------------------}
procedure TForm1.PaintBox1Paint(Sender: TObject);
var
 i: Integer;
begin
 SetWindowOrgEx(PaintBox1.Canvas.Handle, TextShowLeft, 0, nil);

 TextShowWidth;

 for i:=0 to TextShowLineCount+1 do
 begin
  {下:行番号表示}
  PaintBox1.Canvas.TextOut(LineNumberMargin, i*Abs(PaintBox1.Canvas.Font.Height),
   IntToStr(TextShowTopRow+i));
  {下:本文表示}
  if (TextShowTopRow+i) <= (FLines.Count-1) then
  PaintBox1.Canvas.TextOut(TextMargin, i*Abs(PaintBox1.Canvas.Font.Height),
   FLines[TextShowTopRow+i]);
 end;
end;
//------------------------------

────────────────────
PaintBox1Paintあたりをよくみて改造すれば

BarPanelを継承して行幅をプロパティで微調整できる
TextViewPanelなんかつくるのは出来そうです。
再利用しやすいかもね。

ま。お勉強程度にどうぞです。


あ、ところで最近はDelphi系の話題ばかりを追っていたので
BCBの掲示板で賑やかな場所がわからなくなりました。
どこの掲示板で質問と回答をやりとりしている人が多いのかしら?
知ってたら教えてください。

ではでは。
スポンサーサイト

| 未分類 | 23:50 | comments:0 | trackbacks:0 | TOP↑

COMMENT















非公開コメント

TRACKBACK URL

http://delfusa.blog65.fc2.com/tb.php/98-ca803e46

TRACKBACK

PREV | PAGE-SELECT | NEXT

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。