2010-12-14 37 views
0


Je souhaite connaître le nom du composant de niveau supérieur d'une fenêtre en connaissant sa poignée de fenêtre.
Cela se fait comme tant en code managé C++:Lier la poignée de la fenêtre (HWND) au nom de la classe/au type de composant dans le code non géré

//handle is the window handle as int 
System::Windows::Forms::Control^ c = Control::FromHandle((System::IntPtr)System::Convert::ToInt32(handle)); 
System::Type^ t= c->GetType(); 
Console::WriteLine(t->FullName);//This is the top level name of the component. 

Cependant, je ne peux pas utiliser le code managé pour la solution que je dois développer.
J'ai essayé d'utiliser GetClassName() comme un équivalent, mais cela me donne juste WindowsForms10.STATIC. [...] mumbo jumbo :)
Est-ce que quelqu'un a une idée de comment cela peut être fait en code non managé?
Je sais que C++ n'offre aucun support natif pour WinForms, mais j'espère obtenir un pointeur dans le bon sens. Je l'ai vu faire dans certaines solutions, mais ont été incapables d'obtenir mon code de travail :(
Merci à l'avance

+0

Est-ce que le composant non géré a vraiment un nom? – Abyx

+1

'Type' et' FullName' existent uniquement dans le monde géré. Il n'y a aucun moyen de contourner cela, sauf si vous écrivez un morceau de code managé qui l'expose au monde non géré. –

+0

L'application que j'analyse est écrite en .NET, en utilisant WinForms. Je ne peux pas utiliser de code managé. Quand j'ai essayé l'extrait de code ci-dessus, j'ai un vrai nom de classe ex. System.Windows.Forms.ComboBox. GetClassName me donne seulement le format mentionné dans la question, qui est inutilisable pour moi, car je dois réagir à certains types de composants spécifiques. – prettyCode

Répondre

1

C'est probablement ce que le code WinForms fait:.

  1. Lorsqu'un fenêtre est créée, utilisez SetWindowLongPtr (handle, GWL_USERDATA, value) pour stocker une référence à l'objet propriétaire de la fenêtre.
  2. le contrôle :: FromHandle appelle GetWindowLongPtr (handle, GWL_USERDATA) pour récupérer la référence d'objet géré que vous pouvez alors faire gestion des choses avec (GetType(), etc.)

Pour ce faire, dans Win32 natif et C++, créez une classe d'interface comme:

class IControl 
{ 
public: 
    virtual const string &GetTypeName() = 0; 
}; 

puis dérivent les contrôles de celui-ci:

class TextBoxControl : public IControl 
{ 
    virtual const string &GetTypeName() { return "TextBox"; } 
} 

puis dans le constructeur de contrôle:

TextBoxControl::TextBoxControl() 
{ 
    handle = CreateWindowEx (parameters to create a text box); 
    SetWindowLongPtr (handle, GWL_USERDATA, this); 
} 

et enfin, étant donné une poignée de fenêtre:

string GetWindowTypeName (HWND handle) 
{ 
    IControl *control = GetWindowLongPtr (handle, GWL_USERDATA); 
    return control->GetTypeName(); 
} 
+0

Merci beaucoup pour la réponse complète. C'est une très bonne solution. Cependant, je ne suis pas autorisé à modifier le code de l'application que j'essaie de lire :((politique de l'entreprise) .J'ai essayé d'appeler le GetWindowLongPtr comme vous l'avez suggéré et il renvoie 0, parce que SetWindowLongPtr n'a pas été appelé pour commencer Je vais regarder comment fonctionne Control :: FromHandle et essayer de trouver quelque chose. – prettyCode