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
- это если вы хотите изменить его поведение.Фактически вы не изменяете поведение в своей процедуре, и нецелесообразно менять поведение на основе окна. Это функция рисования, которая имеет дело только с контекстами устройств.
GetAncestor ожидает дескриптор окна, вы передаете ему контекст рисования. Чтобы получить дескриптор окна из контекста чертежа, вызовите [GetWindowFromDC] (https://msdn.microsoft.com/en-us/library/dd145201 (VS.85) .aspx). –
Что вы пытаетесь сделать? – andlabs
WindowFromDC не работает! –