Votre code et votre texte suggèrent que vous avez plusieurs malentendus sur le fonctionnement des gestionnaires de messages. Tout d'abord, vous posez des questions sur l'accès aux gestionnaires de messages privés. Vous n'avez pas besoin d'accéder aux gestionnaires de messages privés des classes parentes. Vous pouvez remplacer le gestionnaire de n'importe quel message, que la classe parent gère ce message ou non. Écrivez simplement votre gestionnaire de message. Il remplacera automatiquement le gestionnaire du parent, même si le gestionnaire du parent était privé. (En fait, nous déclarons souvent les gestionnaires de messages privés en premier lieu - les descendants peuvent toujours les ignorer, et puisqu'il n'y a pas de raison d'en appeler directement un, il n'y a aucune raison de le rendre public.)
Essayez d'obtenir le comportement de gestion des messages de la classe de base en appelant le DefaultHandler
. Cela fonctionnera parfois, mais seulement par accident. DefaultHandler
va au gestionnaire de messages de la classe de base. S'il existe d'autres classes entre la classe de base et votre descendant, un appel à DefaultHandler
ignorera leurs gestionnaires. Au lieu de cette fonction, utilisez la directive inherited
, comme vous le feriez lors du remplacement de méthodes ordinaires.
Lorsque vous voulez que votre objet se comporte comme si un message lui avait été envoyé, vous n'avez pas toujours besoin de lui envoyer un message avec SendMessage
. Au lieu de cela, vous pouvez appeler la méthode Perform
de l'objet. Toutes les mêmes opérations de répartition des messages se produiront, mais vous pouvez ignorer la file d'attente des messages Windows.
Si vous avez deux méthodes qui doivent effectuer de nombreuses tâches similaires, vous avez quelques options:
- Copiez et collez le code afin que les deux fonctions sont similaires.
- Placez tout le code dans une fonction, puis appelez-le à partir de la deuxième fonction.
- Placez tout le code dans une troisième fonction, puis appelez-le à partir des deux fonctions.
La première option n'est généralement pas une bonne idée. La deuxième option peut être bonne si la première fonction est garantie d'être toujours un sous-ensemble de la deuxième fonction. S'il doit faire quelque chose que la deuxième fonction ne veut pas toujours, il n'est pas approprié de l'appeler depuis la deuxième fonction. La troisième option est ce que suggère Robert's answer.
La deuxième option pourrait être ce dont vous avez besoin, si ma boule de cristal fonctionne correctement. Je pense que vous souhaitez que votre gestionnaire wm_SysCommand effectue des tests de hit, vous devez donc appeler le gestionnaire de messages wm_NCHitTest
. C'est facile.
procedure TForm1.WMSysCommand;
var
Hit: DWord;
begin
Hit := Perform(wm_NCHitTest, ...);
if (Msg.CmdType = SC_MAXIMIZE) or (Hit = htCaption) then // if command is Maximize or reciever message of Caption Bar click
begin
if CheckWin32Version(6, 0) then
Constraints.MaxHeight := 507
else
Constraints.MaxHeight := 499;
Constraints.MaxWidth := 0;
end
else if (Msg.CmdType = SC_MINIMIZE) or (Hit = htCaption) then // if command is Minimize
begin
if (EnsureRange(Width, 252, 510) >= (510/2)) then
PreviewOpn.Caption := '<'
else
PreviewOpn.Caption := '>';
end;
inherited;
end;
Notez quelques modifications que j'ai apportées à votre code. Tout d'abord, j'utilise Perform
pour appeler le gestionnaire wm_NCHitTest de l'objet, et je stocke le résultat dans une variable. J'utilise cette variable dans les conditions suivantes pour vérifier où la souris a été cliquée. Deuxièmement, j'ai retiré les tests or
de vos conditions. Vous avez combiné les constantes nommées avec leurs équivalents numériques, ce qui est inutile et déroutant. Troisièmement, j'ai remplacé l'appel DefaultHandler
par un à inherited
.
Attention, cependant: Le message wm_SysCommand est envoyé pour clavier messages ainsi que les messages de la souris. Il n'y aura pas toujours de test de réussite valide. Vous allez probablement à propos de ce gestionnaire sys-commande tout faux, mais il est difficile de dire ce que vous êtes vraiment après.
Il semble que la question que vous auriez dû poser était la suivante: * Comment modifier le comportement des boutons de la barre de légende? * –
Wll - pas exeatly. Le plus approprié serait - comment imiter WM d'une autre procédure WM ... "", mais je ne l'ai pas tapé car il est dans un sens que le piratage prédefines OS comportement ... ne pas risquer de parler sérieusement avec les modérateurs ici. –