C# 在窗口出现之前拦截并隐藏窗口

C# 在窗口出现之前拦截并隐藏窗口,c#,c++,windows,message-queue,subclass,C#,C++,Windows,Message Queue,Subclass,我正在开发一个(进程中)应用程序插件,作为插件的一部分,我想用我自己的工具提示替换应用程序的工具提示。但是,没有API可供我使用,所以我决定采用低级别 我知道工具提示的窗口类,但问题是,如何检测它的创建,以及之后如何关闭它 以下是我到目前为止的想法: 在WM_Create上创建一个系统范围的钩子 捕获时,检查WM_创建目标的类和过程 确认它确实是我关心的窗口: 如果进程是我的插件所在的进程 如果类的类型正确 以及是否正确的应用程序处于焦点位置(在多个应用程序的情况下) 将WM_销毁发送到创建

我正在开发一个(进程中)应用程序插件,作为插件的一部分,我想用我自己的工具提示替换应用程序的工具提示。但是,没有API可供我使用,所以我决定采用低级别

我知道工具提示的窗口类,但问题是,如何检测它的创建,以及之后如何关闭它

以下是我到目前为止的想法:

  • 在WM_Create上创建一个系统范围的钩子
  • 捕获时,检查WM_创建目标的类和过程
  • 确认它确实是我关心的窗口:
    • 如果进程是我的插件所在的进程
    • 如果类的类型正确
    • 以及是否正确的应用程序处于焦点位置(在多个应用程序的情况下)
  • 将WM_销毁发送到创建的窗口,并在其位置创建我自己的窗口
  • 听起来怎么样?假设确实没有API来处理工具提示,有没有更简单的方法来满足我的需要

    谢谢


    p.S标记为C++/C,因为我打算用这两种语言编写它(C++用于系统范围的钩子,C#用于其他所有语言)

    这不起作用。考虑应用程序的观点,即您正在替换工具提示并假设您可以告诉它销毁Windows。当应用程序决定需要关闭工具提示时会发生什么?它没有你的新窗口的句柄,它有你破坏的旧窗口的句柄。是时候出问题了


    你的插件系统需要明确支持替换工具提示,如果你想让它顺利工作的话。插件框架的一个可选部分可能是RequestTooltip函数。如果它不存在,或者返回null,或者其他任何情况,那么将使用默认工具提示,否则将使用插件提供的工具提示。

    如果您知道要阻止的窗口类型,只需将其子类化,并在自己的
    WndProc
    中处理销毁。与工具提示类上的
    GCL\u WNDPROC
    一起使用,与
    GCL\u WNDPROC
    一起使用,设置自己的
    WNDPROC
    ,并让它在
    WM\u CREATE
    上调用DestroyWindow(),其余部分调用旧的
    WNDPROC
    。这是真的,它比那更复杂-我需要自己开始跟踪鼠标来隐藏我自己的窗口。原始应用程序将无法为我隐藏工具提示,但是,我不明白为什么它会导致问题。例如,如果销毁“旧”工具提示有问题,我可以尝试隐藏它,然后销毁就可以了(事实上,我甚至可以挂起销毁旧工具提示来隐藏我的新工具提示)。关于第二个问题:恐怕应用程序没有API,它会查询工具提示的存在,因此我无法做到这一点=\tooltips通常是通过在每个顶级父窗口中创建并保留一个工具提示窗口来完成的。然后,该工具提示窗口将在需要时调整和显示,在不需要时隐藏。因此,你需要跟踪窗口的显示时间,而不是创建时间,而且你显然不想破坏它(你可能不想隐藏它)。@Leo:谢谢你的评论。那可能是真的。我很困惑。。。GetClassLongPtr()需要一个HWND,但对于工具提示,它还并没有创建。你是说我可以使用GetClassLongPtr()/SetClassLongPtr()来为一个尚未存在的窗口创建子类?是的,你需要先创建一个虚拟工具提示窗口并使用它。@kichik:有趣。。。如果我这样做,该类窗口的所有未来实例都将使用该MessagePump?确实如此。虽然这不是MessagePump的问题,而是WndProc的问题。您还可以使用getClassInfo()、UnregisterClass()和RegisterClassEx()重新注册该类。@kichik:这似乎工作得很好,而且比挂钩容易得多。谢谢