home *** CD-ROM | disk | FTP | other *** search
/ C Programming Starter Kit 2.0 / SamsPublishing-CProgrammingStarterKit-v2.0-Win31.iso / bc45 / ddemlwin.pak / DDECLNT.C next >
C/C++ Source or Header  |  1997-07-23  |  13KB  |  426 lines

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