如何在 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_ADVDATA
的 docs,我需要 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 的文档。
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_ADVDATA
的 docs,我需要 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 的文档。