Функция обратного вызова DDEML
Когда сервер или клиент регистрирует себя в библиотеке DDEML при помощи функции DdeInitialize, он указывает адрес переходника, созданного для функции обратного вызова. Функция обратного вызова предназначена для обработки всех событий, возникающих в процессе создания каналов связи и передачи данных.
В простейшем случае функция обратного вызова сервера DDEML может выглядеть следующим образом:
HDDEDATA EXPENTRY _export DDEServerCallback( WORD wType, // код транзакции WORD wFmt, // формат данных HCONV hConv, // идентификатор канала HSZ hsz1, // первый идентификатор строки HSZ hsz2, // второй идентификатор строки HDDEDATA hData, // идентификатор глобальной области данных DWORD dwData1, // первое дополнительное двойное слово DWORD dwData2) // второе дополнительное двойное слово { switch(wType) { // Создание канала передачи данных case XTYP_CONNECT: { ........... return((HDDEDATA)TRUE); }
// Запрос данных от сервера case XTYP_REQUEST: { ........... return(hData); }
// Запрос на выполнение команды case XTYP_EXECUTE: ........... break;
// Передача данных серверу case XTYP_POKE: { ........... return((HDDEDATA)DDE_FACK); }
// Подтверждение создания канала case XTYP_CONNECT_CONFIRM: { ........... break; }
// Завершение работы канала case XTYP_DISCONNECT: { ........... break; }
// Ошибка case XTYP_ERROR: { ........... break; } } return((HDDEDATA)NULL); }
Функция обратного вызова должна быть определена как экспортируемая, поэтому мы указали ключевое слово _export.
Через первый параметр wType передается код транзакции. Подобно функции окна, которая обрабатывает сообщения, функция обратного вызова DDEML выполняет обработку транзакций. В зависимости от кода транзакции и результата обработки функция обратного вызова DDEML возвращает то или иное значение.
Второй параметр задает код формата передаваемых данных. Для кодов формата используются те же значения, что и для форматов Clipboard, например, CF_TEXT.
Через параметр hConv передается идентификатор канала передачи данных (который мы еще не научились создавать).
Назначение остальных параметров функции обратного вызова зависит от кода транзакции. В приведенном выше фрагменте кода используются символические имена кодов транзакций, определенные в файле ddeml.h, и имеющие префикс имени XTYP. В дальнейшем мы подробно расскажем о некоторых транзакциях, использованных в наших приложениях.
Функция обратного вызова для клиента DDEML выглядит точно также, отличаясь лишь составом обрабатываемых транзакций. Приведем для примера исходный текст такой функции из нашего приложения DDEMLCL:
HDDEDATA EXPENTRY DDEClientCallback( WORD wType, WORD wFmt, HCONV hConv, HSZ hsz1, HSZ hsz2, HDDEDATA hData, DWORD dwData1, DWORD dwData2) { switch(wType) { case XTYP_DISCONNECT: return((HDDEDATA) NULL);
case XTYP_ERROR: break;
case XTYP_XACT_COMPLETE: break; } return((HDDEDATA)NULL); }
При регистрации приложения в библиотеке DDEML функцией DdeInitialize можно указать флаги, запрещающие или разрешающие поступление транзакций некоторых типов в функцию обратного вызова. Запретив вызов функции обратного вызова для необрабатываемых транзакций, можно ускорить работу приложения.