Delphi - chemin d'accès de style elliptique (get path ellipsis)

0/5 (18 avis)

Vue 7 782 fois - Téléchargée 625 fois

Description

Comment tronquer un chemin d'accès de fichier trop long en une expression elliptique.
Naturellement, la fonction peut être surchargée pour accepter d'autres contrôles qu'une zone de texte (TEdit).
Pour tronquer une chaîne de caractères trop longue et ajouter des points de suspension, il vous faut simplement remplacer l'option DT_PATH_ELLIPSIS par DT_WORD_ELLIPSIS.

Source / Exemple :


function GetPathEllipsis(ASender: TEdit; APath: string): string;
{ Retourne une expression elliptique d'un emplacement de fichier }
var
  PChr: PChar;
  Rct: TRect;
begin
  if Assigned(ASender) then
    with TCanvas.Create do
      try
        Handle:=GetDC(ASender.Handle);
        if (Handle<>0) and (APath<>EmptyStr) and (ASender.ClientWidth>0) then begin
          // Un simple transtypage peut générer une erreur mémoire (chaîne AZT modifiée)
          PChr:=StrAlloc(Length(APath) + 5);
          StrPCopy(PChr, APath);
          Rct:=ASender.ClientRect;
          // Réserver 2 pixels aux marges gauche et droite
          Rct.Right:=Rct.Right-2;
          Font:=ASender.Font;
          if (DrawText(Handle, PChr, Length(Apath), Rct, DT_MODIFYSTRING Or DT_SINGLELINE or DT_PATH_ELLIPSIS)>0) then
            Result:=PChr;
          StrDispose(PChr);
        end;
      finally
        if (handle<>0) then
          ReleaseDC(ASender.Handle, Handle);
        Free;
      end;
end;

Conclusion :


Voir le projet en demo (comparaison des méthodes DrawText et MinimizeName).

Nota bene : rappelez-vous qu'une chaîne AZT modifiée par une API ne doit pas être créée par simple transtypage (PChar).

Codes Sources

A voir également

Ajouter un commentaire Commentaires
FENETRES Messages postés 196 Date d'inscription jeudi 15 juillet 2004 Statut Membre Dernière intervention 14 avril 2009
25 nov. 2008 à 11:46
Annule et remplace l'implémentation précédente (omission de la condition de libération du DC) :
--------------------------------------------------------
function GetPathEllipsis(ASender: TEdit; APath: string): string;
{ Retourne une expression elliptique du chemin d'accès }
var
DTParams: DrawTextParams;
PChr: PChar;
Rct: TRect;
begin
with DTParams do begin
cbSize:=SizeOf(DrawTextParams);
iLeftMargin:=1;
iRightMargin:=1;
end;
with TCanvas.Create do
try
Handle:=GetDC(ASender.Handle);
if (Handle<>0) and (APath<>EmptyStr) and (ASender.ClientWidth>0) then begin
PChr:=StrAlloc(Length(APath) + 5);
StrPCopy(PChr, APath);
Rct:=ASender.ClientRect;
Font:=ASender.Font;
if DrawTextEx(Handle, PChr, -1, Rct, DT_MODIFYSTRING Or DT_SINGLELINE or DT_PATH_ELLIPSIS, @DTParams) <> 0 then
Result:=PChr;
StrDispose(PChr);
end;
finally
if (handle<>0) then ReleaseDC(ASender.Handle, Handle);
Free;
end;
end;
--------------------------------------------------------
FENETRES Messages postés 196 Date d'inscription jeudi 15 juillet 2004 Statut Membre Dernière intervention 14 avril 2009
25 nov. 2008 à 10:14
Procédure équivalente avec l'API DrawTextEx (cf. ci-dessous) :
--------------------------------------------------------------------
function GetPathEllipsis(ASender: TEdit; APath: string): string;
{ Retourne une expression elliptique du chemin d'accès }
var
DTParams: DrawTextParams;
PChr: PChar;
Rct: TRect;
begin
with DTParams do begin
cbSize:=SizeOf(DrawTextParams);
iLeftMargin:=1;
iRightMargin:=1;
end;
with TCanvas.Create do
try
Handle:=GetDC(ASender.Handle);
Font:=ASender.Font;
if (Handle<>0) and (APath<>EmptyStr) and (ASender.ClientWidth>0) then begin
PChr:=StrAlloc(Length(APath) + 5);
StrPCopy(PChr, APath);
Rct:=ASender.ClientRect;
if DrawTextEx(Handle, PChr, -1, Rct, DT_MODIFYSTRING Or DT_SINGLELINE or DT_PATH_ELLIPSIS, @DTParams) <> 0 then
Result:=PChr;
StrDispose(PChr);
end;
finally
ReleaseDC(ASender.Handle, Handle);
Free;
end;
end;
--------------------------------------------------------------------
Min. required OS:
- DrawTex requires Windows NT 3.1 or later; Requires Windows 95 or later
- DrawTextEx requires Windows NT 4.0 or later; Requires Windows 95 or later
FENETRES Messages postés 196 Date d'inscription jeudi 15 juillet 2004 Statut Membre Dernière intervention 14 avril 2009
21 nov. 2008 à 10:31
Erratum, lire plutôt :
Indispensable et simple à mettre en oeuvre, une vérification d'éventuelles fuites de mémoire devrait être systématique !
FENETRES Messages postés 196 Date d'inscription jeudi 15 juillet 2004 Statut Membre Dernière intervention 14 avril 2009
21 nov. 2008 à 10:14
En remplacant l'instruction précédente par :
« ReportMemoryLeaksOnShutdown:=(DebugHook <> 0); » le gestionnaire de mémoire ne sera actif qu'en mode de débogage.
Indispensable parce que simple à mettre en oeuvre, cette vérification d'éventuels fuites de mémoire devrait être systématique !
FENETRES Messages postés 196 Date d'inscription jeudi 15 juillet 2004 Statut Membre Dernière intervention 14 avril 2009
20 nov. 2008 à 17:38
A propos, si quelqu'un continue à penser qu'il est possible de supprimer une instruction de libération dans le projet alors ajouter une vérification de la mémoire dans le fichier dpr comme ci-dessous :
--------------------------------
program Demo;

uses
Forms,
MainUnit in 'MainUnit.pas' {FrmDemo};

{$R *.res}

begin
ReportMemoryLeaksOnShutDown:=True;
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TFrmDemo, FrmDemo);
Application.Run;
end.

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.