@Luckie: Mal ´ne Frage; hattest du noch was an deinem Editor gemacht? Ich habe nämlich bei mir auf der Platte nur eine Version gefunden, die zwar suchen konnte aber nur in Richtung Textende. Das Suchen zum Anfang hin klappte nicht.
Ich habe das Problem jetzt gelöst. Wo is´n der Smiley mit der Wand?
< ------------ >
Also, alex, zuerst die Vorarbeit:
Delphi-Quellcode:
// RichEdit 2.0 erzeugen
hEdit := CreateWindowEx(WS_EX_CLIENTEDGE,'RichEdit20A',nil,
...);
RichEdit20 := (hEdit <> 0);
// hat nicht geklappt, dann RichEdit 1.0 erzeugen
if(not RichEdit20) then
hEdit := CreateWindowEx(WS_EX_CLIENTEDGE,'RICHEDIT',nil,
...);
Die Bool-Variable "RichEdit20" ist global, weil sie noch anderweitig benutzt wird! In Luckies Programm wird dann beim Suchen die Prozedur "Find" aufgerufen. Sollte kein RichEdit 2.0 erzeugt worden sein, wird das Feld mit der Suchrichtung versteckt:
Delphi-Quellcode:
var
fnd : TFindReplace;
FindStr : array[0..4096]of Char;
FindLen : DWORD = SizeOf(FindStr) - 1;
FindTextMsgId : UINT;
procedure Find(hWnd: THandle; hWndEdit: Thandle);
const
sFlag : array[boolean]of cardinal =
(FR_HIDEUPDOWN,FR_DOWN);
begin
fnd.lStructSize := sizeof(TFindReplace);
fnd.hWndOwner := hWnd;
fnd.Flags := sFlag[RichEdit20];
fnd.lpstrFindWhat := FindStr;
fnd.wFindWhatLen := FindLen;
FindTextMsgId := RegisterWindowMessage(FINDMSGSTRING);
CommDlg.FindText(fnd);
end;
Hm, etwas blöd zu erklären, aber ... Dieser Teil steckt in der WNDPROC deines Fensters drin. Da es sich aber bei der Nachricht um keine Konstante handelt, kannst du sie nicht mit case-of abfragen. Deswegen so:
Delphi-Quellcode:
// Suchfunktion, by NicoDE
if(uMsg = FindTextMsgId) and (FindTextMsgId <> 0) then begin
FindParam := PFindReplace(lp);
if(FindParam.Flags and FR_DIALOGTERM = FR_DIALOGTERM) then begin
hWndDlg := 0;
end else if(FindParam.Flags and FR_FINDNEXT = FR_FINDNEXT) then
SearchText(FindParam.hWndOwner, FindParam.lpstrFindWhat,
(FindParam.Flags and FR_DOWN = FR_DOWN) or not RichEdit20,
FindParam.Flags and FR_MATCHCASE = FR_MATCHCASE,
FindParam.Flags and FR_WHOLEWORD = FR_WHOLEWORD);
Result := false;
end
Das "or not RichEdit20" habe
ich eingefügt, damit -beim RichEdit 1.0- die Suchrichtung auf das Textende (Abwärts) festgelegt wird. Vergisst man das, wird genau einmal gesucht.
So, auf die Weise wird also die Prozedur "SearchText" aufgerufen, die letztlich den gesuchten Text im RichEdit markiert:
Delphi-Quellcode:
procedure SearchText(wnd: HWND; Text: pchar; Down, Sense, Whole: Bool);
var
REdit : HWND;
Flags : integer;
FindRec : TFindText;
FindPos : integer;
ErrMsg : array[0..4096]of Char;
begin
REdit := GetDlgItem(wnd,IDC_EDIT);
if(REdit <> 0) then begin
SendMessage(REdit,EM_EXGETSEL,0,LPARAM(@FindRec.chrg));
if(not Down) then FindRec.chrg.cpMin := FindRec.chrg.cpMax - 1
else FindRec.chrg.cpMin := FindRec.chrg.cpMax;
FindRec.chrg.cpMax := -1;
FindRec.lpstrText := Text;
Flags := 0;
if(Down) then Flags := FR_DOWN;
if(Sense) then Flags := Flags or FR_MATCHCASE;
if(Whole) then Flags := Flags or FR_WHOLEWORD;
FindPos := SendMessage(REdit,EM_FINDTEXT,
Flags,LPARAM(@FindRec));
if(FindPos > 0) then begin
FindRec.chrg.cpMin := FindPos;
FindRec.chrg.cpMax := FindPos + lstrLen(Text);
SendMessage(REdit,EM_EXSETSEL,0,LPARAM(@FindRec.chrg));
end else begin
lstrcpy(ErrMsg,pchar('"' + Text + '"'));
lstrcat(ErrMsg,CANNOT_FINDTEXT);
MessageBox(wnd,ErrMsg,APPNAME,MB_ICONINFORMATION);
end;
end;
end;
Die Zeile
if(not Down) then ...
behebt das am Anfang angesprochene Problem mit der Suche in Richtung Textanfang. Jetzt sucht das Ding wie wild.
@alex: Falls was unklar ist, frag einfach. Okay?
btw: Die Suchfunktion ist,
IMHO, übrigens komplett von NicoDE. Wir woll´n uns ja nicht mit fremden Federn schmücken.