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 >
Wrap
C/C++ Source or Header
|
1997-07-23
|
13KB
|
426 lines
/* Borland C++ - (C) Copyright 1994 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>
#pragma hdrstop
#include <ddeml.h>
#include <dde.h>
#include <windowsx.h>
#include <stdio.h>
#include <string.h>
#include "ddeclnt.h"
HANDLE hInst; /* Current instance of application */
HWND hWnd; /* Handle of Main window */
int xScreen; /* Screen metrics */
int yScreen; /* ... */
int yFullScreen; /* ... */
int xFrame; /* ... */
int yMenu; /* ... */
TEXTMETRIC tm; /* Text metrics */
int cxChar; /* Character metrics */
int cyChar; /* ... */
char szScreenText[10][80]; /* Contains 10 lines of display data*/
int cCurrentLine; /* Index into szScreenText */
int 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 = (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, 0, 0 ) )
{
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, 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 */
}
/***************************************************************************/
#pragma warn -eff
LRESULT CALLBACK _export MainWndProc ( HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam )
{
HDC hDC;
PAINTSTRUCT ps;
DLGPROC dlgProcAbout;
int i;
int j;
int 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 ( GET_WM_COMMAND_ID(wParam, lParam) )
{
case IDM_EXIT:
DestroyWindow ( hWnd );
break;
case IDM_CONNECT_SERVER:
if ( hConv == (HCONV)NULL )
{
hConv = DdeConnect ( idInst, hszService, hszTopic,
(PCONVCONTEXT) NULL );
if ( hConv == (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 != (HCONV)NULL )
{
DdeDisconnect ( hConv );
hConv = (HCONV)NULL;
HandleOutput ( "Disconnected from server." );
}
else
HandleOutput ( "Must be connected before disconnecting." );
break;
case IDM_MSG_TO_SERVER:
if ( hConv != (HCONV)NULL )
{
iClientCount ++;
sprintf ( tbuf, "%3d.", iClientCount );
strncpy ( &szDDEString[36], tbuf, 5 );
#if defined(__WIN32__)
hData = DdeCreateDataHandle ( idInst, (LPBYTE) szDDEString,
#else
hData = DdeCreateDataHandle ( idInst, szDDEString,
#endif
sizeof ( szDDEString ), 0L, hszItem, wFmt, 0 );
if ( hData != (HDDEDATA)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 != (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 != (HCONV)NULL )
{
DdeDisconnect ( hConv );
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 warn .eff
/***************************************************************************/
#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 ( GET_WM_COMMAND_ID(wParam, lParam) == IDOK ||
GET_WM_COMMAND_ID(wParam, lParam) == IDCANCEL )
{
EndDialog ( hDlg, TRUE ); /* Exits the dialog box */
return ( TRUE );
}
break;
}
return ( FALSE ); /* Didn't process a message */
}
/***************************************************************************/
#pragma argsused
HDDEDATA EXPENTRY _export DDECallback ( WORD wType, WORD wFmt, HCONV hConvX, HSZ hsz1,
HSZ hsz2, HDDEDATA hData, DWORD dwData1,
DWORD dwData2 )
{
switch ( wType )
{
case XTYP_DISCONNECT:
hConv = (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 ( DWORD 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 );
}