home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_C / CENVIW9.ZIP / DDE.LIB < prev    next >
Text File  |  1994-03-08  |  8KB  |  244 lines

  1. // DDE.lib - Library for common DDE functions.
  2. // ver.1
  3. //
  4. //***** struct ddeSession: Structure to define a session
  5. // Many of the following functions refer to the parameters of a dde
  6. // session in some or all elements of a ddeSession structure, which
  7. // contains the following members (along with other non-documented
  8. // members that should be of no concern):
  9. //  .Application: string - DDE Server application name
  10. //  .Topic: string - DDE Server string
  11. //  .hwndClient: int - Window handle of the DDE client
  12. //  .hwndServer: int - Window handle of the DDE server
  13. //  .TerminateFunction: string - function to call when other party terminates
  14. //
  15. //
  16. //***** ServerDirectory(): Get the handle for this window
  17. // SYNTAX: int ServerDirectory(string Application,string Topic,struct[] ServerList)
  18. // WHERE: Application: DDE Server application string, or NULL for ALL
  19. //        Topic: DDE Server Topic, or NULL for ALL
  20. //        ServerList: array created for each entry.  Array elements are:
  21. //            .Application - Returned application name
  22. //            .Topic - Returned Topic name
  23. // RETURN: Count of elements in ServerList
  24. // MODIFY: Modifies ServerList to be an array.  Undefined if returns 0.
  25. //
  26. //
  27.  
  28. #include <Window.lib>
  29.  
  30. //*************************************************************
  31. //*************** Globals and Defines Used ********************
  32. //*************************************************************
  33.  
  34. DDELibMainHwnd;
  35.  
  36. #define DEFAULT_TIMEOUT    10000     // timeout if none supplied to functions
  37.  
  38. #define WM_DDE_INITIATE    0x03E0
  39. #define WM_DDE_TERMINATE   0x03E1
  40. #define WM_DDE_ADVISE      0x03E2
  41. #define WM_DDE_UNADVISE    0x03E3
  42. #define WM_DDE_ACK         0x03E4
  43. #define WM_DDE_DATA        0x03E5
  44. #define WM_DDE_REQUEST     0x03E6
  45. #define WM_DDE_POKE        0x03E7
  46. #define WM_DDE_EXECUTE     0x03E8
  47.  
  48. #define WM_DESTROY   0x0002
  49. #define CF_TEXT      1
  50.  
  51. #define GMEM_MOVEABLE   0x0002
  52. #define GMEM_DDESHARE   0x2000
  53.  
  54.  
  55. //*****************************************************************
  56. //***** Main DDE window, for finding servers, and being found *****
  57. //*****************************************************************
  58.  
  59. DDEGettingServerDirectory = False;
  60. DDEServerDirectory;
  61. DDELibMainHwnd = MakeWindow(NULL,NULL,"DDELibMainFunction","CEnvi DDE Library",
  62.                             WS_POPUP,0,0,0,0,NULL);
  63. assert( NULL != DDELibMainHwnd );
  64.  
  65. DDELibMainFunction(hwnd,msg,wParm,lParm)
  66. {
  67.    switch ( msg ) {
  68.       case WM_DDE_ACK:
  69.          if ( DDEGettingServerDirectory ) {
  70.  
  71.             // Save application and topic in our growing array
  72.             tAtomApp = LoWord(lParm);
  73.             tAtomTop = HiWord(lParm);
  74.             tIndex = defined(DDEServerDirectory)
  75.                    ? 1 + GetArraySpan(DDEServerDirectory) : 0 ;
  76.             DDEServerDirectory[tIndex].Application = GetAtomString(tAtomApp);
  77.             DDEServerDirectory[tIndex].Topic = GetAtomString(tAtomTop);
  78.  
  79.             // Tell server to terminate this connection
  80.             PostMessage(wParm,WM_DDE_TERMINATE,hwnd,0);
  81.  
  82.             return(0);
  83.          }
  84.          break;
  85.    }
  86. }
  87.  
  88. ServerDirectory(pApplication,pTopic,pServerList)
  89. {
  90.    // Create atom for Server and Topic (0 if NULL strings)
  91.    sdAtomApp = pApplication ? GlobalAddAtom(pApplication) : 0 ;
  92.    sdAtomTop = pTopic ? GlobalAddAtom(pTopic) : 0 ;
  93.  
  94.    // Send message to all windows to initiate DDE connection
  95.    undefine(pServerList);
  96.    Multitask(False);
  97.    DDEGettingServerDirectory = True;
  98.    SendMessage(0xFFFF,WM_DDE_INITIATE,DDELibMainHwnd,sdAtomApp,sdAtomTop);
  99.    DDEGettingServerDirectory = False;
  100.    Multitask(True);
  101.  
  102.    // undo atoms that were made
  103.    if ( sdAtomApp ) GlobalDeleteAtom(sdAtomApp);
  104.    if ( sdAtomTop ) GlobalDeleteAtom(sdAtomTop);
  105.  
  106.    // DDEServerDirectory will contain all responses
  107.    if ( defined(DDEServerDirectory) ) {
  108.       pServerList = DDEServerDirectory;
  109.       undefine(DDEServerDirectory);
  110.       return 1 + GetArraySpan(pServerList);
  111.    } else {
  112.       return 0;
  113.    }
  114. }
  115.  
  116. //******************************************************
  117. //*************** Utility functions ********************
  118. //******************************************************
  119.  
  120. DoPostedDDEMessage(pddeSession,pTimeout)  // DoWindows until Postedmessage is null or timeout
  121. {                                         // -1 to never timeout
  122.    if ( -1 != pTimeout )
  123.       tEndTime = clock() + pTimeout * CLOCKS_PER_SEC / 1000;
  124.    while( 0 != pddeSession.PostedMessage
  125.        && ( -1 == pTimeout || clock() < tEndTime )
  126.        && DoWindows(True) ) ;
  127. }
  128.  
  129. SendMessage(Window,Message,wParam,lParamLo,lParamHi)
  130. {
  131.    if ( va_arg() == 4 )
  132.       return(SendMessage(Window,Message,wParam,lParamLo & 0xFFFF,(lParamLo >> 16) & 0xFFFF));
  133.    return( DynamicLink("USER","SENDMESSAGE",UWORD32,PASCAL,
  134.                        Window,Message,wParam,lParamHi,lParamLo) );
  135. }
  136.  
  137. PostMessage(Window,Message,wParam,lParamLo,lParamHi)
  138. {
  139.    if ( va_arg() == 4 )
  140.       return(PostMessage(Window,Message,wParam,lParamLo & 0xFFFF,(lParamLo >> 16) & 0xFFFF));
  141.    return( DynamicLink("USER","POSTMESSAGE",SWORD16,PASCAL,
  142.                        Window,Message,wParam,lParamHi,lParamLo) );
  143. }
  144.  
  145. GlobalAddAtom(pAtomString)
  146. {
  147.    return DynamicLink("USER","GLOBALADDATOM",UWORD16,PASCAL,pAtomString);
  148. }
  149.  
  150. GlobalDeleteAtom(pAtom)
  151. {
  152.    return DynamicLink("USER","GLOBALDELETEATOM",UWORD16,PASCAL,pAtom);
  153. }
  154.  
  155. LoWord(dword)
  156. {
  157.    return dword & 0xFFFF
  158. }
  159.  
  160. HiWord(dword)
  161. {
  162.    return (dword >> 16) & 0xFFFF
  163. }
  164.  
  165. GetAtomString(pAtom,pAtomBuffer,pAtomBufferLength)
  166. {
  167.    #define MAX_ATOM_BUFFER_SIZE  50
  168.    lAtomBuffer[MAX_ATOM_BUFFER_SIZE-1] = '\0';
  169.    if ( 0 == DynamicLink("USER","GLOBALGETATOMNAME",UWORD16,PASCAL,
  170.                          pAtom,lAtomBuffer,MAX_ATOM_BUFFER_SIZE) )
  171.       return("");
  172.    strcpy(lString,lAtomBuffer);
  173.    return lString;
  174. }
  175.  
  176. GlobalLock(pMemoryHandle)  // return locked pointer to memory
  177. {
  178.    return DynamicLink("KERNEL","GLOBALLOCK",UWORD32,PASCAL,pMemoryHandle);
  179. }
  180.  
  181. GlobalUnlock(pMemoryHandle)
  182. {
  183.    return DynamicLink("KERNEL","GLOBALUNLOCK",SWORD16,PASCAL,pMemoryHandle);
  184. }
  185.  
  186. GlobalAlloc(pFlags,pSize)
  187. {
  188.    return DynamicLink("KERNEL","GLOBALALLOC",UWORD16,PASCAL,
  189.                       pFlags,HiWord(pSize),LoWord(pSize));
  190. }
  191.  
  192. GlobalFree(pMemoryHandle)
  193. {
  194.    return DynamicLink("KERNEL","GLOBALFREE",UWORD16,PASCAL,pMemoryHandle);
  195. }
  196.  
  197. GlobalSize(pMemoryHandle)
  198. {
  199.    return DynamicLink("KERNEL","GLOBALSIZE",UWORD32,PASCAL,pMemoryHandle);
  200. }
  201.  
  202. DdeAckToWord(pDdeAck)   // convert DdeAck structure to a word
  203. {
  204.    lWord = pDdeAck.bAppReturnedCode;
  205.    if ( pDdeAck.fBusy ) lWord |= 0x40;
  206.    if ( pDdeAck.fAck ) lWord |= 0x80;
  207. }
  208.  
  209. WordToDdeAck(pWord)     // convert word to DdeAck structure
  210. {
  211.    lDdeAck.bAppReturnedCode = pWord & 0xFF;
  212.    lDdeAck.fBusy = (pWord >> 14) & 1;
  213.    lDdeAck.fAck = (pWord >> 15) & 1;
  214.    return lDdeAck;
  215. }
  216.  
  217. DdeAdviseStuctureToHandle(pDdeAdvise)
  218. {
  219.    lDWord = pDdeAdvise.cfFormat << 16;
  220.    if ( pDdeAdvise.fDeferUpd ) lDWord |= 0x40;
  221.    if ( pDdeAdvise.fAckReq ) lDWord |= 0x80;
  222.    assert( lhDdeAdvise = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE,4) );
  223.    poke(GlobalLock(lhDdeAdvise),lDWord,UWORD32);
  224.    GlobalUnlock(lhDdeAdvise);
  225.    return lhDdeAdvise;
  226. }
  227.  
  228. DdeDataHandleToStructure(hDdeData)
  229. {
  230.    lpDdeData = GlobalLock(hDdeData);
  231.    lBits = peek(lpDdeData+1);
  232.    lDdeData.fResponse = (lBits >> 4) & 1;
  233.    lDdeData.fRelease = (lBits >> 5) & 1;
  234.    lDdeData.fAckReq = (lBits >> 7) & 1;
  235.    if ( CF_TEXT == (lDdeData.cfFormat = peek(lpDdeData+2,SWORD16)) ) {
  236.       // read in buffer up to NULL
  237.       lDdeData.Value = peek(lpDdeData+4,GlobalSize(hDdeData)-4);
  238.       SetArraySpan(lDdeData.Value,strlen(lDdeData.Value));
  239.    }
  240.    GlobalUnlock(hDdeData);
  241.    return lDdeData;
  242. }
  243.  
  244.