如何在 DdeCallback 函数中实现 return 代码

How to implement return codes in DdeCallback function

DdeCallback函数的正确写法是什么?更准确地说,我说的是 return 代码。

来自官方docs:

The return value depends on the transaction class. For more information about the return values, see descriptions of the individual transaction types

例如,我的应用程序需要自己处理 XTYP_ADVDATA 条消息并忽略其他消息。

因此,根据 XTYP_ADVDATAdocs,我需要 return DDE_FACK 如果我处理了这条消息:

A DDE callback function should return DDE_FACK if it processes this transaction, DDE_FBUSY if it is too busy to process this transaction, or DDE_FNOTPROCESSED if it rejects this transaction

但是其他消息呢?在其他情况下我应该 return 什么?

//初始化

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(), paying attention to the description for its afCmd parameter. Also read the documentation about DDE's Basic Concepts, in particular the sections describing Initialization and the Callback function 的文档。