Это немного сложно объяснить.
Вы, вероятно, исходит от фона, на котором вы подключите функцию в розетку для обработки событий, что-то вроде
extern void onClicked(void);
button->OnClicked = onClicked;
И хотя это вполне возможно для Windows, чтобы сделали это с самого начала, у вас есть помните, что Windows изначально была предназначена для работы в системах с сильно ограниченной памятью, поэтому важно, чтобы элементы управления не теряли память. И есть много событий, которые вы можете получить с помощью кнопки:
void (*OnClicked)(void);
void (*OnDoubleClicked)(void);
void (*OnDisabled)(void);
void (*OnHighlight)(void);
void (*OnKillFocus)(void);
void (*OnPaint)(void);
void (*OnSetFocus)(void);
void (*OnUnhighlight)(void);
void (*OnUnpushed)(void);
HBRUSH (*OnCtlColorButton)(void);
Имея это для каждой кнопки в программе - то есть, кнопки, флажки, радио-кнопка, и рамки группа - большинство из них, скорее всего, быть неиспользуемым будет просто огромная потеря памяти.
Поскольку Windows нуждается в способе связи между системой и окном и между окнами, Microsoft решила создать интерфейс передачи сообщений, в котором каждое сообщение имело 16-разрядный код и два размера указателя (изначально один 32-разрядный и один 16-разрядный) и возвращаемое значение размера указателя. И не так много сообщений, которые нужны Windows для себя, предоставляя как оконным классам, так и приложению много недвижимости для использования сообщений для общения. Так почему бы не использовать сообщение для оповещения о событии?
Использование сообщения позволяет избежать потери памяти, в то же время позволяя кнопке передавать данные и возвращать данные из целевого окна. Таким образом, логика следует, что все кнопки будет нужно сделать, это
/* this is not the correct syntax but let's use it for expository purposes */
#define BN_CLICKED someNumberHere
case WM_LBUTTONUP:
SendMessage(GetParent(hwnd), BN_CLICKED, hwnd);
break;
и родитель будет обращаться с этим:
case BN_CLICKED:
if (whichButton == button1)
doButton1Stuff();
break;
Нет впустую память, но все же гибким и расширяемым. И что еще более важно, также двоично-совместимое: если позже было добавлено больше событий, размер таблицы указателей функций должен был бы измениться, а более новые программы, которые пытались использовать более новые события в старых системах, могли бы сбивать случайную память. С сообщениями, эти программы имели бы только мертвый код.
Теперь зачем отправлять сообщение родителям? Если мы рассматриваем окна как конечные точки связи, то это очевидно: вы хотите, чтобы кнопка сообщила родителям, что она была нажата, потому что вы сообщаете, что нажата кнопка!
Но, что более важно, вы не указали процедуру окна кнопки. Microsoft сделала, и они предоставляют одну и ту же программу для каждой программы. Если бы вы могли обработать сообщение в процедуре кнопки, куда бы вы его положили? В конце концов, вы не можете изменить процедуру кнопки.
(В настоящее время мы, что называется «подклассы», который позволяет переопределить оконную процедуру единого окна, чтобы сделать собственную обработку. Это не используется для обработки событий, потому что это больше работы, чем просто отправка до родителя.)
Все это распространяется на пользовательскую ничью; просто замените «custom draw» на «clicked», и это все равно имеет смысл. Надеюсь, это объяснение было ясным даже с этой ментальной заменой.
Если вы хотите, вы можете написать собственное средство обработки событий в пути указателя функций. Сохраните карту оконных дескрипторов функций событий и вызовите глобальную функцию отправки во всех ваших оконных процедурах для обработки сообщений о событиях WM_COMMAND
, WM_NOTIFY
и (для трековых баров) WM_HSCROLL
и WM_VSCROLL
. Как вы это делаете, зависит от вас, но подумайте, действительно ли вы хотите сделать это таким образом; иногда это необходимо, но иногда это не так. Если вы это сделаете, не забудьте предоставить способ передачи произвольных данных функции события, которая была решена при подключении к событию, поэтому обработчик события может сделать что-то разумное, не полагаясь на глобальное состояние.
Что вы подразумеваете под 'не было бы лучше иметь все это в файле класса? Значение всех параметров, включая пользовательский draw.' Покажите нам пример кода – stackptr
Трудно понять, о чем идет речь. Похоже, вы задаетесь вопросом, почему вы должны поместить определенные вещи в определенные исходные файлы? Возможно, если вы представите пример, это может облегчить людям понимание вашего вопроса. В вашем заголовке задается вопрос программирования WinAPI, который в целом не упоминается. –
В качестве альтернативы вы можете переопределить 'WM_PAINT' при нажатии кнопки подкласса. –