Delphi

Tipps zur Programmiersprache Delphi. Für Entwickler vielleicht interessant, denn es sind meist Dinge, die ich selbst als Problem hatte und nirgends eine gute Lösung fand.


 

Dreifachklicks in Delphi

Last modified on 2008-06-05 18:23:52 GMT. 0 comments. Top.

4. Dezember 2007

(Dies ist ein Post, den ich im Dezember 2007 auf meinem google Blog veröffentlicht hatte und der hier wiederholt wird.)

Oft steht man vor dem Wunsch, z.B. per Dreifachklick ein Editierfeld vollständig zu markieren o.ä.

Es gibt nun keinen Event wie den DblClick-Event, den man da einfach benutzen kann. Man kann sich aber wie folgt behelfen: Wenn jemand dreifach klickt, dann macht er zuerst einen Doppelklick und dann noch einen einfachen Klick. Der einfache Klick muss aber folgende Eigenschaften haben:

1.) Er darf nicht zu spät kommen
2.) Die Maus darf nicht sehr weit bewegt worden sein.

Ich gehe mal davon aus, dass man die Maus 4 Pixel bewegen darf und frage hier keine Systemeigenschaften ab.

Bei der Zeit ist es aber so, dass viele Anwender die Doppelklickgeschwindigkeit ändern, sodass man das berücksichtigen sollte. Das kann man mit der Windows-API-Funktion GetDoubleClickTime ermitteln.

Also, hier ist der Code für einen Dreifachklick auf Edit1:

1.)Definiere in der Form die Variablen:
dblclickinterval, dblclicktime, dblclickx, dblclicky: cardinal;

2.) In Formshow (nicht in FormCreate, was - zumindest in D2007 - zum Chaos führt) das Intervall ermitteln:

procedure TForm1.FormShow(Sender: TObject);
begin
dblclickinterval:=windows.GetDoubleClickTime;
end;

3.) Dbl von Edit1: Werte merken.

procedure TForm1.Edit1DblClick(Sender: TObject);
begin
dblclickx:=mouse.CursorPos.X;
dblclicky:=mouse.CursorPos.Y;
dblclicktime:=GetTickCount;
end;

4.) Klicken von Edit1 anfangen und auswerten:

procedure TForm1.Edit1Click(Sender: TObject);
begin
if GetTickCount-dblclicktime<=dblclickinterval then begin
if (abs(mouse.CursorPos.X-dblclickx)<=4) and (abs(mouse.CursorPos.Y-dblclicky)<=4)
then begin
Edit1.SelectAll;
end;
end;
end;

SelectAll beim TEdit gibt es vielleicht in früheren Delphiversionen nicht, oder es funktioniert einfach nicht. Es geht aber in D2007. In älteren Versionen muss man evtl. dem TEdit eine Botschaft senden, die den Text markiert.


Schnelle StringReplace in Delphi

Last modified on 2009-02-02 17:57:50 GMT. 0 comments. Top.

Vor kurzem hatte ich das Problem, dass die StringReplace-Funktion in Delphi sehr langsam wird, wenn der String lang ist. Ich hab das Problem sehr oft, z.B. Zeilenumbrüche aus großen Strings durch Leerzeichen zu ersetzen usw.

Meine Recherche im Internet ergab zwar einige Treffer mit Verbesserungen um Faktor 3-10, aber ich habe dann stattdessen einfach versucht, den String zu unterteilen und die Funktion einfach auf kleinere Strings anzuwenden. Das Problem dabei ist aber, dass an der Schnittstelle, dort wo eine Unterteilung ist, das alte Pattern vielleicht zerschnitten wurde. Dem muss man Rechnung tragen.

Heraus kam diese Funktion, die eine Verbesserung um Faktoren bis zu 100 bringt!
Hier ist es einfach mit der Option [RfReplaceAll] gemacht.

function StringReplace_schnell(s,oldpattern,newpattern: String; abschnitte: integer=255): String;
var i,k,le, le2m1, lem1, ende: integer; s1: String;
oldpatterngeschnitten: boolean;
begin
Result:='';
le:=Length(oldpattern);
le2m1:=le+le-1;
lem1:=le-1;
k:=0;
repeat
//Problem ist, dass das oldpattern vielleicht gerade hier ist,
//wo der Schnitt gemacht wird...
ende:=k+Abschnitte;
oldpatterngeschnitten:=Pos(oldpattern,copy(s,ende-lem1,le2m1))>0;
if oldpatterngeschnitten then begin
repeat
ende:=ende+le;
oldpatterngeschnitten:=Pos(oldpattern,copy(s,ende-lem1,le2m1))>0;
until not oldpatterngeschnitten;
end;
s1:=copy(s,k+1,ende-k);
k:=ende;
Result:=Result+StringReplace(s1,oldpattern,newpattern,[RfReplaceAll]);
until s1=”;
end;

Ich habe das getestet und Geschwindigkeitsvorteil bis Faktor 100 festgestellt.

Update Feb. 2009:
Ich habe nach einigen Tests die Erfahrung gemacht, dass ein Wert von 255 Zeichen für die Unterteilung ein guter Wert ist, den man in vielen Fällen standardmäßig einsetzen kann. Ich habe diesen Algorithmus unter diesem Aspekt unter vielen Situationen daraufhin überprüft.

Vor allem ist zu sagen, dass die verschiedenen Versionen von Delphi hier auch unterschiedlich reagieren. So muss man unter seiner eigenen Entwicklungsumgebung selbst entscheiden, was der beste Wert ist. Ausserdem ist auch die zu erwartende Verteilung des Suchbegriffs ein Einflußfaktor.
Viele Grüße
Andreas Lindae