home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 May / Pcwk5b98.iso / Borland / Cplus45 / BC45 / TSTAPP.PAK / DDESRVR.C < prev    next >
C/C++ Source or Header  |  1995-08-29  |  12KB  |  360 lines

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