Где определить PAINTSTRUCT и зачем определять HDC?

Мои вопросы очень простые и не очень важные.

  1. Я начал изучать написание приложений Win32. Когда я читаю код от других людей, я часто вижу, что они ставят PAINTSTRUCT ps; перед оператором переключения в WndProc, Почему они не положили это в дело WM_PAINT? Они выделяют память для ps а потом не пользуетесь?

  2. Я всегда вижу PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps);, Но я проверил значение ps.hdc несколько раз и значения ps.hdc а также hdc равны каждый раз. Есть ли еще одна причина для определения hdc чем просто читабельность или писать меньше кода?

(И извините, если мой английский плох и вопросы не на уровне этого сообщества)

2

Решение

Чтобы ответить на пункт 1: Win32 API был разработан для C (он довольно старый) и поставить PAINTSTRUCT ps; внутри case Заявление потребует помещения содержимого case внутри скобки {} поскольку C не допускает встроенные объявления. C ++ также может иметь проблемы с объявлением переменных внутри case операторы без скобок — вызов деструкторов без вызова конструктора. Вы быстро обнаружите, что switch() case... стиль станет неудобным для поддержания, функция станет довольно большой и громоздкой, и она не очень хорошо сочетается с такими вещами, как Intellisense. Довольно часто вы увидите, что разработчики используют карту для связи функций с конкретными сообщениями:

WindowProc (args)
{
func_ptr = some_map.GetValue (message_type)
if func_ptr not null
call func_ptr
else
DefWindowProc (args)
}

Что касается пункта 2, значение hdc будет null когда есть ошибка и она выглядит чище hdc вместо ps.hdc, Кроме того, hdc легче перейти на другие функции, чем ps, Но кроме этого, документация не вызывает никаких причин, почему ps.hdc будет отличаться от результата BeginPaint,

5

Другие решения

Когда я читаю код от других людей, я часто вижу, что они помещают PAINTSTRUCT ps; перед оператором switch в WndProc. Почему они не помещают это в дело WM_PAINT?

Несколько возможностей:

  1. Они используют или использовали более старый стиль C, где все локальные переменные должны быть определены в начале функции.
  2. В зависимости от вашего компилятора и уровня его предупреждений вы можете получать предупреждения при попытке объявить переменные внутри наблюдений в операторе switch.
  3. Они просто небрежны.

Оконная процедура, вероятно, не должна «обрабатывать» сообщения, а вместо этого отправлять их обработчикам сообщений. Таким образом, случай WM_PAINT в WndProc, вероятно, должен вызывать отдельную функцию, выполняющую рисование, и PAINTSTRUCT может быть локальным для этой отдельной функции. Но мы решаемся с мнением, поэтому я оставлю это на этом.

Я всегда вижу PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps);,

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

Считайте возвращенный HDC удобным. Если ваша картина проста и не требует каких-либо других полей в PAINTSTRUCT, это дает вам простой способ обратиться к контексту устройства.

2

  1. Это действительно не имеет значения, и многие реализации будут «выделять» память каждый раз, когда вызывается оконная процедура, независимо от того, объявлены ли переменные в верхней части функции или внутри WM_PAINT корпус выключателя.

  2. BeginPaint делает больше, чем просто возвращает ps.hdc,

1

Я часто вижу, что они ставят PAINTSTRUCT ps; перед оператором переключения в WndProc, Почему они не положили это в дело WM_PAINT? Они выделяют память для пс, а затем не используют ее?

Это плохая практика. Рекомендуется вызывать отдельную функцию для рисования и избегать использования оконной процедуры длиной в несколько страниц. Но если вам нужно рисовать в оконной процедуре, объявите ваши переменные как можно более локально.

Есть ли другая причина для определения HDC, чем просто читаемость или писать меньше кода?

Это удобство. Поскольку функция рисования снова и снова обращается к контексту устройства, удобно хранить ее в локальной переменной, что делает код менее подробным. И да, когда BeginPaint успешно, гарантируется, что HDC вернулся BeginPaint равно HDC в структуре краски.

1
По вопросам рекламы [email protected]