ふにゃるんv2

もとは、http://d.hatena.ne.jp/Wacky/

TMemoに検索機能を付ける

自分用小物プログラムに、適当検索機能を付けた際に、参考にさせてもらったコードを忘れないようメモ。


以下のコードは、フォームに以下のコンポーネントを貼り付けた後の、検索コード例。

以下のコードで、検索ダイアログを開いて「検索」ボタンを押すと、Findイベントが呼ばれ、そこから検索文字列を検索&選択します。

// 指定位置版のAnsiPos
// N.E.SITE - Delphi 工房 - Tips - 部分文字列の検索
// http://www.din.or.jp/~egawa-n/delphi/tips/search.html
function AnsiSearch(const SubStr, Str: string; StartPos: Integer): Integer;
var
  P: PChar;
begin
  if StartPos > 0 then begin
    P := PChar(Str);
    if ByteType(Str, StartPos) = mbLeadByte then Inc(StartPos);
    Inc(P, StartPos);
    P := AnsiStrPos(P, PChar(SubStr));
    if Assigned(P) then Result := P - PChar(Str) + 1
    else Result := 0
  end else Result := AnsiPos(SubStr, Str)
end;

// TMemo内のテキストを検索&選択する関数
// TMemo内のテキストを検索する関数はあるのか?
// http://homepage1.nifty.com/MADIA/delphi/delphi_bbs/200406/200406_04060025.html
procedure FindAndSel(const Str:string; Memo:TMemo; idx:integer);
var
  iPos:integer;
begin
  iPos := AnsiSearch(Str, Memo.Lines.Text, idx);
  if iPos <> 0 then begin
    Memo.SelStart := iPos-1;
    Memo.SelLength := Length(Str);
  end else
    ShowMessage('見つかりません');
  Memo.SetFocus;
end;

// 検索実行を指示された
procedure TFormMain.FindDialog1Find(Sender: TObject);
var
  idx: integer;
  src: TMemo;
begin
  src := Memo1;
  idx := src.SelStart;
  if src.SelLength > 0 then idx := idx + src.SelLength;
  FindAndSel(FindDialog1.FindText, src, idx);
end;

余談

最近、Delphiは元気無いですねぇ。(正確には、Delphiを売ってる元会社)
Win32専用アプリを作るのに結構重宝するんですが、何故か売ってた会社自体から冷遇されているとしか思えない仕打ちを受け続けて、サパーリな状態になっちゃいました。
(何とかトゲザー買収して、方針転換とか言い出した時、そんなに あっちの市場は大きいのかと思ったんだけど、結局どうだったんだろう?)

ちなみに、個人的には結構好きなんですが、周りはC系のせいか、「Delphi」より「C++ Builder」を選択する人ばっかです。
Delphiの方がコンパイル速度も速いし、作成されるコードも安定していると思うんだけどなぁ。