Microsoft KB Archive/102571

{|
 * width="100%"|

INFO: Calling DdePostAdvise from XTYP_ADVREQ

 * }

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 Server versions 3.5, 3.51
 * Microsoft Windows NT Workstation 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 :

Issue type : kbinfo

Technology : kbAudDeveloper kbSDKSearch kbWin32sSearch kbWin32API kbWinSDKSearch