#c #mfc #gdi #screen-capture
#c #мфц #гди #захват экрана #mfc #gdi
Вопрос:
В моей программе есть эта странная ошибка, которую я пытаюсь исправить, но я действительно не понимаю, что это может быть. В этой части моей программы есть диалоговое окно, в котором отображаются предварительные просмотры различных элементов с использованием MFC / GDI. Когда я прокручиваю разные элементы, иногда изображение предварительного просмотра просто исчезает и становится пустым. Однако это:
- Происходит только на некоторых машинах
- По-видимому, происходит как в Windows 7, так и в XP
- Не происходит для одного и того же элемента каждый раз
- Элемент ВСЕ ЕЩЕ ПРИСУТСТВУЕТ при создании снимка экрана, но он пуст при обычном просмотре.
- Кажется, это происходит в случайных местах по всему коду, когда я пытаюсь проследить его с помощью точек останова. Не всегда в одном и том же месте экран переходит от изображения к пустому, что наводит меня на мысль, что это происходит не в том же потоке, что и мой основной поток, хотя на самом деле это единственный поток, который не заблокирован в этот момент. Это означает, что это происходит в потоке Windows или что-то в этом роде, не так ли?
Я предполагаю, что это какое-то состояние гонки, но поведение предварительного просмотра на скриншотах, в частности, меня несколько смущает. Почему это было бы нормально при создании скриншота, но было бы пустым при просмотре его на экране? Есть ли какая-то механика «printscreen», которая обходит то, что отображается или обновляется на экране?
Я понимаю, что я не дал много информации и что люди, очевидно, не могут сильно помочь, но если кто-нибудь может ЧТО-НИБУДЬ придумать, это было бы очень ценно 🙂
Спасибо!
Комментарии:
1. У кого-нибудь есть какие-либо указания? Спасибо
2. Я также обнаружил, что если я помещаю точку останова в свою функцию OnPaint () для окна, оно ВСЕГДА прерывается и становится просто пустым. Похоже ли это на состояние гонки?
Ответ №1:
Другая теория: утечка ресурсов GDI
Если вы забудете освободить свои объекты GDI, начнут происходить странные вещи, включая неокрашенные области.
- Выполнить taskmgr.exe и добавьте столбец «Объекты GDI».
- Запустите свое программное обеспечение и отслеживайте количество объектов GDI. Стабилизируется ли оно?
- Если количество объектов вашего GDI не стабилизируется, посмотрите в соответствующих обработчиках WM_PAINT.
Вот пример утечки GDI:
void CMyWnd::OnPaint()
{
CPaintDC dc(this);
dc.SelectObject(amp;font);
}
Выбранные объекты GDI всегда должны быть отменены:
void CMyWnd::OnPaint()
{
CPaintDC dc(this);
CFont *pOldFont = dc.SelectObject(amp;font);
// Use font
dc.SelectObject(pOldFont);
}
Ответ №2:
При записи экрана вы читаете рабочий стол, используя GDI API? В этом случае любая поверхность с аппаратным ускорением может стать черной (или, возможно, белой). Чтобы проверить это, вы можете отключить аппаратное ускорение для вашей видеокарты. Если ваш рекордер начинает работать, значит, вы нашли виновника!
Для записи этих поверхностей, отличных от GDI, вам, вероятно, потребуется прочитать поверхность с помощью DirectX / OpenGL. Я бы начал с этой статьи:http://www.codeproject.com/KB/dialog/screencap.aspx
Комментарии:
1. Моя программа не записывает экраны. Я просто использую printscreen или screen recorder, чтобы попытаться записать проблему. Проблема возникает в моей программе, которая использует GDI / mfc для рисования графика / изображения на экране. На большинстве компьютеров нет никаких проблем, и на экране отображается изображение, как и должно быть, но я могу время от времени воспроизводить его на нескольких случайных машинах. Проблема НЕ возникает при использовании PrintScreen.