Раскрась окно Win32 в файл - PullRequest
1 голос
/ 19 августа 2010

В приложении WPF (C #) одним из элементов является окно Win32, созданное путем переопределения класса HwndHost.Существует около 10 экземпляров этого окна Win32 в WPF в любой момент времени.Один должен отображаться полностью (работает нормально), а другие 9 должны показывать только предварительные просмотры, без создания окна Win32, только растровое изображение.

Я пытался найти способ генерирования указанного растрового изображения.Перепробовал много разных вещей, но пока ничего не получалось.Основная проблема, с которой я сталкиваюсь, заключается в том, что HwndHost.WndProc вызывается только тогда, когда окно является видимым.

Я могу сделать снимок экрана видимого окна, отобразить его в памяти и создать точный рисунок .. Мне просто нужнокакой-то способ сделать это, пока окно не видно.

Мое понимание все еще довольно размыто, поэтому любая оценка приветствуется.

Ответы [ 4 ]

4 голосов
/ 20 августа 2010

Вы можете заставить окно рисовать в растровое изображение, имитируя сообщение WM_PAINT. Вам нужно будет настроить DC памяти и выбрать в нем свой целевой битовый массив, а затем передать этот дескриптор DC в качестве аргумента в сообщении рисования. Подробности см. В MSDN .

Когда все аргументы будут готовы к работе, выполните SendMessage (HwndHost.Handle, WM_PAINT и т. Д. И т. Д.). Когда этот вызов возвращается, растровое изображение должно содержать изображение окна.

Обратите внимание, что для полного рисования всего окна требуется много сообщений. Общий шаблон:

  1. Сделать недействительной всю клиентскую область окна. В противном случае ничего не будет нарисовано, потому что прямоугольник клипа будет пустым.
  2. Настройка растрового изображения в памяти DC
  3. Отправка сообщения WM_ERASEBKGND дескриптору окна с передачей в память дескриптора постоянного тока
  4. Отправляет сообщение WM_PAINT дескриптору окна, передавая в память дескриптор постоянного тока

Изображение окна теперь должно быть в битовой карте памяти.

Если вы также хотите захватить границу, оконную рамку и заголовок окна целевого окна, вам нужно будет смоделировать сообщение рисования, не связанное с клиентом: WM_NCPAINT является основным, вне макушки моей головы.

Существует также сообщение WM_PRINT, которое предположительно помогает при рисовании в памяти DC, предназначенной для печати, но у меня были проблемы с этим несколько версий назад Windows. Дочерние элементы управления не рисуют себя и т. Д.

1 голос
/ 05 октября 2011

Вы не должны напрямую отправлять сообщение WM_PAINT в соответствии со спецификацией MSDN. Вы можете использовать PrintWindow () начиная с Windows XP, возможно, форсировать обновления с помощью RedrawWindow () вызывается с установленным флагом RDW_INTERNALPAINT.

0 голосов
/ 19 августа 2010

Я не знаю, как это работает в C # с WPF, поэтому я просто дам вам перспективу Windows API и надеюсь, что некоторые из них приведут вас к решению.

Все рисование выполняется в контексте устройства (DC). Когда Windows просит вас нарисовать окно, она также дает вам доступ к DC, соответствующему рисуемой поверхности окна.

Чтобы рисовать без окна, вам нужно создать свой собственный DC, и, поскольку биты не идут в окно, вам нужно выбрать битовый массив в DC, чтобы сохранить результаты. В Windows API вы бы использовали CreateCompatibleDC и SelectObject. Когда у вас есть DC, вы рисуете его как обычно, затем снимаете выделение с растрового изображения.

0 голосов
/ 19 августа 2010

Посмотрите на графическую технику "двойной буферизации". Как только вы поймете эту технику - это не сложно - у вас будет решение вашей проблемы. По моему мнению. : -)

Ссылки:

Двойная буферизация Win32

Двойная буферизация MSDN Ссылки O *

Двойная буферизация WinForms Обнаружено через Google - неизвестное качество

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...