2010-06-14 9 views
0

J'utilise les messages WMSysCommand pour modifier le bouton de la barre de légende (Maximize/Minimize) behaivor et la mise à jour récente requise pour utiliser WMNCHitTest, mais je ne souhaite pas scinder ces deux messages liés en multiplier les procédures en raison d'un long code. Puis-je accéder à une déclaration privée (message) à partir d'un autre message? Et si je peux - Comment faire?Accès et héritage de Windows Message pour un autre message Windows dans Delphi

procedure TForm1.WMNCHitTest(var Msg: TWMNCHitTest) ; 
    begin 
    SendMessage(Handle, HTCAPTION, WM_NCHitTest, 0); // or other wParam or lParam ???? 
    end; 

    procedure TForm1.WMSysCommand; 
    begin 
    if (Msg.CmdType = SC_MAXIMIZE or 61488) or (Msg.Result = htCaption or 2) 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 61472) or (Msg.Result = htCaption or 2) then // if command is Minimize 
    begin 
     if (EnsureRange(Width, 252, 510) >= (510/2)) then 
     PreviewOpn.Caption := '<' 
     else 
     PreviewOpn.Caption := '>'; 
    end; 
    DefaultHandler(Msg); // reset Message handler to default (Application) 
    end; 

Soo ... que je pense correctement et sipmly ne sais pas les commandes correctes ou je pense au total bullsh * t?

Cordialement. Merci pour toute aide ...

+0

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? * –

+0

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. –

Répondre

3

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:

  1. Copiez et collez le code afin que les deux fonctions sont similaires.
  2. Placez tout le code dans une fonction, puis appelez-le à partir de la deuxième fonction.
  3. 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.

+0

Rob, "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. (...)" Mais que se passe-t-il si je l'utilise dans la boucle avec la commande ProcessMessages? Cela ne signifie-t-il pas que Perform() agira en tant que SendMesssage() exclusif? Oh - et numérique équaux est juste pour moi de se souvenir de ces foutus numéros pour la gestion des exceptions internes et externes et les traitements WER ... En fait - je peux toujours vérifier le code Keys par Ord() donc je ne pense pas qu'il sera gros problème .. –

+0

ProcessMessages n'a rien à voir avec ça. Effectuer est également utile pour appeler des gestionnaires de messages sur des objets qui n'ont pas de poignées de fenêtre. –