2010-12-14 12 views
0

Ich möchte den Top-Level-Komponentennamen eines Fensters aus dem Fenster kennen lernen.
Das ist wie so in Managed C++ Code getan:Bindefensterhandle (HWND) an Klassenname/Komponententyp in nicht verwaltetem Code

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

Allerdings kann ich nicht verwalteten Code für die Lösung nutzen, die ich entwickeln müssen.
Ich habe versucht, GetClassName() als Äquivalent zu verwenden, aber das gibt mir nur WindowsForms10.STATIC. [...] Hokuspokus :)
Hat jemand eine Idee, wie dies in unmanaged Code getan werden kann?
Ich weiß, dass C++ nativ keine Unterstützung für WinForms bietet, aber ich hoffe, einen Zeiger in der richtigen Weise zu bekommen. Ich habe es in einigen Lösungen getan gesehen, aber nicht gelungen, meinen Code zum Laufen zu bringen :(
Danke im Voraus

+0

Hat die nicht verwaltete Komponente wirklich einen Namen? – Abyx

+1

'Type' und' FullName' existieren nur in der verwalteten Welt. Es gibt keine Möglichkeit, dies zu umgehen, es sei denn, Sie schreiben einen verwalteten Code, der ihn der nicht verwalteten Welt zugänglich macht. –

+0

Die Anwendung, die ich analysiere, ist in .NET mit WinForms geschrieben. Ich kann verwalteten Code einfach nicht verwenden. Als ich oben das Code-Snippet ausprobierte, bekomme ich einen echten Klassennamen. System.Windows.Forms.ComboBox. GetClassName gibt mir nur das Format, das in der Frage erwähnt wird, was für mich unbrauchbar ist, da ich auf bestimmte Komponententypen reagieren muss. – prettyCode

Antwort

1

Dies ist wahrscheinlich das, was der WinForms Code tut.

  1. Wenn ein Fenster erstellt wird, verwenden SetWindowLongPtr (handle, GWL_USERDATA, value) einen Verweis auf das Objekt zu speichern besitzen das Fenster.
  2. Das Control :: Fromhandle GetWindowLongPtr (handle, GWL_USERDATA) ruft die verwaltete Objektverweis abzurufen, die Sie dann geschafft haben Sachen mit (GetType(), usw.)

Um dies zu tun in nativen Win32 und C++, erstellen Sie eine Interface-Klasse wie:

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

und dann ableiten Kontrollen daraus:

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

und dann in der Steuer Konstruktor:

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

und schließlich, bei einem Fenstergriff:

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

Vielen Dank für die vollständige Antwort. Es ist eine sehr gute Lösung. Ich darf jedoch nicht den Code der Anwendung ändern, die ich zu lesen versuche :((Firmenrichtlinie). Ich habe versucht, GetWindowLongPtr aufzurufen, wie Sie es vorgeschlagen haben, und es gibt 0 zurück, weil SetWindowLongPtr nicht zum Starten aufgerufen wurde Ich werde sehen, wie Control :: FromHandle funktioniert und versuchen, etwas zu finden. – prettyCode