MFC -- фреймворк устаревший, написанный вразрез с парадигмой ООП. Тем не менее, на нём у нас крутятся проекты. Особенность этого фреймворка в том, что он очень близок к чистому WinAPI. И знание основ WinAPI может помочь определить, в чём проблема.

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

Я так уклончиво начинаю, а что случилось-то? История крайне странная.

Создаю чекбокс. Мне надо, чтобы при клике на чекбокс производились определённые действия. Пишу действия -- это называется "обработчик". Обработчик не вызывается. В окне есть другой чекбокс, со своим обработчиком -- он прекрасно вызывается. Никакой разницы между чекбоксами нет. Переименовал чекбокс, создал новый обработчик -- не помогает. В чём же дело?

Тогда я полез проверять идентификаторы чекбоксов. Идентификатор -- это просто число, которое уникально для каждого элемента управления в окне. Как же происходит нажатие кнопки в WinAPI? (а кнопка и чекбокс с точки зрения WinAPI отличаются слабо).

Когда пользователь нажимает кнопку, генерируется сообщение, например, WM_COMMAND. Это сообщение ставится в очередь сообщений для того окна, где нажали кнопку. Цикл обработки сообщений на очередной итерации узнает, что произошёл щелчок. Но как он узнает, по какой кнопке щёлкнули? А вот у каждого сообщения есть "параметр" и этот параметр содержит идентификатор кнопки.

MFC и вижуал студия хорошо назначают идентификаторы только когда вы рисуете окно с нуля и ничего в нём не переделываете. Много ума для этого не надо. Когда же вы начинаете удалять элементы управления, студия за вами не "подчищает" мусор. Это надо делать самому. И для этого надо понимать, что и где чистить. Ситуация парадоксальная: ломать сложнее, чем строить.

ОКАЗАЛОСЬ

Много лет назад в диалоговом окне, где я рисовал чекбокс, уже была кнопка с идентификатором 1016. Потом её удалили. А идентификатор и обработчик нажатия остались. Когда я добавил новый чекбокс, студия посмотрела, какие идентификаторы не заняты? Ага, 1016 не занят ни одной кнопкой. Ставим его.

И тут в игру вступил притаившийся устаревший обработчик. Хотя у меня и было указано, что вызывать надо новый, но мои указания были в самом конце таблицы вызовов. А при поиске обработчика таблица просматривается с начала. При клике на чекбокс вызывался обработчик старой, давно удалённой кнопки! Ну и когда я его удалил -- всё заработало.