熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Delphi編程 >> 正文

DELPHI基礎教程:文本編輯器的設計(二)[2]

2013-11-23 17:52:05  來源: Delphi編程 

  SearchMemo代碼如下

  unit Search;

  interface

  uses WinProcs SysUtils StdCtrls Dialogs;

  const

  WordDelimiters: set of Char = [##] [azAZ];

  function SearchMemo(Memo: TCustomEdit;

  const SearchString: String;

  Options: TFindOptions) Boolean;

  function SearchBuf(Buf: PChar; BufLen: Integer;

  SelStart SelLength: Integer;

  SearchString: String;

  Options: TFindOptions) PChar;

  implementation

  function SearchMemo(Memo: TCustomEdit;

  const SearchString: String;

  Options: TFindOptions) Boolean;

  var

  Buffer P: PChar;

  Size: Word;

  begin

  Result := False;

  if (Length(SearchString) = ) then Exit;

  Size := MemoGetTextLen;

  if (Size = ) then Exit;

  Buffer := StrAlloc(Size +

  try

  MemoGetTextBuf(Buffer Size +

  P := SearchBuf(Buffer Size MemoSelStart

  MemoSelLengthSearchString Options)

  if P <> nil then

  begin

  MemoSelStart := P Buffer;

  MemoSelLength := Length(SearchString)

  Result := True;

  end;

  finally

  StrDispose(Buffer)

  end;

  end;

  function SearchBuf(Buf: PChar; BufLen: Integer;

  SelStart SelLength: Integer;

  SearchString: String;

  Options: TFindOptions) PChar;

  var

  SearchCount I: Integer;

  C: Char;

  Direction: Shortint;

  CharMap: array [Char] of Char;

  function FindNextWordStart(var BufPtr: PChar) Boolean;

  begin { (True XOR N) is equivalent to

  (not N) }

  Result := False; { (False XOR N) is equivalent

  to (N) }

  { When Direction is forward ( skip non

  delimiters then skip delimiters }

  { When Direction is backward ( skip delims then

  skip non delims }

  while (SearchCount > ) and

  ((Direction = ) xor (BufPtr^ in

  WordDelimiters)) do

  begin

  Inc(BufPtr Direction)

  Dec(SearchCount)

  end;

  while (SearchCount > ) and

  ((Direction = ) xor (BufPtr^ in

  WordDelimiters)) do

  begin

  Inc(BufPtr Direction)

  Dec(SearchCount)

  end;

  Result := SearchCount > ;

  if Direction = then

  begin { back up one char to leave ptr on first non

  delim }

  Dec(BufPtr Direction)

  Inc(SearchCount)

  end;

  end;

  begin

  Result := nil;

  if BufLen <= then Exit;

  if frDown in Options then

  begin

  Direction := ;

  Inc(SelStart SelLength) { start search past end of

  selection }

  SearchCount := BufLen SelStart Length(SearchString)

  if SearchCount < then Exit;

  if Longint(SelStart) + SearchCount > BufLen then

  Exit;

  end

  else

  begin

  Direction := ;

  Dec(SelStart Length(SearchString))

  SearchCount := SelStart;

  end;

  if (SelStart < ) or (SelStart > BufLen) then Exit;

  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) sizeof(CharMap))

  AnsiUpperBuff(@SearchString[]

  Length(SearchString))

  end;

  while SearchCount > do

  begin

  if frWholeWord in Options then

  if not FindNextWordStart(Result) then Break;

  I := ;

  while (CharMap[Result[I]] = SearchString[I+]) do

  begin

  Inc(I)

  if I >= Length(SearchString) then

  begin

  if (not (frWholeWord in Options)) or

  (SearchCount = ) or

  (Result[I] in WordDelimiters) then

  Exit;

  Break;

  end;

  end;

  Inc(Result Direction)

  Dec(SearchCount)

  end;

  Result := nil;

  end;

  end

  

[]  []  []  []  


From:http://tw.wingwit.com/Article/program/Delphi/201311/25253.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.