home *** CD-ROM | disk | FTP | other *** search
- // ObjectWindows - (C) Copyright 1992 by Borland International
- //
- // ddecli.cpp
-
- /*
- * This is a sample application using the OWL library that demonstrats the
- * use of the Windows 3.1 DDEML API in a client application. You should
- * first build the server application, DDESVR.EXE, and run it. Then run the
- * client application, DDECLI.EXE, to start a conversation. Detailed
- * information on DDEML can found in the online help and is suggested
- * reading for anyone interested in writing DDEML applications. Search on
- * the keyword DDEML.
- */
-
- #include "ddecli.h"
-
- PTDMLClWnd pStaticThis = NULL;
-
- TDMLClApp::TDMLClApp( LPSTR lpszNam, HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpszCmdLn, int nCmdShw )
- : TApplication( lpszNam, hInst, hPrevInst, lpszCmdLn, nCmdShw )
- {
- }
-
- TDMLClApp::~TDMLClApp()
- {
- }
-
- void TDMLClApp::InitMainWindow()
- {
- MainWindow = new TDMLClWnd( NULL, "DDECLI (A DDE Client)" );
- }
-
- TDMLClWnd::TDMLClWnd( PTWindowsObject AParent, LPSTR ATitle )
- : TWindow( AParent, ATitle )
- {
- }
-
- TDMLClWnd::~TDMLClWnd()
- {
- /*
- * This clean up is required for those resources that were allocated during the
- * DDEML conversation.
- */
- if( hConv != 0 )
- {
- DdeDisconnect( hConv ); // Let the other party know we are leaving
- hConv = 0;
- }
- if( idInst != 0 )
- {
- DdeFreeStringHandle( idInst, hszService );
- DdeFreeStringHandle( idInst, hszTopic );
- DdeFreeStringHandle( idInst, hszItem );
- DdeUninitialize(idInst);
- idInst = 0;
- }
- if( lpCallBack != NULL )
- {
- FreeProcInstance( (FARPROC)lpCallBack );
- lpCallBack = NULL;
- }
- }
-
- void TDMLClWnd::SetupWindow()
- {
- AssignMenu( TDMLClWnd_MENU );
- pStaticThis = this;
- idInst = 0; // MUST be 0 the first time DdeInitialize() is called!
- hConv = 0;
- tfLoop = 0;
- szData[0] = '\0';
- hszService = hszTopic = hszItem = 0;
- /*
- * The code below sets up the DDEML call back function that is used by the
- * DDE Management Library to carry out data transfers between applications.
- */
- lpCallBack = MakeProcInstance( (FARPROC)TDMLClWnd::CallBack, GetApplication()->hInstance );
- if( lpCallBack != NULL )
- {
- if( DdeInitialize( &idInst, (PFNCALLBACK)lpCallBack, APPCMD_CLIENTONLY, 0 ) == DMLERR_NO_ERROR )
- {
- hszService = DdeCreateStringHandle( idInst, "TDMLSR_Server", CP_WINANSI );
- hszTopic = DdeCreateStringHandle( idInst, "Borland", CP_WINANSI );
- hszItem = DdeCreateStringHandle( idInst, "Products", CP_WINANSI );
- if( (hszService == NULL) || (hszTopic == NULL) || (hszItem == NULL) )
- {
- MessageBox( HWindow, "Creation of strings failed.", Title, MB_ICONSTOP );
- PostQuitMessage( 0 );
- }
- } else {
- MessageBox( HWindow, "Initialization failed.", Title, MB_ICONSTOP );
- PostQuitMessage( 0 );
- }
- } else {
- MessageBox( HWindow, "Setup of callback failed.", Title, MB_ICONSTOP );
- PostQuitMessage( 0 );
- }
- }
-
- void TDMLClWnd::Paint( HDC hdc, PAINTSTRUCT _FAR & )
- {
- RECT rTemp;
- char szTemp[] = "This example of the Dynamic Data Exchange Management \
- Library obtains the names of various Borland products from the server \
- DDESVR.EXE. To get started, first run DDESVR.EXE and then select the \"Connect!\" menu item.";
-
- GetClientRect( HWindow, &rTemp );
- if( szData[0] != '\0' )
- {
- // The szData string is obtained from the DDESVR.EXE DDE Server.
- DrawText( hdc, szData, strlen( szData ), &rTemp, DT_SINGLELINE | DT_CENTER | DT_VCENTER );
- } else {
- DrawText( hdc, szTemp, strlen( szTemp ), &rTemp, DT_WORDBREAK );
- }
- }
-
- void TDMLClWnd::CMExit( RTMessage Msg )
- {
- TWindow::CMExit( Msg );
- }
-
- void TDMLClWnd::WMInitMenu( RTMessage Msg )
- {
- HMENU hmTemp;
-
- /*
- This trick is used to automatically update the status of the various
- menu choices just before it is displayed.
- */
- hmTemp = (HMENU)Msg.WParam;
- EnableMenuItem( hmTemp, CM_U_CONNECT, ( hConv == 0 )? MF_ENABLED : MF_GRAYED );
- EnableMenuItem( hmTemp, CM_U_REQUEST, ( hConv != 0 )? MF_ENABLED : MF_GRAYED );
- EnableMenuItem( hmTemp, CM_U_POKE, ( hConv != 0 )? MF_ENABLED : MF_GRAYED );
- EnableMenuItem( hmTemp, CM_U_ADVISE, ( hConv != 0 )? MF_ENABLED : MF_GRAYED );
- CheckMenuItem( hmTemp, CM_U_ADVISE, MF_BYCOMMAND | ( tfLoop == TRUE )? MF_CHECKED : MF_UNCHECKED );
- DrawMenuBar( HWindow );
- }
-
- // The following 4 functions are used to communicate with DDE Server(s).
-
- void TDMLClWnd::CMUConnect( RTMessage )
- {
- hConv = DdeConnect( idInst, hszService, hszTopic, NULL );
- if( hConv != 0 )
- {
- PostMessage( HWindow, WM_INITMENU, (WPARAM)GetMenu( HWindow ), 0 );
- } else {
- MessageBox( HWindow, "Can't start conversation.\nTry running DDESVR (the server).", Title, MB_ICONSTOP );
- }
- }
-
- void TDMLClWnd::CMURequest( RTMessage )
- {
- HDDEDATA hData;
-
- hData = DdeClientTransaction( NULL, 0, hConv, hszItem, CF_TEXT, XTYP_REQUEST, 0, NULL );
- if( hData != FALSE ) ReceivedData( hData );
- }
-
- void TDMLClWnd::CMUPoke( RTMessage )
- {
- char szTemp[42] = "";
-
- if( GetApplication()->ExecDialog( new TInputDialog( this, Title, "Poke string : ", szTemp, sizeof( szTemp ) ) ) == IDOK )
- {
- DdeClientTransaction( (LPBYTE)szTemp, strlen( szTemp ) + 1, hConv, hszItem, CF_TEXT, XTYP_POKE, 1000, NULL );
- }
- }
-
- void TDMLClWnd::CMUAdvise( RTMessage Msg )
- {
- HMENU hTempMenu;
- DWORD dwTempResult;
-
- hTempMenu = GetMenu( HWindow );
- if( GetMenuState( hTempMenu, Msg.WParam, MF_BYCOMMAND ) == MF_UNCHECKED )
- {
- if( (BOOL)DdeClientTransaction( NULL, 0, hConv, hszItem, CF_TEXT, XTYP_ADVSTART | XTYPF_ACKREQ, 1000, &dwTempResult ) == TRUE )
- {
- CheckMenuItem( hTempMenu, Msg.WParam, MF_BYCOMMAND | MF_CHECKED );
- tfLoop = TRUE;
- }
- } else {
- if( (BOOL)DdeClientTransaction( NULL, 0, hConv, hszItem, CF_TEXT, XTYP_ADVSTOP, 1000, &dwTempResult ) == TRUE )
- {
- CheckMenuItem( hTempMenu, Msg.WParam, MF_BYCOMMAND | MF_UNCHECKED );
- tfLoop = FALSE;
- }
- }
- DrawMenuBar( HWindow );
- }
-
- void TDMLClWnd::CMUHelpAbout( RTMessage )
- {
- MessageBox( HWindow, "DDECLI.EXE\nWritten using ObjectWindows\nCopyright (c) 1992 by Borland International", "About DDECLI", MB_ICONINFORMATION );
- }
-
- void TDMLClWnd::ReceivedData( HDDEDATA hData )
- {
- /*
- This function is called when the callback function is notified of
- available data.
- */
- if( hData != NULL )
- {
- DdeGetData( hData, &szData, sizeof( szData ), 0 );
- InvalidateRect( HWindow, NULL, TRUE );
- }
- }
-
- /*
- This call back function is the heart of interaction between this program
- and DDEML. Because Windows doesn't pass C++ 'this' pointers to call
- back functions, a static 'this' pointer was used. If you wanted to
- create a Client that would allow for more than one conversation, using a
- List of conversations and their associated 'this' pointers would be one
- possible method to try. The XTYP_ constants are described in detail in
- the online help.
- */
- HDDEDATA FAR PASCAL _export TDMLClWnd::CallBack( WORD wType, WORD, HCONV hConv, HSZ, HSZ, HDDEDATA hData, DWORD, DWORD )
- {
- switch( wType )
- {
- case XTYP_ADVDATA :
- if( hConv == pStaticThis->hConv )
- {
- pStaticThis->ReceivedData( hData );
- }
- return (HDDEDATA)DDE_FACK;
- case XTYP_XACT_COMPLETE :
- if( hConv == pStaticThis->hConv ) pStaticThis->ReceivedData( hData );
- break;
- case XTYP_DISCONNECT :
- MessageBox( pStaticThis->HWindow, "Disconnected.", pStaticThis->Title, MB_ICONINFORMATION );
- pStaticThis->hConv = 0;
- pStaticThis->tfLoop = 0;
- PostMessage( pStaticThis->HWindow, WM_INITMENU, (WPARAM)GetMenu( pStaticThis->HWindow ), 0 );
- break;
- case XTYP_ERROR :
- MessageBox( pStaticThis->HWindow, "A critical DDE error has occured.", pStaticThis->Title, MB_ICONINFORMATION );
- break;
- default :
- break;
- }
- return NULL;
- }
-
- int PASCAL WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpszCmdLn, int nCmdShw )
- {
- TDMLClApp App( "DDECLI Application", hInst, hPrevInst, lpszCmdLn, nCmdShw );
-
- App.Run();
- return App.Status;
- }
-