SearchMemo代碼如下
unit Search;
interface
uses WinProcs
const
WordDelimiters: set of Char = [#
function SearchMemo(Memo: TCustomEdit;
const SearchString: String;
Options: TFindOptions)
function SearchBuf(Buf: PChar; BufLen: Integer;
SelStart
SearchString: String;
Options: TFindOptions)
implementation
function SearchMemo(Memo: TCustomEdit;
const SearchString: String;
Options: TFindOptions)
var
Buffer
Size: Word;
begin
Result := False;
if (Length(SearchString) =
Size := Memo
if (Size =
Buffer := StrAlloc(Size +
try
Memo
P := SearchBuf(Buffer
Memo
if P <> nil then
begin
Memo
Memo
Result := True;
end;
finally
StrDispose(Buffer)
end;
end;
function SearchBuf(Buf: PChar; BufLen: Integer;
SelStart
SearchString: String;
Options: TFindOptions)
var
SearchCount
C: Char;
Direction: Shortint;
CharMap: array [Char] of Char;
function FindNextWordStart(var BufPtr: PChar)
begin { (True XOR N) is equivalent to
(not N) }
Result := False; { (False XOR N) is equivalent
to (N) }
{ When Direction is forward (
delimiters
{ When Direction is backward (
skip non delims }
while (SearchCount >
((Direction =
WordDelimiters)) do
begin
Inc(BufPtr
Dec(SearchCount)
end;
while (SearchCount >
((Direction =
WordDelimiters)) do
begin
Inc(BufPtr
Dec(SearchCount)
end;
Result := SearchCount >
if Direction =
begin { back up one char
delim }
Dec(BufPtr
Inc(SearchCount)
end;
end;
begin
Result := nil;
if BufLen <=
if frDown in Options then
begin
Direction :=
Inc(SelStart
selection }
SearchCount := BufLen
if SearchCount <
if Longint(SelStart) + SearchCount > BufLen then
Exit;
end
else
begin
Direction :=
Dec(SelStart
SearchCount := SelStart;
end;
if (SelStart <
Result := @Buf[SelStart];
{ Using a Char map array is faster than calling
AnsiUpper on every character }
for C := Low(CharMap) to High(CharMap) do
CharMap[C] := C;
if not (frMatchCase in Options) then
begin
AnsiUpperBuff(PChar(@CharMap)
AnsiUpperBuff(@SearchString[
Length(SearchString))
end;
while SearchCount >
begin
if frWholeWord in Options then
if not FindNextWordStart(Result) then Break;
I :=
while (CharMap[Result[I]] = SearchString[I+
begin
Inc(I)
if I >= Length(SearchString) then
begin
if (not (frWholeWord in Options)) or
(SearchCount =
(Result[I] in WordDelimiters) then
Exit;
Break;
end;
end;
Inc(Result
Dec(SearchCount)
end;
Result := nil;
end;
end
[
From:http://tw.wingwit.com/Article/program/Delphi/201311/25253.html