Допустим, у меня есть приложение MFC с кнопкой управления на нем. Есть ли способ получить ту функцию, в которую OON_BN_CLICKED отображает ее? Я знаю, что CWnd имеет функцию GetDlgItem, которая будет возвращать указатель на элемент управления. Есть ли способ получить функцию, на которую отображается элемент управления, если у меня есть этот указатель?
Я нашел метод, который, по моему мнению, можно использовать для отправки сообщения элементу или элементу диалога: CWnd :: SendDlgItemMessage (http://msdn.microsoft.com/en-us/library/e2a6czt1.aspx), но я бы хотел знать возможные сообщения.
В большинстве случаев вы знаете сообщения, которые вы можете отправить в окно. Я сильно подозреваю, что вы, возможно, не выбрали правильный путь для вашей задачи. Что вы пытаетесь достичь на самом деле? То есть то, что вы спрашиваете, необычно, и реальная задача, скорее всего, может быть решена другими способами.
В любом случае. Если у вас есть указатель на некоторый объект, производный от MFC CWnd, все еще возможно «перепроектировать» его обработчики сообщений MFC, определенные в классе, указанном этим CWnd *. MFC определяет все обработчики сообщений в карте, используя BEGIM_MESSAGE_MAP / END_MESSAGE_MAP. Что эти макросы на самом деле делают, так это определяют виртуальную функцию GetMessageMap () и массив данных, содержащий структуры, описывающие сопоставление сообщений. Таким образом, вы можете использовать wnd-> GetMessageMap (), а затем перебрать обработчики отображенных сообщений. Каждая запись содержит информацию об обработчике сообщений и отображенной функции. Обратите внимание, что GetMessageMap является защищенной функцией, поэтому для доступа к ней извне вам понадобится оболочка. Что-то вроде этого:
struct Accessor : public CWnd
{
// overwrite protected
virtual const AFX_MSGMAP* GetMessageMap() const { return CWnd::GetMessageMap(); }
};
Accessor* msg_map_access = (Accessor*) window;
const AFX_MSGMAP* msg_map = msg_map_access->GetMessageMap();
const AFX_MSGMAP_ENTRY* entry = msg_map->lpEntries;
while (entry->nSig != AfxSig_end)
{
/// do something with the entries
}
Опять же, это не обычная практика; как правило, вы никогда не делаете это. Так что было бы приятно услышать мотивацию, зачем вам это нужно.