home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c081_7 / 2.ddi / WEXAMPLE.ZIP / DDESRVR.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-13  |  11.0 KB  |  334 lines

  1. // Borland C++ - (C) Copyright 1991 by Borland International
  2.  
  3. //*******************************************************************
  4. //
  5. // program - DDESrvr.c
  6. // purpose - DDE server interface routines. This file is part of the
  7. //           MSGWND project.
  8. //
  9. //*******************************************************************
  10.  
  11.  
  12. #include <windows.h>
  13. #include <dde.h>
  14. #include <stdio.h>
  15. #include <string.h>
  16.  
  17. # include "ddesrvr.h"
  18.  
  19. # define WW_CLIENT 0
  20. # define ACK       0x8000
  21. # define BUSY      0x4000
  22.  
  23. static int  nServerClassRegistered;
  24. static char szServerClass[] = "ddeserver";
  25. static WORD wLastDDEServerMsg;
  26.  
  27. //*******************************************************************
  28. // DDEServerInit - called in response to WM_DDE_INITIATE
  29. //
  30. // paramaters:
  31. //             hParentWnd    - The handle of the server window trying to
  32. //                             respond to this dde conversation.
  33. //             hClientWnd    - The handle of the client window trying to start
  34. //                             this dde conversation.
  35. //             lParam        - lParam send by client window.
  36. //                             Contains atoms of application and topic client
  37. //                             wants to talk about.
  38. //             szApp         - The name of the application server represents.
  39. //             szTopic       - The name of the topic server knows about.
  40. //
  41. // returns:
  42. //             The handle of the channel to use to continue the conversation
  43. //                or
  44. //             NULL if conversation could not be opened.
  45. //
  46. //*******************************************************************
  47. HWND DDEServerInit(HWND hParentWnd, HWND hClientWnd, LONG lParam,
  48.           char *szApp, char *szTopic)
  49. {
  50.     HANDLE   hInst;
  51.     HWND     hChannel;
  52.     ATOM     aApp;
  53.     ATOM     aTopic;
  54.     WNDCLASS wclass;
  55.     char     szClassName[sizeof(szServerClass) + 10];
  56.  
  57.     // Get atoms representing application and topic we will talk about.
  58.     aApp = GlobalAddAtom(szApp);
  59.     if (!aApp)
  60.         return(0);
  61.  
  62.     aTopic = GlobalAddAtom(szTopic);
  63.     if (!aTopic)
  64.     {
  65.         GlobalDeleteAtom(aApp);
  66.         return(0);
  67.     }
  68.  
  69.     // If request is not for application and topic we will talk about
  70.     // do not open conversaton.
  71.     if ((aApp != LOWORD(lParam)) || (aTopic != HIWORD(lParam)))
  72.     {
  73.         GlobalDeleteAtom(aApp);
  74.         GlobalDeleteAtom(aTopic);
  75.         return(0);
  76.     }
  77.  
  78.     // Get parents instance to use in creating window to carry on
  79.     // dde conversation.
  80.     hInst = GetWindowWord(hParentWnd, GWW_HINSTANCE);
  81.     if (!hInst)
  82.         return(0);
  83.  
  84.     // Create a unique class name for this instance of the server.
  85.     sprintf(szClassName, "%s%04X", szServerClass, hInst);
  86.  
  87.     // If we have not already done it, register the window class to
  88.     // carry on this conversation.
  89.     if (!nServerClassRegistered)
  90.     {
  91.         wclass.style         = CS_HREDRAW | CS_VREDRAW;
  92.         wclass.lpfnWndProc   = DDEServerWndProc;
  93.         wclass.cbClsExtra    = 0;
  94.         wclass.cbWndExtra    = 2;
  95.         wclass.hInstance     = hInst;
  96.         wclass.hIcon         = 0;
  97.         wclass.hCursor       = 0;
  98.         wclass.hbrBackground = 0;
  99.         wclass.lpszMenuName  = 0;
  100.         wclass.lpszClassName = szClassName;
  101.  
  102.         // Do not fail if register fails, because another app may have
  103.         // already registered this class.
  104.         RegisterClass(&wclass);
  105.  
  106.     // So we won't try to register again.
  107.         nServerClassRegistered = 1;
  108.     }
  109.  
  110.     // Create the window that will remain hidden but will carry on the
  111.     // conversation wih the dde client.
  112.     hChannel = CreateWindow(szClassName,      // window class name
  113.                             NULL,             // window title
  114.                             WS_CHILD,         // window style
  115.                             CW_USEDEFAULT,    // window origin
  116.                             0,
  117.                             CW_USEDEFAULT,    // window size
  118.                             0,
  119.                             hParentWnd,       // window parent
  120.                             NULL,             // window id
  121.                             hInst,            // window instance
  122.                             NULL);            // no parms
  123.  
  124.     // If create of window failed we cannot continue.
  125.     if (!hChannel)
  126.         return(0);
  127.  
  128.     // Remember the handle of our client.
  129.     SetWindowWord(hChannel, WW_CLIENT, hClientWnd);
  130.  
  131.     // Send acknowledgement to client.
  132.     wLastDDEServerMsg = WM_DDE_ACK;
  133.     SendMessage(hClientWnd, wLastDDEServerMsg, hChannel, MAKELONG(aApp, aTopic));
  134.  
  135.     // Return handle of window that will carry on the conversation for
  136.     // this server.
  137.     return(hChannel);
  138. }
  139.  
  140. //*******************************************************************
  141. // DDEServerClose - close the dde conversation with a client
  142. //
  143. // paramaters:
  144. //             hChannel      - The handle of the window conducting
  145. //                             the dde conversation.
  146. //
  147. //*******************************************************************
  148. int DDEServerClose(HWND hChannel)
  149. {
  150.     HWND hClientWnd;
  151.  
  152.     // If the channel is still active.
  153.     if (IsWindow(hChannel))
  154.     {
  155.         wLastDDEServerMsg = WM_DDE_TERMINATE;
  156.  
  157.         // Get handle of client we were conversing with.
  158.         hClientWnd = GetWindowWord(hChannel, WW_CLIENT);
  159.  
  160.         // If he is still active.
  161.         if (IsWindow(hClientWnd))
  162.             SendMessage(hClientWnd, wLastDDEServerMsg, hChannel, 0L);
  163.     }
  164.  
  165.     return(1);
  166. }
  167.  
  168. //*******************************************************************
  169. // DDEServerWndProc - window proc to manage interface with client
  170. //
  171. // paramaters:
  172. //             hWnd          - The window handle for this message
  173. //             message       - The message number
  174. //             wParam        - The WORD parmater for this message
  175. //             lParam        - The LONG parmater for this message
  176. //
  177. // returns:
  178. //             depends on message.
  179. //
  180. //*******************************************************************
  181. LONG FAR PASCAL DDEServerWndProc(HWND hWnd, WORD message,
  182.                  WORD wParam, LONG lParam)
  183. {
  184.     WORD         wStatus;
  185.     HWND         hClientWnd;
  186.     HANDLE       hCommand;
  187.     HANDLE       hData;
  188.     LPSTR        lpData;
  189.     HANDLE       hShData;
  190.     DDEDATA FAR *lpShData;
  191.     char         szItem[30];
  192.     ATOM         aItem;
  193.     LPSTR        lpCommand;
  194.     int          nRc;
  195.     int          nSize;
  196.  
  197.     switch (message)
  198.     {
  199.         case WM_DDE_EXECUTE:         // execute a command for client
  200.             // Get handle of client.
  201.         hClientWnd = wParam;
  202.  
  203.             // Init status.
  204.             wStatus = 0;
  205.  
  206.             // Get handle of command client is sending us.
  207.             hCommand = HIWORD(lParam);
  208.  
  209.             // Lock it down to get address.
  210.             lpCommand = GlobalLock(hCommand);
  211.             if (lpCommand)
  212.             {
  213.                 // Call our function to execute the command.
  214.                 if (DDEExecuteCommand(lpCommand))
  215.                     wStatus = ACK;
  216.  
  217.                 GlobalUnlock(hCommand);
  218.             }
  219.  
  220.         // Send acknowledgement back to client.
  221.             PostMessage(hClientWnd, WM_DDE_ACK, hWnd,
  222.                         MAKELONG(wStatus, hCommand));
  223.             break;
  224.  
  225.         case WM_DDE_REQUEST:         // data request from a client
  226.             // Get handle of client.
  227.             hClientWnd = wParam;
  228.  
  229.             // Get atom representing data request item.
  230.             aItem = HIWORD(lParam);
  231.             if (!GlobalGetAtomName(aItem, szItem, sizeof(szItem)))
  232.             {
  233.                 // Error if atom not found.
  234.                 PostMessage(hClientWnd, WM_DDE_ACK, hWnd,
  235.                             MAKELONG(0, aItem));
  236.                 return(0L);
  237.             }
  238.  
  239.         // Init return code.
  240.             nRc = 0;
  241.  
  242.             // Don't care about case.
  243.             strupr(szItem);
  244.  
  245.             // Call our function to get the data item.
  246.             nSize = DDEData(szItem, &hData);
  247.  
  248.             // If any data found.
  249.             if (nSize)
  250.             {
  251.                 // Get shared memory to send item back in.
  252.                 hShData = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT | GMEM_DDESHARE,
  253.                                       (DWORD) (nSize + sizeof(DDEDATA) + 1));
  254.                 if (hShData)
  255.                 {
  256.                     // Lock it down to get address.
  257.                     lpShData = (DDEDATA FAR *) GlobalLock(hShData);
  258.             if (lpShData)
  259.                     {
  260.                         // Setup data header.
  261.                         lpShData->fResponse = 1;
  262.                         lpShData->fRelease = 1;
  263.                         lpShData->fAckReq = 0;
  264.                         lpShData->cfFormat = CF_TEXT;
  265.  
  266.                         // Lock out local copy of data to get address.
  267.                         lpData = GlobalLock(hData);
  268.                         if (lpData)
  269.                         {
  270.                             // Copy data to shared memory.
  271.                             _fstrcpy(lpShData->Value, lpData);
  272.                             GlobalUnlock(hData);
  273.  
  274.                             nRc = 1;
  275.                         }
  276.  
  277.             GlobalUnlock(hShData);
  278.                     }
  279.                 }
  280.  
  281.                 GlobalFree(hData);
  282.             }
  283.  
  284.             if (nRc)
  285.             {
  286.                 // If ok send data back.
  287.                 PostMessage(hClientWnd, WM_DDE_DATA, hWnd,
  288.                             MAKELONG(hShData, aItem));
  289.             }
  290.             else
  291.             {
  292.                 // If errors just send negative acknowlegement back.
  293.                 PostMessage(hClientWnd, WM_DDE_ACK, hWnd,
  294.                             MAKELONG(0, aItem));
  295.             }
  296.         break;
  297.  
  298.         case WM_DDE_TERMINATE:      // server says terminate conversation
  299.             // Get handle of client we are dealing with.
  300.             hClientWnd = GetWindowWord(hWnd, WW_CLIENT);
  301.  
  302.             // Ignore if not from our client.
  303.             if (wParam != hClientWnd)
  304.                 return(0L);
  305.  
  306.             // Forget who client is.
  307.             SetWindowWord(hWnd, WW_CLIENT, 0);
  308.  
  309.             // Tell our parent conversation closed.
  310.             SendMessage(GetParent(hWnd), WMU_DDE_CLOSED, hWnd, 0L);
  311.  
  312.             // Send terminate to server to acknowledge we recieved
  313.             // terminate,  if we did not initiate the termination ourselves.
  314.             if ((wLastDDEServerMsg != WM_DDE_TERMINATE) && IsWindow(hClientWnd))
  315.         PostMessage(hClientWnd, WM_DDE_TERMINATE, hWnd, 0L);
  316.  
  317.             // Terminate this child window.
  318.             DestroyWindow(hWnd);
  319.             break;
  320.  
  321.         case WM_DESTROY:            // destroy this window
  322.             // Terminate any ongoing conversation on our way out.
  323.             DDEServerClose(hWnd);
  324.             break;
  325.  
  326.         default:
  327.             return(DefWindowProc(hWnd, message, wParam, lParam));
  328.     }
  329.  
  330.     return(0L);
  331. }
  332.  
  333. //*******************************************************************
  334.