Microsoft KB Archive/102571

From BetaArchive Wiki
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

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


Last Reviewed: December 16, 2000
© 2001 Microsoft Corporation. All rights reserved. Terms of Use.