Huge thank you for the "color commentary" as well. Folks act like Software development happens without anyone being responsible for their decisions- and the implementation choices MS and others make are often deplorable and need to be called out "as if written by a fourth grader!" -- exactly!

ЕМА: Когда я беру границу изменения размера моего приложения Windows, особенно верхнюю или левую границы, и изменяю размер окна, содержимое окна изменяет размер «вживую» при перетаскивании, но они изменяют размер отвратительным образом, который выглядит как вопиющая ошибка даже для самого начинающего пользователя: содержимое на противоположном краю окна от края, который я дико перетаскиваю джиттер / мерцание / скачок назад и вперед. В зависимости от ситуации явление может выглядеть следующим образом:

содержимое, которое, кажется, сходит с края окна и возвращается назад, когда мы замедляемся или перестаем перетаскиватьсодержимое, которое, кажется, тянет в окно, периодически смещается границей различных цветов, часто черного или белогосерьезно уродливое «двойное изображение» с двумя перекрывающимися копиями контента, смещенными на расстояние, пропорциональное тому, насколько / насколько быстро мы перетаскиваем

Ужасное явление прекращается, как только я прекращаю перетаскивать, но во время перетаскивания оно заставляет приложение выглядеть любительским и непрофессиональным.

Это не преуменьшение, чтобы сказать, что эта проблема Windows имеетсводит с ума тысячи разработчиков приложений.

Вот два примера картины этого явления, любезно подготовленные длясвязанный вопрос поРоман Старков:

Другой пример, показывающий злое явление «двойного изображения» (обратите внимание на быструю вспышку) изКенни Лю:

Другой пример видео явления с диспетчером задачВот.

ЦЕЛЬ ЭТОГО ВОПРОСА: Любой разработчик, столкнувшийся с этой проблемой, быстро обнаруживает, что есть по меньшей мере 30 вопросов StackOverflow, некоторые из которых были недавно, а некоторые из них датированы 2008 годом, и содержат многообещающие ответы, которые редко работают. Реальность такова, что эта проблема имеетмного причини существующие вопросы / ответы StackOverflow никогда не проясняют более широкий контекст. Этот вопрос стремится ответить:

Каковы наиболее вероятные причины этого вида уродливого дрожания / мерцания / прыжков?Как я могу сказать, что, потому что я вижу?это причина специфическая для конкретных графических драйверов или общая для Windows?как исправить каждую причину? может ли приложение это исправить?

СФЕРА ЭТОГО ВОПРОСА: В рамках этого вопроса StackOverflow такое явление имеет место:

как родные Win32, так и управляемые приложения .NET / WPF / Windows Formsи обычные окна Win32 и окна диалога Win32Версии Windows, включая XP, Vista, 7, 8 и 10 (но см. Ниже темную правду о множественных причинах)

НЕ ФЛАГИРУЙТЕ ШИРОК ИЛИ ДУПА: Пожалуйста, прочитайте полный ответ ниже, прежде чем пометить как дупла или широкую пометку. Мы уже прошли этот цикл, и пользователи SO впоследствии вновь открыли вопрос, поняв следующее: этот вопрос приносит пользу сообществу, поскольку он является первым Q & A, объясняющим все различные причины дрожания изменения размера окна, чтобы пользователи могли определить, какой из причины вызывает их проблему и решить ее. Приведенные ниже ответы являются длинными, просто потому, что сложно объяснить, почему джиттер возникает в целом, а не потому, что этот вопрос охватывает множество отдельных ошибок / проблем, которые будут лучше обслуживаться отдельными вопросами и ответами. Как вы увидите, все приведенные выше перестановки (нативная / управляемая, окно / диалоговое окно, XP-10) сводятся только к двум основным причинам, но выявление того, что у вас есть, является сложной задачей. Вот о чем этот вопрос. Разделение вопроса полностью сведет на нет эту выгоду. Мы дополнительно ограничим сферу вопроса в следующем разделе ...

НЕ В СФЕРЕ ЭТОГО ВОПРОСА:

Если ваше приложение имеет одно или несколько дочерних окон (дочерних HWND), информация в этом вопросе будет полезна для вас (так как вызывающий рывокBitBlts мы опишем, применяются ли они к вашим дочерним окнам вместе с родительским окном), но во время изменения размера окна у вас возникает дополнительная проблема, которая выходит за рамки этого вопроса: вам нужно заставить все ваши дочерние окна двигаться атомарно и синхронно с родительское окно. Для этой задачи вы, вероятно, захотитеBeginDeferWindowPos/DeferWindowPos/EndDeferWindowPos и вы можете узнать о нихВот а такжеВот.

Этот вопрос предполагает, что если ваше приложение обращается к окну с использованием GDI, DirectX или OpenGL, то вы уже реализовалиWM_ERASEBKGND обработчик в вашемwndproc это просто возвращает 1.WM_ERASEBKGND тайный остаток Windows от Windows 3.1, который предшествуетWM_PAINT чтобы дать вашему приложению возможность "стереть фон" вашего окна, прежде чем вы начнете рисовать окно ... ага. Если вы позволитеWM_ERASEBKGND сообщение входит вDefWindowProc()Это приведет к тому, что все ваше окно будет окрашено в сплошной цвет, обычно белый, при каждой перерисовке, включая перерисовки, которые происходят при изменении размера живого окна. В результате получается мерзкое мерцание в полноэкранном режиме, но не тот тип джиттера / мерцания / прыжков, о котором мы говорим в этом вопросе. ПерехвативWM_ERASEBKGND исправляет эту проблему немедленно.

Этот вопрос в первую очередь касается изменения размера в реальном времени путем перетаскивания границ окна с помощью мыши. Тем не менее, многое из того, что написано здесь, также относится к уродливым артефактам, которые вы можете увидеть, когда приложение вручную изменяет размер окна, используяSetWindowPos(), Они менее заметны, потому что они мерцают на экране только на одно мгновение, а не в течение длительного периода перетаскивания.

Этот вопрос не о том, как сделать так, чтобы ваш код рисования для конкретного приложения работал быстрее, хотя во многих случаях это может быть решением проблемы с изменяемым размером. Если вашему приложению действительно требуется много времени для повторного отображения его содержимого при изменении размера живого окна, рассмотрите возможность оптимизации кода рисования в целом или, по крайней мере, переключитесь на более быстрый и менее качественный режим рисования во время изменения размера, перехватываяWM_ENTERSIZEMOVE/WM_EXITSIZEMOVE сообщения для определения изменения размера.

Если ваше приложение вообще не может изменить размер во время изменения размера приложения (например, оно «зависает» во время изменения размера, особенно если это OpenGL, использующий GLFW или другую библиотеку), посмотрите эти другие вопросы, которые объясняют ужасный вложенный / модальный цикл событий Microsoft внутри.WM_SYSCOMMAND во время перетаскивания:Вот особенноэтот хороший ответ, Вот, Вот, Вот, а такжеВот.

НАЧАЛЬНЫЕ ОТВЕТЫ

Для начала мы предоставили два начальных ответа, которые вы должны прочитать в следующем порядке:

ЧАСТЬ 1:Что делает изменение размера выглядеть хорошо или плохо?

ЧАСТЬ 2:Выявление и устранение проблем с изменением размера Windows

2а. Изменение размера задач изSetWindowPos() BitBlt и фоновая заливка2b: Проблемы с изменением размера при заполнении композиции DWM2с: как диагностировать вашу проблему

а также список исходного материала, который может помочь другим понять:

ЧАСТЬ 3:Галерея Скорби: аннотированный список ссылок по теме

Мы надеемся, что люди дадут больше ответов с творческими способами избежать проблем, описанных в 2a и особенно 2b.

Ответы на вопрос(3)

Ваш ответ на вопрос