Как правильно написать DdeCallback
функционировать? Чтобы быть более точным, я говорю о кодах возврата.
От официального документы:
Возвращаемое значение зависит от класса транзакции. Для большего
информация о возвращаемых значениях, см. описания
отдельные типы транзакций
Например, мое приложение должно обрабатывать XTYP_ADVDATA
сообщения сами по себе и игнорировать другие.
Итак, согласно документы за XTYP_ADVDATA
Мне нужно вернуться DDE_FACK
если я обработал это сообщение:
Функция обратного вызова DDE должна возвращать DDE_FACK, если обрабатывает это
транзакция, DDE_FBUSY, если она слишком занята для обработки этой транзакции,
или DDE_FNOTPROCESSED, если он отклоняет эту транзакцию
Но как насчет других сообщений? Что я должен вернуть в других случаях?
// Инициализация
DWORD id_inst = 0;
UINT res = DdeInitializeA(
&id_inst,
(PFNCALLBACK)DdeCallback,
APPCLASS_STANDARD | APPCMD_CLIENTONLY,
0 // Reserved; must be set to zero
);
// XTYP_ADVSTART
HDDEDATA data = DdeClientTransaction(
NULL, // The beginning of the data the client must pass to the server. This parameter is required only if the wType parameter is XTYP_EXECUTE or XTYP_POKE. Otherwise, this parameter should be NULL
0, // The length, in bytes, of the data pointed to by the pData parameter
conv,
item,
CF_TEXT,
XTYP_ADVSTART,
30000, // The maximum amount of time, in milliseconds, that the client will wait for a response from the server application in a synchronous transaction
NULL // A pointer to a variable that receives the result of the transaction. An application that does not check the result can use NULL for this value
);
HDDEDATA CALLBACK DdeCallback(
UINT uType, // The transaction type
UINT uFmt, // The format atom of the data sent from the server
HCONV hconv, // A handle to the conversation
HSZ hsz1, // A handle to the topic name
HSZ hsz2, // A handle to the item name
HDDEDATA hdata, // A handle to the data associated with the topic name and item name pair
DWORD dwData1, // Not used
DWORD dwData2) // Not used
{
switch (uType)
{
case XTYP_ADVDATA:
DWORD data_size = DdeGetData(hdata, NULL, 0, 0);
std::unique_ptr<char[]> buf(new char[data_size]);
DdeGetData(
hdata,
(BYTE *)buf.get(),
data_size,
0 // An offset within the DDE object. Data is copied from the object beginning at this offset
);
std::cout << "Data received: " << buf.get() << std::endl;
return (HDDEDATA)DDE_FACK;
}
return /* ??? */;
}
Вы получаете только тот тип сообщений, для которых вы регистрируетесь (или, точнее, не фильтруете) при вызове DdeInitialize()
, Если вы регистрируетесь только для получения (или не игнорировать) XTYP_ADVDATA
сообщения, это все, что вы получите, и вам не нужно беспокоиться об обработке других типов сообщений. Любой тип сообщения, который вы не отфильтровываете, ДОЛЖЕН быть правильно обработан в вашем обратном вызове, в соответствии с правилами каждого типа сообщений.
Прочитайте документацию для DdeInitialize()
, обращая внимание на описание для его afCmd
параметр. Также прочитайте документацию о DDE Основные понятия, в частности, разделы, описывающие инициализация и Функция обратного вызова.
Других решений пока нет …