home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ddesampl.zip / CLIENT.C next >
C/C++ Source or Header  |  1993-11-09  |  23KB  |  926 lines

  1. /*
  2.  *    Copyright (C) 1993 IBM Corporation
  3.  *
  4.  *    DISCLAIMER OF WARRANTIES.  The following [enclosed] code is sample
  5.  *    code created by IBM Corporation.  This sample code is not part of
  6.  *    any standard or IBM product and is provided to you solely for the
  7.  *    purpose of assisting you in the development of your applications.
  8.  *    The code is provided "AS IS", without warranty of any kind.
  9.  *    IBM shall not be liable for any damages arising out of your
  10.  *    use of the sample code, even if they have been advised of the
  11.  *    possibility of such damages.
  12.  */
  13.  
  14. #define INCL_WIN
  15. #include <os2.h>
  16. #include <string.h>
  17. #include <stdlib.h>
  18.  
  19. #include "client.h"            /* Resource symbolic identifiers*/
  20. #include "resource.h"
  21.  
  22.  
  23. #define    MAX_MSG_SZ    300        /* max size of text string    */
  24.  
  25. #define    MENU_STARTCONV    0x0001
  26. #define    MENU_STOPCONV    0x0002
  27. #define    MENU_REQUEST    0x0004
  28. #define    MENU_POKE    0x0008
  29. #define    MENU_ADVISE    0x0010
  30. #define    MENU_ENDADVISE    0x0020
  31. #define    MENU_TRIGCHN    0x0040
  32. #define    MENU_ALARM    0x0080
  33.  
  34. extern    void    DdeMsgLog( USHORT, HWND, void * );
  35.  
  36.  
  37. /* Function prototypes */
  38. #pragma linkage( MyWindowProc,    system )
  39. #pragma linkage( InitDlgProc,    system )
  40. #pragma linkage( DialogProc,    system )
  41. #pragma linkage( GetDlgProc,    system )
  42. #pragma linkage( PokeDlgProc,    system )
  43. #pragma linkage( AlarmProc,    system )
  44. #pragma linkage( DdeWndProc,    system )
  45.  
  46.  
  47. /* globals */
  48.  
  49. USHORT    menuState = MENU_STARTCONV;
  50.  
  51. BOOL    fConnected = FALSE;        /* status of a DDE conversation    */
  52. USHORT    usAdvise = 0;            /* number of hot link        */
  53. HWND    hwndFrame,
  54.     hwndMenu,
  55.     hwndDDEserver;
  56.  
  57. CHAR    szMsg[MAX_MSG_SZ];        /* text string            */
  58. CHAR    szDDEItemName[CV_MAXDDENAME];    /* DDE item (piece of data) in topic format*/
  59. PFNWP    pWndProc;
  60. DDECONV ddec;                /* DDE Server name and requested topic*/
  61. USHORT    usItem = 0;            /* Menu item            */
  62. char    itemName[ 64 ];
  63. char    itemData[ 256 ];
  64. USHORT    itemFormat = CF_TEXT;
  65. USHORT    itemState;
  66.  
  67. struct {
  68.     USHORT    state;
  69.     char    text[ 20 ];
  70. }    almState[] = {
  71.     { 0,    "ALM_NORMAL"        },
  72.     { 1,    "ALM_IN_ALARM"        },
  73.     { 2,    "ALM_HIGH"        },
  74.     { 3,    "ALM_HIGH_HIGH"        },
  75.     { 4,    "ALM_INSTR_HIGH"    },
  76.     { 5,    "ALM_OUT_CLAMP_HIGH"    },
  77.     { 6,    "ALM_LOW"        },
  78.     { 7,    "ALM_LOW_LOW"        },
  79.     { 8,    "ALM_INSTR_LOW"        },
  80.     { 9,    "ALM_OUT_CLAMP_LOW"    }
  81. };
  82.  
  83. static    short    topicsCnt = 0,
  84.         applsCnt = 0;
  85.  
  86. static    char    *ddeTopics[ 256 ],
  87.         *ddeApplications[ 64 ];
  88.  
  89. static    ATOM    atomIS2,
  90.         atomCsv;
  91.  
  92.  
  93. MRESULT EXPENTRY
  94. InitDlgProc( HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2 )
  95. {
  96.     static HWND    hwndServer = NULLHANDLE,
  97.             hwndTopic = NULLHANDLE;
  98.     register int    i;
  99.  
  100.     switch ( msg )
  101.     {
  102.     case WM_INITDLG:
  103.         if ( hwndServer = WinWindowFromID( hwnd, ID_SERVER_CBX ) )
  104.         {
  105.         WinSetWindowText( hwndServer, ddec.szDDEServerName );
  106.         WinSendMsg( hwndServer, EM_SETSEL,
  107.                 MPFROM2SHORT( (USHORT) 0, (USHORT) CV_MAXDDENAME ),
  108.                 (MPARAM) 0 );
  109.  
  110.         for ( i = 0; i < applsCnt; i++ )
  111.             WinInsertLboxItem( hwndServer, LIT_END, ddeApplications[i] );
  112.         }
  113.         if ( hwndTopic = WinWindowFromID( hwnd, ID_TOPIC_CBX ) )
  114.         {
  115.         WinSetWindowText( hwndTopic, ddec.szDDETopicName );
  116.         for ( i = 0; i < topicsCnt; i++ )
  117.             WinInsertLboxItem( hwndTopic, LIT_END, ddeTopics[i] );
  118.         }
  119.         return 0;
  120.  
  121.     case WM_COMMAND:
  122.         switch ( SHORT1FROMMP( mp1 ) )
  123.         {
  124.         case DID_OK:
  125.         WinQueryWindowText( hwndServer, CV_MAXDDENAME,
  126.                     ddec.szDDEServerName );
  127.         WinQueryWindowText( hwndTopic, CV_MAXTOPICNAME,
  128.                     ddec.szDDETopicName );
  129.         return (MRESULT) WinDismissDlg( hwnd, TRUE );
  130.  
  131.         case DID_CANCEL:
  132.         return (MRESULT) WinDismissDlg( hwnd, FALSE );
  133.         }
  134.         break;
  135.  
  136.     case WM_SYSCOMMAND:
  137.         switch ( LOUSHORT( mp1 ) )
  138.         {
  139.         case SC_CLOSE:
  140.         return (MRESULT) WinDismissDlg( hwnd, FALSE );
  141.  
  142.         default:
  143.         return WinDefDlgProc( hwnd, msg, mp1, mp2 );
  144.         }
  145.         break;
  146.     }
  147.  
  148.     return WinDefDlgProc( hwnd, msg, mp1, mp2 );
  149. }
  150.  
  151.  
  152. MRESULT EXPENTRY
  153. DialogProc( HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2 )
  154. {
  155.     switch ( msg )
  156.     {
  157.     case WM_INITDLG:
  158.         WinSetDlgItemText( hwnd, IDC_ITEM, itemName );
  159.         return 0;
  160.  
  161.     case WM_COMMAND:
  162.         switch ( SHORT1FROMMP( mp1 ) )
  163.         {
  164.         case DID_OK:
  165.         WinQueryDlgItemText( hwnd, IDC_ITEM, sizeof(itemName), (PSZ) itemName );
  166.         return (MRESULT) WinDismissDlg( hwnd, TRUE );
  167.  
  168.         case DID_CANCEL:
  169.         return (MRESULT) WinDismissDlg( hwnd, FALSE );
  170.         }
  171.         break;
  172.  
  173.     case WM_SYSCOMMAND:
  174.         switch ( LOUSHORT( mp1 ) )
  175.         {
  176.         case SC_CLOSE:
  177.         return (MRESULT) WinDismissDlg( hwnd, FALSE );
  178.  
  179.         default:
  180.         return WinDefDlgProc( hwnd, msg, mp1, mp2 );
  181.         }
  182.         break;
  183.     }
  184.  
  185.     return WinDefDlgProc( hwnd, msg, mp1, mp2 );
  186. }
  187.  
  188.  
  189. MRESULT EXPENTRY
  190. GetDlgProc( HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2 )
  191. {
  192.     switch ( msg )
  193.     {
  194.     case WM_INITDLG:
  195.         WinSetDlgItemText( hwnd, IDC_ITEM, itemName );
  196.         if ( itemFormat == atomIS2 )
  197.         WinPostMsg( WinWindowFromID( hwnd, IDC_FMT_IS2 ) ,
  198.                 BM_CLICK, MPFROMSHORT( TRUE ), MPVOID );
  199.         else if ( itemFormat == atomCsv )
  200.         WinPostMsg( WinWindowFromID( hwnd, IDC_FMT_CSV ) ,
  201.                 BM_CLICK, MPFROMSHORT( TRUE ), MPVOID );
  202.         else
  203.         WinPostMsg( WinWindowFromID( hwnd, IDC_FMT_CFTEXT ) ,
  204.                 BM_CLICK, MPFROMSHORT( TRUE ), MPVOID );
  205.         return 0;
  206.  
  207.         case WM_CONTROL:
  208.         switch ( SHORT1FROMMP( mp1 ) )
  209.         {
  210.         case IDC_FMT_CFTEXT:
  211.         itemFormat = CF_TEXT;
  212.         break;
  213.  
  214.         case IDC_FMT_IS2:
  215.         itemFormat = atomIS2;
  216.         break;
  217.  
  218.         case IDC_FMT_CSV:
  219.         itemFormat = atomCsv;
  220.         break;
  221.         }
  222.         break;
  223.  
  224.     case WM_COMMAND:
  225.         switch ( SHORT1FROMMP( mp1 ) )
  226.         {
  227.         case DID_OK:
  228.         WinQueryDlgItemText( hwnd, IDC_ITEM, sizeof(itemName), (PSZ) itemName );
  229.         return (MRESULT) WinDismissDlg( hwnd, TRUE );
  230.  
  231.         case DID_CANCEL:
  232.         return (MRESULT) WinDismissDlg( hwnd, FALSE );
  233.         }
  234.         break;
  235.  
  236.     case WM_SYSCOMMAND:
  237.         switch ( LOUSHORT( mp1 ) )
  238.         {
  239.         case SC_CLOSE:
  240.         return (MRESULT) WinDismissDlg( hwnd, FALSE );
  241.  
  242.         default:
  243.         return WinDefDlgProc( hwnd, msg, mp1, mp2 );
  244.         }
  245.         break;
  246.     }
  247.  
  248.     return WinDefDlgProc( hwnd, msg, mp1, mp2 );
  249. }
  250.  
  251.  
  252. MRESULT EXPENTRY
  253. PokeDlgProc( HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2 )
  254. {
  255.     switch ( msg )
  256.     {
  257.     case WM_INITDLG:
  258.         WinSetDlgItemText( hwnd, IDC_ITEM, itemName );
  259.         if ( itemFormat == atomCsv )
  260.         WinPostMsg( WinWindowFromID( hwnd, IDC_FMT_CSV ) ,
  261.                 BM_CLICK, MPFROMSHORT( TRUE ), MPVOID );
  262.         else
  263.         WinPostMsg( WinWindowFromID( hwnd, IDC_FMT_CFTEXT ) ,
  264.                 BM_CLICK, MPFROMSHORT( TRUE ), MPVOID );
  265.         return 0;
  266.  
  267.         case WM_CONTROL:
  268.         switch ( SHORT1FROMMP( mp1 ) )
  269.         {
  270.         case IDC_FMT_CFTEXT:
  271.         itemFormat = CF_TEXT;
  272.         break;
  273.  
  274.         case IDC_FMT_CSV:
  275.         itemFormat = atomCsv;
  276.         break;
  277.         }
  278.         break;
  279.  
  280.     case WM_COMMAND:
  281.         switch ( SHORT1FROMMP( mp1 ) )
  282.         {
  283.         case DID_OK:
  284.         WinQueryDlgItemText( hwnd, IDC_ITEM, sizeof(itemName), (PSZ) itemName );
  285.         WinQueryDlgItemText( hwnd, IDC_DATA, sizeof(itemData), (PSZ) itemData );
  286.         return (MRESULT) WinDismissDlg( hwnd, TRUE );
  287.  
  288.         case DID_CANCEL:
  289.         return (MRESULT) WinDismissDlg( hwnd, FALSE );
  290.         }
  291.         break;
  292.  
  293.     case WM_SYSCOMMAND:
  294.         switch ( LOUSHORT( mp1 ) )
  295.         {
  296.         case SC_CLOSE:
  297.         return (MRESULT) WinDismissDlg( hwnd, FALSE );
  298.  
  299.         default:
  300.         return WinDefDlgProc( hwnd, msg, mp1, mp2 );
  301.         }
  302.         break;
  303.     }
  304.  
  305.     return WinDefDlgProc( hwnd, msg, mp1, mp2 );
  306. }
  307.  
  308.  
  309. MRESULT EXPENTRY
  310. AlarmProc( HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2 )
  311. {
  312.     static HWND    hwndState = (HWND) NULL;
  313.     register int    i;
  314.     char    state[ 64 ];
  315.  
  316.     switch ( msg )
  317.     {
  318.     case WM_INITDLG:
  319.         WinSetDlgItemText( hwnd, IDC_ITEM, itemName );
  320.         if ( hwndState = WinWindowFromID( hwnd, IDC_STATE ) )
  321.         {
  322.         WinSetWindowText( hwndState, almState[0].text );
  323.         for ( i = 0; i < (sizeof(almState)/sizeof(almState[0])); i++ )
  324.         {
  325.             WinInsertLboxItem( hwndState, LIT_END,
  326.                        almState[i].text );
  327.         }
  328.         } 
  329.         return 0;
  330.  
  331.     case WM_COMMAND:
  332.         switch ( SHORT1FROMMP( mp1 ) )
  333.         {
  334.         case DID_OK:
  335.         WinQueryDlgItemText( hwnd, IDC_ITEM, sizeof(itemName), (PSZ) itemName );
  336.         WinQueryDlgItemText( hwnd, IDC_DATA, sizeof(itemData), (PSZ) itemData );
  337.         
  338.         WinQueryDlgItemText( hwnd, IDC_STATE, sizeof(state), (PSZ) state );
  339.         for ( i = 0, itemState = 0; i < (sizeof(almState)/sizeof(almState[0])); i++ )
  340.         {
  341.             if ( !strcmp( state, almState[i].text ) )
  342.             {
  343.                 itemState = almState[i].state;
  344.                 break;
  345.             }
  346.         }
  347.         return (MRESULT) WinDismissDlg( hwnd, TRUE );
  348.  
  349.         case DID_CANCEL:
  350.         return (MRESULT) WinDismissDlg( hwnd, FALSE );
  351.         }
  352.         break;
  353.  
  354.     case WM_SYSCOMMAND:
  355.         switch ( LOUSHORT( mp1 ) )
  356.         {
  357.         case SC_CLOSE:
  358.         return (MRESULT) WinDismissDlg( hwnd, FALSE );
  359.  
  360.         default:
  361.         return WinDefDlgProc( hwnd, msg, mp1, mp2 );
  362.         }
  363.         break;
  364.     }
  365.  
  366.     return WinDefDlgProc( hwnd, msg, mp1, mp2 );
  367. }
  368.  
  369.  
  370. PDDESTRUCT
  371. MakeDDEDataSeg( USHORT usFormat, PSZ pszItemName,
  372.         PVOID pvData, USHORT cbData, USHORT fsStatus )
  373. {
  374.     PDDESTRUCT pdde = NULL;        /* ptr to dde data structure    */
  375.     ULONG    rc = 0;            /* api return code holder    */
  376.     PULONG    pulSharedObj = NULL;    /* pointer to shared object    */
  377.     PCHAR    psz = NULL;        /* string ptr for text format    */
  378.     USHORT    cbObjSize = 0;        /* count of bytes to request    */
  379.  
  380.     cbObjSize = (USHORT) strlen( pszItemName ) + cbData + 1;
  381.     rc = DosAllocSharedMem(
  382.             (PPVOID) &pulSharedObj,
  383.             NULL,
  384.             cbObjSize,
  385.             PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_GIVEABLE
  386.          );
  387.     if ( rc && pulSharedObj )
  388.         return NULL;
  389.  
  390.     pdde = (PDDESTRUCT) pulSharedObj;
  391.     pdde->usFormat = usFormat;
  392.     pdde->offszItemName = (USHORT) sizeof(DDESTRUCT); /* ptr to item name*/
  393.     strcpy( DDES_PSZITEMNAME(pdde), pszItemName );    /* item name*/
  394.     pdde->cbData = cbData;        /* count of bytes of user data*/
  395.     pdde->offabData = (USHORT) pdde->offszItemName + (USHORT) strlen( pszItemName ) + 1;
  396.     pdde->fsStatus = fsStatus;    /* set status flags */
  397.  
  398.     if ( cbData != 0 && pvData != NULL )
  399.     {
  400.         switch ( usFormat )
  401.         {
  402.         case CF_TEXT:
  403.         strncpy( DDES_PABDATA( pdde ), pvData, (size_t) pdde->cbData++ );
  404.         break;
  405.  
  406.         default:
  407.         memcpy( DDES_PABDATA( pdde ), pvData, (size_t) pdde->cbData );
  408.         break;
  409.         }
  410.     }
  411.  
  412.     return pdde;
  413. }
  414.  
  415.  
  416. /*
  417.  * Pre - hwnd is a valid window handle, szMsg is a null terminated string
  418.  * Post - writes szMsg in hwnd centered vertically and horizontally
  419.  */
  420.  
  421. VOID EXPENTRY
  422. PaintWindow( HWND hwnd, CHAR *szMsg )
  423. {
  424.     RECTL    rcl;
  425.     HPS    hps = WinBeginPaint( hwnd, (HPS) NULL, &rcl );
  426.  
  427.     if ( !hps )
  428.     {
  429.         WinAlarm( HWND_DESKTOP, WA_ERROR );    /* failed to get cached-micro ps */
  430.         return;
  431.     }
  432.  
  433. //    fill in the background window color
  434.     WinFillRect( hps, &rcl, SYSCLR_WINDOW );
  435.  
  436.     WinQueryWindowRect( hwnd, &rcl );
  437. //    write text to window - centered vertical and horizontal
  438.     WinDrawText( hps, -1, szMsg, &rcl, CLR_NEUTRAL,
  439.              CLR_BACKGROUND, DT_CENTER | DT_VCENTER | DT_ERASERECT );
  440.  
  441.     WinEndPaint( hps );
  442. }
  443.  
  444.  
  445. MRESULT EXPENTRY
  446. DdeWndProc( HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2 )
  447. {
  448.     PDDEINIT    pddei = NULL;    /* DDE init struct ptr        */
  449.     PDDESTRUCT    pdde = NULL,
  450.             pddeOut = NULL; /* DDE Transaction struct ptr    */
  451.  
  452.     DdeMsgLog( msg, (HWND) mp1, (void *) mp2 );
  453.  
  454.     switch ( msg )
  455.     {
  456.     case WM_DDE_DATA:
  457.         /* ignore responses from other servers */
  458.         if ( hwndDDEserver != (HWND) mp1 )
  459.         break;
  460.  
  461. //        write incomming text message to screen
  462.  
  463.         pdde = (PDDESTRUCT) mp2;
  464.         strncpy( szMsg, (PSZ) DDES_PABDATA(pdde), pdde->cbData ); /* Extract data*/
  465.         if ( strlen( szMsg ) == 0 )
  466.         strcpy( szMsg, "<no text message from server>" );
  467.         PaintWindow( hwnd, szMsg );
  468.         WinInvalidateRect( hwnd, NULL, FALSE );
  469.  
  470.         if ( pdde->fsStatus & DDE_FACKREQ )    /* does server requre ack? */
  471.         {
  472.         pddeOut = MakeDDEDataSeg( CF_TEXT, szDDEItemName, NULL, 0, DDE_FACK );
  473.         if ( pddeOut )
  474.         {
  475.             WinDdePostMsg( hwndDDEserver, hwnd,
  476.                    WM_DDE_ACK, pddeOut, TRUE );
  477.         }
  478.         }
  479.         DosFreeMem( (PVOID) mp2 );
  480.         break;
  481.  
  482.     case WM_DDE_ACK:
  483.         pdde = (PDDESTRUCT) mp2;
  484.  
  485.         switch ( usItem )        /* what request was last issued */
  486.         {
  487. //        if the ack was in response to our hot link request,
  488. //        change status of menu items
  489.  
  490.         case IDM_ADVISE:
  491.         if ( pdde->fsStatus & DDE_FACK )
  492.         {
  493.             menuState |= MENU_ENDADVISE;
  494.             usAdvise++;
  495.  
  496. //            Get current value
  497.             pddeOut = MakeDDEDataSeg( itemFormat, itemName, NULL, 0, 0 );
  498.             if ( pddeOut )
  499.             {
  500.             WinDdePostMsg( hwndDDEserver, hwnd,
  501.                        WM_DDE_REQUEST, pddeOut, TRUE );
  502.             usItem = IDM_REQUEST;
  503.             }
  504.         }
  505.         break;
  506.  
  507.         case IDM_ENDADVISE:
  508.         if ( pdde->fsStatus & DDE_FACK )
  509.         {
  510.             if ( --usAdvise == 0 )
  511.             menuState &= ~MENU_ENDADVISE;
  512.         }
  513.         break;
  514.  
  515.         case IDM_POKE:
  516.         case IDM_REQUEST:
  517.         if ( !( pdde->fsStatus & DDE_FACK ) )
  518.             WinAlarm( HWND_DESKTOP, WA_ERROR );
  519.         break;
  520.         }
  521.         DosFreeMem( (PVOID) mp2 );
  522.         break;
  523.  
  524.     case WM_DDE_INITIATEACK:
  525.         WinAlarm( HWND_DESKTOP, WA_NOTE );
  526.         pddei = (PDDEINIT) mp2;           /* MS V2 PG 430 */
  527.  
  528.         if ( !ddec.szDDEServerName[0] && !ddec.szDDETopicName[0] )
  529.         {
  530.         register int i;
  531.  
  532.         for ( i = 0; i < topicsCnt; i++ )
  533.             if ( !stricmp( ddeTopics[i], pddei->pszTopic ) )
  534.                 break;
  535.         if ( i >= topicsCnt )
  536.             ddeTopics[ topicsCnt++ ] = strdup( pddei->pszTopic );
  537.  
  538.         for ( i = 0; i < applsCnt; i++ )
  539.             if ( !stricmp( ddeApplications[i], pddei->pszAppName ) )
  540.                 break;
  541.         if ( i >= applsCnt )
  542.             ddeApplications[ applsCnt++ ] = strdup( pddei->pszAppName );
  543.         }
  544.         else if ( fConnected && hwndDDEserver != (HWND) mp1 )
  545.         WinDdePostMsg( (HWND) mp1, hwnd, WM_DDE_TERMINATE, NULL, TRUE );
  546.         else if ( !stricmp( ddec.szDDETopicName, pddei->pszTopic )
  547.            || !stricmp( ddec.szDDEServerName, pddei->pszAppName ) )
  548.         {
  549.         hwndDDEserver = (HWND) mp1;   /* store client window handle*/
  550.         if ( !strcmp( pddei->pszTopic, SZDDESYS_TOPIC ) )
  551.             menuState = MENU_STOPCONV | MENU_REQUEST;
  552.         else
  553.             menuState = ~( MENU_STARTCONV | MENU_ENDADVISE );
  554.         WinSetWindowText( hwndFrame, "DDE Client - Connected" );
  555.         fConnected = TRUE;
  556.         }
  557.  
  558.         DosFreeMem( (PVOID) mp2 );
  559.         break;
  560.  
  561.     case WM_DDE_TERMINATE:
  562.         if ( hwndDDEserver != (HWND) mp1 )    /* ignore responses from other servers*/
  563.         break;
  564.         menuState = MENU_STARTCONV;
  565.         hwndDDEserver = (HWND) NULL;           /* store client window handle*/
  566.         WinSetWindowText( hwndFrame, "DDE Client - Not Connected" );
  567.         fConnected = FALSE;
  568.         usAdvise = 0;
  569.         break;
  570.  
  571.     default:
  572.         return (*pWndProc)( hwnd, msg, mp1, mp2 );
  573.     }
  574.  
  575.     return WinDefWindowProc( hwnd, msg, mp1, mp2 );
  576. //    return (MRESULT) NULL;
  577. }
  578.  
  579.  
  580. static void
  581. loadFormat( BOOL option )
  582. {
  583.     HATOMTBL hAtomTbl = WinQuerySystemAtomTable();
  584.     static BOOL    rmAtomIS2 = FALSE,
  585.             rmAtomCsv = FALSE;
  586.  
  587.     if ( option == TRUE )
  588.     {
  589.         atomIS2 = WinFindAtom( hAtomTbl, "IS2" );
  590.  
  591.         if ( atomIS2 == 0 )
  592.         {
  593.         atomIS2 = WinAddAtom( hAtomTbl, "IS2" );
  594.         rmAtomIS2 = TRUE;
  595.         }
  596.  
  597.         atomCsv = WinFindAtom( hAtomTbl, "Csv" );
  598.  
  599.         if ( atomCsv == 0 )
  600.         {
  601.         atomCsv = WinAddAtom( hAtomTbl, "Csv" );
  602.         rmAtomCsv = TRUE;
  603.         }
  604.     }
  605.     else
  606.     {
  607.         if ( rmAtomIS2 == TRUE )
  608.         WinDeleteAtom( hAtomTbl, atomIS2 );
  609.         if ( rmAtomCsv == TRUE )
  610.         WinDeleteAtom( hAtomTbl, atomCsv );
  611.     }
  612. }
  613.  
  614.  
  615. VOID
  616. DisplayMessage( PCH str )
  617. {
  618.     WinMessageBox(
  619.         HWND_DESKTOP,
  620.         HWND_DESKTOP,
  621.         (PCH) str,
  622.         (PCH) "Error Messages For The DDE Sample",
  623.         ID_MESSAGEBOX,
  624.         MB_OK | MB_APPLMODAL | MB_MOVEABLE | MB_ERROR
  625.     );
  626. }
  627.  
  628.  
  629. static void
  630. setup()
  631. {
  632.     /* set up our default dde conversation block (struct) */
  633.     ddec.szDDEServerName[0] = 0;
  634.     ddec.szDDETopicName[0] = 0;
  635.  
  636.     ddeApplications[ applsCnt++ ] = strdup( CV_DDEAPPNAME );
  637.     ddeTopics[ topicsCnt++ ] = strdup( CV_DDETOPIC );
  638.     ddeTopics[ topicsCnt++ ] = strdup( SZDDESYS_TOPIC );
  639.  
  640.     strcpy( szDDEItemName, CV_DDEITEMSG );
  641.  
  642.     loadFormat( TRUE );
  643. }
  644.  
  645.  
  646. MRESULT EXPENTRY
  647. MyWindowProc( HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2 )
  648. {
  649.     PDDESTRUCT    pdde = NULL,
  650.             pddeOut = NULL; /* DDE Transaction struct ptr */
  651.     register int    i;
  652.  
  653.     switch ( msg )
  654.     {
  655.     /* set up  */
  656.     case WM_CREATE:
  657.         /* Get the window handles for this instances menu and frame window */
  658.         hwndFrame = WinQueryWindow( hwnd, QW_PARENT );
  659.         hwndMenu = WinWindowFromID( hwndFrame, (USHORT) FID_MENU );
  660.         pWndProc = WinSubclassWindow( hwnd, (PFNWP) DdeWndProc );
  661.         setup();
  662.         WinSetWindowText( hwndFrame, "DDE Client - Not Connected" );
  663.         /* position window on users screen */
  664.         WinSetWindowPos( hwndFrame, HWND_TOP,
  665.             50,50,    /* window position (x,y) */
  666.             WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN)/3,    /* window width */
  667.             WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN)/3,    /* window height */
  668.             SWP_SIZE | SWP_MOVE | SWP_SHOW );
  669.         return 0;
  670.  
  671.     case WM_INITMENU:
  672.         WinEnableMenuItem( hwndMenu, IDM_TRIGCHN,    menuState & MENU_TRIGCHN );
  673.         WinEnableMenuItem( hwndMenu, IDM_ALARM,    menuState & MENU_ALARM );
  674.         WinEnableMenuItem( hwndMenu, IDM_REQUEST,    menuState & MENU_REQUEST );
  675.         WinEnableMenuItem( hwndMenu, IDM_POKE,    menuState & MENU_POKE );
  676.         WinEnableMenuItem( hwndMenu, IDM_ADVISE,    menuState & MENU_ADVISE );
  677.         WinEnableMenuItem( hwndMenu, IDM_ENDADVISE,    menuState & MENU_ENDADVISE );
  678.         WinEnableMenuItem( hwndMenu, IDM_STOPCONV,    menuState & MENU_STOPCONV );
  679.         WinEnableMenuItem( hwndMenu, IDM_STARTCONV,    menuState & MENU_STARTCONV );
  680.         break;
  681.  
  682.     case WM_COMMAND:
  683.         switch ( SHORT1FROMMP( mp1 ) )
  684.         {
  685.         case IDM_STARTCONV:
  686.         if ( WinDlgBox(HWND_DESKTOP,
  687.             hwndFrame,
  688.             (PFNWP) InitDlgProc,
  689.                         0,
  690.                         IDD_INIT_DLG,
  691.                         NULL) )
  692.         {
  693.             if ( !WinDdeInitiate( hwnd, ddec.szDDEServerName,
  694.                       ddec.szDDETopicName,
  695.                       (PCONVCONTEXT) 0 ) )
  696.             {
  697.             WinAlarm( HWND_DESKTOP, WA_ERROR );
  698.             DisplayMessage( "WinDdeInitiate() failed!" );
  699.             }
  700.         }
  701.         return 0;
  702.  
  703.         case IDM_STOPCONV:
  704.         WinDdePostMsg( hwndDDEserver, hwnd, WM_DDE_TERMINATE, NULL, TRUE );
  705.         menuState = MENU_STARTCONV;
  706.         hwndDDEserver = (HWND) NULL;
  707.         WinSetWindowText( hwndFrame, "DDE Client - Not Connected" );
  708.         fConnected = FALSE;
  709.         usAdvise = 0;
  710.         return 0;
  711.  
  712.         case IDM_REQUEST:
  713.         if ( WinDlgBox(HWND_DESKTOP,
  714.             hwndFrame,
  715.             (PFNWP) GetDlgProc,
  716.                         0,
  717.                         IDD_GET_ITEM,
  718.                         NULL) )
  719.         {
  720. //            if a conversation on the System topic is esablished,
  721. //            issuing a request causes the current status to be retrieved
  722.  
  723.             pdde = MakeDDEDataSeg( itemFormat, itemName, NULL, 0, 0 );
  724.             if ( pdde )
  725.             {
  726.             WinDdePostMsg( hwndDDEserver, hwnd, WM_DDE_REQUEST, pdde, TRUE );
  727.             usItem = IDM_REQUEST;
  728.             }
  729.             else
  730.             {
  731.             WinAlarm( HWND_DESKTOP, WA_ERROR );
  732.             WinSetWindowText( hwndFrame, "...MakeDDEDataSeg() failed.." );
  733.             break;
  734.             }
  735.         }
  736.         return 0;
  737.  
  738.         case IDM_TRIGCHN:
  739.         if ( WinDlgBox(HWND_DESKTOP,
  740.             hwndFrame,
  741.             (PFNWP) DialogProc,
  742.                         0,
  743.                         IDD_ITEM,
  744.                         NULL) )
  745.         {
  746. //            if a conversation on the System topic is esablished,
  747. //            issuing a request causes the current status to be retrieved
  748.  
  749.             pdde = MakeDDEDataSeg( CF_TEXT, itemName, NULL, 0, 0 );
  750.             if (pdde)
  751.             {
  752.             WinDdePostMsg( hwndDDEserver, hwnd, WM_DDE_EXECUTE, pdde, TRUE );
  753.             usItem = IDM_TRIGCHN;
  754.             }
  755.             else
  756.             {
  757.             WinAlarm( HWND_DESKTOP, WA_ERROR );
  758.             WinSetWindowText( hwndFrame, "...MakeDDEDataSeg() failed.." );
  759.             break;
  760.             }
  761.         }
  762.         return 0;
  763.  
  764.         case IDM_ALARM:
  765.         if ( WinDlgBox(HWND_DESKTOP,
  766.             hwndFrame,
  767.             (PFNWP) AlarmProc,
  768.             0,
  769.             IDD_ALARM,
  770.             NULL) )
  771.         {
  772.             struct alarm_param_s {
  773.                 USHORT    state;
  774.                 char    data[ 64 ];
  775.             }    args;
  776.             args.state = itemState;
  777.             strcpy( args.data, itemData );
  778. //            if a conversation on the System topic is esablished,
  779. //            issuing a request causes the current status to be retrieved
  780.  
  781.             pdde = MakeDDEDataSeg( atomIS2, itemName,
  782.                        &args, strlen(args.data)+sizeof(USHORT)+1, 0 );
  783.             if (pdde)
  784.             {
  785.             WinDdePostMsg( hwndDDEserver, hwnd,
  786.                        WM_DDE_EXECUTE, pdde, TRUE );
  787.             usItem = IDM_POKE;
  788.             }
  789.             else
  790.             {
  791.             WinAlarm( HWND_DESKTOP, WA_ERROR );
  792.             WinSetWindowText( hwndFrame,
  793.                       "...MakeDDEDataSeg() failed.." );
  794.             break;
  795.             }
  796.         }
  797.         return 0;
  798.  
  799.         case IDM_POKE:
  800.         if ( WinDlgBox(HWND_DESKTOP,
  801.             hwndFrame,
  802.             (PFNWP) PokeDlgProc,
  803.             0,
  804.             IDD_PUT_ITEM,
  805.             NULL) )
  806.         {
  807. //            if a conversation on the System topic is esablished,
  808. //            issuing a request causes the current status to be retrieved
  809.  
  810.             pdde = MakeDDEDataSeg( itemFormat, itemName,
  811.                        itemData, strlen(itemData), 0 );
  812.             if ( pdde )
  813.             {
  814.             WinDdePostMsg( hwndDDEserver, hwnd, WM_DDE_POKE, pdde, TRUE );
  815.             usItem = IDM_POKE;
  816.             }
  817.             else
  818.             {
  819.             WinAlarm( HWND_DESKTOP, WA_ERROR );
  820.             WinSetWindowText( hwndFrame, "...MakeDDEDataSeg() failed.." );
  821.             break;
  822.             }
  823.         }
  824.         return 0;
  825.  
  826.         case IDM_ADVISE:
  827.         if ( WinDlgBox(HWND_DESKTOP,
  828.             hwndFrame,
  829.             (PFNWP) GetDlgProc,
  830.             0,
  831.             IDD_GET_ITEM,
  832.             NULL) )
  833.         {
  834.             pddeOut = MakeDDEDataSeg( itemFormat, itemName, NULL, 0, DDE_FACKREQ);
  835.             if (pddeOut)
  836.             {
  837.             WinDdePostMsg( hwndDDEserver, hwnd,
  838.                        WM_DDE_ADVISE, pddeOut, TRUE );
  839.             WinSetWindowText( hwndFrame,
  840.                       "DDE Client - sent hot link request" );
  841.             }
  842.             usItem = IDM_ADVISE;                   /* set state to advise */
  843.         }
  844.         break;
  845.  
  846.         case IDM_ENDADVISE:
  847.         if ( WinDlgBox(HWND_DESKTOP,
  848.             hwndFrame,
  849.             (PFNWP) DialogProc,
  850.             0,
  851.             IDD_ITEM,
  852.             NULL) )
  853.         {
  854.             pddeOut = MakeDDEDataSeg( itemFormat, itemName, NULL, 0, DDE_FACKREQ );
  855.             if ( pddeOut )
  856.             {
  857.             WinDdePostMsg( hwndDDEserver, hwnd,
  858.                        WM_DDE_UNADVISE, pddeOut, TRUE );
  859.             WinSetWindowText( hwndFrame, "DDE Client - sent hot link terminate request" );
  860.             usItem = IDM_ENDADVISE;
  861.             }
  862.         }
  863.         break;
  864.         }
  865.         break; /* wm_command */
  866.  
  867.     case WM_PAINT:
  868.         PaintWindow( hwnd, szMsg );
  869.         return 0;
  870.  
  871.     case WM_CLOSE:
  872.         loadFormat( FALSE );
  873.         if ( hwndDDEserver )
  874.         WinDdePostMsg( hwndDDEserver, hwnd, WM_DDE_TERMINATE, NULL, TRUE );
  875.         WinPostMsg( hwnd, WM_QUIT, 0L, 0L );
  876.         return 0;
  877.  
  878.     case WM_ERASEBACKGROUND:
  879.         return (MRESULT) 1;
  880.     }
  881.  
  882.     return WinDefWindowProc( hwnd, msg, mp1, mp2 );
  883. }
  884.  
  885.  
  886. int
  887. main()
  888. {
  889.     HAB    hab = WinInitialize( 0 );
  890.     HMQ    hmq = WinCreateMsgQueue( hab, 0 );
  891.     HWND    hwndClient;
  892.     QMSG    qmsg;
  893.     ULONG    flCreate = FCF_STANDARD;
  894.  
  895.     WinRegisterClass(
  896.         hab,
  897.         "MyWindow",
  898.         (PFNWP) MyWindowProc,
  899.         CS_SIZEREDRAW,
  900.         0
  901.     );
  902.  
  903.     hwndFrame = WinCreateStdWindow(
  904.             HWND_DESKTOP,
  905.             WS_VISIBLE,
  906.             &flCreate,
  907.             "MyWindow",
  908.             "",
  909.             0L,
  910.             (HMODULE) NULL,
  911.             ID_MAINWND,
  912.             &hwndClient
  913.             );
  914.  
  915.     if ( hwndFrame != (HWND) NULL )
  916.     {
  917.         while ( WinGetMsg( hab, &qmsg, (HWND) NULL, 0, 0 ) )
  918.             WinDispatchMsg( hab, &qmsg );
  919.  
  920.         WinDestroyWindow( hwndFrame );
  921.     }
  922.  
  923.     WinDestroyMsgQueue( hmq );
  924.     WinTerminate( hab );
  925. }
  926.