Понимание CStatic и CWnd и маршрутизации сообщений

Я пытаюсь понять, как работает маршрутизация сообщений в MFC, и у меня есть несколько вопросов по этому поводу. Представьте себе элемент управления, расширяющий CWnd. Мой первый вопрос: все ли сообщения в этом элементе управления передаются родительскому элементу управления?

Я знаю, что это не происходит с CStatic, который передает определенные сообщения только когда вы устанавливаете стиль SS_NOTIFY. Что я пытаюсь понять, если это специфично для CStatic или происходит со всеми элементами управления. В частности, я пытаюсь создать элемент управления, который имеет несколько дочерних элементов управления с единственной целью определения их макета. Я хотел, чтобы все сообщения дочерних элементов управления обрабатывались родителем этого промежуточного элемента управления. Например, если этот элемент управления макета имеет дочернюю кнопку, при нажатии кнопки сообщение будет отправлено родительскому элементу для обработки.

Однако я не собираюсь обрабатывать все сообщения вручную. Итак, если я расширю свой контроль из CWnd вместо CStatic, будет ли передано сообщение? Доступно ли FORWARD_NOTIFICATIONS() в MFC? Если нет, я бы предпочел расширить свои промежуточные классы для обработки сообщений по мере необходимости. Любые другие решения, которые вы знаете?

2 ответа

Сообщения отправляются в само окно.

Некоторые окна отправляют сообщения своим родителям, обычно в форме сообщений WM_NOTIFY или (например, для кнопок) в виде "специальных" сообщений, таких как BN_CLICKED.

В MFC есть система (система "отражения"), позволяющая окнам отправлять эти сообщения обратно в само окно, так что вы можете иметь дело с сообщениями в элементе управления, а не с родительским элементом управления.

Это примерно как это работает в резюме. То, что вы хотите (чтобы родительский элемент управления обрабатывал все сообщения, отправляемые всем дочерним элементам управления), обычно не так, как вы "должны" это делать. Например, вы не хотите, чтобы все WM_PAINT для дочерних окон отправлялись родителям.

То, что вы хотите сделать (обработка нажатий кнопок) отличается. Нажатие кнопки "испускается" кнопкой в ​​виде BN_CLICKED. В любом случае это будет сделано родителем.

Если вы все еще уверены, что вы можете взять на себя WndProc дочерних окон, чтобы выполнить некоторую "фильтрацию". Обычно это делается с помощью виртуальной функции PreTranslateMessage().

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

Вы всегда можете избежать архитектуры обмена сообщениями Windows\MFC и использовать систему, основанную на событиях. Что-то вроде Boost.Signals2. В наших приложениях мы используем смесь WM_NOTIFY сообщения и Boost.Signals2.

Другие вопросы по тегам