home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / epmdde.zip / DDESAMP.C < prev    next >
Text File  |  1992-12-09  |  20KB  |  421 lines

  1. /*────────────────────────────────────────────────────────────────────┐
  2. │                                                                     │
  3. │  Sample DDE Client Application which connects with EPM v6.00        │
  4. │  (32-bit version)                                                   │
  5. │                                                                     │
  6. │  John Ponzo    11/92                                                │
  7. └────────────────────────────────────────────────────────────────────*/
  8.  
  9. #include "ddesamp.h"
  10. HAB  hab;
  11.  
  12. main(void)
  13. {
  14.   HMQ  hmq;                             /* Message queue handle         */
  15.   HWND hwndClient;                      /* Client area window handle    */
  16.   HWND hwndFrame;                       /* Frame window handle          */
  17.   QMSG qmsg;                            /* Message from message queue   */
  18.   ULONG flCreate;                       /* Window creation control flags*/
  19.  
  20.   hab = WinInitialize(0);               /* Initialize PM                */
  21.   hmq = WinCreateMsgQueue( hab, 0 );    /* Create a message queue       */
  22.  
  23.   WinRegisterClass(                     /* Register window class        */
  24.      hab,                               /* Anchor block handle          */
  25.      "DDESAMP",                         /* Window class name            */
  26.      DdeSampleWndProc,                  /* Address of window procedure  */
  27.      CS_SIZEREDRAW,                     /* Class style                  */
  28.      0);                                /* No extra window words        */
  29.  
  30.   flCreate = FCF_SYSMENU | FCF_MENU | FCF_TITLEBAR | FCF_SIZEBORDER |
  31.              FCF_MINMAX  | FCF_ICON | FCF_TASKLIST;
  32.  
  33.  
  34.    hwndFrame = WinCreateStdWindow(
  35.                HWND_DESKTOP,            /* Desktop window is parent     */
  36.                0L,                      /* No frame styles              */
  37.                &flCreate,               /* Frame control flag           */
  38.                "DDESAMP",               /* Client window class name     */
  39.                "",                      /* No window text               */
  40.                0L,                      /* No special class style       */
  41.                0,                       /* Resource is in .EXE file     */
  42.                ID_WINDOW,               /* Frame window identifier      */
  43.                &hwndClient              /* Client window handle         */
  44.                );
  45.  
  46.   WinSetWindowPos( hwndFrame,           /* Shows and activates frame    */
  47.                    HWND_TOP,            /* window at position 100, 100, */
  48.                    100, 100, 200, 200,  /* and size 200, 200.           */
  49.                    SWP_SIZE | SWP_MOVE | SWP_ACTIVATE | SWP_SHOW
  50.                  );
  51.  
  52.   while( WinGetMsg( hab, &qmsg, 0, 0, 0 ) )
  53.     WinDispatchMsg( hab, &qmsg );
  54.  
  55.   WinDestroyWindow( hwndFrame );        /* Tidy up...                   */
  56.   WinDestroyMsgQueue( hmq );            /* and                          */
  57.   WinTerminate( hab );                  /* terminate the application    */
  58. }
  59.  
  60. MRESULT EXPENTRY DdeSampleWndProc( HWND hwnd, MSG msg, MPARAM mp1, MPARAM mp2 )
  61. {
  62.   HPS            hps;              /* Presentation Space handle    */
  63.   RECTL          rc;               /* Rectangle coordinates        */
  64.   POINTL         pt;               /* String screen coordinates    */
  65.   PDDECLIENTINFO pDDEClientInfo;   /* Client Info Structure        */
  66.  
  67.  
  68.   //Get pointer to DDEClientInfo Struct stored in window ULong
  69.   pDDEClientInfo = (PDDECLIENTINFO) WinQueryWindowULong(
  70.                                            WinQueryWindow(hwnd, QW_PARENT),
  71.                                            QWL_USER);
  72.  
  73.   switch( msg )
  74.   {
  75.  
  76.  
  77.          /*──────────────────────────────────────────────────────────────────┐
  78.          │Allocate memory for DDEClientInfo Structure. If memory allocation  │
  79.          │fails terminate application. If successful set bConnected field to │
  80.          │FALSE, and set the window ulong to pDDEClientInfo.                 │
  81.          └──────────────────────────────────────────────────────────────────*/
  82.  
  83.     case WM_CREATE:
  84.          {
  85.             LONG rc;
  86.  
  87.             rc = DosAllocMem((PPVOID)&pDDEClientInfo,
  88.                               sizeof(DDECLIENTINFO),
  89.                               PAG_READ | PAG_WRITE | PAG_COMMIT);
  90.  
  91.             if(rc){
  92.                WinPostMsg(hwnd, WM_QUIT, 0, 0);
  93.                return ((MRESULT)1);
  94.             }  else {
  95.                pDDEClientInfo->bConnected = FALSE;
  96.                WinSetWindowULong(WinQueryWindow(hwnd,QW_PARENT), QWL_USER, (ULONG)pDDEClientInfo);
  97.             }
  98.          }
  99.          break;
  100.  
  101.  
  102.          /*─────────────────────────────────────────────────────────────────────┐
  103.          │This message is sent if a DDE Server has responded to our request to  │
  104.          │initiate a DDE conversation. Check the pszAppName and pszTopic fields │
  105.          │of pDdeInit to make sure that the Server that responded has the       │
  106.          │correct name and topic.                                               │
  107.          └─────────────────────────────────────────────────────────────────────*/
  108.     case WM_DDE_INITIATEACK:
  109.          {
  110.             PDDEINIT pDdeInit = (PDDEINIT)mp2;
  111.             if(((HWND)mp1 != hwnd) &&
  112.                (!pDDEClientInfo->bConnected) &&
  113.                !strcmp(pDdeInit->pszAppName, EPMDDEAPPNAME) &&
  114.                !strcmp(pDdeInit->pszTopic,   EPM_DDE_TOPIC) )
  115.             {
  116.                pDDEClientInfo->hwndDDEServer = (HWND)mp1;
  117.                pDDEClientInfo->bConnected = TRUE;
  118.                DosFreeMem(mp2);
  119.                DosBeep(200, 200);
  120.                return((MPARAM)1);
  121.             }
  122.          }
  123.          break;
  124.  
  125.  
  126.          /*────────────────────────────────────────────────────────────────────┐
  127.          │WM_DDE_ACK is sent whenever the DDE Server responds to a previously  │
  128.          │sent WM_DDE_*  message. Check mp2(hwnd of the Responding server), to │
  129.          │see if it matches the hwnd of the DDE Server we are currently        │
  130.          │connected to. If it is the correct server store the status, and      │
  131.          │Free the giveable mem that was  allocated.                           │
  132.          └────────────────────────────────────────────────────────────────────*/
  133.     case WM_DDE_ACK:
  134.          {
  135.             PDDESTRUCT pDdeStruct = (PDDESTRUCT)mp2;
  136.             if(pDDEClientInfo->hwndDDEServer != (HWND)mp1) {
  137.                return WinDefWindowProc( hwnd, msg, mp1, mp2 );
  138.             }
  139.             pDDEClientInfo->usAck = pDdeStruct->fsStatus;
  140.             DosFreeMem(pDdeStruct);
  141.             return((MRESULT)1);
  142.          }
  143.          break;
  144.  
  145.  
  146.         /*───────────────────────┐
  147.         │ Process the menu items │
  148.         └───────────────────────*/
  149.     case WM_COMMAND:
  150.          {
  151.  
  152.             switch(SHORT1FROMMP(mp1)) {
  153.  
  154.  
  155.  
  156.                     /*───────────────────────────────────────────────────┐
  157.                     │Broadcast a message to all top level windows in the │
  158.                     │system, requesting a DDE server named EPMDDEAPPNAME,│
  159.                     │who will handle the topic named EPM_DDE_TOPIC.      │
  160.                     │Return if we are already connected to a DDE Server. │
  161.                     └───────────────────────────────────────────────────*/
  162.  
  163.                case ID_INIT_DDE:
  164.                   {
  165.                       CONVCONTEXT ConvContext;
  166.                       memset(&ConvContext, 0, sizeof(CONVCONTEXT));
  167.                       ConvContext.cb = sizeof(CONVCONTEXT);
  168.                       if(!pDDEClientInfo->bConnected) {
  169.                          WinDdeInitiate(hwnd, EPMDDEAPPNAME, EPM_DDE_TOPIC, &ConvContext);
  170.                       }
  171.                       return((MRESULT)1);
  172.                   }
  173.                   break;
  174.  
  175.  
  176.                     /*────────────────────────────────────────────────────────┐
  177.                     │Send a Command to the connected DDE Server. Put the      │
  178.                     │EPM edit command string in EditCommand,           and    │
  179.                     │call MakeDDEMsg() to set up the pDdeStruct we need to    │
  180.                     │send. Post the message WM_DDE_EXECUTE to the server with │
  181.                     │pDdeStruct.                                              │
  182.                     └────────────────────────────────────────────────────────*/
  183.  
  184.                case ID_SEND_COMMAND:
  185.                   {
  186.                      COMMANDDLGSTRUCT CommandDlgStruct;
  187.                      UCHAR              EditCommand[200];
  188.                      PDDESTRUCT       pDdeStruct;
  189.  
  190.                      //Don't send any commands unless we are connected to the EPM Server
  191.                      if(!pDDEClientInfo->bConnected) {
  192.                         return((MPARAM)1);
  193.                      }
  194.  
  195.                      CommandDlgStruct.Size = sizeof(COMMANDDLGSTRUCT);
  196.                      WinDlgBox(HWND_DESKTOP, WinQueryWindow(hwnd, QW_PARENT), CommandDlgBox, (HMODULE)NULL, IDD_COMMAND, &CommandDlgStruct);
  197.                      strcpy(EditCommand, CommandDlgStruct.Buffer);
  198.                      pDdeStruct = MakeDDEMsg(DDEFMT_TEXT, DDE_ITEM_EDIT_COMMAND,
  199.                                                 &EditCommand, sizeof(EditCommand));
  200.                      WinDdePostMsg(pDDEClientInfo->hwndDDEServer, hwnd, WM_DDE_EXECUTE, pDdeStruct, TRUE);
  201.                   }
  202.                   break;
  203.  
  204.                    /*───────────────────────────────────────────────────────┐
  205.                    │Terminate the current DDE conversation if one currently │
  206.                    │exists.                                                 │
  207.                    └───────────────────────────────────────────────────────*/
  208.  
  209.               case ID_TERMINATE_DDE:
  210.                  {
  211.                      if(pDDEClientInfo->bConnected) {
  212.                         WinDdePostMsg(pDDEClientInfo->hwndDDEServer, hwnd, WM_DDE_TERMINATE, NULL, TRUE);
  213.                         pDDEClientInfo->bConnected = 0;
  214.                      }
  215.                      return((MRESULT)1);
  216.                  }
  217.                  break;
  218.  
  219.  
  220.                    /*───────────────────────┐
  221.                    │ Close the application. │
  222.                    └───────────────────────*/
  223.               case ID_EXITPROG:
  224.                  WinPostMsg(hwnd, WM_CLOSE, (MPARAM)0, (MPARAM)0);
  225.                  break;
  226.  
  227.             }
  228.          }
  229.          break;
  230.  
  231.          /*────────────────────────────────────────────────────────────────────┐
  232.          │WM_DDE_TERMINATE is sent to us in reponse to a WM_DDE_TERMINATE that │
  233.          │we sent to the server, or as a server request to terminate the       │
  234.          │DDE connection. If pDDEClientInfo->bConnected is TRUE the server is  │
  235.          │requesting to terminate the conversation. In this case respond to    │
  236.          │the terminate request by sending WM_DDE_TERMINATE and setting        │
  237.          │pDDEClientInfo->bConnect to FALSE. If we are not connected then      │
  238.          │this a response from our request to terminate the connection.        │
  239.          │In this case do nothing.                                             │
  240.          └────────────────────────────────────────────────────────────────────*/
  241.  
  242.  
  243.     case WM_DDE_TERMINATE:
  244.          {
  245.             if(pDDEClientInfo->bConnected) {
  246.                WinDdePostMsg(pDDEClientInfo->hwndDDEServer, hwnd, WM_DDE_TERMINATE, NULL, FALSE);
  247.                pDDEClientInfo->bConnected = FALSE;
  248.             }
  249.          }
  250.          break;
  251.  
  252.          /*────────────────────────────────────────────────────────────┐
  253.          │Data is sent back from the EPM window. Display the item name │
  254.          │and the data in a message box.                               │
  255.          └────────────────────────────────────────────────────────────*/
  256.  
  257.     case WM_DDE_DATA:
  258.          {
  259.            if( pDDEClientInfo->bConnected &&
  260.                  ((HWND)mp1==pDDEClientInfo->hwndDDEServer)) {
  261.               PDDESTRUCT pDdeStruct = (PDDESTRUCT)mp2;
  262.               PSZ ItemName;
  263.               PSZ Data;
  264.               UCHAR MessageString[300];
  265.               if(pDdeStruct->usFormat == DDEFMT_TEXT) {
  266.                     ItemName = ((PSZ)pDdeStruct+pDdeStruct->offszItemName);
  267.                     Data     = ((PSZ)pDdeStruct+pDdeStruct->offabData);
  268.               }
  269.               sprintf(MessageString,"The Item String is '%s', The Data String is '%s'",
  270.                       ItemName, Data);
  271.               WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, MessageString, "WM_DDE_DATA Message Received",
  272.                             100, MB_OK);
  273.               if(pDdeStruct->fsStatus == DDE_FACKREQ) {
  274.                  WinDdePostMsg(pDDEClientInfo->hwndDDEServer,
  275.                                hwnd,
  276.                                WM_DDE_ACK,pDdeStruct,TRUE);
  277.  
  278.               }
  279.            }
  280.          }
  281.  
  282.  
  283.          /*───────────────────────────────────────────────────────┐
  284.          │Return TRUE to request PM to paint the window background│
  285.          │in SYSCLR_WINDOW.                                       │
  286.          └───────────────────────────────────────────────────────*/
  287.     case WM_ERASEBACKGROUND:
  288.          return (MRESULT)( TRUE );
  289.  
  290.  
  291.     case WM_PAINT:
  292.          hps = WinBeginPaint( hwnd, 0, &rc );  // Create a presentation space
  293.          pt.x = 50; pt.y = 50;                    // Set the text coordinates,
  294.          GpiSetColor( hps, CLR_NEUTRAL );         // colour of the text,
  295.          GpiSetBackColor( hps, CLR_BACKGROUND );  // its background and
  296.          GpiSetBackMix( hps, BM_OVERPAINT );      // how it mixes,
  297.                                                   // and draw the string...
  298.          WinEndPaint( hps );                      // Drawing is complete
  299.          break;
  300.  
  301.  
  302.          /*────────────────────────────────────────────────────────────┐
  303.          │If the application is closing make sure that we terminate an │
  304.          │existing DDE connection.                                     │
  305.          └────────────────────────────────────────────────────────────*/
  306.     case WM_CLOSE:
  307.          if(pDDEClientInfo->bConnected) {
  308.             WinDdePostMsg(pDDEClientInfo->hwndDDEServer, hwnd, WM_DDE_TERMINATE, NULL, TRUE);
  309.             pDDEClientInfo->bConnected = 0;
  310.          }
  311.          WinPostMsg( hwnd, WM_QUIT, 0L, 0L );  //Cause termination
  312.          break;
  313.  
  314.     default:
  315.          return WinDefWindowProc( hwnd, msg, mp1, mp2 );
  316.   }
  317.   return FALSE;
  318. }
  319.  
  320.  
  321.  
  322. /*─────────────────────────────────────────────────────────────────────────────────────┐
  323. │    MAKEDDEReqSeg()                                                                   │
  324. │                                                                                      │
  325. │        This procedure is used to allocate and fill in a PDDESTRUCT variable          │
  326. │        with information that we want to send in our next message that                │
  327. │        we send to the DDE server we are connected to.                                │
  328. │                                                                                      │
  329. │        Parameters:                                                                   │
  330. │            usFormat:  Format of the Data being sent.                                 │
  331. │                       When communicating with EPM this field is always               │
  332. │                       DDEFMT_TEXT.                                                   │
  333. │            pszItemName: Name of the data item being sent. We issuing an              │
  334. │                         Edit Command to EPM. This will always be DDE_ITEM_EDIT.      │
  335. │                                                                                      │
  336. │            Data:        This is a pointer to the Data that you want to send          │
  337. │                         in you DDE message. When sending a DDE_ITEM_EDIT item        │
  338. │                         this will always be an edit command string.                  │
  339. │                                                                                      │
  340. │            usDataSize:  The size of the Data item being sent.                        │
  341. │                                                                                      │
  342. └─────────────────────────────────────────────────────────────────────────────────────*/
  343.  
  344. PDDESTRUCT MakeDDEMsg(USHORT usFormat,PSZ pszItemName,PVOID Data, USHORT usDataSize)
  345. {
  346.   PDDESTRUCT pdde = (PDDESTRUCT)0;
  347.   ULONG      rc   = 0;
  348.   ULONG     usSegSize;
  349.   ULONG     totalsize;
  350.  
  351.   /**************************************************************************/
  352.   /* 1) Allocate  givable shared memory                                     */
  353.   /**************************************************************************/
  354.  
  355.   usSegSize = (USHORT)strlen(pszItemName)+1;
  356.   totalsize = sizeof(DDESTRUCT)+usDataSize+usSegSize;
  357.  
  358.   rc = DosAllocSharedMem((PPVOID)&pdde,
  359.                          (PSZ)0,
  360.                          totalsize,
  361.                          PAG_READ | PAG_WRITE | PAG_COMMIT | OBJ_TILE
  362.                          | OBJ_GIVEABLE | OBJ_GETTABLE);
  363.  
  364.   if (rc) {
  365.     return  ((PDDESTRUCT)0);
  366.   }
  367.  
  368.  
  369.   /**************************************************************************/
  370.   /* 2) Fill in the new DDE structure                                       */
  371.   /**************************************************************************/
  372.  
  373.   memset((PVOID)pdde, 0, (size_t)usSegSize); // zero out memory
  374.   pdde->usFormat = usFormat;
  375.   pdde->offszItemName = (USHORT)sizeof(DDESTRUCT);
  376.   memcpy(DDES_PSZITEMNAME(pdde), pszItemName,usSegSize);
  377.   pdde->offabData = (USHORT)sizeof(DDESTRUCT)+usSegSize;
  378.   memcpy(DDES_PABDATA(pdde), Data,usDataSize);
  379.   pdde->fsStatus = 0;           // set status flags
  380.   pdde->cbData = (ULONG)totalsize;
  381.   return  pdde;
  382. }
  383.  
  384.  
  385. /*───────────────────────────────────────────────────────────────────────────┐
  386. │    CommandDlgBox                                                           │
  387. │                                                                            │
  388. │        Simple Command Dialog Box used to retrieve Edit commands that the   │
  389. │        user want to send to the connected EPM DDE server.                  │
  390. └───────────────────────────────────────────────────────────────────────────*/
  391.  
  392. MRESULT EXPENTRY CommandDlgBox(HWND hwndDlg, MSG msg, MPARAM mp1, MPARAM mp2)
  393. {
  394.    PCOMMANDDLGSTRUCT CommandDlgStruct;
  395.  
  396.    switch(msg) {
  397.       case WM_INITDLG:
  398.            WinSetWindowULong(hwndDlg, QWL_USER, (ULONG)mp2);
  399.            return((MPARAM)0);
  400.       case WM_COMMAND:
  401.            {
  402.               switch(LOUSHORT(mp1)) {
  403.                  case IDD_OK:
  404.                       CommandDlgStruct = (PCOMMANDDLGSTRUCT)WinQueryWindowULong(hwndDlg, QWL_USER);
  405.                       WinQueryDlgItemText(hwndDlg, IDD_ENTRYFIELD, MAXLEN, CommandDlgStruct->Buffer);
  406.                       WinDismissDlg(hwndDlg, (USHORT)0);
  407.                       break;
  408.                    case IDD_CANCEL:
  409.                       CommandDlgStruct = (PCOMMANDDLGSTRUCT)WinQueryWindowULong(hwndDlg, QWL_USER);
  410.                       CommandDlgStruct->Buffer[0] = 0;
  411.                       WinDismissDlg(hwndDlg, 0);
  412.                       break;
  413.               }
  414.            }
  415.            break;
  416.       default:
  417.            return((MRESULT)WinDefDlgProc(hwndDlg, msg, mp1, mp2));
  418.    }
  419.    return((MPARAM)0);
  420. }
  421.