Снимок экрана не работает в приложении MFC в Vista

StackOverflow https://stackoverflow.com/questions/87007

  •  01-07-2019
  •  | 
  •  

Вопрос

У нас есть несколько собственных приложений, встроенных в MFC, с процедурами рисования OpenGL.Все они используют один и тот же код для рисования на экране и либо распечатывают экран, либо сохраняют его в файл JPEG.В Windows XP все работает нормально, и мне нужно найти способ заставить их работать в Vista.

В трех наших приложениях все работает.В оставшемся я могу получить границу окна, строку заголовка, меню и панель задач, но внутренняя часть никогда не отображается.Как я уже сказал, эти приложения используют один и тот же код для записи на экран и захвата изображения окна, и единственная разница, которую я вижу, которая может иметь значение, заключается в том, что проблемное приложение использует многодокументный интерфейс MFC, а те, которые в этой работе используется единый интерфейс документа.

Либо ответа нет в сети, либо я хуже гуглю, чем думал.Я спросил на форумах MSDN, и единственное практическое предложение, которое я получил, — это использовать GDI+ вместо GDI, и это ничего не изменило.Я пробовал разные вещи с каждой частью кода, которая захватывает, печатает или сохраняет, учитывая указатель на окно, так что, очевидно, дело в самом окне.Я еще не пересобрал проблемное приложение с помощью SDI, и других идей у ​​меня действительно нет.

Кто-нибудь видел что-нибудь подобное?


У меня есть четыре приложения.Они используют много общего кода и совместно используют файлы .h и .cpp, поэтому я знаю, что код рисования и захвата экрана идентичен.

Существует процедура WindowtoDIB(), которая принимает *pWnd, а также исходный прямоугольник и размер назначения.Это похоже на слегка адаптированный код Microsoft, и я нашел в этом файле другие функции на сайте Microsoft.Из четырех моих приложений три справляются с этим нормально, а одно — нет.Наиболее очевидное отличие состоит в том, что проблема заключается в MDI.

Мне кажется, что проблема в *pWnd.Я ни в коем случае не являюсь гуру MFC, и мне кажется, что проблема может заключаться в том, что у нас есть одна настройка окна в SDI и более одной в MDI.Возможно, я передаю в функцию неправильный *pWnd.

Тем временем он начал правильно работать на тестовой машине с 64-битной Vista, хотя по-прежнему не работает на машине с 32-битной Vista.Понятия не имею почему.Я ничего не изменил со времени последних тестов, и не думаю, что кто-то еще это сделал.(В 32-разрядной версии клавиша Print Screen работает должным образом, но не сохраняет экран в формате JPEG.)

Это было полезно?

Решение 5

В конечном итоге мы решили эту проблему, создав другой контекст OpenGL и нарисовав все на нем.Мы отказались от захвата экрана.

Другие советы

В заголовке вашего вопроса упоминается снимок экрана, но в вашем самом вопросе этого нет.Пожалуйста, изложите более четко.Проблема в том, что вы можете сделать скриншот трех своих приложений, но не четвертого?Вы можете использовать другое программное обеспечение для захвата экрана, которое может захватывать окна OpenGL/DirectX.Эти поверхности обрабатываются непосредственно диспетчером окон и не отображаются с помощью простого «PrtScn».

Переход на GDI+ не решит эту проблему, как и переход на SDI.

Если вам нужно содержимое CView, то да, это должно быть правильно.Если это содержимое всего экрана (по крайней мере, содержимое без панелей инструментов и строки состояния), то вам следует передать ему CMainFrame (это имя по умолчанию, которое могло быть изменено, то, которое получено из CMDIFrameWnd ).

Можете ли вы опубликовать код WindowToDIB()?Я только что попробовал, и это работает для меня (TM), но без кода OpenGL в представлении.Попробуйте передать следующие окна в функцию WindowToDIB():

CMainFrame* mainfrm = static_cast<CMainFrame*>(::AfxGetMainWnd());

- mainfrm

- mainfrm->MDIGetActive()

- mainfrm->MDIGetActive()->GetActiveView()

и посмотрите, что вы получите.

Содержимое каждого окна представляет собой поверхность DirectX и собирается только оконным менеджером видеокарты.Вы не сможете это запечатлеть, если не отключите новый интерфейс (DWM) или не напишете код специально для захвата экрана из DWM.

В Википедии есть хорошее описание Диспетчер окон рабочего стола (DWM)

Извините, я все еще не понимаю.Вы пытаетесь заставить клавишу Print Screen работать во всех четырех приложениях?Или вы пытаетесь заставить работать функцию WindowtoDIB(), которая делает «скриншот» (из вашего собственного приложения) самого приложения, чтобы его можно было сохранить в виде файла изображения?

Кроме того, что вы имеете в виду под словами «Клавиша Print Screen работает как положено, но не сохраняет экран в формате JPEG»?Print Screen копирует только в буфер обмена. Что произойдет, если вставить в Paint?

Если ваша функция WindowtoDIB() только «захватывает» окно, которое вы ей передаете, то да, ваши дочерние окна MDI не будут отображаться.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top