DrawText в строке заголовка Windows больше не работает

Чтобы написать текст в правом конце строки заголовка, моя программа перехватывает WM_NCPAINT, получает контекст устройства, вычисляет позицию для записи текста и затем вызывает DrawText. Раньше этот код работал, но в Windows 8 и Windows 10 он больше не работает. Похоже, вы просто не можете рисовать на строке заголовка в этих новых версиях Windows.

Контекст устройства получается следующим образом с использованием Win API (не MFC):

HDC hDC = GetWindowDC(hwnd);

который описан в Центре разработки для Windows таким образом: -

Функция GetWindowDC извлекает контекст устройства (DC) для всего окна, включая строку заголовка, меню и полосы прокрутки. Контекст оконного устройства позволяет рисовать в любом месте окна, потому что источником контекста устройства является верхний левый угол окна, а не клиентская область.

Нет упоминания о том, что эта функция зависит от версии Windows, но то, что она описывает, просто больше не работает. Замена вызова DrawText большим черным прямоугольником (-300,-300,1000,1000) оставляет строку заголовка совершенно нетронутой, показывая, что закрасить весь прямоугольник окна невозможно.

Вместо этого я попытался получить контекст устройства следующим образом:

HDC hDC = GetDCEx(hwnd, (HRGN)wParam, DCX_WINDOW|DCX_INTERSECTRGN);

как описано в документации для WM_NCPAINT. Пока класс окна зарегистрирован с одним из CS_CLASSDC, CS_OWNDC или CS_PARENTDC, возвращается hDC (если возвращается не ноль). Но у этого hDC точно такая же проблема.

Я попробовал вариацию вышеописанного, потому что отсечение показалось сомнительным. Я попытался:-

HDC hDC = GetDCEx(hwnd, 0, DCX_WINDOW);

после того, как вся документация говорит о DCX_WINDOW: -

Значение: DCX_WINDOW.

Значение. Возвращает DC, соответствующий прямоугольнику окна, а не прямоугольнику клиента.

Этот контекст устройства также демонстрирует такое же поведение.

Как мне получить контекст устройства, который позволяет мне DrawText или рисовать что-либо в строке заголовка?


person Morag Hughson    schedule 20.05.2019    source источник
comment
@OlafHess - я не использую MFC, который является API, упомянутым в этом вопросе.   -  person Morag Hughson    schedule 20.05.2019
comment
Неважно, MFC — это просто очень легкая оболочка вокруг Win32.   -  person David Heffernan    schedule 20.05.2019
comment
Как пользователь WinAPI, ищущий ответы на эту проблему, я не нашел примеров MFC, потому что я не использую этот API. Хотя ссылка на ответ может быть той же, поиск вопросов отличается.   -  person Morag Hughson    schedule 20.05.2019


Ответы (1)


В Windows Vista появилась тема Aero, а вместе с ней и Диспетчер окон рабочего стола: Функция композиции рабочего стола, представленная в Windows Vista, коренным образом изменила способ, которым приложения отображают пиксели на экране. Когда включена композиция рабочего стола, отдельные окна больше не отображаются непосредственно на экране или основном устройстве отображения, как это было в предыдущих версиях Windows. Вместо этого их рисунок перенаправляется на закадровые поверхности в видеопамяти, которые затем преобразуются в изображение рабочего стола и отображаются на дисплее.

В статье Пользовательская рамка окна с помощью DWM показано, как использовать API диспетчера окон рабочего стола (DWM) для создания пользовательских оконных рамок для вашего приложения. Это включает в себя рисование текста в строке заголовка окна. Windows Vista и Windows 7 позволяли пользователю отключать тему Aero, чтобы программа могла управлять строкой заголовка программы так же, как в XP и более ранних версиях. Начиная с Windows 8, композиция рабочего стола всегда включена.

person Olaf Hess    schedule 20.05.2019
comment
Спасибо. Я попробую это. Я отправил отзыв на странице WM_NCPAINT Windows Doc, чтобы сообщить им, что он устарел. Произойдет ли что-нибудь в результате этого, еще неизвестно. - person Morag Hughson; 20.05.2019