2011-10-18 3 views
0

Comment trouver la liste des messages qu'un certain composant VCL peut accepter ???/quel genre de messages VCL accepter?/

Par exemple, si je veux faire défiler la Memo1 en envoyant un message à ce I probablement rédigera les lignes de code ci-dessous, sachant que la note de service peut accepter EM_LINESCROLL

SendMessage(Memo1->Handle,EM_LINESCROLL,-1,0); 
//Memo1->Perform(EM_SCROLL,SB_LINEUP,0); 
Memo1->Perform(EM_SCROLL,SB_LINEDOWN,0); 

Comment trouver pour savoir si certains comps VCL peuvent accepter ou ne pas accepter les messages ???

Répondre

5

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.

+0

Merci Sergey pour votre réponse détaillée! À l'avenir, je vais découvrir cela en regardant les codes sources des VCL! –

0

TMemo est un wrapper fin autour d'un contrôle Win32 API multiligne EDIT standard. Vous devez lire la documentation MSDN pour voir quels messages un contrôle EDIT gère nativement. TMemo ne traite pas directement EM_LINESCROLL, mais Windows le fait.