The DDEML requires that Windows be running; otherwise, the system cannot load the DDEML dynamic-link library. Before calling any DDEML function, an application should call the GetWinFlags function, checking the return value for the WF_PMODE flag. If this flag is returned, the application can call DDEML functions.
Before calling any other DDEML function, an application must call the DdeInitialize function. The DdeInitialize function obtains an instance identifier for the application, registers the application's DDE callback function with the DDEML, and specifies the transaction filter flags for the callback function.
The DDEML uses instance identifiers so that it can support applications that allow multiple DDEML instances. Each instance of an application must pass its instance identifier as the idInst parameter to any other DDEML function that requires it. An application that uses multiple DDEML instances should assign a different DDE callback function to each instance. This makes it possible for the application to identify each instance within its callback function.
The purpose for multiple DDEML instances is to support DLLs using the DDEML. It is not recommended that an application have multiple DDE instances.
Transaction filters optimize system performance by preventing the DDEML from passing unwanted transactions to the application's DDE callback function. An application sets the transaction filters when it calls the DdeInitialize function. An application should specify a transaction filter flag for each type of transaction that it does not process in its callback function. An application can change its transaction filters with a subsequent call to the DdeInitialize function. For a complete list of transaction filter flags, see the description of the DdeInitialize function in the Microsoft Windows Programmer's Reference, Volume 2.
For more information about transactions, see Section 5.8, “Transaction Management.”
The following example shows how to initialize an application to use the DDEML:
DWORD idInst = 0L; /* instance identifier */
HANDLE hInst; /* instance handle */
FARPROC lpDdeProc; /* procedure instance address */
lpDdeProc = MakeProcInstance((FARPROC) DdeCallback, hInst);
if (DdeInitialize(&idInst, /* receives instance identifier */
(PFNCALLBACK) lpDdeProc, /* address of callback function */
CBF_FAIL_EXECUTES | /* filter XTYP_EXECUTE transactions */
CBF_FAIL_POKES, 0L); /* filter XTYP_POKE transactions */
return FALSE;
This example obtains a procedure-instance address for the callback func-tion named DdeCallback and then passes the address to the DDEML. The CBF_FAIL_EXECUTES and CBF_FAIL_POKES filters prevent the DDEML from passing XTYP_EXECUTE or XTYP_POKE transactions to the callback function.
An application should call the DdeUninitialize function when it no longer needs to use the DDEML. This function terminates any conversations currently open for the application and frees the DDEML resources that the system allocated for the application.
The DDEML may have difficulty terminating a conversation. This occurs when the other partner in a conversation fails to terminate its end of the conversation. In this case, the system enters a modal loop while it waits for any conversations to be terminated. A system-defined timeout period is associated with this loop. If the timeout period expires before the conversations have been terminated, a message box appears that gives the user the choice of waiting for another timeout period (Retry), waiting indefinitely (Ignore), or exiting the modal loop (Abort). An application should call DdeUninitialize after it has become invisible to the user and after its message loop has terminated.