【问题标题】:CreateWindowEx fails with ERROR_CANNOT_FIND_WND_CLASSCreateWindowEx 失败并显示 ERROR_CANNOT_FIND_WND_CLASS
【发布时间】:2011-05-21 06:21:45
【问题描述】:

我正在尝试创建一个具有特定类类型(“VSDebugger CDataTipWnd”)的窗口,但是,当我运行 CreateWindowEx 时它失败了,并且 GetLastError 告诉我找不到该类。以下是供参考的代码,尽管没关系:

const Win32WindowStyles dwStyle = Win32WindowStyles.WS_POPUP;
IntPtr wnd = NativeMethods.CreateWindowEx(0L, "VSDebugger CDataTipWnd", "MyWindow",
                                                  dwStyle, 100, 100, 100, 100, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);

我在进程中作为插件运行,并且我知道之前创建了此类的窗口(我使用 Winspector/Spy++ 确保了这一点),但是,当我尝试创建这种类型的窗口时我自己,它不起作用,我不知道为什么。

documentation 表示“类名可以是注册到 RegisterClass 或 RegisterClassEx 的任何名称,前提是注册该类的模块也是创建窗口的模块。类名也可以是任何预定义的系统类名称。有关系统类名称的列表,请参阅备注部分。 RegisterClass 是否可能确实是在另一个模块(dll/exe)中创建的?仅仅在另一个模块中创建一个类是否会使另一个模块无法通过名称访问它?如果是这样,我还能以某种方式找到那个类并用它创建一个窗口吗?

谢谢! 生命力

【问题讨论】:

    标签: windows winapi createwindow


    【解决方案1】:

    您将 IntPtr.Zero 传递给 HINSTANCE 参数。

    注册该类的模块(EXE或DLL)的HINSTANCE必须提供给CreateWindowEx。

    如果您认为主 EXE 注册了该类,那么您可以通过 GetModuleHandle(IntPtr.Zero) 获取其 HINSTANCE。

    如果另一个 DLL 注册了该类,那么您将需要一些方法来知道哪个并获取它的 HINSTANCE/HMODULE(这两个现在都是一样的)。

    【讨论】:

    • 使用 GetModuleHandle(null) 似乎不起作用...我想我会尝试枚举所有模块并找到正确的模块:|没有更好的方法吗?比如询问进程是哪个模块创建了 X 类?
    • 如果您可以在屏幕上看到窗口类的实例,请使用 Visual Studio 附带的 Spy++ 工具来定位该窗口(您可以将十字准线拖到它上面,只需指向它即可找到它),然后查看 Class 选项卡,它会告诉您实例句柄。如果然后切换到 Process Explorer,选择进程并打开 DLL 视图(下面板),它应该是 Base 列显示相同编号的 DLL。 (请注意,Process Explorer 不会填充数字,因此例如 0x600000 很容易与 0x6000000 等混淆。)在您的代码中,尝试在该 DLL 上为句柄使用 LoadLibrary
    • 非常感谢您的帮助!这是一个很棒的提示,它确实有效......我现在可以访问课程(仍然无法从中创建一个窗口:()。但无论如何,我学到了很多!谢谢!
    • 如MSDN文档中所写,允许为CreateWindowEx的hInstance参数传递一个空指针(该参数指定为可选,所以空指针是可以的)。
    【解决方案2】:

    大概就是这样。该程序是否提供 API 来执行此操作?您提到您正在作为插件运行 - 我认为这就是这样做的方式。

    【讨论】:

    • 恐怕不会……我是在放弃了不同的方式之后才走这条路的。
    猜你喜欢
    • 1970-01-01
    • 2021-03-17
    • 2015-12-31
    • 1970-01-01
    • 2021-12-10
    • 2020-02-08
    • 2012-05-04
    • 2019-07-21
    • 1970-01-01
    相关资源
    最近更新 更多