INFO: Calling DdePostAdvise() from XTYP_ADVREQ
ID: Q102571
|
The information in this article applies to:
-
Microsoft Windows Software Development Kit (SDK) 3.1
-
Microsoft Win32 Application Programming Interface (API), used with:
-
Microsoft Windows NT, versions 3.5, 3.51
-
Microsoft Windows 95
SUMMARY
The documentation for DdePostAdvise() in the Windows 3.1 Software
Development Kit "Programmer's Reference, Volume 2: Functions" states
the following in the Comments section:
If a server calls DdePostAdvise() with a topic/item/format name set
that includes the set currently being handled in an XTYP_ADVREQ
callback, a stack overflow may result.
MORE INFORMATION
This is merely a warning against calling DdePostAdvise() from within a
DDE callback function's XTYP_ADVREQ transaction, because it may result
in a stack overflow.
Like window procedures, DDE callbacks must be coded with care to avoid
infinite recursion (eventually resulting in a stack overflow). Because
DdePostAdvise() causes DDEML to send an XTYP_ADVREQ transaction to the
calling application's DDE callback function, calling DdePostAdvise()
on the same topic/item/format name set as the one currently being
handled results in an infinite loop.
An analogous piece of code that has become a classic problem in
Windows programming involves calling UpdateWindow() in a WM_PAINT
case:
case WM_PAINT:
InvalidateRect (hWnd, NULL, TRUE);
UpdateWindow (hWnd);
Calling UpdateWindow() as in the code above causes a WM_PAINT message
to be sent to a window procedure, and thus results in the same type of
infinite recursion that occurs when calling DdePostAdvise() from an
XTYP_ADVREQ transaction.
An example of a situation that would lend itself to this scenario
would be one where data needs to be updated as a result of a previous
data change. There are two ways to work around the stack overflow
problem in this case:
- Post a user-defined message and handle the data change
asynchronously. For example,
// in DdeCallback:
case XTYP_ADVREQ:
if ((!DdeCmpStringHandles (hsz1, ghszTopic)) &&
(!DdeCmpStringHandles (hsz2, ghszItem)) &&
(fmt == CF_SOMEFORMAT))
{
HDDEDATA hData;
hData = DdeCreateDataHandle ();
PostMessage (hWnd, WM_DATACHANGED,hData,);
return (hData);
}
break;
// in MainWndProc():
case WM_DATACHANGED:
DdePostAdvise (idInst, ghszTopic, ghszItem);
:
- Return CBR_BLOCK from the XTYP_ADVREQ and let DDEML suspend further
transactions on that conversation, while the server prepares data
asynchronously.
More information on how returning CBR_BLOCK allows an application to
process data "asynchronously" may be derived from Section 5.8.6 of the
Windows 3.1 Software Development Kit (SDK) "Programmer's Reference,
Volume 1: Overview," or by querying on the following words in the
Microsoft Knowledge Base:
DDEML and CBR_BLOCK
Additional query words:
3.10 3.50 4.00
Keywords :
Version : WINDOWS:3.1,95; winnt:3.5,3.51
Platform : WINDOWS winnt
Issue type : kbinfo
|