Мои вопросы очень простые и не очень важные.
Я начал изучать написание приложений Win32. Когда я читаю код от других людей, я часто вижу, что они ставят PAINTSTRUCT ps;
перед оператором переключения в WndProc
, Почему они не положили это в дело WM_PAINT
? Они выделяют память для ps
а потом не пользуетесь?
Я всегда вижу PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps);
, Но я проверил значение ps.hdc
несколько раз и значения ps.hdc
а также hdc
равны каждый раз. Есть ли еще одна причина для определения hdc
чем просто читабельность или писать меньше кода?
(И извините, если мой английский плох и вопросы не на уровне этого сообщества)
Чтобы ответить на пункт 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
,
Когда я читаю код от других людей, я часто вижу, что они помещают PAINTSTRUCT ps; перед оператором switch в WndProc. Почему они не помещают это в дело WM_PAINT?
Несколько возможностей:
Оконная процедура, вероятно, не должна «обрабатывать» сообщения, а вместо этого отправлять их обработчикам сообщений. Таким образом, случай WM_PAINT в WndProc, вероятно, должен вызывать отдельную функцию, выполняющую рисование, и PAINTSTRUCT может быть локальным для этой отдельной функции. Но мы решаемся с мнением, поэтому я оставлю это на этом.
Я всегда вижу
PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps);
,
Кажется, я помню, что был неясный случай, когда возвращаемый дескриптор контекста устройства мог отличаться от описанного в PAINTSTRUCT, но, вероятно, был чрезвычайно редким и может не существовать в современных версиях Windows.
Считайте возвращенный HDC удобным. Если ваша картина проста и не требует каких-либо других полей в PAINTSTRUCT, это дает вам простой способ обратиться к контексту устройства.
Это действительно не имеет значения, и многие реализации будут «выделять» память каждый раз, когда вызывается оконная процедура, независимо от того, объявлены ли переменные в верхней части функции или внутри WM_PAINT
корпус выключателя.
BeginPaint делает больше, чем просто возвращает ps.hdc
,
Я часто вижу, что они ставят
PAINTSTRUCT ps;
перед оператором переключения вWndProc
, Почему они не положили это в делоWM_PAINT
? Они выделяют память для пс, а затем не используют ее?
Это плохая практика. Рекомендуется вызывать отдельную функцию для рисования и избегать использования оконной процедуры длиной в несколько страниц. Но если вам нужно рисовать в оконной процедуре, объявите ваши переменные как можно более локально.
Есть ли другая причина для определения HDC, чем просто читаемость или писать меньше кода?
Это удобство. Поскольку функция рисования снова и снова обращается к контексту устройства, удобно хранить ее в локальной переменной, что делает код менее подробным. И да, когда BeginPaint
успешно, гарантируется, что HDC
вернулся BeginPaint
равно HDC
в структуре краски.