Карта отображения сообщений в Win32, без MFC

Для добавления к предыдущим объяснениям вызовы статического метода связываются с определенным методом в время компиляции , который скорее исключает полиморфное поведение.

5
задан whoi 7 December 2009 в 21:49
поделиться

4 ответа

Depending on your use case, you can work around that using references:

template<typename T>
void f(const T& x) {
    std::cout << sizeof(T);
}

char a[27];
f(a);

That prints 27, as desired.

Секрет понимания того, как работает этот код, состоит в том, чтобы помнить, что wndProc в классе xWindow не что иное, как оконная процедура Win32 , переданная в RegisterClassEx , когда окно Win32 зарегистрировано.

Теперь, если вы посмотрите на код wndProc , вы увидите, что он выполняет небольшую настройку и проверку, но обычно он не делает ничего, кроме отправки сообщения Windows методу отправки .

Метод dispatch еще проще, поскольку он не делает ничего, кроме упаковки сообщения Windows в легко перемещаемую структуру , а затем отправляет его в dispatchToMsgMap ].

Теперь посмотрите на класс MyWindow , и вы увидите этот код:

BEGIN_MSG_MAP    
   //-- command message handlers    
   CMD_HANDLER(onAdd   , IDPB_ADD   )    
   CMD_HANDLER(onDelete, IDPB_DELETE)    

   //-- other message handling    
   MSG_HANDLER(onClose , WM_CLOSE)    
   MSG_HANDLER(onSize  , WM_SIZE )  
END_MSG_MAP(xWindow)

Этот код просто использует макросы, определенные ранее. Если вы внимательно посмотрите на эти макросы, вы увидите, что приведенный выше код на самом деле создает метод dispatchToMsgMap . Это тот же метод dispatchToMsgMap , который был вызван методом dispatch .

Я знаю, что этот метод обработки сообщений Windows действительно работает, поскольку я использую точно такой же подход в редакторе Zeus для Windows .

13
ответ дан 18 December 2019 в 14:47
поделиться

Карта сообщений MFC не использует обычный WndProc как таковой. IIRC, он основан на каком-то механизме перехвата.

Однако я думаю, что не должно быть очень сложно адаптировать макросы к обычному WndProc.

Первый подход, который приходит на ум, - позволить макросам создать массив пар функций идентификатора сообщения / обработчика. Еще лучше: используйте карту для повышения производительности.

Ваш WndProc будет перебирать этот массив, чтобы идентифицировать данный WM и выполнить соответствующий обработчик.

Вам также может понадобиться BEGIN_MESSAGE_MAP макрос для имитации оператора switch , где каждая строка ON_BLAH () будет строкой case внутри switch ().

Это тоже должно быть жесткий.

0
ответ дан 18 December 2019 в 14:47
поделиться

Вы можете использовать что-то вроде std :: map . Где short - это сообщение в окне, а MessageFn - это функция, обрабатывающая сообщение. Затем вы можете обрабатывать сообщения следующим образом:

if ( messageMap.find( uMsg ) != messageMap.end() )
{
   messageMap[uMsg]( wParam, lParam );
}

Это будет не так аккуратно, но будет довольно легко реализовать, хотя вы определяете карту сообщений во время выполнения, а не во время компиляции.

Другое решение - прочитать код макроса MFC и посмотреть, как это удалось Microsoft ...

Другое решение, если вы хотите, чтобы поведение MFC было без дополнительных затрат, - это использование ATL. Вы также можете взглянуть на определения макросов ATL, чтобы увидеть, как они это сделали ....

Редактировать: Вы можете решить проблему с обработкой WM_COMMAND или WM_NOTIFY, сохранив CommandMap и NotifyMap. Затем вы устанавливаете обработчик WM_COMMAND на функцию, которая затем выполняет аналогичные действия и передает команду через CommandMap.

Самая большая проблема заключается в том, что вы не получаете ничего в сообщении, которое идентифицирует конкретный экземпляр класса. Это не проблема, если вам нужен только hWnd, но вам может понадобиться сохранить дополнительную глобальную карту HWND для экземпляров классов ...

Это только одно решение. Вы можете решить проблему разными способами. Я просто предлагаю вам одну идею.

Вы можете решить проблему разными способами. Я просто предлагаю вам одну идею.

Вы можете решить проблему разными способами. Я просто предлагаю вам одну идею.

0
ответ дан 18 December 2019 в 14:47
поделиться

Трудно сделать это с помощью чего-то вроде std :: map . В частности, это требует, чтобы каждый элемент на карте имел один и тот же тип, но разные сообщения имели обработчики, которые принимают разное количество параметров, поэтому указатели на них не одного типа.

Возможно, вы захотите взглянуть на макросы взломщика сообщений (особенно HANDLE_MSG ) в windowsx.h. Хотя на самом деле это просто генерирует регистры для оператора switch, он все же позволяет писать код, который выглядит примерно как карта сообщений MFC.

0
ответ дан 18 December 2019 в 14:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: