2016-09-05 6 views
-3

Я использую Easy Hook lib. Как получить дескриптор окна владельца?Получить родительскую учетную запись от ребенка в DrawText Hook

[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 и другие не являются работой, слишком как получить родительское окно?

+1

GetAncestor ожидает дескриптор окна, вы передаете ему контекст рисования. Чтобы получить дескриптор окна из контекста чертежа, вызовите [GetWindowFromDC] (https://msdn.microsoft.com/en-us/library/dd145201 (VS.85) .aspx). –

+0

Что вы пытаетесь сделать? – andlabs

+0

WindowFromDC не работает! –

ответ

0
var parent = GetAncestor(hDc, GetAncestorFlags.GetParent); // always return 0! why???????????????? 

Этот код полностью неправильно. Единственная причина, по которой вы его скомпилируете, состоит в том, что как HWND, так и HDC вводятся в качестве указателей() в управляемой среде. Если вы пишете на C или C++, вы получите ошибку компиляции, что упростит задачу.

Функция DrawText, которую вы подключили, имеет в качестве первого параметра дескриптор контекста устройства (HDC), на котором должен быть нарисован текст.

Функция GetAncestor, которую вы вызываете, имеет в качестве первого параметра дескриптор окна (HWND). HDC и HWND - несовместимые типы; они не могут быть взаимозаменяемы.

Контексты устройства (HDC) не имеют «предков», и даже если они это сделали, функция GetAncestor предназначена только для окон. Он не знает, что делать с контекстом устройства, поэтому он терпит неудачу. Вы передали ему неправильный дескриптор окна.

Насколько ваш фактический вопрос, как получить «родительское окно», соответствующее DC, этот вопрос не имеет никакого смысла. Контексты устройства не имеют «родительских» окон, и только некоторые контексты устройств даже связаны с окном. Если контекст устройства связан с окном, вы можете вызвать WindowFromDC function, передав в HDC, чтобы получить связанный HWND. Опять же, я должен подчеркнуть, что это не решит вашу актуальную проблему. Контекст устройства не может быть связан с окном. Контекст устройства может быть связан с экраном или может быть постоянным томом памяти, или может быть устройством DC (связанным с физическим монитором, принтером или другим устройством вывода). Во всех этих случаях WindowFromDC вернет NULL (нулевой указатель или значение IntPtr.Zero).

Если вы думаете об этом логически, вы увидите, что то, что вы просите, разваливается. Рассмотрим простой случай, когда приложение создает DC памяти и вызывает DrawText для вставки в него текста. Какое «окно» вы хотите получить? Может быть, «главное» окно для процесса? Во-первых, нет способа определить это для произвольного процесса. Во-вторых, процесс может даже не иметь любые окна! Я могу создать процесс без окон, который создает и рисует текст в DC. Если я это сделаю, лучше не сломать свой крючок!

Вы отказались от нескольких мотивов в комментариях, чтобы объяснить, что такое цель настоящего кода. Пока неясно, почему вы подключаете DrawText. Ваша процедура крюка ничего полезного не делает. Кроме того, вы пропустите случай, когда приложение вызывает DrawTextEx, ExtTextOut или TextOut для рисования текста, и предполагается, что он даже использует GDI для рисования текста. Если он использует GDI +, DirectDraw или какой-либо другой API-интерфейс рисования, ваш крючок никогда не будет вызван. Единственная причина для перехвата звонков на DrawText - это если вы хотите изменить его поведение.Фактически вы не изменяете поведение в своей процедуре, и нецелесообразно менять поведение на основе окна. Это функция рисования, которая имеет дело только с контекстами устройств.

+0

благодарит за ответ! –

+0

У меня есть вопросы. У нас много приложений для Windows. Каждое окно имеет свою конфигурацию. Мне нужно изменить текст в элементе управления, в зависимости от окна. Как получить доступ к этим элементам управления? spy ++ не видит их (у них нет окна) с помощью C# –

+0

Затем вам нужно выкопать исходный код вашего приложения или надеяться, что [System.Windows.Automation] (https://msdn.microsoft.com/en -us/library/ms747327 (v = vs.110) .aspx) может видеть элементы управления или изменять текст. Или, если строки взяты из ресурса таблицы строк, используйте редактор ресурсов. Удачи. – andlabs