home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / msysjour / vol05 / 04 / pmaccess / client.c < prev    next >
C/C++ Source or Header  |  1990-07-01  |  9KB  |  287 lines

  1. // client.c RHS
  2.  
  3.  
  4. #define INCL_WIN
  5. #define INCL_DOSPROCESS
  6. #define INCL_DOSQUEUES
  7. #include <os2.h>
  8. #include <mt\string.h>
  9. #include <mt\stdio.h>
  10. #include <mt\malloc.h>
  11. #include "msgq.h"
  12. #include "pmserver.h"
  13. #include "pmsvmsgs.h"
  14. #include "client.h"
  15.  
  16.  
  17. //
  18. // Defines
  19. //
  20. #define QWP_USER    0
  21.  
  22. //
  23. // Structures
  24. //
  25. typedef struct clientdata 
  26.     {
  27.     HAB             hab;
  28.     HWND            hwndServer;
  29.     PCLIENT         pclient;
  30.     } CDATA;
  31. typedef CDATA *PCDATA;
  32.  
  33. //
  34. // Function prototypes
  35. //
  36. extern MRESULT CALLBACK DdeClientProc(HWND, USHORT, MPARAM, MPARAM);
  37. PDDESTRUCT MakeDDESeg(HWND Destwin, PSZ itemname, USHORT status,
  38.         USHORT format, PVOID dataptr, USHORT datalen);
  39.  
  40.  
  41. // creates DDE client object window
  42.  
  43. VOID    FAR    CreateClient(PCLIENT pclient)
  44.     {
  45.     CDATA    ClientData;
  46.     QMSG    qmsg;
  47.     HMQ     hmq;
  48.  
  49.     ClientData.pclient = pclient;
  50.     ClientData.hab = WinInitialize(0);
  51.     hmq = WinCreateMsgQueue(ClientData.hab, 0);
  52.  
  53.     WinRegisterClass(ClientData.hab, "DdeClient", DdeClientProc, 0L,
  54.         sizeof(PCDATA));
  55.  
  56.     pclient->hwnd = WinCreateWindow(HWND_OBJECT,
  57.                                 "DdeClient",
  58.                                 NULL,
  59.                                 0L,
  60.                                 0, 0, 0, 0,
  61.                                 NULL,
  62.                                 HWND_TOP,
  63.                                 1,
  64.                                 &ClientData,
  65.                                 NULL);
  66.  
  67.     while (WinGetMsg(NULL, (PQMSG)&qmsg, NULL, 0, 0))
  68.         WinDispatchMsg(NULL, (PQMSG)&qmsg);
  69.  
  70.     WinDestroyWindow(pclient->hwnd);            // destroy window
  71.     WinDestroyMsgQueue(hmq);                    // destroy msg queue
  72.     DosEnterCritSec();                          // freeze threads
  73.                                                 // tell PMServer
  74.     WinPostMsg(pclient->hwndpmserver,PMSV_THREAD_TERMINATE,
  75.         pclient->hwnd,0L);
  76.     WinTerminate(ClientData.hab);               // discard resources
  77.     DosExit(EXIT_THREAD, 0);                    // exit and unfreeze
  78.     }
  79.  
  80.  
  81.     // DDE client object window proc
  82. MRESULT CALLBACK DdeClientProc(HWND hwnd, USHORT msg, MPARAM mp1,
  83.         MPARAM mp2)
  84.     {
  85.     PCDATA          pClientData = WinQueryWindowPtr(hwnd, QWP_USER);
  86.     PDDESTRUCT      pdde;
  87.     PDDEINIT        pddeinit;
  88.     HWND            hwndSender = HWNDFROMMP(mp1);
  89.  
  90.     switch (msg)
  91.         {
  92.         case WM_DDE_INITIATE:
  93.             break;
  94.         case WM_CREATE:
  95.             {
  96.             PCLIENT    pclient;
  97.  
  98.             pClientData = PVOIDFROMMP(mp1);
  99.             pclient = pClientData->pclient;
  100.             WinSetWindowPtr(hwnd, QWP_USER, pClientData);
  101.             pClientData->hwndServer = NULL;
  102.             WinDdeInitiate(hwnd, pclient->appname,
  103.                 pclient->topicname);
  104.             WinStartTimer(pClientData->hab, hwnd, 0, 100);
  105.             break;
  106.             }
  107.  
  108.         case WM_TIMER:
  109.             {
  110.             WinStopTimer(pClientData->hab, hwnd, 0);
  111.             if (!pClientData->hwndServer)
  112.                 {
  113.                 MsgQSend(pClientData->pclient->qhandle,NULL,0,
  114.                     PMS_DDE_INITNAK);
  115.                 WinPostMsg(hwnd, WM_QUIT, 0L, 0L);
  116.                 }
  117.             break;
  118.             }
  119.  
  120.         case WM_DDE_INITIATEACK:
  121.             {
  122.             pddeinit = PVOIDFROMMP(mp2);
  123.             pClientData->hwndServer = hwndSender;
  124.             MsgQSend(pClientData->pclient->qhandle,NULL,0,
  125.                     PMS_DDE_INITACK);
  126.             DosFreeSeg(PDDEITOSEL(pddeinit));
  127.             break;
  128.             }
  129.  
  130.         case WM_DDE_ACK:
  131.             {
  132.             PITEMREQ    iReq;
  133.             PVOID    pVoid;
  134.             USHORT  size;
  135.  
  136.             pdde        = PVOIDFROMMP(mp2);
  137.             iReq = malloc(size = (sizeof(ITEMREQ)+
  138.                     (USHORT)pdde->cbData+1));
  139.  
  140.             strcpy(iReq->item, DDES_PSZITEMNAME(pdde));
  141.             pVoid = DDES_PABDATA(pdde);
  142.             memcpy(iReq->value, DDES_PABDATA(pdde),
  143.                     (size_t)pdde->cbData);
  144.  
  145.             MsgQSend(pClientData->pclient->qhandle,iReq,size,
  146.                 (pdde->fsStatus & DDE_FACK ? PMS_DDE_ACK :
  147.                 PMS_DDE_NAK));
  148.             DosFreeSeg(PDDESTOSEL(pdde));
  149.             free(iReq);
  150.             break;
  151.             }
  152.  
  153.         case WM_DDE_DATA:
  154.             {
  155.             PITEMREQ    iReq;
  156.             char *excel = "excel";
  157.             USHORT size,i;
  158.  
  159.             pdde = PVOIDFROMMP(mp2);
  160.             iReq = (PITEMREQ)malloc(size = (sizeof(ITEMREQ)+
  161.                     (USHORT)pdde->cbData+2));
  162.             strcpy(iReq->item, DDES_PSZITEMNAME(pdde));
  163.                 // if the app is Excel...
  164.             if(!strnicmp(excel,pClientData->pclient->appname,
  165.                     strlen(excel)))
  166.                 memcpy(iReq->value, DDES_PABDATA(pdde),
  167.                     i = (USHORT)pdde->cbData);
  168.             else
  169.                 memcpy(iReq->value, DDES_PABDATA(pdde),
  170.                     i = ((USHORT)pdde->cbData-pdde->offabData-1));
  171.             iReq->value[i] = '\0';
  172.  
  173.             MsgQSend(pClientData->pclient->qhandle,iReq,size,
  174.                 (pdde->fsStatus & DDE_FNODATA) ? PMS_DDE_DATACHANGE :
  175.                 PMS_DDE_DATA);
  176.  
  177.             DosFreeSeg(PDDESTOSEL(pdde));
  178.             free(iReq);
  179.             break;
  180.             }
  181.  
  182.         case WM_CLOSE:
  183.         case PMSV_TERMINATE:               // PMServer terminating
  184.         case WM_DDE_TERMINATE:             // server/client is term.
  185.             {
  186.             WinDdePostMsg(
  187.                 (msg == WM_DDE_TERMINATE ?
  188.                     hwndSender : pClientData->hwndServer),
  189.                 hwnd, WM_DDE_TERMINATE, NULL, FALSE);
  190.             MsgQSend(pClientData->pclient->qhandle,0,0,
  191.                     PMS_DDE_TERMINATE);
  192.             pClientData->hwndServer = NULL;
  193.  
  194.             WinPostMsg(hwnd, WM_QUIT, 0L, 0L);
  195.             break;
  196.             }
  197.  
  198.         case PMSV_REQUEST:
  199.         case PMSV_ADVISE:
  200.         case PMSV_ADVISE_NO_DATA:
  201.         case PMSV_POKE:
  202.         case PMSV_UNADVISE:
  203.         case PMSV_EXECUTE:
  204.             {
  205.             PITEMREQ piReq = PVOIDFROMMP(mp2);
  206.             USHORT DDEmsg;
  207.  
  208.             switch(msg)
  209.                 {
  210.                 case PMSV_REQUEST:
  211.                     DDEmsg = WM_DDE_REQUEST;
  212.                     break;
  213.                 case PMSV_ADVISE:
  214.                 case PMSV_ADVISE_NO_DATA:
  215.                     DDEmsg = WM_DDE_ADVISE;
  216.                     break;
  217.                 case PMSV_POKE:
  218.                     DDEmsg = WM_DDE_POKE;
  219.                     break;
  220.                 case PMSV_UNADVISE:
  221.                     DDEmsg = WM_DDE_UNADVISE;
  222.                     break;
  223.                 case PMSV_EXECUTE:
  224.                     DDEmsg = WM_DDE_EXECUTE;
  225.                     break;
  226.                 }
  227.  
  228.              pdde = MakeDDESeg(pClientData->hwndServer,
  229.                 ((msg == PMSV_EXECUTE) ? (PSZ)"" : (PSZ)piReq->item),
  230.                 ((msg == PMSV_ADVISE_NO_DATA) ? DDE_FNODATA : 0),
  231.                 DDEFMT_TEXT,
  232.                 ((msg == PMSV_POKE || msg == PMSV_EXECUTE)
  233.                         ? piReq->value : NULL),
  234.                 ((msg == PMSV_POKE || msg == PMSV_EXECUTE)
  235.                         ? strlen(piReq->value)+1 : 0));
  236.  
  237.             WinDdePostMsg(pClientData->hwndServer,
  238.                 hwnd,
  239.                 DDEmsg,
  240.                 pdde,
  241.                 TRUE);
  242.             break;
  243.             }
  244.         
  245.         default:
  246.             return (WinDefWindowProc(hwnd, msg, mp1, mp2));
  247.         }
  248.     return (0);
  249.     }
  250.  
  251.  
  252.     // creates DDE Seg, returns pointer to it.
  253. PDDESTRUCT MakeDDESeg(HWND Destwin, PSZ itemname, USHORT status,
  254.         USHORT format, PVOID dataptr, USHORT datalen)
  255.     {
  256.     PDDESTRUCT  ddeptr;
  257.     USHORT      itemlen,totalen;
  258.     SEL         localSEL, sharedSEL;
  259.     PID         receiverPID, receiverTID;
  260.  
  261.     itemlen = strlen(itemname)+1;
  262.     totalen = sizeof(DDESTRUCT) + itemlen + datalen;
  263.  
  264.     if(!DosAllocSeg(totalen, &localSEL, SEG_GIVEABLE))
  265.         {
  266.         ddeptr = SELTOPDDES(localSEL);
  267.         ddeptr->cbData = totalen;
  268.         ddeptr->fsStatus = status;
  269.         ddeptr->usFormat = format;
  270.         ddeptr->offszItemName = sizeof(DDESTRUCT);
  271.         ddeptr->offabData = ((datalen && dataptr) ?
  272.                 (sizeof(DDESTRUCT)+itemlen) : 0);
  273.  
  274.         strcpy(DDES_PSZITEMNAME(ddeptr),itemname);
  275.         memmove(DDES_PABDATA(ddeptr),dataptr,datalen);
  276.         WinQueryWindowProcess(Destwin, &receiverPID, &receiverTID);
  277.  
  278.         if(!DosGiveSeg(localSEL,receiverPID,&sharedSEL))
  279.             {
  280.             ddeptr = SELTOPDDES(sharedSEL);
  281.             return ddeptr;
  282.             }
  283.         }
  284.     return NULL;
  285.     }
  286.  
  287.