home *** CD-ROM | disk | FTP | other *** search
- /* Borland C++ - (C) Copyright 1992 by Borland International */
-
- /***************************************************************************
-
- Program Name DDEClnt.c
-
- Purpose A simple DDE client application, which communicates
- to a DDE server using the new 3.1 api DDEML calls.
-
- To use this program, build DDEClnt and DDESrvr. There
- are project files for this. From the DDEClnt, connect
- to the server, and send pre-formatted messages to the
- the server, and request messages from the server.
- Disconnect before closing app.
-
- ****************************************************************************/
-
- #define STRICT
-
- #include <windows.h>
- #include <ddeml.h>
- #include <dde.h>
-
- #include <stdio.h>
- #include <string.h>
-
- #include "ddeclnt.h"
-
-
- HANDLE hInst; /* Current instance of application */
- HWND hWnd; /* Handle of Main window */
-
- short xScreen; /* Screen metrics */
- short yScreen; /* ... */
- short yFullScreen; /* ... */
- short xFrame; /* ... */
- short yMenu; /* ... */
- TEXTMETRIC tm; /* Text metrics */
- short cxChar; /* Character metrics */
- short cyChar; /* ... */
-
- char szScreenText[10][80]; /* Contains 10 lines of display data*/
- short cCurrentLine; /* Index into szScreenText */
- short cTotalLines; /* Total lines in szScreenText */
-
- /*
- The DDE variables
- */
-
- DWORD idInst = 0L; /* Instance of app for DDEML */
- FARPROC lpDdeProc; /* DDE callback function */
- HSZ hszService;
- HSZ hszTopic;
- HSZ hszItem;
- HCONV hConv = NULL; /*Handle of established conversation*/
- HDDEDATA hData;
- DWORD dwResult;
- WORD wFmt = CF_TEXT; /* Clipboard format */
- char szDDEString[80]; /* Local allocation of data buffer */
- char szDDEData[80]; /* Local receive data buffer */
- int iClientCount = 0; /* Client to Server message counter*/
- char tbuf[5]; /* Temporary, to hold count */
-
- char szAppName[] = "DDEClientApplication";
-
-
- /***************************************************************************/
-
- #pragma argsused
- int PASCAL WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance,
- LPSTR lpszCmdLine, int nCmdShow )
- {
- MSG msg;
-
-
- if ( !hPrevInstance ) /* Other instances of app running? */
- if ( !InitApplication ( hInstance ) ) /* Initialize shared things */
- return ( FALSE ); /* Exits if unable to initialize */
-
- if ( !InitInstance ( hInstance, nCmdShow ) )
- return ( FALSE );
-
- while ( GetMessage ( &msg, NULL, NULL, NULL ) )
- {
- TranslateMessage ( &msg );
- DispatchMessage ( &msg );
- }
-
- DdeUninitialize ( idInst );
-
- return ( msg.wParam );
- }
-
- /***************************************************************************/
-
- BOOL FAR PASCAL InitApplication ( HANDLE hInstance )
- {
- WNDCLASS wc;
-
- wc.style = CS_HREDRAW | CS_VREDRAW;
- wc.lpfnWndProc = MainWndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = hInstance;
- wc.hIcon = LoadIcon ( hInstance, "DDEClientIcon" );
- wc.hCursor = LoadCursor ( NULL, IDC_ARROW );
- wc.hbrBackground = GetStockObject ( WHITE_BRUSH );
- wc.lpszMenuName = "DDEClientMenu";
- wc.lpszClassName = szAppName;
-
- if ( !RegisterClass ( &wc ) )
- return ( FALSE );
-
- return ( TRUE );
- }
-
- /***************************************************************************/
-
- BOOL InitInstance ( HANDLE hInstance, short int nCmdShow )
- {
- hInst = hInstance;
-
- xScreen = GetSystemMetrics ( SM_CXSCREEN );
- yScreen = GetSystemMetrics ( SM_CYSCREEN );
-
- hWnd = CreateWindow ( szAppName,
- "DDE Client Window",
- WS_OVERLAPPEDWINDOW,
- 10, /* These co-ordinates look */
- 10, /* good on a VGA monitor */
- xScreen - 200, /* running in 640x480. No */
- yScreen / 2 - 50, /* combination was tried. */
- NULL,
- NULL,
- hInstance,
- NULL );
-
- /*
- If window could not be created, return "failure"
- */
-
- if ( !hWnd )
- return ( FALSE );
-
- /*
- Make the window visible; update its client area; and return "success"
- */
-
- ShowWindow ( hWnd, nCmdShow ); /* Show the window */
- UpdateWindow ( hWnd ); /* Sends WM_PAINT message */
- return ( TRUE ); /* Returns the value from PostQuitMessage */
-
- }
-
- /***************************************************************************/
-
- LRESULT CALLBACK MainWndProc ( HWND hWnd, UINT message,
- WPARAM wParam, LPARAM lParam )
- {
- HDC hDC;
- PAINTSTRUCT ps;
- DLGPROC dlgProcAbout;
- int i;
- int j;
- short y;
-
-
- switch ( message )
- {
- case WM_CREATE:
- hDC = GetDC ( hWnd );
-
- GetTextMetrics ( hDC, &tm );
- cxChar = tm.tmAveCharWidth;
- cyChar = tm.tmHeight + tm.tmExternalLeading;
-
- ReleaseDC ( hWnd, hDC );
-
- lpDdeProc = MakeProcInstance ( (FARPROC) DDECallback, hInst );
- if ( DdeInitialize ( (LPDWORD)&idInst, (PFNCALLBACK)lpDdeProc,
- APPCMD_CLIENTONLY, 0L ) )
- {
- HandleOutput ( "Client DDE initialization failure." );
- return ( FALSE );
- }
-
- hszService = DdeCreateStringHandle ( idInst, "Borland", CP_WINANSI );
- hszTopic = DdeCreateStringHandle ( idInst, "DDEExample", CP_WINANSI );
- hszItem = DdeCreateStringHandle ( idInst, "DDEData", CP_WINANSI );
-
- cCurrentLine = 0;
- cTotalLines = 0;
-
- strcpy ( szDDEString, "Client application message number: " );
- break;
-
- case WM_COMMAND:
- switch ( wParam )
- {
- case IDM_EXIT:
- DestroyWindow ( hWnd );
- break;
-
- case IDM_CONNECT_SERVER:
- if ( hConv == NULL )
- {
- hConv = DdeConnect ( idInst, hszService, hszTopic,
- (PCONVCONTEXT) NULL );
- if ( hConv == NULL )
- {
- HandleError ( DdeGetLastError ( idInst ) );
- HandleOutput ( "Unsuccessful connection." );
- }
- else
- HandleOutput ( "Successful connection." );
- }
- else
- HandleOutput ( "Already connected to DDE Server." );
-
- break;
-
- case IDM_DISCONNECT_SERVER:
- if ( hConv != NULL )
- {
- DdeDisconnect ( hConv );
- hConv = NULL;
- HandleOutput ( "Disconnected from server." );
- }
- else
- HandleOutput ( "Must be connected before disconnecting." );
-
- break;
-
- case IDM_MSG_TO_SERVER:
- if ( hConv != NULL )
- {
- iClientCount ++;
- sprintf ( tbuf, "%3d.", iClientCount );
- strncpy ( &szDDEString[36], tbuf, 5 );
-
- hData = DdeCreateDataHandle ( idInst, &szDDEString,
- sizeof ( szDDEString ), 0L, hszItem, wFmt, 0 );
-
- if ( hData != NULL )
- hData = DdeClientTransaction ( (LPBYTE)hData, -1, hConv,
- hszItem, wFmt, XTYP_POKE, 1000, &dwResult );
- else
- HandleOutput ( "Could not create data handle." );
- }
- else
- HandleOutput ( "A connection to a DDE Server has not been established." );
-
- break;
-
- case IDM_MSG_FROM_SERVER:
- if ( hConv != NULL )
- {
- hData = DdeClientTransaction ( NULL, 0, hConv,
- hszItem, wFmt, XTYP_REQUEST, 1000, &dwResult );
-
- if ( dwResult == DDE_FNOTPROCESSED )
- HandleOutput ( "Data not available from server." );
- else
- {
- DdeGetData ( hData, (LPBYTE) szDDEData, 80L, 0L );
-
- if ( szDDEData != NULL )
- HandleOutput ( szDDEData );
- else
- HandleOutput ( "Message from server is null." );
- }
- }
- else
- HandleOutput ( "A connection to a DDE Server has not been established." );
-
- break;
-
- case IDM_ABOUT:
- dlgProcAbout = (DLGPROC) MakeProcInstance ( (FARPROC)About, hInst );
- DialogBox ( hInst, "AboutBox", hWnd, dlgProcAbout );
- FreeProcInstance ( (FARPROC) dlgProcAbout );
- break;
-
- default:
- return ( DefWindowProc ( hWnd, message, wParam, lParam ) );
- }
- break;
-
- case WM_PAINT:
- hDC = BeginPaint ( hWnd, &ps );
-
- y = 0;
-
- for ( i = 0; i < cTotalLines; i ++ )
- {
- if ( cTotalLines == 8 )
- j = ( (cCurrentLine + 1 + i) % 9 );
- else
- j = i; // can't do this if we clear window and start in middle of array
-
- TextOut ( hDC, 0, y, (LPSTR)(szScreenText[j]),
- lstrlen ( szScreenText[j] ) );
- y = y + cyChar;
- }
-
- EndPaint ( hWnd, &ps );
- break;
-
- case WM_DESTROY:
- if ( hConv != NULL )
- {
- DdeDisconnect ( hConv );
- hConv = NULL;
- }
-
- DdeFreeStringHandle ( idInst, hszService );
- DdeFreeStringHandle ( idInst, hszTopic );
- DdeFreeStringHandle ( idInst, hszItem );
-
- FreeProcInstance ( lpDdeProc );
-
- PostQuitMessage ( 0 );
- break;
-
- default:
- return ( DefWindowProc ( hWnd, message, wParam, lParam ) );
- }
-
- return ( FALSE );
- }
-
- /***************************************************************************/
-
- #pragma argsused
- BOOL CALLBACK About ( HWND hDlg, UINT message,
- WPARAM wParam, LPARAM lParam )
- {
- switch ( message )
- {
- case WM_INITDIALOG: /* message: initialize dialog box */
- return ( TRUE );
-
- case WM_COMMAND: /* message: received a command */
- if ( wParam == IDOK || wParam == IDCANCEL )
- {
- EndDialog ( hDlg, TRUE ); /* Exits the dialog box */
- return ( TRUE );
- }
- break;
- }
- return ( FALSE ); /* Didn't process a message */
- }
-
- /***************************************************************************/
-
- #pragma argsused
- HDDEDATA EXPENTRY DDECallback ( WORD wType, WORD wFmt, HCONV hConvX, HSZ hsz1,
- HSZ hsz2, HDDEDATA hData, DWORD dwData1,
- DWORD dwData2 )
- {
- switch ( wType )
- {
- case XTYP_DISCONNECT:
- hConv = NULL;
- HandleOutput ( "The server forced a disconnect." );
- return ( (HDDEDATA) NULL );
-
- case XTYP_ERROR:
- break;
-
- case XTYP_XACT_COMPLETE:
- // compare transaction identifier, indicate transaction complete
- break;
-
- }
-
- return ( (HDDEDATA) NULL );
- }
-
- /***************************************************************************/
-
- void HandleError ( WORD DdeError )
- {
- switch ( DdeError )
- {
- case DMLERR_DLL_NOT_INITIALIZED:
- HandleOutput ( "DLL not initialized." );
- break;
-
- case DMLERR_INVALIDPARAMETER:
- HandleOutput ( "Invalid parameter." );
- break;
-
- case DMLERR_NO_CONV_ESTABLISHED:
- HandleOutput ( "No conversation established." );
- break;
-
- case DMLERR_NO_ERROR:
- HandleOutput ( "No error." );
- break;
- }
- }
-
- /***************************************************************************/
-
- void HandleOutput ( char *szOutputString )
- {
- strcpy ( szScreenText[cCurrentLine], szOutputString );
- cCurrentLine = ( cCurrentLine + 1 ) % 9;
-
- if ( cTotalLines < 8 )
- cTotalLines++;
-
- InvalidateRect ( hWnd, NULL, TRUE );
- UpdateWindow ( hWnd );
- }
-
-