home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / DDE21.ZIP / CLIENT / CLIENT.C next >
Text File  |  1993-04-09  |  16KB  |  468 lines

  1. /*
  2.   $Workfile:   client.c  $
  3.   $Revision:   1.1.1.0  $
  4.   $Date:   09 May 1991 18:10:02  $
  5.   $Logfile:   W:/dde/client.c_v  $
  6.   $Author:   mikem  $
  7.   $Modtime:   09 May 1991 18:07:04  $
  8.  
  9.    Sample Client DDE application
  10.    Copyright (C) Personal Systems Developer, IBM Corporation 1991
  11.    Author: Michael R. MacFaden
  12.    Internet: macfaden@paloic1.vnet.ibm.com
  13.  
  14. */
  15.  
  16. #pragma  comment(compiler)
  17. #pragma  comment(user, "Copyright (C) IBM Corp 1991")
  18.  
  19. #define  INCL_WIN       
  20. #define  INCL_ERRORS    
  21. #define  INCL_DOS
  22. #include <os2.h>       
  23. #include <stdio.h>       
  24. #include <string.h>     
  25. #include "pmutils.h"
  26. #include "client.h"
  27.  
  28. MRESULT EXPENTRY ClientWndProc(HWND,USHORT,MPARAM,MPARAM);
  29. VOID EXPENTRY PaintWindow(HWND hwnd,CHAR *szMsg);
  30. PDDESTRUCT EXPENTRY MakeDDEReqSeg(USHORT usFormat,PSZ pszItemName,BOOL fAck);
  31. MRESULT EXPENTRY InitDlgProc(HWND hwnd,USHORT msg,MPARAM mp1,MPARAM mp2);
  32. MRESULT EXPENTRY AboutDlgProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2);
  33.  
  34. /* globals */
  35. #define  MAX_MSG_SZ    300             // max size of text string
  36. CHAR szClientClass[] = "DDE-Sample";
  37. CHAR szBuf[MAX_MSG_SZ+1];                       // formatting buffer
  38. HWND hwndFrame,hwndClient,hwndMenu,hwndDDEserver;
  39. USHORT cbDDEMsg;                       // length of message
  40. BOOL fConnected = FALSE;               // status of a DDE conversation
  41. BOOL fAdvise = FALSE;                  // status of hot link
  42.  
  43. INT main()
  44. {
  45.   static ULONG flFrameFlags = FCF_TITLEBAR|FCF_SYSMENU|FCF_SIZEBORDER|
  46.      FCF_MINMAX|FCF_TASKLIST|FCF_MENU;
  47.   HAB hab = (ULONG ) 0;
  48.   HMQ hmq = (ULONG ) 0;
  49.   QMSG qmsg;
  50.  
  51.   hab = WinInitialize(0);
  52.   hmq = WinCreateMsgQueue(hab, 0);
  53.   if(!WinRegisterClass(hab, szClientClass,(PFNWP)ClientWndProc,0,0))
  54.    {
  55.       WinAlarm(HWND_DESKTOP, WA_ERROR);        /* Register failed */
  56.       DosExit(EXIT_PROCESS,1);
  57.    }
  58.    hwndFrame = 0;
  59.    hwndFrame = WinCreateStdWindow(HWND_DESKTOP, WS_VISIBLE,
  60.                                   &flFrameFlags, szClientClass, szClientClass,
  61.                                   0, (HMODULE)0, ID_MAINWND, &hwndClient);
  62.    if(!hwndFrame)
  63.    {
  64.       WinAlarm(HWND_DESKTOP, WA_ERROR); /* Window create failed */
  65.       DosExit(EXIT_PROCESS,1);
  66.    }
  67.  
  68.  /* Use default system icon */
  69.   WinSendMsg(hwndFrame, WM_SETICON, (MPARAM)WinQuerySysPointer(HWND_DESKTOP, 
  70.     SPTR_APPICON, FALSE), NULL);
  71.  
  72.  while(WinGetMsg(hab,&qmsg,0,0,0))        /* Message loop */
  73.     WinDispatchMsg(hab,&qmsg);
  74.  
  75.   WinDestroyWindow(hwndFrame);     /* clean up */
  76.   WinDestroyMsgQueue(hmq);
  77.   WinTerminate(hab);
  78.   return 0;
  79.  
  80.  
  81. MRESULT EXPENTRY ClientWndProc(HWND hwnd,USHORT msg,MPARAM mp1,MPARAM mp2)
  82. {
  83.   static DDECONV ddec;              // DDE Server name and requested topic
  84.   static CHAR szDDEItemName[CV_MAXDDENAME]; // DDE item (piece of data) in topic format
  85.   static CHAR szMsg[MAX_MSG_SZ];       // text string
  86.   static USHORT usItem = 0;            // Menu item
  87.   PDDEINIT pddei = NULL;               // DDE init struct ptr
  88.   PDDESTRUCT pdde = NULL,pddeOut = NULL; // DDE Transaction struct ptr
  89.   static CONVCONTEXT Context;
  90.  
  91.   switch (msg)
  92.     {
  93.     case  WM_CREATE :
  94.       hwndFrame = WinQueryWindow(hwnd, QW_PARENT);
  95.       hwndMenu = WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT), (USHORT)FID_MENU);
  96.  
  97.       strcpy(ddec.szDDEServerName, CV_DDEAPPNAME);
  98.       strcpy(ddec.szDDETopicName, CV_DDETOPIC);
  99.       strcpy(szDDEItemName, CV_DDEITEMSG);
  100.       WinSetWindowText(hwndFrame, "...Not Connected...");
  101.       /* position window on users screen */
  102.       WinSetWindowPos(hwndFrame,HWND_TOP,
  103.         50,50,    /* window position (x,y) */
  104.         250,250,  /* window size (width/height) */
  105.         SWP_SIZE | SWP_MOVE | SWP_SHOW);
  106.       return 0;
  107.  
  108.     case  WM_COMMAND :
  109.       switch (SHORT1FROMMP(mp1))
  110.         {
  111.         case  IDM_STARTCONV :
  112.           if (WinDlgBox(HWND_DESKTOP,
  113.                         hwndFrame,
  114.                         (PFNWP) InitDlgProc,
  115.                         0, 
  116.                         IDD_INIT_DLG,
  117.                         &ddec))
  118.             if (!WinDdeInitiate(hwnd, ddec.szDDEServerName, 
  119.                ddec.szDDETopicName, &Context))
  120.               {
  121.               WinAlarm(HWND_DESKTOP, WA_ERROR);
  122.               WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, 
  123.                  "WinDdeInitiate() failed!", "API Failure", 1, MB_OK|
  124.                  MB_ICONEXCLAMATION|MB_APPLMODAL|MB_MOVEABLE);
  125.               } 
  126.           return 0;
  127.  
  128.         case  IDM_STOPCONV :
  129.           WinDdePostMsg(hwndDDEserver, hwnd, WM_DDE_TERMINATE, NULL, TRUE);
  130.           EnableMenuItem(hwndMenu, IDM_REQUEST, FALSE);
  131.           EnableMenuItem(hwndMenu, IDM_ADVISE, FALSE);
  132.           EnableMenuItem(hwndMenu, IDM_ENDADVISE, FALSE);
  133.           EnableMenuItem(hwndMenu, IDM_STOPCONV, FALSE);
  134.           EnableMenuItem(hwndMenu, IDM_STARTCONV, TRUE);
  135.           hwndDDEserver = (HWND) NULL;        // store client window handle
  136.           WinSetWindowText(hwndFrame, "...Not Connected...");
  137.               fConnected = FALSE;
  138.           return 0;
  139.  
  140.         case  IDM_REQUEST :
  141.           /* if a conversation on the System topic is esablished,
  142.            issuing a request causes the current status to be retrieved
  143.           */
  144.               if (strcmp("System", ddec.szDDETopicName) == 0)
  145.                 pdde = MakeDDEReqSeg(CF_TEXT, "Status", 0);
  146.               else      
  147.                  pdde = MakeDDEReqSeg(CF_TEXT, szDDEItemName, 0);
  148.           if (pdde)
  149.             {
  150.             WinDdePostMsg(hwndDDEserver, hwnd, WM_DDE_REQUEST, pdde, TRUE);
  151.             usItem = IDM_REQUEST;
  152.             } 
  153.           else
  154.             {
  155.             WinAlarm(HWND_DESKTOP, WA_ERROR);
  156.             WinSetWindowText(hwndFrame, "...MakeDDEReqSeg() failed..");
  157.             break;
  158.             }
  159.           return 0;
  160.  
  161.         case  IDM_ADVISE :
  162.           fAdvise = TRUE;
  163.           pddeOut = MakeDDEReqSeg(CF_TEXT, szDDEItemName, DDE_FACKREQ);
  164.           if (pddeOut)
  165.             {
  166.             WinDdePostMsg(hwndDDEserver, hwnd, WM_DDE_ADVISE, pddeOut, TRUE);
  167.             WinSetWindowText(hwndFrame, "...sent hot link request...");
  168.             EnableMenuItem(hwndMenu, IDM_ADVISE, FALSE);
  169.             } 
  170.           usItem = IDM_ADVISE;
  171.           break;
  172.  
  173.         case  IDM_ENDADVISE :
  174.           fAdvise = FALSE;
  175.           pddeOut = MakeDDEReqSeg(CF_TEXT, szDDEItemName, DDE_FACKREQ);
  176.           if (pddeOut)
  177.             {
  178.             WinDdePostMsg(hwndDDEserver, hwnd, WM_DDE_UNADVISE, pddeOut, 
  179.                TRUE);
  180.             WinSetWindowText(hwndFrame, "...sent hot link terminate request...");
  181.             usItem = IDM_ENDADVISE;
  182.             } 
  183.           break;
  184.  
  185.         case IDM_ABOUT:
  186.           WinDlgBox (HWND_DESKTOP, hwnd, (PFNWP) AboutDlgProc,
  187.                      (HMODULE) NULL, IDD_ABOUT, NULL) ;
  188.           return 0 ;
  189.  
  190.         } 
  191.       break; /* wm_command */
  192.  
  193.     case  WM_DDE_INITIATEACK :
  194.       WinAlarm(HWND_DESKTOP, WA_NOTE);
  195.       if (hwndDDEserver != (HWND)mp1 && fConnected) // is this our server
  196.         {
  197.         WinDdePostMsg((HWND)mp1, hwnd, WM_DDE_TERMINATE, NULL, TRUE);
  198.             break;
  199.         } 
  200.  
  201.       pddei = (PDDEINIT)mp2;           // MS V2 PG 430
  202.       if (!strcmp(ddec.szDDEServerName, pddei->pszAppName))
  203.         {
  204.         if (!strcmp(ddec.szDDETopicName, pddei->pszTopic))
  205.           {
  206.           hwndDDEserver = (HWND)mp1;   // store client window handle
  207.           EnableMenuItem(hwndMenu, IDM_STARTCONV, FALSE);
  208.           EnableMenuItem(hwndMenu, IDM_STOPCONV, TRUE);
  209.           EnableMenuItem(hwndMenu, IDM_REQUEST, TRUE);
  210.           EnableMenuItem(hwndMenu, IDM_ADVISE, TRUE);
  211.           WinSetWindowText(hwndFrame, "Connected...");
  212.           fConnected = TRUE;
  213.           } 
  214.         } 
  215.       break;
  216.  
  217.     case  WM_DDE_ACK :                 /* server sent DDE Acknowledgement   */
  218.       pdde = (PDDESTRUCT)mp2;
  219.       if (!pdde)
  220.         break;
  221.  
  222.       switch (usItem)                 // what was this ack in response to?
  223.         {
  224.         case  IDM_ADVISE :
  225.           if (pdde->fsStatus & DDE_FACK)
  226.             {
  227.             EnableMenuItem(hwndMenu, usItem, FALSE);
  228.             EnableMenuItem(hwndMenu, IDM_REQUEST, FALSE);
  229.             EnableMenuItem(hwndMenu, IDM_ENDADVISE, TRUE);
  230.             } 
  231.           else
  232.             {
  233.             EnableMenuItem(hwndMenu, usItem, TRUE);
  234.             EnableMenuItem(hwndMenu, IDM_REQUEST, TRUE);
  235.             EnableMenuItem(hwndMenu, IDM_ENDADVISE, FALSE);
  236.                 fAdvise = FALSE;
  237.             } 
  238.           break;
  239.  
  240.         case  IDM_ENDADVISE :
  241.           if (pdde->fsStatus & DDE_FACK)
  242.             {
  243.             EnableMenuItem(hwndMenu, usItem, FALSE);
  244.             EnableMenuItem(hwndMenu, IDM_REQUEST, TRUE);
  245.             EnableMenuItem(hwndMenu, IDM_ADVISE, TRUE);
  246.             } 
  247.           break;
  248.  
  249.         case  IDM_REQUEST :
  250.           if (!(pdde->fsStatus&DDE_FACK))
  251.             WinAlarm(HWND_DESKTOP, WA_ERROR);
  252.           break;
  253.         }                              // switch()
  254.       break;
  255.  
  256.     case  WM_DDE_DATA :                // server sent a chunk of data
  257.       if (hwndDDEserver != (HWND)mp1) // ignore responses from other servers
  258.         break;
  259.       pdde = (PDDESTRUCT)mp2;
  260.       if (!pdde)                       // check ptr
  261.         break;
  262.       // write incomming text message to screen
  263.       strcpy(szMsg, (PSZ)DDES_PABDATA(pdde)); // Extract data
  264.       if (strlen(szMsg) == 0)
  265.         strcpy(szMsg, "<no text message from server>");
  266.       PaintWindow(hwnd, szMsg);
  267.       WinInvalidateRect(hwnd, NULL, FALSE);
  268.  
  269.       if (pdde->fsStatus&DDE_FACKREQ)  // does server requre ack?
  270.         {
  271.         pddeOut = MakeDDEReqSeg(CF_TEXT, szDDEItemName, DDE_FACK);
  272.         if (pddeOut)
  273.           {
  274.           WinDdePostMsg(hwndDDEserver, hwnd, WM_DDE_ACK, pdde, TRUE);
  275.           } 
  276.         } 
  277.       break;
  278.  
  279.     case  WM_CLOSE :
  280.       if (hwndDDEserver)
  281.         WinDdePostMsg(hwndDDEserver, hwnd, WM_DDE_TERMINATE, NULL, TRUE);
  282.       WinPostMsg(hwnd, WM_QUIT, 0L, 0L);
  283.       return 0;
  284.  
  285.     case  WM_PAINT :
  286.       PaintWindow(hwnd, szMsg);
  287.       return 0;
  288.  
  289.     case  WM_DDE_TERMINATE :
  290.       if (hwndDDEserver != (HWND)mp1) // ignore responses from other servers
  291.         break;
  292.       EnableMenuItem(hwndMenu, IDM_STARTCONV, TRUE);
  293.       EnableMenuItem(hwndMenu, IDM_STOPCONV, FALSE);
  294.          if (fAdvise)
  295.       EnableMenuItem(hwndMenu, IDM_ENDADVISE, FALSE);
  296.       hwndDDEserver =(HWND) NULL;            // store client window handle
  297.       WinSetWindowText(hwndFrame, "...Not Connected...");
  298.       fConnected = FALSE;
  299.       break;
  300.  
  301.     case  WM_ERASEBACKGROUND :
  302.       return (MRESULT)1;
  303.     } 
  304.   return  WinDefWindowProc(hwnd, msg, mp1, mp2);
  305. }
  306.  
  307. /*
  308. Pre - hwnd is a valid window handle, szMsg is a null terminated string (PSZ)
  309. Post - writes szMsg in hwnd centered vertically and horizontally
  310. */
  311.  
  312. VOID EXPENTRY PaintWindow(HWND hwnd,CHAR *szMsg)
  313. {
  314.   HPS hps = NULL;
  315.   RECTL rcl;
  316.  
  317.   hps = WinBeginPaint(hwnd, (HPS)NULL, NULL);
  318.   if (!hps)
  319.     return ;
  320.   WinQueryWindowRect(hwnd, &rcl);
  321.   WinDrawText(hps, -1, szMsg, &rcl, CLR_NEUTRAL, CLR_BACKGROUND, DT_CENTER|
  322.      DT_VCENTER|DT_ERASERECT);
  323.  
  324.   WinEndPaint(hps);
  325. } // PaintWindow()
  326.  
  327. /*
  328. Pre  - this routine is called directly by PM
  329. Post - handles all window processing for dialog box: IDD_INIT_DLG
  330. */
  331.  
  332. MRESULT EXPENTRY InitDlgProc(HWND hwnd,USHORT msg,MPARAM mp1,MPARAM mp2)
  333. {
  334.   static PDDECONV pddec = NULL;        // ptr to dde server name and topic
  335.   static HWND hwndServer = NULL,hwndTopic = NULL; // text entry window handles
  336.  
  337.   switch (msg)
  338.     {
  339.     case  WM_INITDLG :
  340.       pddec = MPFROMP(mp2);
  341.       if (pddec == NULL)
  342.         {
  343.         WinMessageBox(HWND_DESKTOP, hwndClient, "Invalid pointer", 
  344.            "PMMSG - Error", 10, MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL|
  345.            MB_MOVEABLE);
  346.         return (MRESULT)WinDismissDlg(hwnd, FALSE);
  347.         } 
  348.       /* 1. Set up text entry field default strings and lengths */
  349.       SetEFTextLength(hwnd, ID_SERVER_CBX, CV_MAXDDENAME);
  350.       SetEFTextLength(hwnd, ID_TOPIC_CBX, CV_MAXTOPICNAME);
  351.       hwndServer = WinWindowFromID(hwnd, ID_SERVER_CBX);
  352.       if (hwndServer)
  353.         {
  354.         WinSetWindowText(hwndServer, pddec->szDDEServerName);
  355.         WinSendMsg(hwndServer, EM_SETSEL,  // highlight for easy discard
  356.            MPFROM2SHORT((USHORT)0, (USHORT)CV_MAXDDENAME), (MPARAM)0);
  357.         /* insert app name into combo box */
  358.         WinSendMsg(hwndServer, LM_INSERTITEM, MPFROMSHORT((SHORT) LIT_END),
  359.            MPFROMP(pddec->szDDEServerName));
  360.         } 
  361.       hwndTopic = WinWindowFromID(hwnd, ID_TOPIC_CBX);
  362.       if (hwndTopic)
  363.         {
  364.         // 2. Enter default topics into combo box
  365.         WinSendMsg(hwndTopic, LM_INSERTITEM, MPFROMSHORT((SHORT) LIT_END), MPFROMP(CV_DDETOPIC));
  366.         WinSendMsg(hwndTopic, LM_INSERTITEM, MPFROMSHORT((SHORT) LIT_END), MPFROMP(SZDDESYS_TOPIC));
  367.         WinSetWindowText(hwndTopic, pddec->szDDETopicName);
  368.         }
  369.       return 0;  /* wm_initdlg */
  370.  
  371.     case  WM_COMMAND :
  372.       switch (SHORT1FROMMP(mp1))
  373.         {
  374.         case  DID_OK :
  375.            // obtain new values to use 
  376.           WinQueryWindowText(hwndServer, CV_MAXDDENAME,  
  377.              pddec->szDDEServerName);
  378.           WinQueryWindowText(hwndTopic, CV_MAXTOPICNAME,  
  379.              pddec->szDDETopicName);
  380.           return (MRESULT)WinDismissDlg(hwnd, TRUE);
  381.  
  382.         case  DID_CANCEL :
  383.           return (MRESULT)WinDismissDlg(hwnd, FALSE);
  384.  
  385.         }                              // wm_command
  386.       break;
  387.  
  388.     case  WM_SYSCOMMAND :              // process dlg box system menu
  389.       switch (LOUSHORT(mp1))
  390.         {
  391.         case  SC_CLOSE :
  392.           return (MRESULT)WinDismissDlg(hwnd, FALSE);
  393.  
  394.         default  :
  395.           return  WinDefDlgProc(hwnd, msg, mp1, mp2);
  396.         }                              // wm_syscommand
  397.  
  398.       break;                           // wm_syscommand
  399.     }                                  // switch()
  400.   return  WinDefDlgProc(hwnd, msg, mp1, mp2);
  401. }                                      // InitDlgProc()
  402.  
  403. /*
  404. Pre - format, item name, and fsStatus are valid
  405. Post - a valid data segment for WM_DDE_REQUEST message is built
  406.        and a pddestruct is returned else (error) null is returned
  407. */
  408.  
  409. PDDESTRUCT EXPENTRY MakeDDEReqSeg(USHORT usFormat,PSZ pszItemName,BOOL fsStatus)
  410. {
  411.   PULONG pulSharedObj = NULL;     /* pointer to shared object */
  412.   PDDESTRUCT pdde = NULL;
  413.   ULONG rc = 0;
  414.   USHORT cbObjSize = 0;                // count of bytes to request
  415.  
  416.   /**************************************************************************/
  417.   /* 1) Allocate a givable memory block                                     */
  418.   /**************************************************************************/
  419.  
  420.   cbObjSize = (USHORT)strlen(pszItemName)+ (USHORT) 1;
  421.   rc = DosAllocSharedMem((VOID *)&pulSharedObj, NULL, cbObjSize,
  422.              PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_GIVEABLE);
  423.   if (rc && pulSharedObj)          // check api return code and ptr
  424.     return  NULL;
  425.  
  426.   /**************************************************************************/
  427.   /* 2) Fill in the new DDE structure                                       */
  428.   /**************************************************************************/
  429.  
  430.   pdde = (PDDESTRUCT) pulSharedObj;
  431.   pdde->cbData = cbObjSize;
  432.   pdde->offszItemName = sizeof(DDESTRUCT);
  433.   pdde->usFormat = usFormat;
  434.   strcpy(DDES_PSZITEMNAME(pdde), pszItemName); // item name
  435.   pdde->offabData = (USHORT) pdde->offszItemName+ (USHORT) strlen(pszItemName)+ (USHORT)1;
  436.   pdde->fsStatus = fsStatus;           // set status flags
  437.   pdde->cbData = 0;                    // no data is needed
  438.   pdde->offabData = 0;
  439.   return  pdde;
  440. }  /* MakeDDESeg() */
  441.  
  442. /*
  443. Pre - valid PM client exists
  444. Post - processing of about dialog box completed
  445. */
  446.  
  447. MRESULT EXPENTRY AboutDlgProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  448. {
  449.   switch (msg)
  450.       {
  451.       case WM_COMMAND:
  452.       switch (SHORT1FROMMP(mp1))
  453.            {
  454.            case DID_OK:
  455.            case DID_CANCEL:
  456.            WinDismissDlg (hwnd, TRUE);
  457.            return 0;
  458.            }
  459.       break ;
  460.       }
  461.   return WinDefDlgProc (hwnd, msg, mp1, mp2) ;
  462. } /* AboutDlgProc */
  463.  
  464.  
  465. // $Workfile:   client.c  $
  466.  
  467.