2015-11-03 2 views
1

Каков правильный способ записи функции DdeCallback? Чтобы быть более точным, я говорю о кодах возврата.Как реализовать коды возврата в функции DdeCallback

Из официального docs:

Возвращаемое значение зависит от класса транзакции. Для получения более подробной информации о возвращаемых значениях см описание отдельных видов операций

Например, мое приложению нужно обрабатывать XTYP_ADVDATA сообщения сам по себе и игнорировать другие.

Таким образом, в соответствии с docs для 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 /* ??? */; 
} 

ответ

3

Вы получаете только тип сообщений, которые зарегистрировались для (или более точно, что вы не отфильтровать) при вызове DdeInitialize(). Если вы регистрируетесь только для получения (или не игнорирования) сообщений XTYP_ADVDATA, это все, что вы получите, и вам не нужно беспокоиться о том, как обращаться с другими типами сообщений. Любой тип сообщения, который вы не отфильтровываете, ДОЛЖЕН быть правильно обработан в вашем обратном вызове, в соответствии с правилами каждого типа сообщений.

Прочитайте документацию для DdeInitialize(), обращая внимание на описание параметра afCmd. Также прочитайте документацию о DDE's Basic Concepts, в частности разделы, описывающие Initialization и Callback function.

+0

«Если вы регистрируетесь только для получения (или не игнорирования) сообщений XTYP_ADVDATA, это все, что вы получите» - вы уверены? Поскольку я пытался распечатать 'uType' для каждого сообщения, которое я получаю в этом обратном вызове, и я заметил, что у меня есть два дополнительных типа сообщений при отключении сервера DDE – FrozenHeart

+1

Вы, очевидно, не отключите все, что вы хотите игнорировать. Но вы не указали, какие другие сообщения вы фактически получаете, или покажите свой фактический код, вызывающий 'DdeInitialize()'. –

+0

http://pastie.org/10528362. Я получаю сообщения с типами 32978 и 32962, когда я завершаю DDE-сервер – FrozenHeart

Смежные вопросы