C++ cli 将窗口句柄(HWND)绑定到非托管代码中的类名/组件类型

C++ cli 将窗口句柄(HWND)绑定到非托管代码中的类名/组件类型,c++-cli,unmanaged,hwnd,C++ Cli,Unmanaged,Hwnd,我想通过了解窗口句柄来找出窗口的顶级组件名称。 这是在托管C++代码中这样做的: //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->FullN


我想通过了解窗口句柄来找出窗口的顶级组件名称。
这是在托管C++代码中这样做的:

//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.
但是,我不能将托管代码用于我必须开发的解决方案。
我曾尝试使用
GetClassName()
作为等效项,但这只会给我
WindowsForms10.STATIC。[…]
mumbo-jumbo:)
有人知道如何在非托管代码中实现这一点吗?
我知道C++没有提供任何支持WiFrm的支持,但是我希望能以正确的方式得到一个指针。我已经在一些解决方案中看到了这一点,但无法让我的代码正常工作:(

提前感谢您。

这可能就是WinForms代码所做的:

  • 创建窗口时,使用
    SetWindowLongPtr(句柄、GWL\U用户数据、值)
    存储对拥有该窗口的对象的引用
  • 控件::FromHandle调用
    GetWindowLongPtr(handle,GWL\u USERDATA)
    来检索托管对象引用,然后可以使用该引用执行托管操作(GetType(),等等)
  • 在本地Win32和C++中这样做,创建一个接口类,如:

    class IControl
    {
    public:
      virtual const string &GetTypeName () = 0;
    };
    
    然后从中派生控件:

    class TextBoxControl : public IControl
    {
      virtual const string &GetTypeName () { return "TextBox"; }
    }
    
    然后在控件构造函数中:

    TextBoxControl::TextBoxControl ()
    {
       handle = CreateWindowEx (parameters to create a text box);
       SetWindowLongPtr (handle, GWL_USERDATA, this);
    }
    
    最后,给定一个窗口句柄:

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

    非托管组件真的有名称吗?
    Type
    FullName
    仅存在于托管世界中。除非您编写一段托管代码将其公开给非托管世界,否则无法避免此问题。我正在分析的应用程序是在.NET中使用WinForms编写的。我无法使用托管代码。当我尝试时在上面的代码片段中,我得到了一个真实的类名,例如System.Windows.Forms.ComboBox。GetClassName只提供了问题中提到的格式,这对我来说是不可用的,因为我需要对某些特定的组件类型做出反应。好的。我知道我不能使用上面的确切方法,我只是为了说明我想要的内容而提供了它ted完成。谢谢你的回答。你不能这样做,窗口类名是自动生成的,它们的字符串值在会话之间不会重复。Managed Spy++实用程序的源代码可以帮助你取得成功,但你必须放弃“无托管代码”的要求。非常感谢你给出完整的答案。这是一个非常好的尝试od解决方案。但是,我不允许修改我试图读取的应用程序的代码:((公司策略)。我尝试按照您的建议调用GetWindowLongPtr,但它返回0,因为SetWindowLongPtr在开始时没有被调用。我将研究Control::FromHandle如何工作,并尝试提出一些建议。