Tous les composants acceptent tous les messages, mais si un composant a pas de gestionnaire de message attribué, il n'a tout simplement rien
Si vous voulez découvrir si le composant VCL ont gestionnaire spécial à certains messages Windows, vous devez examiner VCL sources, qui sont généralement fournies avec C++ Builder (sauf Starter Edition de XE et XE2).
Sources VCL sont situés en% CBuilderDir% \ Sources \ VCL (regardant mon CBuilder5/6)
Les sources sont écrits en delphi, mais il ne sera pas difficile de trouver tout ce dont nous avons besoin.
D'abord, vous devrez trouver la définition de votre classe cible. Vous pouvez rechercher dans toute la dir source VCL pour le fichier avec la ligne ressemblant à
TMemo = Class
(pour votre exemple avec TMemo)
Ouvrir le fichier où vous avez trouvé votre classe, (habituellement il sera stdctrls.pas ou Controls.pas - y sont situés) des composants les plus utiles, vont à la ligne avec la définition de classe et faire défiler un peu vers le bas jusqu'à ce que vous trouviez un groupe de procédures, ressemblant à
procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
procedure WMRButtonDown(var Message: TWMRButtonDown); message WM_RBUTTONDOWN;
... et ainsi de suite. Ces procédures sont appelées en réponse à certains messages, lesquels sont fournis après la définition de la procédure.
Si une classe a une procédure pour un certain message, alors elle fournit une réponse à celle-ci. Les gestionnaires de messages sont hérités dans Delphi, donc si vous n'avez pas trouvé de gestionnaire pour votre message, vous pouvez regarder dans les classes de base et leurs gestionnaires de messages. Pour découvrir la hiérarchie de classe complète, vous pouvez simplement regarder dans le fichier d'aide, ou regarder à nouveau la définition de classe TMemo = class (TCustomMemo)
et prendre le nom de la classe parent à partir des accolades.
Ensuite, vous pouvez répéter la recherche de gestionnaire de messages pour toutes les classes de parents jusqu'à ce que vous atteigniez TObject
:-)
Soit dit en passant. Simpy cherchant dans le répertoire source VCL de mon CBuilder5 pour toute présence de EM_LINESCROLL
J'ai supposé qu'aucun composant VCL ne le traitait.
Si vous avez seulement besoin de fournir une interaction spéciale pour certains messages, sans essayer de comprendre si un composant a déjà ou non des gestionnaires de messages, vous pouvez simplement remplacer la méthode WindowProc
de votre composant. Tous les descendants de TControl
ont cette méthode.
Cette méthode traite tous les messages reçus par le composant et vous pouvez ajouter une réponse à des messages système ou utilisateur supplémentaires ici.
void __fastcall TMyForm::NewWndProc(Messages::TMessage &Message)
{
if (Message.Msg == EM_LINESCROLL)
// Do something special for this message
else OldWndProc(Message);
}
La seule chose que vous devez faire est de préserver la valeur de la vieille WindowProc, appeler dans NewWndProc après que vous faites tous vos trucs.
Il est préférable de définir et assignez NewWndProc
et stocker vieux WindowProc
pour TMemo sous la forme qui contient votre composant, de sorte que vous aurez pas besoin de faire jouer avec nouveau composant hérité de TMemo
. Ainsi, définir TWndMethod OldWndProc
sous forme et mettre ci-dessous, par exemple, sous forme OnCreate()
gestionnaire
TWndMethod OldWndProc = MyMemo->WindowProc;
MyMemo->WindowProc = NewWndProc;
De plus, votre mise à feu peut empêcher des gestionnaires prédéfinis, en ne passant que certains messages à OldWndProc. Attention, si vous empêchez le traitement des messages système sensibles (comme WM_CREATE), vous obtiendrez des erreurs.
Merci Sergey pour votre réponse détaillée! À l'avenir, je vais découvrir cela en regardant les codes sources des VCL! –