Trucs et astuces pour DELPHI


Voici en vrac quelques astuces qui peuvent apporter un peu d'originalité à une application. Elles sont utilisables avec toute les versions 32 bits de Delphi et certainement adaptables à C++ Builder.

Comment placer un contrôle dans une barre d'état?

Vous avez essayé? C'est impossible. Le contrôle se place quelque part au dessus, mais jamais dedans. Qu'est-ce qu'on peut faire, alors?

TStatusBar est dérivé de TWinControl. Or, je connais des TWinControls qui peuvent contenir d'autres contrôles, ne serait-ce que TPanel. Pour qu'un tel contrôle devienne un conteneur, il faut qu'il aît csAcceptsControls dans sa propriété ControlStyle lors de sa création et, de toute évidence, ce n'est pas le cas pour TStatusBar.

Première solution : elle consiste à créer son propore composant dérivé de TStatusBar ou TCustomStatusBar. Il suffit de surcharger le constructeur Create pour lui ajouter ces lignes:

inherited Create(aOwner);
ControlStyle := Controlstyle + [csAcceptsControls];

L'avantage est qu'on pourra y placer un contrôle en mode conception, mais l'inconvénient est qu'il faudra créer un bitmap et un paquet pour ajouter ce nouveau composant dans la palette.

Deuxième solution : elle est plus simple, car la modification se passe en mode exécution. Voici un exemple qui insère une barre de progression dans le premier volet d'une barre d'état:

  1. Editer la propriété Panels de la barre d'état de telle façon qu'il y aît au moins deux volets et spécifier 150 comme largeur pour le premier volet.
  2. Placer un contrôle TProgressBar n'importe où sur la fiche, même dans un autre contrôle. Sa largeur par défaut est 150 et sa hauteur 16.
  3. Dans la procédure Form1.FormCreate, ajouter les lignes de code suivantes:

StatusBar1.ControlStyle := StatusBar1.ControlStyle + [csAcceptsControls];
ProgressBar1.Parent := StatusBar1;
ProgressBar1.SetBounds(0, 2, 150, 16);
ProgressBar1.BringToFront;

C'est tout. Maintenant mon application peut modifier la propriété Position de ProgressBar1, qui s'affiche dans la barre d'état comme s'il s'agissait du premier volet. Pour corser le tout, imaginons que vous vouliez utiliser le premier volet pour afficher du texte pendant que la barre de progression n'est pas utilisée... Rien de plus simple: mettez la propriété Visible de ProgressBar1 à False.


Comment démarrer une application avec une fenêtre invisible?

Delphi est bien gentil, mais vous avez déjà essayé de démarrer une application avec la fenêtre principale invisible (application résidente dans la barre des tâches ou tout simplement contrôler l'affichage de la fenêtre après toutes les intialisations)? Les "Visible := False" ou autres "ShowWindow(Handle, SW_HIDE)" n'y font rien. La fenêtre principale s'obstine à s'afficher...

La solution n'est pas bien compliquée, mais encore faut-il la trouver. Ca m'est arrivé par pur hasard, alors la voici.

Dans la procédure Form1.FormCreate, ajoutez simplement la ligne suivante:

Application.ShowMainWindow := False;

C'est bête comme chou, non? Cela n'affecte que la visibilité au démarrage. Lorsque vous voulez afficher la fenêtre, un simple Visible := True suffit.


Comment gérer le Drag&Drop avec l'interface de Windows?

Supposons que la fenêtre de l'application soit en mesure d'accepter des éléments provenant de l'interface de Windows (explorateur, bureau, dossiers ouverts, etc.), tels que des fichiers ou des raccourcis. Voici la marche à suivre...

1. Indiquer à Windows que la fenêtre accepte le glissement d'objets. Lors de sa création (FormCreate), il suffit de placer l'instruction ci-dessous:

DragAcceptFiles(Handle, True);

2. Une fois cela fait, la fenêtre recevra de Windows un message WM_DROPFILES lorsqu'on y lâchera quelquechose. Il faut donc déclarer une procédure de gestion du message dans la section interface:

protected
procedure WMDropFiles(var Msg: TMessage); message WM_DROPFILES;

3. L'implémentation de cette procédure prend en charge le fait que des fichiers sont lâchés et les utilise pour les besoins de l'application. Pour cela, il faut d'abord récupérer un handle hDrop envoyé avec le message WM_DROPFILES dans wParam. Ce handle est le premier paramètre obligatoire des fonctions gérant le Drag&Drop.

hDrop := THandle(Msg.wParam);

4. Pour connaître le nombre de fichiers lâchés, on utilise la fonction DragQueryFiles en lui passant -1 comme second paramètre:

nbFiles := DragQueryFiles(hDrop, UINT(-1), nil, 0);

5. Ensuite, on utilise la même fonction pour connaître le nom complet de chaque fichier lâché:

pName := StrAlloc(255); // pName est un pChar
for i := 0 to nbFiles -1 do begin

DragQueryFile(hDrop, i, pName, 255);
ListBox1.Items.Add(StrPas(pName)); // par exemple

end;
StrDispose(pName);

6. Enfin, lorsqu'on a fini de récupérer les noms des fichiers lâchés, il ne faut surtout pas oublier de l'indiquer à Windows par la procédure suivante (toujours dans l'implémentation de WmDropFiles):

DragFinish(hDrop);


Comment transformer une icône en bitmap?

Ces deux types d'image n'ont en commun que l'aspect. Les formats de fichiers sont incompatibles. Heureusement, Delphi propose des objets graphiques assez simples à manipuler qui vont permettre d'assurer la conversion en quelques lignes de code.

1. Il faut créer un objet TIcon, si on n'a pas déjà un à disposition, puis y charger l'icône à partir d'un fichier, par exemple. On crée également un objet TBitmap:

aIcon := TIcon.Create;
aBmp := TBitmap.Create;
try
aIcon.LoadFromFile('fichier.ico');

2. Il faut donner au bitmap quelques paramètres initiaux tels que ses dimensions, le nombre de couleurs et la couleur de fond:

aBmp.Width := 32; // même taille que l'icône
aBmp.Height := 32;
aBmp.PixelFormat := pf8bit; // 256 couleurs

// (ou pf4bit pour 16 couleurs, inutile d'en donner plus)
aBmp.Canvas.Brush.Color := clYellow; // couleur de fond jaune, par exemple
// par défaut, c'est clWhite

3. Maintenant, on peut dessiner l'icône dans le bitmap. A noter que les zones transparentes de l'icône prendront la couleur définie précédemment comme couleur de fond du bitmap.

aBmp.Canvas.Draw(0, 0, aIcon);

4. Enregistrer le bitmap dans un fichier et détruire les objets créés dont on n'a plus besoin:

aBmp.SaveToFile('fichier.bmp');
finally
aBmp.Free;
aIcon.Free;
end;

5. Vous pouvez maintenant récupérer le fichier BMP pour le modifier ou l'incorporer dans un bouton.

Quelques remarques: