C# 从DrawText挂钩中的子级获取父Hwd

C# 从DrawText挂钩中的子级获取父Hwd,c#,winapi,easyhook,C#,Winapi,Easyhook,我正在使用Easy Hook lib。如何获得所有者窗口句柄 [StructLayout(LayoutKind.Sequential)] public struct Rect { public int Left; public int Top; public int Right; public int Bottom; public override string ToString()

我正在使用Easy Hook lib。如何获得所有者窗口句柄

    [StructLayout(LayoutKind.Sequential)]
    public struct Rect
    {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;

        public override string ToString()
        {
            return $"[Left: {Left}, Top: {Top}, Right: {Right}, Bottom: {Bottom}]";
        }
    }

    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    public static extern int DrawText(IntPtr hDc, string lpString, int nCount, ref Rect lpRect, uint uFormat);

    [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
    public delegate int DDrawText(IntPtr hDc, string lpString, int nCount, ref Rect lpRect, uint uFormat);



    private int DrawText_Hooked(IntPtr hDc, string lpString, int nCount, ref Rect lpRect, uint uFormat)
    {
        var This = (Main) HookRuntimeInfo.Callback;
        lock (This._queue)
        {
            var parent = GetAncestor(hDc, GetAncestorFlags.GetParent); // always return 0! why????????????????                                  
            This._queue.Push($"parent [{parent}]");
        }
        return DrawText(hDc, lpString, nCount, ref lpRect, uFormat);
    }
GetWindowDC、GetDC、GetParent和其他也不工作 如何获取父窗口

var parent = GetAncestor(hDc, GetAncestorFlags.GetParent); // always return 0! why????????????????
这个代码是完全错误的。您能够编译它的唯一原因是,在托管环境中,HWND和HDC都被类型化为指针IntPtr。如果你用C或C++写,你会得到编译错误,使问题更容易看到。 已钩住的DrawText函数的第一个参数是要在其上绘制文本的设备上下文HDC的句柄

您正在调用的get祖先函数的第一个参数是窗口HWND的句柄。HDC和HWND是不兼容的类型;它们不能互换

设备上下文HDC没有祖先,即使它们有祖先,get祖先函数也只为windows设计。它不知道如何处理设备上下文,因此失败了。您传递给它的窗口句柄无效

至于您的实际问题,即如何获得与DC对应的父窗口,这个问题没有任何意义。设备上下文没有父窗口,只有一些设备上下文甚至与窗口关联。如果设备上下文与窗口关联,则可以调用,传入HDC以检索关联的HWND。我必须再次强调,这并不能解决你的实际问题。设备上下文不保证与窗口关联。设备上下文可能与屏幕关联,也可能是内存DC,也可能是与物理监视器、打印机或其他输出设备关联的设备DC。在所有这些情况下,WindowFromDC将返回NULL一个NULL指针,或值IntPtr.Zero

如果你有逻辑地思考这个问题,你会发现你所要求的东西有什么不同。考虑应用程序创建内存DC并调用DRAWTEXT将文本绘制到其中的简单情况。您希望检索哪个窗口?也许是这个过程的主窗口?首先,对于任意进程,无法确定这一点。第二,进程甚至可能没有任何窗口!我可以创建一个无窗口进程,创建文本并将其绘制到内存中。如果我这样做,它最好不要撞坏你的钩子


您拒绝了评论中解释此代码用途的几项请求。现在还不清楚为什么要首先挂起DrawText。钩子过程没有做任何有用的事情。此外,您还忽略了应用程序调用DrawTextEx、ExtTextOut或TextOut来绘制文本的情况,这是假设它甚至使用GDI来绘制文本。如果它使用GDI+、DirectDraw或其他绘图API,则永远不会调用钩子。挂接对DrawText的调用的唯一原因是如果您想更改其行为。实际上,您并没有在钩子过程中更改行为,基于窗口更改其行为既不可能也不明智。它是一个只处理设备上下文的绘图函数。

GetSencenter需要一个窗口句柄,您要传递给它一个绘图上下文。若要从绘图上下文中获取窗口句柄,请调用。您想做什么?WindowFromDC无效!>>你想干什么?答:有很多窗口应用程序。我想知道什么属于设备窗口。不,我是说你为什么要挂起DrawText?你们想完成什么?我有一些问题。我们有很多windows应用程序。每个窗口都有自己的配置。我需要更改控件中的文本,具体取决于窗口。如何访问这些控件?spy++看不到它们它们没有窗口使用CYou将需要挖掘应用程序的源代码,或者希望可以看到控件或让您更改文本。或者,如果字符串来自字符串表资源,请使用资源编辑器。祝你好运