home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_122 / 7.ddi / DDEML31.ZIP / DDECLNT.C next >
Encoding:
C/C++ Source or Header  |  1992-06-10  |  13.3 KB  |  418 lines

  1. /* Borland C++ - (C) Copyright 1992 by Borland International               */
  2.  
  3. /***************************************************************************
  4.  
  5.       Program Name      DDEClnt.c
  6.  
  7.       Purpose           A simple DDE client application, which communicates
  8.                         to a DDE server using the new 3.1 api DDEML calls.
  9.  
  10.                         To use this program, build DDEClnt and DDESrvr. There
  11.                            are project files for this.  From the DDEClnt, connect
  12.                         to the server, and send pre-formatted messages to the
  13.                         the server, and request messages from the server.
  14.                         Disconnect before closing app.
  15.  
  16. ****************************************************************************/
  17.  
  18. #define STRICT
  19.  
  20. #include <windows.h>
  21. #include <ddeml.h>
  22. #include <dde.h>
  23.  
  24. #include <stdio.h>
  25. #include <string.h>
  26.  
  27. #include "ddeclnt.h"
  28.  
  29.  
  30. HANDLE         hInst;                  /*  Current instance of application */
  31. HWND           hWnd;                   /*  Handle of Main window           */
  32.  
  33. short          xScreen;                /* Screen metrics                   */
  34. short          yScreen;                /*  ...                             */
  35. short          yFullScreen;            /*  ...                             */
  36. short          xFrame;                 /*  ...                             */
  37. short          yMenu;                  /*  ...                             */
  38. TEXTMETRIC     tm;                     /* Text metrics                     */
  39. short          cxChar;                 /* Character metrics                */
  40. short          cyChar;                 /*  ...                             */
  41.  
  42. char           szScreenText[10][80];   /* Contains 10 lines of display data*/
  43. short          cCurrentLine;           /* Index into szScreenText          */
  44. short          cTotalLines;            /* Total lines in szScreenText      */
  45.  
  46. /*
  47.          The DDE variables
  48. */
  49.  
  50. DWORD          idInst = 0L;            /*  Instance of app for DDEML       */
  51. FARPROC        lpDdeProc;              /*  DDE callback function           */
  52. HSZ            hszService;
  53. HSZ            hszTopic;
  54. HSZ            hszItem;
  55. HCONV          hConv = NULL;           /*Handle of established conversation*/
  56. HDDEDATA       hData;
  57. DWORD          dwResult;
  58. WORD           wFmt = CF_TEXT;         /*  Clipboard format                */
  59. char           szDDEString[80];        /*  Local allocation of data buffer */
  60. char           szDDEData[80];          /*  Local receive data buffer       */
  61. int            iClientCount = 0;       /*  Client to Server message counter*/
  62. char           tbuf[5];                /*  Temporary, to hold count        */
  63.  
  64. char szAppName[] = "DDEClientApplication";
  65.  
  66.  
  67. /***************************************************************************/
  68.  
  69. #pragma argsused
  70. int PASCAL WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  71.                      LPSTR lpszCmdLine, int nCmdShow )
  72. {
  73.     MSG         msg;
  74.  
  75.  
  76.    if ( !hPrevInstance )               /* Other instances of app running?  */
  77.       if ( !InitApplication ( hInstance ) ) /* Initialize shared things    */
  78.          return ( FALSE );             /* Exits if unable to initialize    */
  79.  
  80.    if ( !InitInstance ( hInstance, nCmdShow ) )
  81.       return ( FALSE );
  82.  
  83.     while ( GetMessage ( &msg, NULL, NULL, NULL ) )
  84.     {
  85.         TranslateMessage ( &msg );
  86.         DispatchMessage ( &msg );
  87.     }
  88.  
  89.    DdeUninitialize ( idInst );
  90.  
  91.     return ( msg.wParam );
  92. }
  93.  
  94. /***************************************************************************/
  95.  
  96. BOOL FAR PASCAL InitApplication ( HANDLE hInstance )
  97. {
  98.     WNDCLASS    wc;
  99.  
  100.    wc.style         = CS_HREDRAW | CS_VREDRAW;
  101.    wc.lpfnWndProc   = MainWndProc;
  102.    wc.cbClsExtra    = 0;
  103.    wc.cbWndExtra    = 0;
  104.    wc.hInstance     = hInstance;
  105.    wc.hIcon         = LoadIcon ( hInstance, "DDEClientIcon" );
  106.    wc.hCursor       = LoadCursor ( NULL, IDC_ARROW );
  107.    wc.hbrBackground = GetStockObject ( WHITE_BRUSH );
  108.    wc.lpszMenuName  = "DDEClientMenu";
  109.    wc.lpszClassName = szAppName;
  110.  
  111.    if ( !RegisterClass ( &wc ) )
  112.       return ( FALSE );
  113.  
  114.    return ( TRUE );
  115. }
  116.  
  117. /***************************************************************************/
  118.  
  119. BOOL InitInstance ( HANDLE hInstance, short int nCmdShow )
  120. {
  121.    hInst = hInstance;
  122.  
  123.    xScreen     = GetSystemMetrics ( SM_CXSCREEN );
  124.    yScreen     = GetSystemMetrics ( SM_CYSCREEN );
  125.  
  126.     hWnd = CreateWindow ( szAppName,
  127.                          "DDE Client Window",
  128.                          WS_OVERLAPPEDWINDOW,
  129.                          10,                    /* These co-ordinates look */
  130.                          10,                    /* good on a VGA monitor   */
  131.                          xScreen - 200,         /* running in 640x480.  No */
  132.                          yScreen / 2 - 50,      /* combination was tried.  */
  133.                          NULL,
  134.                          NULL,
  135.                          hInstance,
  136.                          NULL );
  137.  
  138. /*
  139.       If window could not be created, return "failure"
  140. */
  141.  
  142.    if ( !hWnd )
  143.       return ( FALSE );
  144.  
  145. /*
  146.       Make the window visible; update its client area; and return "success"
  147. */
  148.  
  149.    ShowWindow ( hWnd, nCmdShow );      /* Show the window                  */
  150.    UpdateWindow ( hWnd );              /* Sends WM_PAINT message           */
  151.    return ( TRUE );              /* Returns the value from PostQuitMessage */
  152.  
  153. }
  154.  
  155. /***************************************************************************/
  156.                 
  157. LRESULT CALLBACK MainWndProc ( HWND hWnd, UINT message,
  158.                                WPARAM wParam, LPARAM lParam )
  159. {
  160.    HDC            hDC;
  161.    PAINTSTRUCT    ps;
  162.    DLGPROC        dlgProcAbout;
  163.    int            i;
  164.    int            j;
  165.    short          y;
  166.  
  167.  
  168.    switch ( message )
  169.    {
  170.       case WM_CREATE:
  171.          hDC = GetDC ( hWnd );
  172.  
  173.          GetTextMetrics ( hDC, &tm );
  174.          cxChar = tm.tmAveCharWidth;
  175.          cyChar = tm.tmHeight + tm.tmExternalLeading;
  176.  
  177.          ReleaseDC ( hWnd, hDC );
  178.  
  179.          lpDdeProc = MakeProcInstance ( (FARPROC) DDECallback, hInst );
  180.          if ( DdeInitialize ( (LPDWORD)&idInst, (PFNCALLBACK)lpDdeProc,
  181.                               APPCMD_CLIENTONLY, 0L ) )
  182.          {
  183.             HandleOutput ( "Client DDE initialization failure." );
  184.             return ( FALSE );
  185.          }
  186.  
  187.          hszService = DdeCreateStringHandle ( idInst, "Borland", CP_WINANSI );
  188.          hszTopic = DdeCreateStringHandle ( idInst, "DDEExample", CP_WINANSI );
  189.          hszItem = DdeCreateStringHandle ( idInst, "DDEData", CP_WINANSI );
  190.  
  191.          cCurrentLine = 0;
  192.          cTotalLines = 0;
  193.  
  194.          strcpy ( szDDEString, "Client application message number:  " );
  195.          break;
  196.  
  197.       case WM_COMMAND:
  198.          switch ( wParam )
  199.          {
  200.             case IDM_EXIT:
  201.                DestroyWindow ( hWnd );
  202.                break;
  203.  
  204.             case IDM_CONNECT_SERVER:
  205.                if ( hConv == NULL )
  206.                {
  207.                   hConv = DdeConnect ( idInst, hszService, hszTopic,
  208.                                        (PCONVCONTEXT) NULL );
  209.                   if ( hConv == NULL )
  210.                   {
  211.                      HandleError ( DdeGetLastError ( idInst ) );
  212.                      HandleOutput ( "Unsuccessful connection." );
  213.                   }
  214.                   else
  215.                      HandleOutput ( "Successful connection." );
  216.                }
  217.                else
  218.                   HandleOutput ( "Already connected to DDE Server." );
  219.  
  220.                break;
  221.  
  222.             case IDM_DISCONNECT_SERVER:
  223.                if ( hConv != NULL )
  224.                {
  225.                   DdeDisconnect ( hConv );
  226.                   hConv = NULL;
  227.                   HandleOutput ( "Disconnected from server." );
  228.                }
  229.                else
  230.                   HandleOutput ( "Must be connected before disconnecting." );
  231.  
  232.                break;
  233.  
  234.             case IDM_MSG_TO_SERVER:
  235.                if ( hConv != NULL )
  236.                {
  237.                   iClientCount ++;
  238.                   sprintf ( tbuf, "%3d.", iClientCount );
  239.                   strncpy ( &szDDEString[36], tbuf, 5 );
  240.  
  241.                   hData = DdeCreateDataHandle ( idInst, &szDDEString,
  242.                            sizeof ( szDDEString ), 0L, hszItem, wFmt, 0 );
  243.  
  244.                   if ( hData != NULL )
  245.                       hData = DdeClientTransaction ( (LPBYTE)hData, -1, hConv,
  246.                                hszItem, wFmt, XTYP_POKE, 1000, &dwResult );
  247.                   else
  248.                      HandleOutput ( "Could not create data handle." );
  249.                }
  250.                else
  251.                   HandleOutput ( "A connection to a DDE Server has not been established." );
  252.  
  253.                break;
  254.  
  255.             case IDM_MSG_FROM_SERVER:
  256.                if ( hConv != NULL )
  257.                {
  258.                   hData = DdeClientTransaction ( NULL, 0, hConv,
  259.                                hszItem, wFmt, XTYP_REQUEST, 1000, &dwResult );
  260.  
  261.                   if ( dwResult == DDE_FNOTPROCESSED )
  262.                      HandleOutput ( "Data not available from server." );
  263.                   else
  264.                   {
  265.                      DdeGetData ( hData, (LPBYTE) szDDEData, 80L, 0L );
  266.  
  267.                      if ( szDDEData != NULL )
  268.                         HandleOutput ( szDDEData );
  269.                      else
  270.                         HandleOutput ( "Message from server is null." );
  271.                   }
  272.                }
  273.                else
  274.                   HandleOutput ( "A connection to a DDE Server has not been established." );
  275.  
  276.                break;
  277.  
  278.             case IDM_ABOUT:
  279.                dlgProcAbout = (DLGPROC) MakeProcInstance ( (FARPROC)About, hInst );
  280.                DialogBox ( hInst, "AboutBox", hWnd, dlgProcAbout );
  281.                FreeProcInstance ( (FARPROC) dlgProcAbout );
  282.                break;
  283.  
  284.             default:
  285.                return ( DefWindowProc ( hWnd, message, wParam, lParam ) );
  286.          }
  287.          break;
  288.  
  289.       case WM_PAINT:
  290.          hDC = BeginPaint ( hWnd, &ps );
  291.  
  292.          y = 0;
  293.  
  294.          for ( i = 0; i < cTotalLines; i ++ )
  295.          {
  296.             if ( cTotalLines == 8 )
  297.                j = ( (cCurrentLine + 1 + i) % 9 );
  298.             else
  299.                j = i;         // can't do this if we clear window and start in middle of array
  300.  
  301.             TextOut ( hDC, 0, y, (LPSTR)(szScreenText[j]),
  302.                                  lstrlen ( szScreenText[j] ) );
  303.             y = y + cyChar;
  304.          }
  305.  
  306.          EndPaint ( hWnd, &ps );
  307.          break;
  308.  
  309.       case WM_DESTROY:
  310.          if ( hConv != NULL )
  311.          {
  312.             DdeDisconnect ( hConv );
  313.             hConv = NULL;
  314.          }
  315.  
  316.          DdeFreeStringHandle ( idInst, hszService );
  317.          DdeFreeStringHandle ( idInst, hszTopic );
  318.          DdeFreeStringHandle ( idInst, hszItem );
  319.  
  320.          FreeProcInstance ( lpDdeProc );
  321.  
  322.          PostQuitMessage ( 0 );
  323.          break;
  324.  
  325.       default:
  326.          return ( DefWindowProc ( hWnd, message, wParam, lParam ) );
  327.    }
  328.  
  329.    return ( FALSE );
  330. }
  331.  
  332. /***************************************************************************/
  333.  
  334. #pragma argsused
  335. BOOL CALLBACK About ( HWND hDlg, UINT message,
  336.                         WPARAM wParam, LPARAM lParam )
  337. {
  338.    switch  ( message )
  339.    {
  340.       case WM_INITDIALOG:           /* message: initialize dialog box */
  341.          return ( TRUE );
  342.  
  343.       case WM_COMMAND:              /* message: received a command */
  344.          if ( wParam == IDOK || wParam == IDCANCEL )
  345.          {
  346.             EndDialog ( hDlg, TRUE );          /* Exits the dialog box         */
  347.             return ( TRUE );
  348.          }
  349.          break;
  350.    }
  351.    return ( FALSE );                  /* Didn't process a message    */
  352. }
  353.  
  354. /***************************************************************************/
  355.  
  356. #pragma argsused
  357. HDDEDATA EXPENTRY DDECallback ( WORD wType, WORD wFmt, HCONV hConvX, HSZ hsz1,
  358.                                 HSZ hsz2, HDDEDATA hData, DWORD dwData1,
  359.                                 DWORD dwData2 )
  360. {
  361.    switch ( wType )
  362.    {
  363.       case XTYP_DISCONNECT:
  364.          hConv = NULL;
  365.          HandleOutput ( "The server forced a disconnect." );
  366.          return ( (HDDEDATA) NULL );
  367.  
  368.       case XTYP_ERROR:
  369.          break;
  370.  
  371.       case XTYP_XACT_COMPLETE:
  372.          // compare transaction identifier, indicate transaction complete
  373.          break;
  374.  
  375.    }
  376.  
  377.    return ( (HDDEDATA) NULL );
  378. }
  379.  
  380. /***************************************************************************/
  381.  
  382. void HandleError ( WORD DdeError )
  383. {
  384.    switch ( DdeError )
  385.    {
  386.       case DMLERR_DLL_NOT_INITIALIZED:
  387.          HandleOutput ( "DLL not initialized." );
  388.          break;
  389.  
  390.       case DMLERR_INVALIDPARAMETER:
  391.          HandleOutput ( "Invalid parameter." );
  392.          break;
  393.  
  394.       case DMLERR_NO_CONV_ESTABLISHED:
  395.          HandleOutput ( "No conversation established." );
  396.          break;
  397.  
  398.       case DMLERR_NO_ERROR:
  399.          HandleOutput ( "No error." );
  400.          break;
  401.    }
  402. }
  403.  
  404. /***************************************************************************/
  405.  
  406. void HandleOutput ( char *szOutputString )
  407. {
  408.    strcpy ( szScreenText[cCurrentLine], szOutputString );
  409.    cCurrentLine = ( cCurrentLine + 1 ) % 9;
  410.  
  411.    if ( cTotalLines < 8 )
  412.       cTotalLines++;
  413.  
  414.    InvalidateRect ( hWnd, NULL, TRUE );
  415.    UpdateWindow ( hWnd );
  416. }
  417.  
  418.