程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 第四章-文本編輯器的設計(二)(1)

第四章-文本編輯器的設計(二)(1)

編輯:Delphi

4.4.2查找對話框部件 

查找對話框部件為應用程序提供查找對話框, 用戶可使用查找對話框在文本文件中查找字符串。

可用Execult方法顯示查找對話框,如圖4.8。應用程序要查找的字符放到FindText屬性中。Options 屬性可決定查找對話框中有哪些選項。例如, 用戶可選擇是否顯示匹配檢查框。Options的常用選項如表4.2所示。

如果用戶在對話框中輸入字符並選擇FindNext按鈕,對話框將發生OnFind事件。 

表4.2 查找對話框的Options屬性的取值及含義

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

取值           含義

───────────────────────────────────────

frDown 如果是真值,對話框中出現Down按鈕,查找方向向下。如果是假

值,Up按鈕將被選中,查找方向向上,frDown 值可在設計或運行

時設置。

frDisableUpDown 如果是真值,Up和Down按鈕將變灰,用戶不能進行選取;如果是

假值,用戶可以選擇其中之一。

frFindNext 如果是真值,應用程序查找在FindNext屬性中的字符串。

frMatchCase 如果是真值,匹配檢查框被選中。設計、運行時均可設置。

frWholeWord 如果是真值,整字匹配檢查框被選中,設計、運行時均可設置。

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 

在OnFind事件中可使用Options屬性來決定以何種方式查找。Find方法響應查找對話框的OnFind事件。 

  procedure TEditform.Find(Sender: TObject);

begin

with Sender as TFindDialog do

if not SearchMemo(Memo1, FindText, Options) then

ShowMessage('Cannot find "' + FindText + '".');

end;

其中SearchMemo函數是Search單元中定義的,SearchMemo可在TEdit,TMemo,以及其它TCustomEdit派生類中查找指定的字符串。查找從控件的脫字號(^)開始, 查找方式由Options決定。如果向後查找從控件的StlStart處開始,如果向前查找則從控件的SelEnd處查找。

如果在控件中找到相匹配的字符串,則字符串被選中,函數返回真值。如無匹配的字符串,函數返回假值。

特別注意的是TEdit,TMemo中有一個HideSeletion屬性,它決定當焦點從該控制轉移至其它控制時,被選中的字符是否保持被選中的狀態。如果是真值,則只有獲得焦點才能保持被選中狀態。查找時,焦點在查找對話框上,因此要想了解查找情況,必須將HideSeletion設成假值。控制的缺省值為真值。

SearchMemo代碼如下: 

unit Search;

interface

uses WinProcs, SysUtils, StdCtrls, Dialogs;

const

WordDelimiters: set of Char = [#0..#255] - ['a'..'z','A'..'Z','1'..'9','0']; 

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) = 0) then Exit;

Size := Memo.GetTextLen;

if (Size = 0) then Exit;

Buffer := StrAlloc(Size + 1);

try

Memo.GetTextBuf(Buffer, Size + 1);

P := SearchBuf(Buffer, Size, Memo.SelStart,

Memo.SelLength,SearchString, Options);

if P <> nil then

begin

Memo.SelStart := P - Buffer;

Memo.SelLength := 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 (1), skip non

delimiters, then skip delimiters. }

{ When Direction is backward (-1), skip delims, then

skip non delims }

while (SearchCount > 0) and

((Direction = 1) xor (BufPtr^ in

WordDelimiters)) do

begin

Inc(BufPtr, Direction);

Dec(SearchCount);

end;

while (SearchCount > 0) and

((Direction = -1) xor (BufPtr^ in

WordDelimiters)) do

begin

Inc(BufPtr, Direction);

Dec(SearchCount);

end;

Result := SearchCount > 0;

if Direction = -1 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 <= 0 then Exit;

if frDown in Options then

begin

Direction := 1;

Inc(SelStart, SelLength); { start search past end of

selection }

SearchCount := BufLen - SelStart - Length(SearchString);

if SearchCount < 0 then Exit;

if Longint(SelStart) + SearchCount > BufLen then

Exit;

end

else

begin

Direction := -1;

Dec(SelStart, Length(SearchString));

SearchCount := SelStart;

end;

if (SelStart < 0) 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[1],

Length(SearchString));

end; 

while SearchCount > 0 do

begin

if frWholeWord in Options then

if not FindNextWordStart(Result) then Break;

I := 0;

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

begin

Inc(I);

if I >= Length(SearchString) then

begin

if (not (frWholeWord in Options)) or

(SearchCount = 0) or

(Result[I] in WordDelimiters) then

Exit;

Break;

end;

end;

Inc(Result, Direction);

Dec(SearchCount);

end;

Result := nil;

end; 

end.

 4.4.3 替換對話框部件 

替換對話框部件為應用程序提供替換對話框。如圖4.9。它包括查找對話框的所有功能,此外還允許使用者更換被選中的字符串。FindText 屬性是應用程序需查找的字符串。ReplaceText屬性是被選中字符的替換字符串。Options 屬性決定對話框的顯示方式。其值如表4.3所示。

與查找對話框一樣,替換對話框亦有OnFind 事件。用戶輸入查找字符串並按FindNext按鈕時,發生OnFind 事件。用戶選擇Replace 或ReplacAll 時, 對話框發生OnRelpace事件,要替換的字符串存入ReplaceText屬性中,要編寫相應的代碼以支持替換功能。 

 表4.3 替換對話框的Options屬性的取值及含義

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

取值              含義

────────────────────────────────────────

frRelpace 如果是真值, 應用程序將ReplaceText 屬性中的字符串替換

          FindText屬性中的字符串。

frReplacAll 如果是真值,應用程序將ReplaceText屬性中的字符串替換,

          查找到的所有FindText屬性中的字符串。

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved