Cliquez et faites glisser un formulaire Delphi sans la barre de légende

La façon la plus courante de déplacer une fenêtre est de la faire glisser par sa barre de titre. Lisez la suite pour découvrir comment vous pouvez fournir des capacités de glissement pour Delphi formulaires sans barre de titre, afin que l'utilisateur puisse déplacer un formulaire en cliquant n'importe où sur la zone client.

Par exemple, considérons le cas d'un Application Windows qui n'a pas de barre de titre, comment déplacer une telle fenêtre? En fait, il est possible de créer des fenêtres avec une barre de titre non standard et même des formes non rectangulaires. Dans ce cas, comment Windows pourrait-il savoir où se trouvent les bordures et les coins de la fenêtre?

Le message Windows WM_NCHitTest

le Système d'exploitation Windows est fortement basé sur gestion des messages. Par exemple, lorsque vous cliquez sur une fenêtre ou un contrôle, Windows lui envoie un message wm_LButtonDown, avec des informations supplémentaires sur l'emplacement du curseur de la souris et les touches de contrôle actuellement pressé. Sonne familier? Oui, ce n'est rien de plus qu'un événement OnMouseDown dans Delphi.

instagram viewer

De même, Windows envoie un message wm_NCHitTest chaque fois qu'un événement de souris se produit, c'est-à-dire lorsque le curseur se déplace ou lorsqu'un bouton de la souris est enfoncé ou relâché.

Code à saisir

Si nous pouvons faire croire à Windows que l'utilisateur fait glisser (a cliqué sur) la barre de titre plutôt que la zone client, alors l'utilisateur peut faire glisser la fenêtre en cliquant dans la zone client. La façon la plus simple de le faire est de "tromper" Windows en lui faisant croire que vous cliquez réellement sur la barre de titre d'un formulaire. Voici ce que vous devez faire:

1. Insérez la ligne suivante dans la section "Déclarations privées" de votre formulaire (déclaration de procédure de traitement des messages):

procédure WMNCHitTest (var Msg: TWMNCHitTest); message WM_NCHitTest; 

2. Ajoutez le code suivant dans la section «implémentation» de l'unité de votre formulaire (où Form1 est le nom de formulaire supposé):

procédure TForm1.WMNCHitTest (var Msg: TWMNCHitTest);

commencer

hérité;

si Msg. Résultat = htClient ensuite Msg. Résultat: = htCaption;

fin; 

La première ligne de code dans le gestionnaire de messages appelle la méthode héritée pour obtenir la gestion par défaut du message wm_NCHitTest. La partie If de la procédure intercepte et modifie le comportement de votre fenêtre. Voici ce qui se passe réellement: lorsque le système d'exploitation envoie un message wm_NCHitTest à la fenêtre, avec les coordonnées de la souris, la fenêtre renvoie un code qui indique quelle partie d'elle-même a été touché. L'information importante, pour notre tâche, réside dans la valeur du Msg. Champ de résultat. À ce stade, nous avons la possibilité de modifier le résultat du message.

Voici ce que nous faisons: si l'utilisateur a cliqué dans la zone client du formulaire, nous faisons croire à Windows que l'utilisateur a cliqué sur la barre de titre. Dans Object Pascal "mots": si la valeur de retour du message est HTCLIENT, nous la changeons simplement en HTCAPTION.

Plus d'événements de souris

En modifiant le comportement par défaut de nos formulaires, nous supprimons la possibilité pour Windows de vous avertir lorsque la souris survole la zone client. Un effet secondaire de cette astuce est que votre formulaire ne générera plus événements pour souris messages.

Fenêtre sans légende et sans bordure

Si vous souhaitez une fenêtre sans bordure sans légende semblable à une barre d'outils flottante, définissez la légende du formulaire sur une chaîne vide, désactivez tous les BorderIcons et définissez BorderStyle sur bsNone.

Un formulaire peut être modifié de différentes manières en appliquant du code personnalisé dans la méthode CreateParams.

Plus d'astuces WM_NCHitTest

Si vous regardez plus attentivement le message wm_NCHitTest, vous verrez que la valeur de retour de la fonction indique la position du point chaud du curseur. Cela nous permet de jouer un peu plus avec le message pour créer des résultats étranges.

Le fragment de code suivant empêchera les utilisateurs de fermer vos formulaires en cliquant sur le bouton Fermer.

si Msg. Résultat = htClose ensuite Msg. Résultat: = htNowhere; 

Si l'utilisateur tente de déplacer le formulaire en cliquant sur la barre de légende et en le faisant glisser, le code remplace le résultat du message par un résultat qui indique que l'utilisateur a cliqué sur la zone client. Cela empêche l'utilisateur de déplacer la fenêtre avec la souris (contrairement à ce que nous faisions au début de l'article).

si Msg. Résultat = htCaption ensuite Msg. Résultat: = htClient; 

Avoir des composants sur un formulaire

Dans la plupart des cas, nous aurons certains composants sur un formulaire. Supposons, par exemple, qu'un objet Panel se trouve sur un formulaire. Si la propriété Align d'un panneau est définie sur alClient, le panneau remplit toute la zone client de sorte qu'il est impossible de sélectionner le formulaire parent en cliquant dessus. Le code ci-dessus ne fonctionnera pas - pourquoi? C'est parce que la souris se déplace toujours sur le composant Panel, pas sur la fiche.

Pour déplacer notre formulaire en faisant glisser un panneau sur le formulaire, nous devons ajouter quelques lignes de code dans la procédure événementielle OnMouseDown du composant Panel:

procédure TForm1.Panel1MouseDown

(Expéditeur: TObject; Bouton: TMouseButton;
Shift: TShiftState; X, Y: Entier);
commencer

 ReleaseCapture;

 SendMessage (Form1.Handle, WM_SYSCOMMAND, 61458, 0);

fin; 

Remarque: Ce code ne fonctionnera pas avec les contrôles non-fenêtres tels que Composants TLabel.

instagram story viewer