delphi中如何用finddialog实现对memo控件的查找

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了delphi中如何用finddialog实现对memo控件的查找相关的知识,希望对你有一定的参考价值。

procedure TForm1.FindDialog1Find(Sender: TObject);
var
I, J, PosReturn,
SkipChars: Integer;
begin
for I := 0 to Memo1.Lines.Count
do
begin
PosReturn := Pos(FindDialog1.FindText,Memo1.Lines[I]);
if
PosReturn <> 0 then found!
begin
Skipchars := 0;
for J := 0 to
I - 1 do
Skipchars := Skipchars + Length(Memo1.Lines[J]);
SkipChars :=
SkipChars + (I*2);
SkipChars := SkipChars + PosReturn -
1;
Memo1.SetFocus;
Memo1.SelStart := SkipChars;
Memo1.SelLength :=
Length(FindDialog1.FindText);
Break;
end;
end;
end;
网上搜的代码 !但是只能查找一次,点查找下一个没反应......而且希望 查找不出输入内容时能弹出窗口“'不能找到'+finddialog1.findtext“ 求解!!!谢谢了!~

参考技术A procedure TForm1.FindDialog1Find(Sender: TObject);
begin
with Sender as TFindDialog do
if not SearchMemo(Memo1, FindText, Options) then
ShowMessage('Cannot find "' + FindText + '".');
end;

===============================================================
unit Search;

interface

uses WinProcs, SysUtils, StdCtrls, Dialogs;

const
Default word delimiters are any character except the core alphanumerics.
WordDelimiters: set of Char = [#0..#255] - ['a'..'z','A'..'Z','1'..'9','0'];

SearchMemo scans the text of a TEdit, TMemo, or other TCustomEdit-derived
component for a given search string. The search starts at the current
caret position in the control. The Options parameter determines whether the
search runs forward (frDown) or backward from the caret position, whether
or not the text comparison is case sensitive, and whether the matching
string must be a whole word. If text is already selected in the control,
the search starts at the 'far end' of the selection (SelStart if searching
backwards, SelEnd if searching forwards). If a match is found, the
control's text selection is changed to select the found text and the
function returns True. If no match is found, the function returns False.
function SearchMemo(Memo: TCustomEdit;
const SearchString: String;
Options: TFindOptions): Boolean;

SearchBuf is a lower-level search routine for arbitrary text buffers. Same
rules as SearchMemo above. If a match is found, the function returns a
pointer to the start of the matching string in the buffer. If no match,
the function returns nil.
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.追问

我照你的代码敲了一遍,虽然没有报错,
但是运行时,无论查找什么,都弹出“无法找到***”。
我是复制粘贴的代码,应该不存在有漏、有错的地方...

追答

要关闭对话框就能显示找到的地址。在对话框打开时,它不能把找到的串标识出来。所以这段代码仍有待完善。
这是delphi示例中的代码。

追问

好的,还是谢谢

本回答被提问者和网友采纳

Java中如何用其他方法实现大小写转换

在不使用touppercase()的情况下,实现大小写转换

public class Test
    public static void main(String[] args)
        Test test = new Test();
        String str1 = "abcdefg";
        String str2 = "QWERT";
        //转成大写
        System.out.println(test.changeString(str1,true));
        //转成小写
        System.out.println(test.changeString(str2,false));
        
    

    //小写字母转大写
    public char toUpper(char ch)
       if(ch <= 122 && ch >= 97)
            ch -= 32;
       
       return ch;
    
    
    //大写字母转小写
    public char toLower(char ch)
        if(ch <= 90 && ch >= 65)
           ch += 32;
        
        return ch;
    
    
    //转换字符窜 flag 为true 大写
    public String changeString(String str,Boolean flag)
        char[] ch = str.toCharArray();
     StringBuffer sbf = new StringBuffer();
        for(int i=0; i< ch.length; i++)
          if(flag)
            sbf.append(toUpper(ch[i]));
          else
             sbf.append(toLower(ch[i]));
          
        
        return sbf.toString();
     
 

参考技术A 写一个map,key是小写字母,value写大写字母。
准备一个stringbuilder对象。
接收一个英文字符串。
写for循环,逐一取字符,根据字符取map中对应Value。
把取得value追加到stringbuilder对象结尾。追问

嗯……可以举个例子写一下大概的代码吗?初学者表示看不大明白

追答

私聊吧

以上是关于delphi中如何用finddialog实现对memo控件的查找的主要内容,如果未能解决你的问题,请参考以下文章

Delphi 200XXE中如何用并行实现循环的计算

delphi中如何用locate定位记录

Delphi中如何用IP地址的方式来连接Oracle数据库?

在delphi中如何用clientsocket进行实时发送。。即在数据库读取到数据就立即发送出去。。

Keil中如何用Keil中如何用汇编调用C函数?

Delphi 如何用多线程进行数据采集