|
|
//Copyright (c) 1998 - 1999 Microsoft Corporation
#include "stdafx.h"
#include <winsta.h>
#include "resource.h"
#include "asyncdlg.h"
#include <utildll.h>
//Most of the code for this has been borrowed from tscfg.
extern void ErrMessage( HWND hwndOwner , INT_PTR iResourceID );
static int LedIds[NUM_LEDS] = { IDC_ATDLG_DTR, IDC_ATDLG_RTS, IDC_ATDLG_CTS, IDC_ATDLG_DSR, IDC_ATDLG_DCD, IDC_ATDLG_RI };
INT_PTR CBInsertInstancedName( LPCTSTR pName , HWND hCombo );
void ParseRootAndInstance( LPCTSTR pString, LPTSTR pRoot, long *pInstance );
//---------------------------------------------------------------------------------------------------
CAsyncDlg::CAsyncDlg( ) { m_hDlg = NULL;
m_pCfgcomp = NULL;
m_nHexBase = 0;
m_szWinstation[ 0 ] = 0;
m_szWDName[ 0 ] = 0;
ZeroMemory( &m_ac , sizeof( ASYNCCONFIG ) );
ZeroMemory( &m_uc , sizeof( USERCONFIG ) );
ZeroMemory( &m_oldAC , sizeof( ASYNCCONFIG ) );
m_nOldAsyncDeviceNameSelection = ( INT )-1;
m_nOldAsyncConnectType = ( INT )-1;
m_nOldBaudRate = ( INT )-1;
m_nOldModemCallBack = ( INT )-1; }
//---------------------------------------------------------------------------------------------------
BOOL CAsyncDlg::OnInitDialog( HWND hDlg , LPTSTR szWDName , LPTSTR szWinstationName , ICfgComp *pCfgcomp ) { TCHAR tchName[ 80 ];
TCHAR tchErrTitle[ 80 ];
TCHAR tchErrMsg[ 256 ];
TCHAR szDecoratedName[ DEVICENAME_LENGTH + MODEMNAME_LENGTH + 1 ];
ASSERT( pCfgcomp != NULL );
if( m_pCfgcomp == NULL ) { m_pCfgcomp = pCfgcomp;
m_pCfgcomp->AddRef( ); }
m_hDlg = hDlg;
m_oldAC = m_ac;
if( szWinstationName != NULL ) { lstrcpyn( m_szWinstation , szWinstationName , SIZE_OF_BUFFER( m_szWinstation ) - sizeof( TCHAR ) ); }
if( szWDName != NULL ) { lstrcpyn( m_szWDName , szWDName , SIZE_OF_BUFFER( m_szWDName ) - sizeof( TCHAR ) ); }
// initialize controls
int idx = 0;
HRESULT hr;
SendMessage( GetDlgItem( hDlg , IDC_ASYNC_CONNECT ) , CB_RESETCONTENT , 0 , 0 );
while( SUCCEEDED( ( hr = pCfgcomp->GetConnTypeName( idx , tchName ) ) ) ) { if( hr == S_FALSE ) { break; }
SendMessage( GetDlgItem( hDlg , IDC_ASYNC_CONNECT ) , CB_ADDSTRING , 0 , ( LPARAM )tchName );
idx++; }
idx = 0;
SendMessage( GetDlgItem( hDlg , IDC_ASYNC_MODEMCALLBACK ) , CB_RESETCONTENT , 0 , 0 );
while( SUCCEEDED( ( hr = pCfgcomp->GetModemCallbackString( idx , tchName ) ) ) ) { if( hr == S_FALSE ) { break; }
SendMessage( GetDlgItem( hDlg , IDC_ASYNC_MODEMCALLBACK ) , CB_ADDSTRING , 0 , ( LPARAM )tchName );
idx++; }
// fill in device list
ULONG ulItems = 0;
LPBYTE pBuffer = NULL;
HWND hCombo = GetDlgItem( hDlg , IDC_ASYNC_DEVICENAME );
SendMessage( hCombo , CB_RESETCONTENT , 0 , 0 );
// szWDname is used for creating a new connection
// szWinstaionName is used if we're editing an existing connection
TCHAR *pszName = NULL;
NameType type = WdName;
if( szWDName == NULL ) { pszName = szWinstationName;
type = WsName; } else { pszName = szWDName; }
ASSERT( pszName != NULL );
hr = pCfgcomp->GetDeviceList( pszName , type , &ulItems , &pBuffer );
if( SUCCEEDED( hr ) ) { PPDPARAMS pPdParams = NULL;
DBGMSG( L"TSCC : GetDeviceList returned %d devices that are available\n" , ulItems );
for( idx = 0 , pPdParams = ( PPDPARAMS )pBuffer; idx < ( int )ulItems ; idx++, pPdParams++ ) { // Form decorated name.
#ifdef DBG
TCHAR temsg[ 128 ];
wsprintf( temsg , L"TSCC : %d ) %s is a device\n" , idx , pPdParams->Async.DeviceName );
ODS( temsg ); #endif
FormDecoratedAsyncDeviceName( szDecoratedName, &( pPdParams->Async ) );
if( pCfgcomp->IsAsyncDeviceAvailable( pPdParams->Async.DeviceName ) ) { CBInsertInstancedName( szDecoratedName , hCombo ); }
#if 0 // this block was taken from tscfg and to this date it still does not make any sense
/*
Don't add this device to the list if it is already in use by a WinStation other than the current one. */
if (FALSE == pCfgcomp->IsAsyncDeviceAvailable(pPdParams->Async.DeviceName)) continue;
// Insert the name into the combo-box if it's not a TAPI modem
// or it is a TAPI modem that's not being used by RAS and it's
// port is currently available.
INT_PTR nRet = SendMessage( hCombo , CB_FINDSTRINGEXACT , ( WPARAM )-1 , ( LPARAM )pPdParams->Async.DeviceName );
if( !*( pPdParams->Async.ModemName ) || ( /*!pPdParams->Async.Parity &&*/ ( nRet != ( INT_PTR )CB_ERR ) ) ) { CBInsertInstancedName( szDecoratedName , hCombo ); } #endif
// If this device is a modem, make sure that the raw port this
// device is configured on is not present in the list. This will
// also take care of removing the raw port for TAPI modems that are
// configured for use by RAS, in which case neither the configured.
// TAPI modem(s) or raw port will be present in the list.
INT_PTR nRet = SendMessage( hCombo , CB_FINDSTRINGEXACT , ( WPARAM )-1 , ( LPARAM )pPdParams->Async.DeviceName );
if( *( pPdParams->Async.ModemName ) && ( nRet != CB_ERR ) ) { ODS(L"Deleting item\n");
SendMessage( hCombo , CB_DELETESTRING , ( WPARAM )nRet , 0 ); }
}
LocalFree( pBuffer );
}
// Always make sure that the currently configured device is in
if( m_ac.DeviceName[0] != 0 ) { FormDecoratedAsyncDeviceName( szDecoratedName , &m_ac );
INT_PTR nRet = SendMessage( hCombo , CB_FINDSTRINGEXACT , ( WPARAM )-1 , ( LPARAM )szDecoratedName );
if( nRet == CB_ERR ) { nRet = CBInsertInstancedName( szDecoratedName , hCombo ); }
SendMessage( hCombo , CB_SETCURSEL , ( WPARAM )nRet , 0 );
m_nOldAsyncDeviceNameSelection = (int)nRet;
} else { SendMessage( hCombo , CB_SETCURSEL , ( WPARAM )0, 0 );
m_nOldAsyncDeviceNameSelection = 0;
}
INT_PTR iitem = SendMessage( hCombo , CB_GETCOUNT , ( WPARAM )0 , ( LPARAM )0); if(0 == iitem || CB_ERR == iitem) { LoadString( _Module.GetResourceInstance( ) , IDS_ERROR_TITLE , tchErrTitle , SIZE_OF_BUFFER( tchErrTitle ) );
LoadString( _Module.GetResourceInstance( ) , IDS_ERROR_NODEVICES , tchErrMsg , SIZE_OF_BUFFER( tchErrMsg ) );
MessageBox( hDlg , tchErrMsg , tchErrTitle , MB_OK | MB_ICONERROR );
return FALSE; }
// Set the BAUDRATE combo-box selection (in it's edit field) and limit the
// edit field text.
TCHAR string[ULONG_DIGIT_MAX];
wsprintf( string, TEXT("%lu"), m_ac.BaudRate );
m_nOldBaudRate = ( INT )m_ac.BaudRate;
HWND hBaud = GetDlgItem( hDlg , IDC_ASYNC_BAUDRATE );
SendMessage( hBaud , CB_RESETCONTENT , 0 , 0 );
SetDlgItemText( hDlg , IDC_ASYNC_BAUDRATE , string );
SendMessage(hBaud , CB_LIMITTEXT , ULONG_DIGIT_MAX - 1 , 0 );
//The Baud rate field should contain only numbers
HWND hEdit = GetWindow(hBaud,GW_CHILD);
if(hEdit) { LONG Style = GetWindowLong(hEdit, GWL_STYLE); SetWindowLong(hEdit,GWL_STYLE, Style | ES_NUMBER); }
TCHAR TempString[100]; // Number enough to hold the baud rate values
//Add the default strings to the BaudRate Field
lstrcpy(TempString, L"9600");
SendMessage(hBaud , CB_ADDSTRING ,(WPARAM)0 ,(LPARAM)(LPCTSTR)TempString );
lstrcpy(TempString, L"19200");
SendMessage(hBaud , CB_ADDSTRING ,(WPARAM)0 ,(LPARAM)(LPCTSTR)TempString );
lstrcpy(TempString, L"38400");
SendMessage(hBaud , CB_ADDSTRING ,(WPARAM)0 ,(LPARAM)(LPCTSTR)TempString );
lstrcpy(TempString, L"57600");
SendMessage(hBaud , CB_ADDSTRING ,(WPARAM)0 ,(LPARAM)(LPCTSTR)TempString );
lstrcpy(TempString, L"115200");
SendMessage(hBaud , CB_ADDSTRING ,(WPARAM)0 ,(LPARAM)(LPCTSTR)TempString );
lstrcpy(TempString, L"230400");
SendMessage(hBaud , CB_ADDSTRING ,(WPARAM)0 ,(LPARAM)(LPCTSTR)TempString );
// Set the CONNECT combo-box selection.
SendMessage( GetDlgItem( hDlg , IDC_ASYNC_CONNECT ) , CB_SETCURSEL , m_ac.Connect.Type , 0 );
m_nOldAsyncConnectType = ( INT )m_ac.Connect.Type;
// CoTaskMemFree( pac );
HWND hCbxModemCallback = GetDlgItem( hDlg , IDC_ASYNC_MODEMCALLBACK );
// Set the MODEMCALLBACK combo-box selection, phone number, and 'inherit'
// checkboxes, based on the current UserConfig settings.
SendMessage( hCbxModemCallback , CB_SETCURSEL , ( WPARAM )m_uc.Callback , 0 );
m_nOldModemCallBack = ( INT )m_uc.Callback;
SetDlgItemText( hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER , m_uc.CallbackNumber );
CheckDlgButton( hDlg , IDC_ASYNC_MODEMCALLBACK_INHERIT , m_uc.fInheritCallback );
CheckDlgButton( hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER_INHERIT , m_uc.fInheritCallbackNumber );
OnSelchangeAsyncDevicename( );
return TRUE;
}
//---------------------------------------------------------------------------------------------------
BOOL CAsyncDlg::OnSelchangeAsyncModemcallback() { HWND hCbx = GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK);
/*
* Ignore this notification if the combo box is in a dropped-down * state. */ if( SendMessage( hCbx , CB_GETDROPPEDSTATE , 0 , 0 ) ) { return FALSE; }
/*
* Fetch current callback selection. */
INT index = (INT)SendMessage(hCbx,CB_GETCURSEL,0,0);
if( index != m_nOldModemCallBack ) { m_uc.Callback = (CALLBACKCLASS)index;
m_nOldModemCallBack = index;
if( index == 0 ) // disabled
{ EnableWindow( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER ) , FALSE );
//EnableWindow( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER_INHERIT ) , FALSE );
} else { // inusre that these controls are in the proper state
OnClickedAsyncModemcallbackPhonenumberInherit(); }
return TRUE; }
return FALSE;
} // end OnSelchangeAsyncModemcallback
//---------------------------------------------------------------------------------------------------
void CAsyncDlg::OnSelchangeAsyncModemcallbackPhoneNumber() { GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER);
/*
* Fetch current callback Phone number. */ GetDlgItemText(m_hDlg, IDC_ASYNC_MODEMCALLBACK_PHONENUMBER, m_uc.CallbackNumber,SIZE_OF_BUFFER(m_uc.CallbackNumber));
return;
} // end OnSelchangeAsyncModemcallback
//---------------------------------------------------------------------------------------------------
BOOL CAsyncDlg::OnSelchangeAsyncConnect() { HWND hCbx = GetDlgItem( m_hDlg , IDC_ASYNC_CONNECT );
/*
* Ignore this notification if the combo box is in a dropped-down * state. */ if( SendMessage( hCbx , CB_GETDROPPEDSTATE , 0 , 0 ) ) { return FALSE; }
INT index = ( INT )SendMessage(hCbx,CB_GETCURSEL,0,0);
if( index != m_nOldAsyncConnectType ) { m_ac.Connect.Type = (ASYNCCONNECTCLASS)index;
m_nOldAsyncConnectType = index;
return TRUE; }
return FALSE; } // end CAsyncDlg::OnSelchangeAsyncConnect
//---------------------------------------------------------------------------------------------------
BOOL CAsyncDlg::OnSelchangeAsyncBaudrate() { HWND hCbx = GetDlgItem( m_hDlg , IDC_ASYNC_BAUDRATE );
ODS( L"TSCC : OnSelchangeAsyncBaudrate\n" );
TCHAR string[ULONG_DIGIT_MAX], *endptr = NULL;
/*
* Ignore this notification if the combo box is in a dropped-down * state. */ if( SendMessage( hCbx , CB_GETDROPPEDSTATE , 0 , 0 ) ) { return FALSE; }
//GetDlgItemText(m_hDlg, IDC_ASYNC_BAUDRATE, string,ULONG_DIGIT_MAX);
int idx = ( int )SendMessage( hCbx , CB_GETCURSEL , 0 , 0 );
SendMessage( hCbx , CB_GETLBTEXT , ( WPARAM )idx , ( LPARAM )&string[ 0 ] );
INT nBaudRate = ( INT )wcstoul(string, &endptr, 10);
if( m_nOldBaudRate != nBaudRate ) { m_ac.BaudRate = nBaudRate;
m_nOldBaudRate = nBaudRate;
return TRUE; }
return FALSE;
} // end CAsyncDlg::OnSelchangeAsyncBaudrate
//---------------------------------------------------------------------------------------------------
void CAsyncDlg::OnClickedModemProperties() { if ( !ConfigureModem( m_ac.ModemName, m_hDlg) ) { ErrMessage(m_hDlg,IDP_ERROR_MODEM_PROPERTIES_NOT_AVAILABLE); } return;
}
//---------------------------------------------------------------------------------------------------
BOOL CAsyncDlg::OnSelchangeAsyncDevicename( ) { HWND hCbx = GetDlgItem( m_hDlg , IDC_ASYNC_DEVICENAME );
BOOL bModemEnableFlag, bDirectEnableFlag;
INT_PTR index;
int nModemCmdShow, nDirectCmdShow;
// Ignore this notification if the combo box is in a dropped-down state.
if( SendMessage( hCbx , CB_GETDROPPEDSTATE , 0 , 0 ) ) { return TRUE; }
if( ( index = SendMessage( hCbx , CB_GETCURSEL , 0 , 0 ) ) != CB_ERR ) {
if( m_nOldAsyncDeviceNameSelection != index ) { TCHAR szDeviceName[DEVICENAME_LENGTH+MODEMNAME_LENGTH+1];
// Fetch current selection and parse into device and modem names.
TCHAR tchErrMsg[ 512 ];
TCHAR tchbuf[ 356 ];
TCHAR tchErrTitle[ 80 ];
LONG lCount = 0;
if( m_pCfgcomp != NULL ) { m_pCfgcomp->QueryLoggedOnCount( m_szWinstation , &lCount );
if( lCount > 0 ) { if( *m_ac.ModemName != 0 ) { VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_CHANGE_ASYNC , tchbuf , SIZE_OF_BUFFER( tchbuf ) ) ); } else { VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_CHANGE_MODEM , tchbuf , SIZE_OF_BUFFER( tchbuf ) ) ); }
wsprintf( tchErrMsg , tchbuf , m_szWinstation ); VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_WARN_TITLE , tchErrTitle , SIZE_OF_BUFFER( tchErrTitle ) ) );
if( MessageBox( m_hDlg , tchErrMsg , tchErrTitle , MB_YESNO | MB_ICONEXCLAMATION ) == IDNO ) { SendMessage( hCbx , CB_SETCURSEL , ( WPARAM )m_nOldAsyncDeviceNameSelection , 0 );
return FALSE;
} } }
SendMessage( hCbx , CB_GETLBTEXT , ( WPARAM )index , ( LPARAM )&szDeviceName[0] );
ParseDecoratedAsyncDeviceName( szDeviceName , &m_ac );
m_nOldAsyncDeviceNameSelection = (INT)index; } else { return FALSE; }
}
/*
* The SetDefaults, Advanced, and Test buttons and Device Connect * and Baud fields are enabled if the configuration is non-modem. * Otherwise, the Configure Modem button and modem callback fields * are enabled. (The Install Modems buttons is always enabled). */ if( ( *m_ac.ModemName != 0 ) ) {
bModemEnableFlag = TRUE; nModemCmdShow = SW_SHOW; bDirectEnableFlag = FALSE; nDirectCmdShow = SW_HIDE;
} else {
bModemEnableFlag = FALSE; nModemCmdShow = SW_HIDE; bDirectEnableFlag = TRUE; nDirectCmdShow = SW_SHOW;
}
ShowWindow( GetDlgItem( m_hDlg, IDL_ASYNC_MODEMCALLBACK) , nModemCmdShow );
EnableWindow( GetDlgItem( m_hDlg, IDL_ASYNC_MODEMCALLBACK ) , bModemEnableFlag );
ShowWindow( GetDlgItem( m_hDlg, IDC_MODEM_PROP_PROP) , nModemCmdShow );
EnableWindow( GetDlgItem( m_hDlg, IDC_MODEM_PROP_PROP ) , bModemEnableFlag );
ShowWindow( GetDlgItem( m_hDlg, IDC_MODEM_PROP_WIZ) , nModemCmdShow );
EnableWindow( GetDlgItem( m_hDlg, IDC_MODEM_PROP_WIZ ) , bModemEnableFlag );
ShowWindow( GetDlgItem( m_hDlg, IDL_ASYNC_MODEMCALLBACK1 ) , nModemCmdShow );
EnableWindow( GetDlgItem( m_hDlg, IDL_ASYNC_MODEMCALLBACK1 ) , bModemEnableFlag );
ShowWindow( GetDlgItem( m_hDlg, IDC_ASYNC_MODEMCALLBACK ) , nModemCmdShow );
EnableWindow( GetDlgItem( m_hDlg, IDC_ASYNC_MODEMCALLBACK ) , bModemEnableFlag );
ShowWindow( GetDlgItem( m_hDlg, IDC_ASYNC_MODEMCALLBACK_INHERIT ) , nModemCmdShow );
EnableWindow( GetDlgItem( m_hDlg, IDC_ASYNC_MODEMCALLBACK_INHERIT ) , bModemEnableFlag );
ShowWindow( GetDlgItem( m_hDlg, IDL_ASYNC_MODEMCALLBACK_PHONENUMBER ) , nModemCmdShow );
EnableWindow( GetDlgItem( m_hDlg, IDL_ASYNC_MODEMCALLBACK_PHONENUMBER ) , bModemEnableFlag );
ShowWindow( GetDlgItem( m_hDlg, IDC_ASYNC_MODEMCALLBACK_PHONENUMBER ) , nModemCmdShow );
EnableWindow( GetDlgItem( m_hDlg, IDC_ASYNC_MODEMCALLBACK_PHONENUMBER ) , bModemEnableFlag );
ShowWindow( GetDlgItem( m_hDlg, IDC_ASYNC_MODEMCALLBACK_PHONENUMBER_INHERIT ) , nModemCmdShow );
EnableWindow( GetDlgItem( m_hDlg, IDC_ASYNC_MODEMCALLBACK_PHONENUMBER_INHERIT ) , bModemEnableFlag );
ShowWindow( GetDlgItem( m_hDlg, IDL_ASYNC_CONNECT ) , nDirectCmdShow );
EnableWindow( GetDlgItem( m_hDlg, IDL_ASYNC_CONNECT ) , bDirectEnableFlag );
ShowWindow( GetDlgItem( m_hDlg, IDC_ASYNC_CONNECT ) , nDirectCmdShow );
EnableWindow( GetDlgItem( m_hDlg, IDC_ASYNC_CONNECT ) , bDirectEnableFlag );
ShowWindow( GetDlgItem( m_hDlg, IDL_ASYNC_BAUDRATE ) , nDirectCmdShow );
EnableWindow( GetDlgItem( m_hDlg, IDL_ASYNC_BAUDRATE ) , bDirectEnableFlag );
ShowWindow( GetDlgItem( m_hDlg, IDC_ASYNC_BAUDRATE ) , nDirectCmdShow );
EnableWindow( GetDlgItem( m_hDlg, IDC_ASYNC_BAUDRATE ) , bDirectEnableFlag );
ShowWindow( GetDlgItem( m_hDlg, IDC_ASYNC_DEFAULTS ) , nDirectCmdShow );
EnableWindow( GetDlgItem( m_hDlg, IDC_ASYNC_DEFAULTS ) , bDirectEnableFlag );
ShowWindow( GetDlgItem( m_hDlg, IDC_ASYNC_ADVANCED ) , nDirectCmdShow );
EnableWindow( GetDlgItem( m_hDlg, IDC_ASYNC_ADVANCED ) , bDirectEnableFlag );
ShowWindow( GetDlgItem( m_hDlg, IDC_ASYNC_TEST ) , nDirectCmdShow );
EnableWindow( GetDlgItem( m_hDlg, IDC_ASYNC_TEST ) , bDirectEnableFlag );
// If this is a modem device, properly set the callback fields.
if( ( *m_ac.ModemName != 0 ) ) { OnClickedAsyncModemcallbackInherit( );
OnClickedAsyncModemcallbackPhonenumberInherit( ); }
return TRUE; }
//---------------------------------------------------------------------------------------------------
void CAsyncDlg::OnClickedAsyncModemcallbackInherit( ) { BOOL bChecked = ( BOOL )SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK_INHERIT ) , BM_GETCHECK , 0 , 0 );
BOOL bEnable = !bChecked;
m_uc.fInheritCallback = bChecked;
EnableWindow( GetDlgItem( m_hDlg , IDL_ASYNC_MODEMCALLBACK1 ) , bEnable );
EnableWindow( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK ) , bEnable );
// now check to see if we need to enable the modem callback number
if( bChecked ) { if( SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK) , CB_GETCURSEL , 0 , 0 ) == 0 ) { if( !( BOOL )SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER_INHERIT ) , BM_GETCHECK , 0 , 0 ) ) { EnableWindow( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER ) , TRUE );
// EnableWindow( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER_INHERIT ) , TRUE );
} } } else { if( (INT)SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK) , CB_GETCURSEL , 0 , 0 ) == 0 ) { if( !( BOOL )SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER_INHERIT ) , BM_GETCHECK , 0 , 0 ) ) { EnableWindow( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER ) , FALSE );
// EnableWindow( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER_INHERIT ) , FALSE );
} } }
return; }
//---------------------------------------------------------------------------------------------------
void CAsyncDlg::OnClickedAsyncModemcallbackPhonenumberInherit( ) { BOOL bChecked = ( BOOL )SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER_INHERIT ) , BM_GETCHECK , 0 , 0 );
BOOL bEnable = !bChecked;
m_uc.fInheritCallbackNumber = bChecked;
if( !bChecked ) { if( !( BOOL )SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK_INHERIT ) , BM_GETCHECK , 0 , 0 ) ) { if( SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK) , CB_GETCURSEL , 0 , 0 ) == 0 ) { EnableWindow( GetDlgItem( m_hDlg , IDL_ASYNC_MODEMCALLBACK_PHONENUMBER ) , FALSE );
EnableWindow( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER ) , FALSE );
return; } } }
EnableWindow( GetDlgItem( m_hDlg , IDL_ASYNC_MODEMCALLBACK_PHONENUMBER ) , bEnable );
EnableWindow( GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER ) , bEnable );
return; }
//---------------------------------------------------------------------------------------------------
BOOL CAsyncDlg::OnCommand( WORD wNotifyCode , WORD wID , HWND hwndCtrl , PBOOL pfPersisted ) { UNREFERENCED_PARAMETER( hwndCtrl );
if( wNotifyCode == BN_CLICKED ) { if( wID == IDC_ASYNC_DEFAULTS ) { if( SetDefaults( ) == S_OK ) { *pfPersisted = FALSE; } } else if( wID == IDC_ASYNC_ADVANCED ) { if( DoAsyncAdvance( ) == S_OK ) { *pfPersisted = FALSE; }
} else if( wID == IDC_ASYNC_TEST ) { DoAsyncTest( ); } else if( wID == IDC_ASYNC_MODEMCALLBACK_INHERIT ) { OnClickedAsyncModemcallbackInherit();
*pfPersisted = FALSE; } else if( wID == IDC_ASYNC_MODEMCALLBACK_PHONENUMBER_INHERIT ) { OnClickedAsyncModemcallbackPhonenumberInherit();
*pfPersisted = FALSE; } else if(wID == IDC_MODEM_PROP_PROP || wID == IDC_MODEM_PROP_WIZ) { OnClickedModemProperties(); }
} else if( wNotifyCode == CBN_SELCHANGE ) { if(wID == IDC_ASYNC_DEVICENAME) { if( OnSelchangeAsyncDevicename( ) ) { *pfPersisted = FALSE; }
} else if(wID == IDC_ASYNC_CONNECT) { if( OnSelchangeAsyncConnect() ) { *pfPersisted = FALSE; } } else if(wID == IDC_ASYNC_BAUDRATE) { if( OnSelchangeAsyncBaudrate() ) { *pfPersisted = FALSE; } } else if(wID == IDC_ASYNC_MODEMCALLBACK) { if( OnSelchangeAsyncModemcallback() ) { *pfPersisted = FALSE; } }
} /*else if( wNotifyCode == CBN_KILLFOCUS)
{ if(wID == IDC_ASYNC_BAUDRATE) { OnSelchangeAsyncBaudrate(); }
}*/ else if(wNotifyCode == EN_CHANGE ) { if(wID == IDC_ASYNC_MODEMCALLBACK_PHONENUMBER) { OnSelchangeAsyncModemcallbackPhoneNumber();
*pfPersisted = FALSE; }
}
return TRUE;
}
//---------------------------------------------------------------------------------------------------
BOOL CAsyncDlg::AsyncRelease( ) { if( m_pCfgcomp != NULL ) { m_pCfgcomp->Release( ); }
return TRUE; }
//---------------------------------------------------------------------------------------------------
HRESULT CAsyncDlg::SetAsyncFields(ASYNCCONFIG& AsyncConfig , PUSERCONFIG pUc) { HRESULT hres = S_OK;
if( pUc == NULL ) { return E_INVALIDARG; }
// check for variation
lstrcpy( AsyncConfig.DeviceName , m_ac.DeviceName );
if( memcmp( ( PVOID )&AsyncConfig , ( PVOID )&m_ac , sizeof( ASYNCCONFIG ) ) == 0 ) { if( memcmp( pUc->CallbackNumber , m_uc.CallbackNumber , sizeof( m_uc.CallbackNumber ) ) == 0 &&
pUc->fInheritCallback == m_uc.fInheritCallback &&
pUc->fInheritCallbackNumber == m_uc.fInheritCallbackNumber )
{ return S_FALSE; } }
BOOL bSelectDefault = !( *AsyncConfig.DeviceName);
HWND hCbx = GetDlgItem( m_hDlg , IDC_ASYNC_DEVICENAME );
HWND hCbxCallback = GetDlgItem( m_hDlg , IDC_ASYNC_MODEMCALLBACK );
TCHAR szDeviceName[DEVICENAME_LENGTH+MODEMNAME_LENGTH+1];
/*
* Set the DEVICE combo-box selection from the current selection. */ FormDecoratedAsyncDeviceName( szDeviceName, &AsyncConfig );
if( SendMessage( hCbx , CB_SELECTSTRING , ( WPARAM )-1 , ( LPARAM )szDeviceName ) == CB_ERR ) { /*
* Can't select current async DeviceName in combo-box. If this is * because we're supposed to select a default device name, select * the first device in the list. */ if( bSelectDefault ) { SendMessage( hCbx , CB_SETCURSEL , 0 , 0 ); } else { hres = E_FAIL; } }
/*
* Set the MODEMCALLBACK combo-box selection, phone number, and 'inherit' * checkboxes, based on the current UserConfig settings. */ SendMessage( hCbxCallback , CB_SETCURSEL , m_uc.Callback , 0 );
SetDlgItemText( m_hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER, m_uc.CallbackNumber );
CheckDlgButton( m_hDlg , IDC_ASYNC_MODEMCALLBACK_INHERIT , m_uc.fInheritCallback );
CheckDlgButton( m_hDlg , IDC_ASYNC_MODEMCALLBACK_PHONENUMBER_INHERIT , m_uc.fInheritCallbackNumber );
/*
* Set the BAUDRATE combo-box selection (in it's edit field) and limit the * edit field text. */
TCHAR string[ULONG_DIGIT_MAX];
wsprintf( string, TEXT("%lu"), AsyncConfig.BaudRate );
SetDlgItemText( m_hDlg , IDC_ASYNC_BAUDRATE, string );
SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_BAUDRATE ) , CB_LIMITTEXT , ULONG_DIGIT_MAX-1 , 0);
HWND hEdit = GetWindow(GetDlgItem( m_hDlg , IDC_ASYNC_BAUDRATE ),GW_CHILD);
if(hEdit) { LONG Style = GetWindowLong(hEdit, GWL_STYLE); SetWindowLong(hEdit,GWL_STYLE, Style | ES_NUMBER); }
/*
* Set the CONNECT combo-box selection. */
SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_CONNECT) , CB_SETCURSEL , AsyncConfig.Connect.Type , 0 );
// copy over default values
CopyMemory( ( PVOID )&m_ac , ( PVOID )&AsyncConfig , sizeof( ASYNCCONFIGW ) );
return hres;
}
//---------------------------------------------------------------------------------------------------
BOOL CAsyncDlg::GetAsyncFields(ASYNCCONFIG& AsyncConfig, USERCONFIG UsrCfg) { /*
* Fetch the currently selected DEVICENAME string. */ HWND hCbx = GetDlgItem( m_hDlg , IDC_ASYNC_DEVICENAME );
ASSERT( hCbx != NULL );
if( !SendMessage( hCbx , CB_GETCOUNT , 0 , 0 ) || SendMessage( hCbx , CB_GETCURSEL , 0 , 0 ) == CB_ERR ) { ErrMessage( m_hDlg , IDS_INVALID_DEVICE );
return FALSE; }
/*
* Get the MODEMCALLBACK phone number (callback state and 'user specified' * flags are already gotten). */
GetDlgItemText(m_hDlg,IDC_ASYNC_MODEMCALLBACK_PHONENUMBER, UsrCfg.CallbackNumber, SIZE_OF_BUFFER(UsrCfg.CallbackNumber) );
/*
* Fetch and convert the BAUDRATE combo-box selection (in it's edit field). */ { TCHAR string[ULONG_DIGIT_MAX], *endptr; ULONG ul;
GetDlgItemText(m_hDlg,IDC_ASYNC_BAUDRATE, string, ULONG_DIGIT_MAX); ul = wcstoul( string, &endptr, 10 );
if ( *endptr != TEXT('\0') ) {
/*
* Invalid character in Baud Rate field. */ ErrMessage( m_hDlg , IDS_INVALID_DEVICE );
return FALSE;
} else { AsyncConfig.BaudRate = ul; } }
/*
* Fetch the CONNECT combo-box selection and set/reset the break * disconnect flag. */
AsyncConfig.Connect.Type = (ASYNCCONNECTCLASS)SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_CONNECT ) , CB_GETCURSEL , 0 , 0 ); if(AsyncConfig.Connect.Type == Connect_FirstChar) { AsyncConfig.Connect.fEnableBreakDisconnect = 1; } else { AsyncConfig.Connect.fEnableBreakDisconnect = 0; }
return(TRUE);
} // end CAsyncDlg::GetAsyncFields
//---------------------------------------------------------------------------------------------------
// returns E_FAIL for general error
// S_OK for default values saved
// S_FALSE for default values have not been changed
//---------------------------------------------------------------------------------------------------
HRESULT CAsyncDlg::SetDefaults() { ASYNCCONFIG AsyncConfig;
PUSERCONFIG pUserConfig = NULL;
HRESULT hResult;
hResult = m_pCfgcomp->GetAsyncConfig(m_szWDName,WdName,&AsyncConfig);
if( SUCCEEDED( hResult ) ) { LONG lsz;
hResult = m_pCfgcomp->GetUserConfig( m_szWinstation , &lsz , &pUserConfig, TRUE ); }
if( SUCCEEDED( hResult ) ) { hResult = SetAsyncFields( AsyncConfig , pUserConfig ); }
if( pUserConfig != NULL ) { CoTaskMemFree( pUserConfig );
}
return hResult;
}
//---------------------------------------------------------------------------------------------------
HRESULT CAsyncDlg::DoAsyncAdvance( ) { CAdvancedAsyncDlg AADlg;
//Initialize the dialog's member variables.
AADlg.m_Async = m_ac;
AADlg.m_bReadOnly = FALSE;
AADlg.m_bModem = FALSE;
AADlg.m_nHexBase = m_nHexBase;
PWS pWs = NULL;
LONG lSize = 0;
if( m_szWDName[ 0 ] != 0 ) { ODS( L"CAsyncDlg::DoAsyncAdvance m_pCfgcomp->GetWdType\n" );
VERIFY_S( S_OK , m_pCfgcomp->GetWdType( m_szWDName , ( ULONG *)&AADlg.m_nWdFlag ) ); } else if( SUCCEEDED( m_pCfgcomp->GetWSInfo( m_szWinstation , &lSize , &pWs ) ) ) { ODS( L"CAsyncDlg::DoAsyncAdvance with m_szWinstation -- m_pCfgcomp->GetWdType\n" );
VERIFY_S( S_OK , m_pCfgcomp->GetWdType( pWs->wdName , ( ULONG *)&AADlg.m_nWdFlag ) ) ;
CoTaskMemFree( pWs ); }
AADlg.m_pCfgcomp = m_pCfgcomp; // addref here
// Invoke dialog
INT_PTR nRet = ::DialogBoxParam( _Module.GetResourceInstance( ) , MAKEINTRESOURCE( IDD_ASYNC_ADVANCED ) , m_hDlg , CAdvancedAsyncDlg::DlgProc , ( LPARAM )&AADlg );
if( nRet == IDOK ) { // Fetch the dialog's member variables.
if( memcmp( ( PVOID )&m_ac ,( PVOID )&AADlg.m_Async , sizeof( ASYNCCONFIG ) ) != 0 ) { m_ac = AADlg.m_Async;
m_nHexBase = AADlg.m_nHexBase;
return S_OK; } }
return S_FALSE; }
//---------------------------------------------------------------------------------------------------
BOOL CAsyncDlg::DoAsyncTest( ) { CAsyncTestDlg ATDlg( m_pCfgcomp );
// WINSTATIONCONFIG2W wsconfig;
HWND hCbx = GetDlgItem( m_hDlg , IDC_ASYNC_DEVICENAME );
ASSERT( hCbx != NULL );
if( !SendMessage( hCbx , CB_GETCOUNT , 0 , 0 ) || SendMessage( hCbx , CB_GETCURSEL , 0 , 0 ) == CB_ERR ) { ErrMessage( m_hDlg , IDS_INVALID_DEVICE );
return FALSE; }
ATDlg.m_ac = m_ac;
ATDlg.m_pWSName = m_szWinstation;
// Invoke the dialog.
INT_PTR nRet = ::DialogBoxParam( _Module.GetResourceInstance( ) , MAKEINTRESOURCE( IDD_ASYNC_TEST ) , m_hDlg , CAsyncTestDlg::DlgProc , ( LPARAM )&ATDlg);
if( nRet == IDOK ) { m_ac = ATDlg.m_ac; }
return TRUE; }
//*******************************************************************************
//
// Help functions from Citrix
//
/*******************************************************************************
* * CBInsertInstancedName - helper function * * Insert the specified 'instanced' name into the specified combo box, * using a special sort based on the 'root' name and 'instance' count. * * ENTRY: * pName (input) * Pointer to name string to insert. * pComboBox (input) * Pointer to CComboBox object to insert name string into. * * EXIT: * (int) Combo box list index of name after insertion, or error code. * ******************************************************************************/
INT_PTR CBInsertInstancedName( LPCTSTR pName, HWND hCombo ) { INT_PTR i, count, result;
TCHAR NameRoot[64], ListRoot[64];
if( pName == NULL || *pName == 0 ) { ODS( L"TSCC: Invalid Arg @ CBInsertInstancedName\n" ); return -1; }
LPTSTR ListString = NULL;
long NameInstance, ListInstance;
/*
* Form the root and instance for this name */ ParseRootAndInstance( pName, NameRoot, &NameInstance );
/*
* Traverse combo box to perform insert. */ for ( i = 0, count = SendMessage( hCombo , CB_GETCOUNT , 0 , 0 ); i < count; i++ ) {
/*
* Fetch current combo (list) box string. */ if( ListString != NULL ) { SendMessage( hCombo , CB_GETLBTEXT , ( WPARAM )i , ( LPARAM )ListString ); }
/*
* Parse the root and instance of the list box string. */ ParseRootAndInstance( ListString, ListRoot, &ListInstance );
/*
* If the list box string's root is greater than the our name string's * root, or the root strings are the same but the list instance is * greater than the name string's instance, or the root strings are * the same and the instances are the same but the entire list string * is greater than the entire name string, the name string belongs * at the current list position: insert it there. */
if ( ((result = lstrcmpi( ListRoot, NameRoot )) > 0) || ((result == 0) && (ListInstance > NameInstance)) || ((result == 0) && (ListInstance == NameInstance) && ( ListString != NULL && lstrcmpi(ListString, pName) > 0) ) ) { return SendMessage( hCombo , CB_INSERTSTRING , ( WPARAM )i , ( LPARAM )pName ); } }
/*
* Insert this name at the end of the list. */ return SendMessage( hCombo , CB_INSERTSTRING , ( WPARAM )-1 , ( LPARAM )pName );
} // end CBInsertInstancedName
/*******************************************************************************
* * ParseRootAndInstance - helper function * * Parse the 'root' string and instance count for a specified string. * * ENTRY: * pString (input) * Points to the string to parse. * pRoot (output) * Points to the buffer to store the parsed 'root' string. * pInstance (output) * Points to the int variable to store the parsed instance count. * * EXIT: * ParseRootAndInstance will parse only up to the first blank character * of the string (if a blank exists). * If the string contains no 'instance' count (no trailing digits), the * pInstance variable will contain -1. If the string consists entirely * of digits, the pInstance variable will contain the conversion of those * digits and pRoot will contain a null string. * ******************************************************************************/
void ParseRootAndInstance( LPCTSTR pString, LPTSTR pRoot, long *pInstance ) { LPCTSTR end, p; TCHAR szString[256];
if( pString == NULL || pString[ 0 ] == 0 ) { ODS( L"TSCC: Invalid arg @ ParseRootAndInstance\n" );
return; }
/*
* Make a copy of the string and terminate at first blank (if present). */ lstrcpyn(szString, pString, SIZE_OF_BUFFER( szString ) );
// szString[ lstrlen(szString) - 1 ] = TEXT('\0');
TCHAR *pTemp = szString;
while( *pTemp && *pTemp != L' ' ) { pTemp++; }
p = &(pTemp[lstrlen(pTemp)-1]);
/*
* Parse the instance portion of the string. */ end = p;
while( (p >= pTemp) && !IsCharAlpha(*p) ) p--;
if ( p == end ) {
/*
* No trailing digits: indicate no 'instance' and make the 'root' * the whole string. */ *pInstance = -1; lstrcpy( pRoot, pTemp );
} else {
/*
* Trailing digits found (or entire string was digits): calculate * 'instance' and copy the 'root' string (null if all digits). */ end = p; *pInstance = (int)_tcstol( p+1, NULL, 10 );
/*
* Copy 'root' string. */ for ( p = szString; p <= end; pRoot++, p++ ) *pRoot = *p;
/*
* Terminate 'root' string. */ *pRoot = TEXT('\0'); }
} // end ParseRootAndInstance
////////////////////////////////////////////////////////////////////////////////
CAdvancedAsyncDlg::CAdvancedAsyncDlg() { m_hDlg = NULL;
} // end CAdvancedAsyncDlg::CAdvancedAsyncDlg
//---------------------------------------------------------------------------------------------------
BOOL CAdvancedAsyncDlg::HandleEnterEscKey(int nID) { /*
* Check HW Flow Receive and Transmit combo boxes. */ HWND hCbx = GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_HWRX );
ASSERT( hCbx != NULL );
if( SendMessage( hCbx , CB_GETDROPPEDSTATE , 0 , 0 ) ) { if( nID == IDCANCEL ) { // select original selection
SendMessage( hCbx , CB_SETCURSEL , ( WPARAM )m_Async.FlowControl.HardwareReceive , 0 ); }
SendMessage( hCbx , CB_SHOWDROPDOWN , ( WPARAM )FALSE , 0 );
return FALSE; }
hCbx = GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_HWTX );
ASSERT( hCbx != NULL );
if( SendMessage( hCbx , CB_GETDROPPEDSTATE , 0 , 0 ) ) { if( nID == IDCANCEL ) { // select original selection
SendMessage( hCbx , CB_SETCURSEL , ( WPARAM )m_Async.FlowControl.HardwareTransmit , 0 );
}
SendMessage( hCbx , CB_SHOWDROPDOWN , ( WPARAM )FALSE , 0 );
return FALSE; }
/*
* No combo boxes are down; process Enter/Esc. */
return TRUE;
} // end CAdvancedAsyncDlg::HandleEnterEscKey
//---------------------------------------------------------------------------------------------------
void CAdvancedAsyncDlg::SetFields() { int nId = 0;
/*
* Set the FLOWCONTROL radio buttons. */ switch( m_Async.FlowControl.Type ) {
case FlowControl_None: nId = IDC_ASYNC_ADVANCED_FLOWCONTROL_NONE; break;
case FlowControl_Hardware: nId = IDC_ASYNC_ADVANCED_FLOWCONTROL_HARDWARE; break;
case FlowControl_Software: nId = IDC_ASYNC_ADVANCED_FLOWCONTROL_SOFTWARE; break; }
CheckRadioButton( m_hDlg , IDC_ASYNC_ADVANCED_FLOWCONTROL_HARDWARE, IDC_ASYNC_ADVANCED_FLOWCONTROL_NONE, nId );
/*
* Set the text of the Hardware flowcontrol button. */ SetHWFlowText();
/*
* If a modem is defined, disable the Flow Control fields, since they cannot * be modified (must match modem's flow control established in Modem dialog). */ if( m_bModem ) { for ( nId = IDL_ASYNC_ADVANCED_FLOWCONTROL; nId <= IDC_ASYNC_ADVANCED_FLOWCONTROL_NONE; nId++ ) { EnableWindow( GetDlgItem( m_hDlg , nId ) , FALSE); } }
/*
* Call member functions to set the Global, Hardware, and Software fields. */ SetGlobalFields(); SetHWFields(); SetSWFields();
} // end CAdvancedAsyncDlg::SetFields
//---------------------------------------------------------------------------------------------------
void CAdvancedAsyncDlg::SetHWFlowText( ) { TCHAR tchStr[ 256 ];
LoadString( _Module.GetResourceInstance( ) , IDS_HARDWARE , tchStr , SIZE_OF_BUFFER( tchStr ) );
switch ( m_Async.FlowControl.HardwareReceive ) {
case ReceiveFlowControl_None:
lstrcat( tchStr , TEXT(" (.../") );
break;
case ReceiveFlowControl_RTS:
lstrcat( tchStr , TEXT(" (RTS/") );
break;
case ReceiveFlowControl_DTR:
lstrcat( tchStr , TEXT(" (DTR/") ) ;
break; }
switch ( m_Async.FlowControl.HardwareTransmit ) { case TransmitFlowControl_None:
lstrcat( tchStr , TEXT("...)" ) );
break;
case TransmitFlowControl_CTS:
lstrcat( tchStr , TEXT("CTS)") );
break;
case TransmitFlowControl_DSR:
lstrcat( tchStr , TEXT("DSR)") );
break; }
SetDlgItemText( m_hDlg , IDC_ASYNC_ADVANCED_FLOWCONTROL_HARDWARE , tchStr );
} // end CAdvancedAsyncDlg::SetHWFlowText
//---------------------------------------------------------------------------------------------------
void CAdvancedAsyncDlg::SetGlobalFields() { /*
* Select proper DTR radio button. */ CheckRadioButton( m_hDlg , IDC_ASYNC_ADVANCED_DTROFF, IDC_ASYNC_ADVANCED_DTRON, IDC_ASYNC_ADVANCED_DTROFF + (int)m_Async.FlowControl.fEnableDTR );
/*
* Select proper RTS radio button. */ CheckRadioButton( m_hDlg , IDC_ASYNC_ADVANCED_RTSOFF, IDC_ASYNC_ADVANCED_RTSON, IDC_ASYNC_ADVANCED_RTSOFF + (int)m_Async.FlowControl.fEnableRTS );
/*
* Set the PARITY radio buttons. */ CheckRadioButton( m_hDlg , IDC_ASYNC_ADVANCED_PARITY_NONE, IDC_ASYNC_ADVANCED_PARITY_SPACE, IDC_ASYNC_ADVANCED_PARITY_NONE + (int)m_Async.Parity );
/*
* Set the STOPBITS radio buttons. */ CheckRadioButton( m_hDlg , IDC_ASYNC_ADVANCED_STOPBITS_1, IDC_ASYNC_ADVANCED_STOPBITS_2, IDC_ASYNC_ADVANCED_STOPBITS_1 + (int)m_Async.StopBits );
/*
* Set the BYTESIZE radio buttons. * * NOTE: the constant '7' that is subtracted from the stored ByteSize * must track the lowest allowed byte size / BYTESIZE radio button. */ CheckRadioButton( m_hDlg , IDC_ASYNC_ADVANCED_BYTESIZE_7, IDC_ASYNC_ADVANCED_BYTESIZE_8, IDC_ASYNC_ADVANCED_BYTESIZE_7 + ((int)m_Async.ByteSize - 7) );
/*
* If the currently selected Wd is an ICA type, disable the BYTESIZE * group box and buttons - user can't change from default. */ if ( m_nWdFlag & WDF_ICA ) { int i;
for( i = IDL_ASYNC_ADVANCED_BYTESIZE ; i <= IDC_ASYNC_ADVANCED_BYTESIZE_8; i++ ) { EnableWindow( GetDlgItem( m_hDlg , i ) , FALSE ); } }
} // end CAdvancedAsyncDlg::SetGlobalFields
//---------------------------------------------------------------------------------------------------
void CAdvancedAsyncDlg::SetHWFields() { int i;
/*
* Initialize HW Receive class combo-box */ HWND hCbx = GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_HWRX );
ASSERT( hCbx != NULL );
SendMessage( hCbx , CB_SETCURSEL , ( WPARAM )m_Async.FlowControl.HardwareReceive , 0 );
/*
* If HW flow control is selected AND the HW Receive class is set to * ReceiveFlowControl_DTR, disable the DTR controls & labels. * Otherwise, enable the DTR control & labels. */ for( i = IDL_ASYNC_ADVANCED_DTRSTATE ; i <= IDC_ASYNC_ADVANCED_DTRON ; i++ ) { EnableWindow( GetDlgItem( m_hDlg , i ) , ( ( m_Async.FlowControl.Type == FlowControl_Hardware) && (m_Async.FlowControl.HardwareReceive == ReceiveFlowControl_DTR) ) ? FALSE : TRUE ); }
/*
* Initialize HW Transmit class combo-box. */
hCbx = GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_HWTX);
SendMessage( hCbx , CB_SETCURSEL , ( WPARAM )m_Async.FlowControl.HardwareTransmit , 0 );
/*
* If HW flow control is selected AND the HW Receive class is set to * ReceiveFlowControl_RTS, disable the RTS controls & labels. * Otherwise, enable the RTS control & labels. */
for( i = IDL_ASYNC_ADVANCED_RTSSTATE ; i <= IDC_ASYNC_ADVANCED_RTSON ; i++ ) { EnableWindow( GetDlgItem( m_hDlg , i ) , ( ( m_Async.FlowControl.Type == FlowControl_Hardware) && ( m_Async.FlowControl.HardwareReceive == ReceiveFlowControl_RTS ) ) ? FALSE : TRUE ); }
/*
* Enable or disable all HW fields. */
for( i = IDL_ASYNC_ADVANCED_HARDWARE ; i <= IDC_ASYNC_ADVANCED_HWTX ; i++ ) {
EnableWindow( GetDlgItem( m_hDlg , i ) , m_Async.FlowControl.Type == FlowControl_Hardware ); }
} // end CAdvancedAsyncDlg::SetHWFields
//---------------------------------------------------------------------------------------------------
void CAdvancedAsyncDlg::SetSWFields() { TCHAR string[UCHAR_DIGIT_MAX];
/*
* Initialize Xon character edit control. */ wsprintf( string, ( m_nHexBase ? TEXT("0x%02X") : TEXT("%d")) , (UCHAR)m_Async.FlowControl.XonChar );
SetDlgItemText( m_hDlg , IDC_ASYNC_ADVANCED_XON , string );
SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_XON ) , EM_SETMODIFY , ( WPARAM )FALSE , 0 );
SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_XON ) , EM_LIMITTEXT , ( WPARAM )UCHAR_DIGIT_MAX-1 , 0 );
/*
* Initialize Xoff character edit control. */ wsprintf( string, ( m_nHexBase ? TEXT( "0x%02X" ) : TEXT( "%d" ) ) , ( UCHAR )m_Async.FlowControl.XoffChar );
SetDlgItemText( m_hDlg , IDC_ASYNC_ADVANCED_XOFF, string );
SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_XOFF ) , EM_SETMODIFY , ( WPARAM )FALSE , 0 );
SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_XOFF ) , EM_LIMITTEXT , ( WPARAM )UCHAR_DIGIT_MAX-1 , 0 );
/*
* Initialize the Xon/Xoff base control. */ CheckRadioButton( m_hDlg , IDC_ASYNC_ADVANCED_BASEDEC, IDC_ASYNC_ADVANCED_BASEHEX, ( int )( IDC_ASYNC_ADVANCED_BASEDEC + m_nHexBase ) );
/*
* Enable or disable all SW fields. */ for( int i = IDL_ASYNC_ADVANCED_SOFTWARE ; i <= IDC_ASYNC_ADVANCED_BASEHEX ; i++ ) { EnableWindow( GetDlgItem( m_hDlg , i ) , m_Async.FlowControl.Type == FlowControl_Software ); }
} // end CAdvancedAsyncDlg::SetSWFields
//---------------------------------------------------------------------------------------------------
BOOL CAdvancedAsyncDlg::GetFields() { /*
* Call member functions to get the Flow Control, Global, Hardware, and * Software fields. */ GetFlowControlFields();
if ( !GetGlobalFields() ) return(FALSE);
if ( !GetHWFields() ) return(FALSE);
if ( !GetSWFields(TRUE) ) return(FALSE);
return(TRUE);
} // end CAdvancedAsyncDlg::GetFields
//---------------------------------------------------------------------------------------------------
void CAdvancedAsyncDlg::GetFlowControlFields() { switch( GetCheckedRadioButton( IDC_ASYNC_ADVANCED_FLOWCONTROL_HARDWARE , IDC_ASYNC_ADVANCED_FLOWCONTROL_NONE ) ) {
case IDC_ASYNC_ADVANCED_FLOWCONTROL_NONE: m_Async.FlowControl.Type = FlowControl_None; break;
case IDC_ASYNC_ADVANCED_FLOWCONTROL_SOFTWARE: m_Async.FlowControl.Type = FlowControl_Software; break;
case IDC_ASYNC_ADVANCED_FLOWCONTROL_HARDWARE: m_Async.FlowControl.Type = FlowControl_Hardware; break; }
} // end CAdvancedAsyncDlg::GetFlowControlFields
//---------------------------------------------------------------------------------------------------
BOOL CAdvancedAsyncDlg::GetGlobalFields() { /*
* Fetch DTR state. */ m_Async.FlowControl.fEnableDTR = (GetCheckedRadioButton( IDC_ASYNC_ADVANCED_DTROFF, IDC_ASYNC_ADVANCED_DTRON ) - IDC_ASYNC_ADVANCED_DTROFF);
/*
* Fetch RTS state. */ m_Async.FlowControl.fEnableRTS = (GetCheckedRadioButton( IDC_ASYNC_ADVANCED_RTSOFF, IDC_ASYNC_ADVANCED_RTSON ) - IDC_ASYNC_ADVANCED_RTSOFF);
/*
* Fetch the selected PARITY. */ m_Async.Parity = (ULONG) (GetCheckedRadioButton( IDC_ASYNC_ADVANCED_PARITY_NONE, IDC_ASYNC_ADVANCED_PARITY_SPACE ) - IDC_ASYNC_ADVANCED_PARITY_NONE);
/*
* Fetch the selected STOPBITS. */ m_Async.StopBits = (ULONG) (GetCheckedRadioButton( IDC_ASYNC_ADVANCED_STOPBITS_1, IDC_ASYNC_ADVANCED_STOPBITS_2 ) - IDC_ASYNC_ADVANCED_STOPBITS_1);
/*
* Fetch the selected BYTESIZE. * * NOTE: the constant '7' that is added to the stored ByteSize * must track the lowest allowed byte size / BYTESIZE radio button. */ m_Async.ByteSize = (ULONG) (GetCheckedRadioButton( IDC_ASYNC_ADVANCED_BYTESIZE_7, IDC_ASYNC_ADVANCED_BYTESIZE_8 ) - IDC_ASYNC_ADVANCED_BYTESIZE_7 + 7);
return(TRUE);
} // end CAdvancedAsyncDlg::GetGlobalFields
//---------------------------------------------------------------------------------------------------
BOOL CAdvancedAsyncDlg::GetHWFields() { /*
* Fetch the HW receive flow class. */ m_Async.FlowControl.HardwareReceive = ( RECEIVEFLOWCONTROLCLASS ) SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_HWRX ) , CB_GETCURSEL , 0 , 0 );
/*
* Fetch the HW transmit flow class. */ m_Async.FlowControl.HardwareTransmit = ( TRANSMITFLOWCONTROLCLASS ) SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_HWTX ) , CB_GETCURSEL , 0 , 0 );
return TRUE;
} // end CAdvancedAsyncDlg::GetHWFields
//---------------------------------------------------------------------------------------------------
BOOL CAdvancedAsyncDlg::GetSWFields( BOOL bValidate ) { TCHAR string[UCHAR_DIGIT_MAX], *endptr; ULONG ul; INT_PTR nNewHexBase, base;
/*
* Determine the current state of the base controls and save. */ nNewHexBase = (GetCheckedRadioButton( IDC_ASYNC_ADVANCED_BASEDEC, IDC_ASYNC_ADVANCED_BASEHEX ) - IDC_ASYNC_ADVANCED_BASEDEC);
/*
* Fetch and convert XON character. */ GetDlgItemText( m_hDlg , IDC_ASYNC_ADVANCED_XON , string , SIZE_OF_BUFFER( string ) );
/*
* If the edit box is modified, use the 'new' base for conversion. */ base = SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_XON ) , EM_GETMODIFY , 0 , 0 ) ? nNewHexBase : m_nHexBase ;
ul = _tcstoul( string, &endptr, (base ? 16 : 10) );
/*
* If validation is requested and there is a problem with the input, * complain and allow user to fix. */ if( bValidate && ( (*endptr != TEXT('\0') ) || ( ul > 255 ) ) ) {
/*
* Invalid character in field or invalid value. */ // ERROR_MESSAGE((IDP_INVALID_XONXOFF))
/*
* Set focus to the control so that it can be fixed. */ SetFocus( GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_XON ) );
return FALSE; }
/*
* Save the Xon character. */ m_Async.FlowControl.XonChar = (UCHAR)ul;
/*
* Fetch and convert XOFF character. */ GetDlgItemText( m_hDlg , IDC_ASYNC_ADVANCED_XOFF , string , SIZE_OF_BUFFER( string ) );
/*
* If the edit box is modified, use the 'new' base for conversion. */
base = SendMessage( GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_XOFF ) , EM_GETMODIFY , 0 , 0 ) ? nNewHexBase : m_nHexBase ;
ul = _tcstoul( string, &endptr, (base ? 16 : 10) );
/*
* If validation is requested and there is a problem with the input, * complain and allow user to fix. */ if( bValidate && ( (*endptr != TEXT('\0' )) || ( ul > 255 ) ) ) { /*
* Invalid character in field or invalid value. */ // ERROR_MESSAGE((IDP_INVALID_XONXOFF))
/*
* Set focus to the control so that it can be fixed. */ SetFocus( GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_XOFF ) );
return FALSE; }
/*
* Save the Xoff character. */ m_Async.FlowControl.XoffChar = (UCHAR)ul;
/*
* Save the current base state. */ m_nHexBase = nNewHexBase;
return TRUE;
} // end CAdvancedAsyncDlg::GetSWFields
////////////////////////////////////////////////////////////////////////////////
// CAdvancedAsyncDlg message map
BOOL CAdvancedAsyncDlg::OnCommand( WORD wNotifyCode , WORD wID , HWND hwndCtrl ) { switch( wNotifyCode ) { case BN_CLICKED: if( wID == IDC_ASYNC_ADVANCED_BASEDEC ) { OnClickedAsyncAdvancedBasedec( ); } else if( wID == IDC_ASYNC_ADVANCED_BASEHEX ) { OnClickedAsyncAdvancedBasehex( ); } else if( wID == IDC_ASYNC_ADVANCED_FLOWCONTROL_HARDWARE ) { OnClickedAsyncAdvancedFlowcontrolHardware( ); } else if( wID == IDC_ASYNC_ADVANCED_FLOWCONTROL_SOFTWARE ) { OnClickedAsyncAdvancedFlowcontrolSoftware( ); } else if( wID == IDC_ASYNC_ADVANCED_FLOWCONTROL_NONE ) { OnClickedAsyncAdvancedFlowcontrolNone( ); } else if( wID == IDOK ) { OnOK( );
return EndDialog( m_hDlg , IDOK ); } else if( wID == IDCANCEL ) { OnCancel( );
return EndDialog( m_hDlg , IDCANCEL ); } else if( wID == ID_HELP ) { TCHAR tchHelpFile[ MAX_PATH ];
VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_ASYNC_HELPFILE , tchHelpFile , SIZE_OF_BUFFER( tchHelpFile ) ) ); WinHelp( GetParent( hwndCtrl ) , tchHelpFile , HELP_CONTEXT , HID_ASYNCADVANCE ); }
break;
case CBN_CLOSEUP:
if( wID == IDC_ASYNC_ADVANCED_HWRX ) { OnCloseupAsyncAdvancedHwrx( ); } else if( wID == IDC_ASYNC_ADVANCED_HWTX ) { OnCloseupAsyncAdvancedHwtx( ); } break;
case CBN_SELCHANGE:
if( wID == IDC_ASYNC_ADVANCED_HWRX ) { OnSelchangeAsyncAdvancedHwrx( ); } else if( wID == IDC_ASYNC_ADVANCED_HWTX ) { OnSelchangeAsyncAdvancedHwtx( ); } break;
}
return TRUE; }
////////////////////////////////////////////////////////////////////////////////
// CAdvancedAsyncDlg commands
//---------------------------------------------------------------------------------------------------
BOOL CAdvancedAsyncDlg::OnInitDialog( HWND hDlg , WPARAM wp , LPARAM lp ) { UNREFERENCED_PARAMETER( wp ); UNREFERENCED_PARAMETER( lp );
// int i;
TCHAR tchString[ 80 ];
HWND hCbx = GetDlgItem( hDlg , IDC_ASYNC_ADVANCED_HWRX );
ASSERT( hCbx != NULL );
// Load up combo boxes with strings.
m_hDlg = hDlg;
int idx = 0;
HRESULT hr;
while( SUCCEEDED( ( hr = m_pCfgcomp->GetHWReceiveName( idx , tchString ) ) ) ) { if( hr == S_FALSE ) { break; }
SendMessage( hCbx , CB_ADDSTRING , 0 , ( LPARAM )tchString );
idx++; }
hCbx = GetDlgItem( hDlg , IDC_ASYNC_ADVANCED_HWTX);
ASSERT( hCbx != NULL );
idx = 0;
while( SUCCEEDED( ( hr = m_pCfgcomp->GetHWTransmitName( idx , tchString ) ) ) ) { if( hr == S_FALSE ) { break; }
SendMessage( hCbx , CB_ADDSTRING , 0 , ( LPARAM )tchString );
idx++; }
// Initalize all dialog fields.
SetFields();
/*
if ( m_bReadOnly ) {
/*
* Document is 'read-only': disable all dialog controls and labels * except for CANCEL & HELP buttons.
for ( i=IDL_ASYNC_ADVANCED_FLOWCONTROL; i <=IDC_ASYNC_ADVANCED_BYTESIZE_8; i++ ) GetDlgItem(i)->EnableWindow(FALSE); GetDlgItem(IDOK)->EnableWindow(FALSE); } */
return(TRUE);
} // end CAdvancedAsyncDlg::OnInitDialog
//---------------------------------------------------------------------------------------------------
void CAdvancedAsyncDlg::OnClickedAsyncAdvancedFlowcontrolHardware() { GetFlowControlFields(); SetFields();
} // end CAdvancedAsyncDlg::OnClickedAsyncAdvancedFlowcontrolHardware
//---------------------------------------------------------------------------------------------------
void CAdvancedAsyncDlg::OnClickedAsyncAdvancedFlowcontrolSoftware() { GetFlowControlFields(); SetFields();
} // end CAdvancedAsyncDlg::OnClickedAsyncAdvancedFlowcontrolSoftware
//---------------------------------------------------------------------------------------------------
void CAdvancedAsyncDlg::OnClickedAsyncAdvancedFlowcontrolNone() { GetFlowControlFields(); SetFields();
} // end CAdvancedAsyncDlg::OnClickedAsyncAdvancedFlowcontrolNone
//---------------------------------------------------------------------------------------------------
void CAdvancedAsyncDlg::OnCloseupAsyncAdvancedHwrx() { OnSelchangeAsyncAdvancedHwrx();
} // end CAdvancedAsyncDlg::OnCloseupAsyncAdvancedHwrx
//---------------------------------------------------------------------------------------------------
void CAdvancedAsyncDlg::OnSelchangeAsyncAdvancedHwrx() { HWND hCbx = GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_HWRX );
ASSERT( hCbx != NULL );
/*
* Ignore this notification if the combo box is in a dropped-down * state. */ if( SendMessage( hCbx , CB_GETDROPPEDSTATE , 0 , 0 ) ) { return; }
/*
* Fetch and Set the Hardware fields to update. */ GetHWFields(); SetHWFields(); SetHWFlowText();
} // end CAdvancedAsyncDlg::OnSelchangeAsyncAdvancedHwrx
//---------------------------------------------------------------------------------------------------
void CAdvancedAsyncDlg::OnCloseupAsyncAdvancedHwtx() { OnSelchangeAsyncAdvancedHwtx();
} // end CAdvancedAsyncDlg::OnCloseupAsyncAdvancedHwtx
//---------------------------------------------------------------------------------------------------
void CAdvancedAsyncDlg::OnSelchangeAsyncAdvancedHwtx() { HWND hCbx = GetDlgItem( m_hDlg , IDC_ASYNC_ADVANCED_HWTX );
ASSERT( hCbx != NULL );
/*
* Ignore this notification if the combo box is in a dropped-down * state. */ if( SendMessage( hCbx , CB_GETDROPPEDSTATE , 0 , 0 ) ) { return; }
/*
* Fetch and Set the Hardware fields to update. */ GetHWFields(); SetHWFields(); SetHWFlowText();
} // end CAdvancedAsyncDlg::OnSelchangeAsyncAdvancedHwtx
//---------------------------------------------------------------------------------------------------
void CAdvancedAsyncDlg::OnClickedAsyncAdvancedBasedec() { /*
* Get/Set the SW fields to display in decimal base. */ GetSWFields(FALSE); SetSWFields();
} // end CAdvancedAsyncDlg::OnClickedAsyncAdvancedBasedec
//---------------------------------------------------------------------------------------------------
void CAdvancedAsyncDlg::OnClickedAsyncAdvancedBasehex() { /*
* Get/Set the SW fields to display in hexadecimal base. */ GetSWFields(FALSE); SetSWFields();
} // end CAdvancedAsyncDlg::OnClickedAsyncAdvancedBasehex
//---------------------------------------------------------------------------------------------------
void CAdvancedAsyncDlg::OnOK() { /*
* If the Enter key was pressed while a combo box was dropped down, ignore * it (treat as combo list selection only). */ if ( !HandleEnterEscKey(IDOK) ) return;
/*
* Fetch the field contents. Return (don't close dialog) if a problem * was found. */ GetFields();
} // end CAdvancedAsyncDlg::OnOK
//---------------------------------------------------------------------------------------------------
void CAdvancedAsyncDlg::OnCancel() { /*
* If the Esc key was pressed while a combo box was dropped down, ignore * it (treat as combo close-up and cancel only). */ HandleEnterEscKey( IDCANCEL );
} // end CAdvancedAsyncDlg::OnCancel
//---------------------------------------------------------------------------------------------------
int CAdvancedAsyncDlg::GetCheckedRadioButton( int nIDFirstButton, int nIDLastButton ) { for (int nID = nIDFirstButton; nID <= nIDLastButton; nID++) { if( IsDlgButtonChecked( m_hDlg , nID ) ) { return nID; // id that matched
} }
return 0; // invalid ID
}
//---------------------------------------------------------------------------------------------------
INT_PTR CALLBACK CAdvancedAsyncDlg::DlgProc( HWND hwnd , UINT msg , WPARAM wp , LPARAM lp ) { CAdvancedAsyncDlg *pDlg;
if( msg == WM_INITDIALOG ) { CAdvancedAsyncDlg *pDlg = ( CAdvancedAsyncDlg * )lp;
SetWindowLongPtr( hwnd , DWLP_USER, ( LONG_PTR )pDlg );
if( !IsBadReadPtr( pDlg , sizeof( CAdvancedAsyncDlg ) ) ) { pDlg->OnInitDialog( hwnd , wp , lp ); }
return 0; }
else { pDlg = ( CAdvancedAsyncDlg * )GetWindowLongPtr( hwnd , DWLP_USER);
if( IsBadReadPtr( pDlg , sizeof( CAdvancedAsyncDlg ) ) ) { return 0; } }
switch( msg ) {
/*case WM_DESTROY:
pDlg->OnDestroy( );
break;*/
case WM_COMMAND:
pDlg->OnCommand( HIWORD( wp ) , LOWORD( wp ) , ( HWND )lp );
break;
case WM_CONTEXTMENU: { POINT pt;
pt.x = LOWORD( lp );
pt.y = HIWORD( lp );
// pDlg->OnContextMenu( ( HWND )wp , pt );
}
break;
case WM_HELP:
// pDlg->OnHelp( hwnd , ( LPHELPINFO )lp );
break;
/*case WM_NOTIFY:
return pDlg->OnNotify( ( int )wp , ( LPNMHDR )lp , hwnd );*/ }
return 0; } /***********************************************************************************************************/
//---------------------------------------------------------------------------------------------------
void CEchoEditControl::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { UNREFERENCED_PARAMETER( nRepCnt ); UNREFERENCED_PARAMETER( nFlags ); /*
* Tell dialog to write the character to the device unless we're * currently processing edit control output. This flag check is needed * because the CEdit::Cut() member function will generate an OnChar() * event, which we need to ignore ('\b' processing). */
if( !m_bProcessingOutput ) { ODS( L"CEchoEditControl::OnChar -- WM_ASYNCTESTWRITECHAR( S )\n" );
::SendMessage( m_hDlg , WM_ASYNCTESTWRITECHAR, nChar, 0 ); }
/*
* Pass character on to the edit control. This will do nothing if * the edit control is 'read only'. To cause a 'local echo' effect, * set the edit control to 'read/write'. */
}
//---------------------------------------------------------------------------------------------------
void CEchoEditControl::SubclassDlgItem( HWND hDlg , int nRes ) { HWND hCtrl = GetDlgItem( hDlg , nRes );
ASSERT( hCtrl != NULL );
m_oldproc = ( WNDPROC )SetWindowLongPtr( hCtrl , GWLP_WNDPROC , ( LONG_PTR )CEchoEditControl::WndProc );
SetWindowLongPtr( hCtrl , GWLP_USERDATA , ( LONG_PTR )this );
}
//---------------------------------------------------------------------------------------------------
LRESULT CALLBACK CEchoEditControl::WndProc( HWND hwnd , UINT msg , WPARAM wp , LPARAM lp ) { CEchoEditControl *pEdit = ( CEchoEditControl * )GetWindowLongPtr( hwnd , GWLP_USERDATA );
if( pEdit == NULL ) { ODS( L"CEchoEditControl static object not set\n" );
return 0; }
switch( msg ) {
case WM_CHAR:
pEdit->OnChar( ( TCHAR )wp , LOWORD( lp ) , HIWORD( lp ) );
break; }
if( pEdit->m_oldproc != NULL ) { return ::CallWindowProc( pEdit->m_oldproc , hwnd , msg ,wp , lp ) ; }
return DefWindowProc( hwnd , msg ,wp , lp ); }
//---------------------------------------------------------------------------------------------------
CLed::CLed( HBRUSH hBrush ) { m_hBrush = hBrush;
m_bOn = FALSE; }
//---------------------------------------------------------------------------------------------------
void CLed::Subclass( HWND hDlg , int nRes ) { HWND hCtrl = GetDlgItem( hDlg , nRes );
ASSERT( hCtrl != NULL );
m_hWnd = hCtrl;
m_oldproc = ( WNDPROC )SetWindowLongPtr( hCtrl , GWLP_WNDPROC , ( LONG_PTR )CLed::WndProc );
SetWindowLongPtr( hCtrl , GWLP_USERDATA , ( LONG_PTR )this ); }
//---------------------------------------------------------------------------------------------------
void CLed::Update(int nOn) { m_bOn = nOn ? TRUE : FALSE;
InvalidateRect( m_hWnd , NULL , FALSE );
UpdateWindow( m_hWnd ); }
//---------------------------------------------------------------------------------------------------
void CLed::Toggle() { ODS(L"CLed::Toggle\n");
m_bOn = !m_bOn;
InvalidateRect( m_hWnd , NULL , FALSE );
// UpdateWindow( m_hWnd );
}
void CLed::OnPaint( HWND hwnd ) { RECT rect; PAINTSTRUCT ps;
ODS(L"CLed::OnPaint\n");
HDC dc = BeginPaint( hwnd , &ps );
HBRUSH brush;
GetClientRect( hwnd , &rect );
#ifdef USING_3DCONTROLS
(rect.right)--; (rect.bottom)--; brush = ( HBRUSH )GetStockObject( GRAY_BRUSH );
FrameRect( dc , &rect, brush );
(rect.top)++; (rect.left)++; (rect.right)++; (rect.bottom)++;
brush = ( HBRUSH )GetStockObject( WHITE_BRUSH );
FrameRect( dc , &rect, brush );
(rect.top)++; (rect.left)++; (rect.right) -= 2; (rect.bottom) -= 2; #else
brush = ( HBRUSH )GetStockObject( BLACK_BRUSH ); FrameRect( dc , &rect , brush ); (rect.top)++; (rect.left)++; (rect.right)--; (rect.bottom)--; #endif
DBGMSG( L"led should be %s\n" , m_bOn ? L"red" : L"grey" );
brush = m_bOn ? m_hBrush : ( HBRUSH )GetStockObject( LTGRAY_BRUSH );
FillRect( dc , &rect , brush );
EndPaint( hwnd , &ps );
}
//---------------------------------------------------------------------------------------------------
LRESULT CALLBACK CLed::WndProc( HWND hwnd , UINT msg , WPARAM wp , LPARAM lp ) { CLed *pWnd = ( CLed * )GetWindowLongPtr( hwnd , GWLP_USERDATA );
if( pWnd == NULL ) { ODS( L"CLed is not available\n" );
return 0; }
switch( msg ) {
case WM_PAINT:
pWnd->OnPaint( hwnd );
break; }
if( pWnd->m_oldproc != NULL ) { return ::CallWindowProc( pWnd->m_oldproc , hwnd , msg ,wp , lp ) ; }
return DefWindowProc( hwnd , msg ,wp , lp );
}
//---------------------------------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
// CThread class construction / destruction, implementation
/*******************************************************************************
* * CThread - CThread constructor * * ENTRY: * EXIT: * ******************************************************************************/
CThread::CThread() { m_hThread = NULL;
m_dwThreadID = 0; } // end CThread::CThread
/*******************************************************************************
* * ~CThread - CThread destructor * * ENTRY: * EXIT: * ******************************************************************************/ CThread::~CThread() { } // end CThread::~CThread
////////////////////////////////////////////////////////////////////////////////
// CThread operations: primary thread
/*******************************************************************************
* * CreateThread - CThread implementation function * * Class wrapper for the Win32 CreateThread API. * * ENTRY: * EXIT: * ******************************************************************************/
HANDLE CThread::CreateThread( DWORD cbStack , DWORD fdwCreate ) { /*
* Simple wrapper for Win32 CreateThread API. */ return( m_hThread = ::CreateThread( NULL, cbStack, ThreadEntryPoint , ( LPVOID ) this, fdwCreate, &m_dwThreadID ) );
} // end CThread::CreateThread
////////////////////////////////////////////////////////////////////////////////
// CThread operations: secondary thread
/*******************************************************************************
* * ThreadEntryPoint - CThread implementation function * (SECONDARY THREAD) * * ENTRY: * EXIT: * ******************************************************************************/
DWORD __stdcall CThread::ThreadEntryPoint( LPVOID lpParam ) { CThread *pThread; DWORD dwResult = ( DWORD )-1;
/*
* (lpParam is actually the 'this' pointer) */ pThread = (CThread*)lpParam;
/*
* Run the thread. */ if( pThread != NULL ) { dwResult = pThread->RunThread(); }
/*
* Return the result. */ return(dwResult);
} // end CThread::ThreadEntryPoint
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// CATDlgInputThread class construction / destruction, implementation
/*******************************************************************************
* * CATDlgInputThread - CATDlgInputThread constructor * * ENTRY: * EXIT: * ******************************************************************************/
CATDlgInputThread::CATDlgInputThread() { /*
* Initialize member variables. */ m_bExit = FALSE; m_ErrorStatus = ERROR_SUCCESS; m_hConsumed = NULL;
ZeroMemory( &m_OverlapSignal , sizeof( OVERLAPPED ) ); ZeroMemory( &m_OverlapRead , sizeof( OVERLAPPED ) );
//m_OverlapSignal.hEvent = NULL;
//m_OverlapRead.hEvent = NULL;
m_BufferBytes = 0;
} // end CATDlgInputThread::CATDlgInputThread
/*******************************************************************************
* * ~CATDlgInputThread - CATDlgInputThread destructor * * ENTRY: * EXIT: * ******************************************************************************/
CATDlgInputThread::~CATDlgInputThread() { /*
* Close the semaphore and events when the CATDlgInputThread * object is destroyed. */ if ( m_hConsumed ) CloseHandle(m_hConsumed);
if ( m_OverlapRead.hEvent ) CloseHandle(m_OverlapRead.hEvent);
if ( m_OverlapSignal.hEvent ) CloseHandle(m_OverlapSignal.hEvent);
} // end CATDlgInputThread::~CATDlgInputThread
/*******************************************************************************
* * RunThread - CATDlgInputThread secondary thread main function loop * (SECONDARY THREAD) * * ENTRY: * EXIT: * (DWORD) exit status for the secondary thread. * ******************************************************************************/
DWORD CATDlgInputThread::RunThread() { HANDLE hWait[2]; DWORD Status; int iStat;
/*
* Initialize for overlapped status and read input. */ m_hConsumed = CreateSemaphore( NULL , 0 , MAX_STATUS_SEMAPHORE_COUNT , NULL );
m_OverlapRead.hEvent = CreateEvent( NULL , TRUE , FALSE , NULL );
m_OverlapSignal.hEvent = CreateEvent( NULL , TRUE , FALSE , NULL );
if ( m_hConsumed == NULL || m_OverlapRead.hEvent == NULL || m_OverlapSignal.hEvent == NULL || !SetCommMask( m_hDevice , EV_CTS | EV_DSR | EV_ERR | EV_RING | EV_RLSD | EV_BREAK ) ) {
NotifyAbort(IDP_ERROR_CANT_INITIALIZE_INPUT_THREAD); return(1); }
/*
* Query initial comm status to initialize dialog with (return if error). */ if ( (iStat = CommStatusAndNotify()) != -1 ) return(iStat);
/*
* Post Read for input data. */ if ( (iStat = PostInputRead()) != -1 ) return(iStat);
/*
* Post Read for status. */ if ( (iStat = PostStatusRead()) != -1 ) return(iStat);
/*
* Loop till exit requested. */ for ( ; ; ) {
/*
* Wait for either input data or an comm status event. */ hWait[0] = m_OverlapRead.hEvent; hWait[1] = m_OverlapSignal.hEvent;
ODS( L"CATDlgInputThread::RunThread waiting on either event to be signaled\n"); Status = WaitForMultipleObjects(2, hWait, FALSE, INFINITE);
/*
* Check for exit. */ if ( m_bExit ) { ODS( L"CATDlgInputThread::RunThread exiting\n" );
return(0); }
if ( Status == WAIT_OBJECT_0 ) {
/*
* Read event: * Get result of overlapped read. */
ODS(L"CATDlgInputThread::RunThread Read event signaled\n" );
if ( !GetOverlappedResult( m_hDevice, &m_OverlapRead, &m_BufferBytes, TRUE ) ) {
NotifyAbort(IDP_ERROR_GET_OVERLAPPED_RESULT_READ); return(1); }
/*
* Notify dialog. */ if ( (iStat = CommInputNotify()) != -1 ) return(iStat);
/*
* Post Read for input data. */ if ( (iStat = PostInputRead()) != -1 ) return(iStat);
} else if ( Status == WAIT_OBJECT_0+1 ) {
ODS(L"CATDlgInputThread::RunThread Signal event signaled\n" );
/*
* Comm status event: * Query comm status and notify dialog. */ if ( (iStat = CommStatusAndNotify()) != -1 ) return(iStat);
/*
* Post Read for status. */ if ( (iStat = PostStatusRead()) != -1 ) return(iStat);
} else {
/*
* Unknown event: Abort. */ NotifyAbort(IDP_ERROR_WAIT_FOR_MULTIPLE_OBJECTS); return(1); } }
} // end CATDlgInputThread::RunThread
////////////////////////////////////////////////////////////////////////////////
// CATDlgInputThread operations: primary thread
/*******************************************************************************
* * SignalConsumed - CATDlgInputThread member function: public operation * * Release the m_hConsumed semaphore to allow secondary thread to continue * running. * * ENTRY: * EXIT: * ******************************************************************************/
void CATDlgInputThread::SignalConsumed() { ReleaseSemaphore( m_hConsumed, 1, NULL );
} // end CATDlgInputThread::SignalConsumed
/*******************************************************************************
* * ExitThread - CATDlgInputThread member function: public operation * * Tell the secondary thread to exit and cleanup after. * * ENTRY: * EXIT: * ******************************************************************************/
void CATDlgInputThread::ExitThread() { DWORD dwReturnCode; int i; // CWaitCursor wait;
/*
* If the thread was not created properly, just delete object and return. */ if ( !m_hThread ) { delete this; return; }
/*
* Set the m_bExit flag to TRUE, wake up the run thread's WaitCommEvent() by * resetting device's Comm mask, and bump the consumed semaphore to assure exit. */ m_bExit = TRUE; SetCommMask(m_hDevice, 0); SignalConsumed();
/*
* Purge the recieve buffer and any pending read. */ PurgeComm(m_hDevice, PURGE_RXABORT | PURGE_RXCLEAR);
/*
* Wait a while for the thread to exit. */ for ( i = 0, GetExitCodeThread( m_hThread, &dwReturnCode ); (i < MAX_SLEEP_COUNT) && (dwReturnCode == STILL_ACTIVE); i++ ) {
Sleep(100); GetExitCodeThread( m_hThread, &dwReturnCode ); }
/*
* If the thread has still not exited, terminate it. */ if( dwReturnCode == STILL_ACTIVE ) { TerminateThread( m_hThread, 1 );
ODS( L"Thread terminated irregularly\n" ); }
/*
* Close the thread handle and delete this CATDlgInputThread object */ CloseHandle( m_hThread );
delete this;
} // end CATDlgInputThread::ExitThread
////////////////////////////////////////////////////////////////////////////////
// CATDlgInputThread operations: secondary thread
/*******************************************************************************
* * NotifyAbort - CATDlgInputThread member function: private operation * (SECONDARY THREAD) * * Notify the dialog of thread abort and reason. * * ENTRY: * idError (input) * Resource id for error message. * EXIT: * ******************************************************************************/
void CATDlgInputThread::NotifyAbort(UINT idError ) { TCHAR tchErrTitle[ 80 ];
TCHAR tchErrMsg[ 256 ]; //::PostMessage(m_hDlg, WM_ASYNCTESTABORT, idError, GetLastError());
LoadString( _Module.GetResourceInstance( ) , IDS_ERROR_TITLE , tchErrTitle , SIZE_OF_BUFFER( tchErrTitle ) );
LoadString( _Module.GetResourceInstance( ) , idError , tchErrMsg , SIZE_OF_BUFFER( tchErrMsg ) );
MessageBox( m_hDlg , tchErrMsg , tchErrTitle , MB_OK | MB_ICONERROR );
} // end CATDlgInputThread::NotifyAbort
/*******************************************************************************
* * CommInputNotify - CATDlgInputThread member function: private operation * (SECONDARY THREAD) * * Notify the dialog of comm input. * * ENTRY: * EXIT: * -1 no error and continue thread * 0 if ExitThread was requested by parent * ******************************************************************************/
int CATDlgInputThread::CommInputNotify() { /*
* Tell the dialog that we've got some new input. */ ::PostMessage(m_hDlg, WM_ASYNCTESTINPUTREADY, 0, 0);
ODS( L"TSCC:CATDlgInputThread::CommInputNotify WM_ASYNCTESTINPUTREADY (P)\n" ); ODS( L"TSCC:CATDlgInputThread::CommInputNotify waiting on semaphore\n" ); WaitForSingleObject(m_hConsumed, INFINITE); ODS( L"TSCC:CATDlgInputThread::CommInputNotify semaphore signaled\n" );
/*
* Check for thread exit request. */ if ( m_bExit ) return(0); else return(-1);
} // end CATDlgInputThread::CommInputNotify
/*******************************************************************************
* * CommStatusAndNotify - CATDlgInputThread member function: private operation * (SECONDARY THREAD) * * Read the comm port status and notify dialog. * * ENTRY: * EXIT: * -1 no error and continue thread * 0 if ExitThread was requested by parent * 1 error condition * ******************************************************************************/
int CATDlgInputThread::CommStatusAndNotify() { PFLOWCONTROLCONFIG pFlow = NULL; DWORD ModemStatus = 0; DWORD Error = 0;
if ( !GetCommModemStatus(m_hDevice, &ModemStatus) ) {
/*
* We can't query the comm information; tell the primary thread * that we've aborted, and return error (will exit thread). */ NotifyAbort(IDP_ERROR_GET_COMM_MODEM_STATUS); return(1); }
/*
* Update modem status */ m_Status.AsyncSignal = ModemStatus;
/*
* Or in status of DTR and RTS */ // pFlow = &m_PdConfig.Params.Async.FlowControl;
pFlow = &m_ac.FlowControl;
if ( pFlow->fEnableDTR ) m_Status.AsyncSignal |= MS_DTR_ON; if ( pFlow->fEnableRTS ) m_Status.AsyncSignal |= MS_RTS_ON;
/*
* OR in new event mask */ m_Status.AsyncSignalMask |= m_EventMask;
/*
* Update async error counters */ if ( m_EventMask & EV_ERR ) { (VOID) ClearCommError( m_hDevice, &Error, NULL ); if ( Error & CE_OVERRUN ) m_Status.Output.AsyncOverrunError++; if ( Error & CE_FRAME ) m_Status.Input.AsyncFramingError++; if ( Error & CE_RXOVER ) m_Status.Input.AsyncOverflowError++; if ( Error & CE_RXPARITY ) m_Status.Input.AsyncParityError++; }
/*
* Tell the dialog that we've got some new status information. */ ::PostMessage(m_hDlg, WM_ASYNCTESTSTATUSREADY, 0, 0);
ODS( L"TSCC:CATDlgInputThread::CommStatusAndNotify WM_ASYNCTESTSTATUSREADY( P )\n"); ODS( L"TSCC:CATDlgInputThread::CommStatusAndNotify waiting on semaphore\n" ); WaitForSingleObject(m_hConsumed, INFINITE); ODS( L"TSCC:CATDlgInputThread::CommStatusAndNotify semaphore signaled\n" );
/*
* Check for thread exit request. */ if ( m_bExit ) return(0); else return(-1);
} // end CATDlgInputThread::CommStatusAndNotify
/*******************************************************************************
* * PostInputRead - CATDlgInputThread member function: private operation * (SECONDARY THREAD) * * Post a ReadFile operation for the device, processing as long as data * is present. * * ENTRY: * EXIT: * -1 if read operation posted sucessfully * 0 if ExitThread was requested by parent * 1 if error condition * ******************************************************************************/
int CATDlgInputThread::PostInputRead() { int iStat;
// TCHAR tchErrTitle[ 80 ];
// TCHAR tchErrMsg[ 256 ];
ODS(L"TSCC:CATDlgInputThread::PostInputRead\n");
/*
* Post read for input data, processing immediataly if not 'pending'. */
while ( ReadFile( m_hDevice, m_Buffer, MAX_COMMAND_LEN, &m_BufferBytes, &m_OverlapRead ) ) { DBGMSG( L"Buffer received %s\n",m_Buffer );
if ( (iStat = CommInputNotify()) != -1 ) return(iStat); }
/*
* Make sure read is pending (not some other error). */ if ( GetLastError() != ERROR_IO_PENDING ) { DBGMSG( L"ReadFile returned 0x%x\n" , GetLastError() );
NotifyAbort(IDP_ERROR_READ_FILE); /* LoadString( _Module.GetResourceInstance( ) , IDS_ERROR_TITLE , tchErrTitle , sizeof( tchErrTitle ) );
LoadString( _Module.GetResourceInstance( ) , IDP_ERROR_READ_FILE , tchErrMsg , sizeof( tchErrMsg ) );
MessageBox( m_hDlg , tchErrMsg , tchErrTitle , MB_OK | MB_ICONERROR );*/
EndDialog(m_hDlg, IDCANCEL);
return(1); }
/*
* Return 'posted sucessfully' status. */ return(-1);
} // end CATDlgInputThread::PostInputRead
/*******************************************************************************
* * PostStatusRead - CATDlgInputThread member function: private operation * (SECONDARY THREAD) * * Post a WaitCommStatus operation for the device. * * ENTRY: * EXIT: * -1 if status operation posted sucessfully * 1 if error condition * ******************************************************************************/
int CATDlgInputThread::PostStatusRead() { /*
* Post read for comm status. */ ODS( L"CATDlgInputThread::PostStatusRead\n");
if ( !WaitCommEvent(m_hDevice, &m_EventMask, &m_OverlapSignal) ) {
/*
* Make sure comm status read is pending (not some other error). */ if ( GetLastError() != ERROR_IO_PENDING ) {
NotifyAbort(IDP_ERROR_WAIT_COMM_EVENT); return(1); } }
/*
* Return 'posted sucessfully' status. */ return(-1);
} // end CATDlgInputThread::PostStatusRead
////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// CAsyncTestDlg class construction / destruction, implementation
/*******************************************************************************
* * CAsyncTestDlg - CAsyncTestDlg constructor * * ENTRY: * EXIT: * (Refer to MFC CDialog::CDialog documentation) * ******************************************************************************/
CAsyncTestDlg::CAsyncTestDlg(ICfgComp * pCfgComp) : m_hDevice(INVALID_HANDLE_VALUE), m_hRedBrush(NULL), m_LEDToggleTimer(0), m_pATDlgInputThread(NULL), m_CurrentPos(0), m_hModem(NULL), m_bDeletedWinStation(FALSE) { /*
* Create a solid RED brush for painting the 'LED's when 'on'. */ m_hRedBrush = CreateSolidBrush( RGB( 255 , 0 , 0 ) );
/*
* Initialize member variables. */
FillMemory( &m_Status , sizeof( PROTOCOLSTATUS ) , 0 );
FillMemory( &m_OverlapWrite , sizeof( OVERLAPPED ) , 0 );
/*
* Create the led objects. */ for( int i = 0 ; i < NUM_LEDS ; i++ ) { m_pLeds[i] = new CLed(m_hRedBrush);
}
m_pCfgComp = pCfgComp;
if( pCfgComp != NULL ) { m_pCfgComp->AddRef(); }
} // end CAsyncTestDlg::CAsyncTestDlg
/*******************************************************************************
* * ~CAsyncTestDlg - CAsyncTestDlg destructor * * ENTRY: * EXIT: * (Refer to MFC CDialog::~CDialog documentation) * ******************************************************************************/
CAsyncTestDlg::~CAsyncTestDlg() { /*
* Zap our led objects. */ for( int i = 0; i < NUM_LEDS; i++ ) { if( m_pLeds[i] != NULL ) { delete m_pLeds[i]; } } if(m_pCfgComp != NULL ) { m_pCfgComp->Release(); }
} // end CAsyncTestDlg::~CAsyncTestDlg
////////////////////////////////////////////////////////////////////////////////
// CAsyncTestDlg operations
/*******************************************************************************
* * NotifyAbort - CAsyncTestDlg member function: private operation * * Post a WM_ASYNCTESTABORT message to notify the dialog of * abort and reason. * * ENTRY: * idError (input) * Resource id for error message. * EXIT: * ******************************************************************************/
void CAsyncTestDlg::NotifyAbort( UINT idError ) { TCHAR tchErrTitle[ 80 ];
TCHAR tchErrMsg[ 256 ];
LoadString( _Module.GetResourceInstance( ) , IDS_ERROR_TITLE , tchErrTitle , SIZE_OF_BUFFER( tchErrTitle ) );
LoadString( _Module.GetResourceInstance( ) , idError , tchErrMsg , SIZE_OF_BUFFER( tchErrMsg ) );
MessageBox( m_hDlg , tchErrMsg , tchErrTitle , MB_OK | MB_ICONERROR );
} // end CAsyncTestDlg::NotifyAbort
/*******************************************************************************
* * DeviceSetParams - CAsyncTestDlg member function: private operation * * Set device parameters for opened device. * * ENTRY: * EXIT: * TRUE - no error; FALSE error. * ******************************************************************************/
BOOL CAsyncTestDlg::DeviceSetParams() { PASYNCCONFIG pAsync; PFLOWCONTROLCONFIG pFlow; DCB Dcb;
/*
* Get pointer to async parameters */ // pAsync = &m_PdConfig0.Params.Async;
pAsync = &m_ac;
/*
* Get current DCB */ if( !GetCommState( m_hDevice, &Dcb ) ) { return(FALSE); }
/*
* Set defaults */ Dcb.fOutxCtsFlow = FALSE; Dcb.fOutxDsrFlow = FALSE; Dcb.fTXContinueOnXoff = TRUE; Dcb.fOutX = FALSE; Dcb.fInX = FALSE; Dcb.fErrorChar = FALSE; Dcb.fNull = FALSE; Dcb.fAbortOnError = FALSE;
/*
* Set Communication parameters */ Dcb.BaudRate = pAsync->BaudRate; Dcb.Parity = (BYTE) pAsync->Parity; Dcb.StopBits = (BYTE) pAsync->StopBits; Dcb.ByteSize = (BYTE) pAsync->ByteSize; Dcb.fDsrSensitivity = pAsync->fEnableDsrSensitivity;
pFlow = &pAsync->FlowControl;
/*
* Initialize default DTR state */ if ( pFlow->fEnableDTR ) Dcb.fDtrControl = DTR_CONTROL_ENABLE; else Dcb.fDtrControl = DTR_CONTROL_DISABLE;
/*
* Initialize default RTS state */ if ( pFlow->fEnableRTS ) Dcb.fRtsControl = RTS_CONTROL_ENABLE; else Dcb.fRtsControl = RTS_CONTROL_DISABLE;
/*
* Initialize flow control */ switch ( pFlow->Type ) {
/*
* Initialize hardware flow control */ case FlowControl_Hardware :
switch ( pFlow->HardwareReceive ) { case ReceiveFlowControl_RTS : Dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; break; case ReceiveFlowControl_DTR : Dcb.fDtrControl = DTR_CONTROL_HANDSHAKE; break; } switch ( pFlow->HardwareTransmit ) { case TransmitFlowControl_CTS : Dcb.fOutxCtsFlow = TRUE; break; case TransmitFlowControl_DSR : Dcb.fOutxDsrFlow = TRUE; break; } break;
/*
* Initialize software flow control */ case FlowControl_Software : Dcb.fOutX = pFlow->fEnableSoftwareTx; Dcb.fInX = pFlow->fEnableSoftwareRx; Dcb.XonChar = (char) pFlow->XonChar; Dcb.XoffChar = (char) pFlow->XoffChar; break;
case FlowControl_None : break;
}
/*
* Set new DCB */ if ( !SetCommState( m_hDevice, &Dcb ) ) return(FALSE);
return( TRUE );
} // end CAsyncTestDlg::DeviceSetParams
/*******************************************************************************
* * DeviceWrite - CAsyncTestDlg member function: private operation * * Write out m_Buffer contents (m_BufferBytes length) to the m_hDevice. * * ENTRY: * EXIT: * TRUE - no error; FALSE error. * ******************************************************************************/
BOOL CAsyncTestDlg::DeviceWrite() { DWORD Error, BytesWritten;
/*
* Write data */ ODS( L"TSCC:CAsyncTestDlg::DeviceWrite Writing out to buffer\n" );
if ( !WriteFile( m_hDevice, m_Buffer, m_BufferBytes, &BytesWritten, &m_OverlapWrite ) ) { DBGMSG( L"TSCC:CAsyncTestDlg::DeviceWrite WriteFile returned 0x%x\n" , GetLastError() );
if ( (Error = GetLastError()) == ERROR_IO_PENDING ) { /*
* Wait for write to complete (this may block till timeout) */ if ( !GetOverlappedResult( m_hDevice, &m_OverlapWrite, &BytesWritten, TRUE ) ) { CancelIo( m_hDevice );
NotifyAbort(IDP_ERROR_GET_OVERLAPPED_RESULT_WRITE);
return(FALSE); }
} else {
NotifyAbort(IDP_ERROR_WRITE_FILE); return(FALSE); } }
return(TRUE);
} // end CAsyncTestDlg::DeviceWrite
//---------------------------------------------------------------------
cwnd * CAsyncTestDlg::GetDlgItem( int nRes ) { HWND hCtrl = ::GetDlgItem( m_hDlg , nRes );
for( int i = 0; i < NUM_LEDS; i++ ) { if( m_pLeds[ i ] != NULL ) { if( m_pLeds[ i ]->m_hWnd == hCtrl ) { return m_pLeds[ i ]; } } }
return 0; }
/*******************************************************************************
* * SetInfoFields - CAsyncTestDlg member function: private operation * * Update the fields in the dialog with new data, if necessary. * * ENTRY: * pCurrent (input) * points to COMMINFO structure containing the current Comm Input data. * pNew (input) * points to COMMINFO structure containing the new Comm Input data. * * EXIT: * ******************************************************************************/
void CAsyncTestDlg::SetInfoFields( PPROTOCOLSTATUS pCurrent , PPROTOCOLSTATUS pNew ) { BOOL bSetTimer = FALSE;
/*
* Set new LED states if state change, or set up for quick toggle if * no state changed, but change(s) were detected since last query. */ if( ( pCurrent->AsyncSignal & MS_DTR_ON ) != ( pNew->AsyncSignal & MS_DTR_ON ) ) { pNew->AsyncSignalMask &= ~EV_DTR;
((CLed *)GetDlgItem(IDC_ATDLG_DTR))->Update(pNew->AsyncSignal & MS_DTR_ON);
} else if ( pNew->AsyncSignalMask & EV_DTR ) {
pCurrent->AsyncSignal ^= MS_DTR_ON;
((CLed *)GetDlgItem(IDC_ATDLG_DTR))->Toggle();
bSetTimer = TRUE; }
if ( (pCurrent->AsyncSignal & MS_RTS_ON) != (pNew->AsyncSignal & MS_RTS_ON) ) {
pNew->AsyncSignalMask &= ~EV_RTS; ((CLed *)GetDlgItem(IDC_ATDLG_RTS))-> Update(pNew->AsyncSignal & MS_RTS_ON);
} else if ( pNew->AsyncSignalMask & EV_RTS ) {
pCurrent->AsyncSignal ^= MS_RTS_ON;
((CLed *)GetDlgItem(IDC_ATDLG_RTS))->Toggle();
bSetTimer = TRUE; }
if ( (pCurrent->AsyncSignal & MS_CTS_ON) != (pNew->AsyncSignal & MS_CTS_ON) ) {
pNew->AsyncSignalMask &= ~EV_CTS; ((CLed *)GetDlgItem(IDC_ATDLG_CTS))-> Update(pNew->AsyncSignal & MS_CTS_ON);
} else if ( pNew->AsyncSignalMask & EV_CTS ) {
pCurrent->AsyncSignal ^= MS_CTS_ON;
((CLed *)GetDlgItem(IDC_ATDLG_CTS))->Toggle();
bSetTimer = TRUE; }
if ( (pCurrent->AsyncSignal & MS_RLSD_ON) != (pNew->AsyncSignal & MS_RLSD_ON) ) {
pNew->AsyncSignalMask &= ~EV_RLSD; ((CLed *)GetDlgItem(IDC_ATDLG_DCD))-> Update(pNew->AsyncSignal & MS_RLSD_ON);
} else if ( pNew->AsyncSignalMask & EV_RLSD ) {
pCurrent->AsyncSignal ^= MS_RLSD_ON;
((CLed *)GetDlgItem(IDC_ATDLG_DCD))->Toggle();
bSetTimer = TRUE; }
if ( (pCurrent->AsyncSignal & MS_DSR_ON) != (pNew->AsyncSignal & MS_DSR_ON) ) {
pNew->AsyncSignalMask &= ~EV_DSR; ((CLed *)GetDlgItem(IDC_ATDLG_DSR))-> Update(pNew->AsyncSignal & MS_DSR_ON);
} else if ( pNew->AsyncSignalMask & EV_DSR ) {
pCurrent->AsyncSignal ^= MS_DSR_ON;
((CLed *)GetDlgItem(IDC_ATDLG_DSR))->Toggle();
bSetTimer = TRUE; }
if ( (pCurrent->AsyncSignal & MS_RING_ON) != (pNew->AsyncSignal & MS_RING_ON) ) {
pNew->AsyncSignalMask &= ~EV_RING; ((CLed *)GetDlgItem(IDC_ATDLG_RI))-> Update(pNew->AsyncSignal & MS_RING_ON);
} else if ( pNew->AsyncSignalMask & EV_RING ) {
pCurrent->AsyncSignal ^= MS_RING_ON;
((CLed *)GetDlgItem(IDC_ATDLG_RI))->Toggle();
bSetTimer = TRUE; }
/*
* Create our led toggle timer if needed. */ if ( bSetTimer && !m_LEDToggleTimer ) { m_LEDToggleTimer = SetTimer( m_hDlg , IDD_ASYNC_TEST , ASYNC_LED_TOGGLE_MSEC, NULL ); }
} // end CAsyncTestDlg::SetInfoFields
////////////////////////////////////////////////////////////////////////////////
// CAsyncTestDlg message map
BOOL CAsyncTestDlg::OnCommand( WORD wNotifyCode , WORD wID , HWND hwndCtrl ) { if( wNotifyCode == BN_CLICKED ) { if( wID == IDC_ATDLG_MODEM_DIAL ) { OnClickedAtdlgModemDial( ); } else if( wID == IDC_ATDLG_MODEM_INIT ) { OnClickedAtdlgModemInit( ); } else if( wID == IDC_ATDLG_MODEM_LISTEN ) { OnClickedAtdlgModemListen( ); } else if( wID == IDOK ) { EndDialog( m_hDlg , IDOK ); } else if( wID == IDCANCEL ) { EndDialog( m_hDlg , IDCANCEL ); } else if( wID == ID_HELP ) { TCHAR tchHelpFile[ MAX_PATH ];
VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_ASYNC_HELPFILE , tchHelpFile , SIZE_OF_BUFFER( tchHelpFile ) ) );
WinHelp( GetParent( hwndCtrl ) , tchHelpFile , HELP_CONTEXT , HID_ASYNCTEST ); }
}
return TRUE; }
////////////////////////////////////////////////////////////////////////////////
// CAsyncTestDlg commands
/*******************************************************************************
* * OnInitDialog - CAsyncTestDlg member function: command (override) * * Performs the dialog intialization. * * ENTRY: * EXIT: * (Refer to CDialog::OnInitDialog documentation) * WM_ASYNCTESTABORT message(s) will have been posted on error. * ******************************************************************************/
BOOL CAsyncTestDlg::OnInitDialog( HWND hDlg , WPARAM wp , LPARAM lp ) { UNREFERENCED_PARAMETER( wp ); UNREFERENCED_PARAMETER( lp );
int i;
DEVICENAME DeviceName;
COMMTIMEOUTS CommTimeouts;
TCHAR tchErrTitle[ 80 ];
TCHAR tchErrMsg[ 256 ];
m_hDlg = hDlg;
//#ifdef WINSTA
ULONG LogonId; //#endif // WINSTA
/*
* Fill in the device and baud fields. */ SetDlgItemText( hDlg , IDL_ATDLG_DEVICE , m_ac.DeviceName );
SetDlgItemInt( hDlg , IDL_ATDLG_BAUD , m_ac.BaudRate , FALSE );
/*
* If a WinStation memory object is currently present, reset it. */ //#ifdef WINSTA
if ( m_pWSName != NULL ) //&& LogonIdFromWinStationName( SERVERNAME_CURRENT , m_pWSName , &LogonId ) )
{ LONG Status;
ULONG Length;
LONG lCount = 0;
TCHAR tchbuf[ 256 ];
if( m_pCfgComp != NULL ) { ODS( L"TSCC : Testing for live connections\n" );
m_pCfgComp->QueryLoggedOnCount( m_pWSName,&lCount);
if( lCount ) { VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_WRN_TSTCON , tchbuf , SIZE_OF_BUFFER( tchbuf ) ) );
wsprintf( tchErrMsg , tchbuf , m_pWSName);
VERIFY_E( 0 , LoadString( _Module.GetResourceInstance( ) , IDS_WARN_TITLE , tchErrTitle , SIZE_OF_BUFFER( tchErrTitle ) ) );
if( MessageBox( hDlg , tchbuf , tchErrTitle , MB_YESNO | MB_ICONEXCLAMATION ) == IDNO ) { PostMessage( hDlg , WM_COMMAND , MAKEWPARAM( IDOK, BN_CLICKED ) , (LPARAM)(::GetDlgItem( hDlg , IDOK ) ) );
return(TRUE); // exit dialog via posted 'OK' click
} } }
Status = RegWinStationQuery( SERVERNAME_CURRENT, m_pWSName, &m_WSConfig, sizeof(WINSTATIONCONFIG2), &Length ); if(Status) { NotifyAbort(IDP_ERROR_DISABLE); return(TRUE); }
m_WSConfig.Create.fEnableWinStation = FALSE;
Status = RegWinStationCreate( SERVERNAME_CURRENT, m_pWSName, FALSE, &m_WSConfig, sizeof(WINSTATIONCONFIG2 ) ) ; if(Status) { NotifyAbort(IDP_ERROR_DISABLE); return(TRUE); }
/*
* Do the reset. If, for some reason, the reset was unsucessful, * the device open will fail (below). */ // CWaitCursor wait;
if( LogonIdFromWinStationName( SERVERNAME_CURRENT , m_pWSName , &LogonId ) ) {
BOOL b = ( BOOL )WinStationReset(SERVERNAME_CURRENT, LogonId, TRUE);
DBGMSG( L"TSCC:CAsyncTestDlg::OnInitDialog WinStationReset returned %s\n", b ? L"TRUE" : L"FALSE" );
//m_bDeletedWinStation = TRUE;
}
m_bDeletedWinStation = TRUE; } //#endif // WINSTA
/*
* Open the specified device. */ lstrcpy( DeviceName, TEXT("\\\\.\\") );
// lstrcat( DeviceName, m_PdConfig0.Params.Async.DeviceName );
lstrcat( DeviceName, m_ac.DeviceName );
if( ( m_hDevice = CreateFile( DeviceName, GENERIC_READ | GENERIC_WRITE, 0, // exclusive access
NULL, // no security attr
OPEN_EXISTING, // must exist
FILE_FLAG_OVERLAPPED, NULL // no template
) ) == INVALID_HANDLE_VALUE ) { NotifyAbort(IDP_ERROR_CANT_OPEN_DEVICE); /* LoadString( _Module.GetResourceInstance( ) , IDS_ERROR_TITLE , tchErrTitle , sizeof( tchErrTitle ) );
LoadString( _Module.GetResourceInstance( ) , IDP_ERROR_CANT_OPEN_DEVICE , tchErrMsg , sizeof( tchErrMsg ) );
MessageBox( hDlg , tchErrMsg , tchErrTitle , MB_OK | MB_ICONERROR );*/
return(FALSE); }
/*
* Set device timeouts & communication parameters and create an event * for overlapped writes. */ FillMemory( &CommTimeouts , sizeof( COMMTIMEOUTS ) , 0 );
CommTimeouts.ReadIntervalTimeout = 1; // 1 msec
CommTimeouts.WriteTotalTimeoutConstant = 1000; // 1 second
m_OverlapWrite.hEvent = CreateEvent( NULL , TRUE , FALSE, NULL );
if( !SetCommTimeouts(m_hDevice, &CommTimeouts) || !DeviceSetParams() || m_OverlapWrite.hEvent == NULL ) {
NotifyAbort(IDP_ERROR_CANT_INITIALIZE_DEVICE); ODS( L"IDP_ERROR_CANT_INITIALIZE_DEVICE\n" );
/* LoadString( _Module.GetResourceInstance( ) , IDS_ERROR_TITLE , tchErrTitle , sizeof( tchErrTitle ) );
LoadString( _Module.GetResourceInstance( ) , IDP_ERROR_CANT_INITIALIZE_DEVICE , tchErrMsg , sizeof( tchErrMsg ) );
MessageBox( hDlg , tchErrMsg , tchErrTitle , MB_OK | MB_ICONERROR );*/
return(TRUE); }
/*
* Create the input thread object and initialize it's member variables. */ m_pATDlgInputThread = new CATDlgInputThread;
m_pATDlgInputThread->m_hDlg = m_hDlg;
m_pATDlgInputThread->m_hDevice = m_hDevice;
// m_pATDlgInputThread->m_PdConfig = m_PdConfig0;
m_pATDlgInputThread->m_ac = m_ac;
if( !m_pATDlgInputThread->CreateThread() ) { NotifyAbort(IDP_ERROR_CANT_CREATE_INPUT_THREAD); ODS( L"IDP_ERROR_CANT_CREATE_INPUT_THREAD\n" );
return(TRUE); }
/*
* Hide the modem string buttons if a modem is not configured, or disable * buttons that are not valid. */ for( int id = IDC_ATDLG_MODEM_INIT ; id <= IDC_ATDLG_PHONE_NUMBER ; id++ ) { EnableWindow( ::GetDlgItem( hDlg , id) , FALSE);
ShowWindow( ::GetDlgItem( hDlg , id) , SW_HIDE); }
/*
* Subclass the edit field to pass messages to dialog first. */ m_EditControl.m_hDlg = m_hDlg;
m_EditControl.m_bProcessingOutput = FALSE;
m_EditControl.SubclassDlgItem( hDlg , IDC_ATDLG_EDIT );
/*
* Determine the edit control's font and format offset metrics. */
TEXTMETRIC tm; RECT Rect; HDC dc; HFONT hFont , hOldFont;
dc = GetDC( m_EditControl.m_hWnd );
hFont = ( HFONT )SendMessage( m_EditControl.m_hWnd , WM_GETFONT , 0 , 0 );
hOldFont = ( HFONT )SelectObject( dc , hFont);
GetTextMetrics( dc , &tm );
SelectObject( dc , hOldFont);
ReleaseDC( m_EditControl.m_hWnd , dc );
m_EditControl.m_FontHeight = tm.tmHeight;
m_EditControl.m_FontWidth = tm.tmMaxCharWidth;
SendMessage( m_EditControl.m_hWnd , EM_GETRECT , 0 , ( LPARAM )&Rect );
m_EditControl.m_FormatOffsetY = Rect.top;
m_EditControl.m_FormatOffsetX = Rect.left;
/*
* Subclass the led controls and default to 'off'. */ for( i = 0; i < NUM_LEDS; i++ ) { m_pLeds[i]->Subclass( hDlg , LedIds[i] );
m_pLeds[i]->Update(0);
}
return ( TRUE );
} // end CAsyncTestDlg::OnInitDialog
/*******************************************************************************
* * OnTimer - CAsyncTestDlg member function: command (override) * * Used for quick 'LED toggle'. * * ENTRY: * EXIT: * (Refer to CWnd::OnTimer documentation) * ******************************************************************************/
void CAsyncTestDlg::OnTimer(UINT nIDEvent) { /*
* Process this timer event if it it our 'LED toggle' event. */ ODS( L"TSCC:CAsyncTestDlg::OnTimer \n" );
if( nIDEvent == m_LEDToggleTimer ) { ODS( L"TSCC:CAsyncTestDlg::OnTimer hit event\n" ); /*
* Toggle each LED that is flagged as 'changed'. */ ODS( L"TSCC:led toggle " );
if( m_Status.AsyncSignalMask & EV_DTR ) { ODS( L"dtr\n");
( ( CLed * )GetDlgItem( IDC_ATDLG_DTR ) )->Toggle(); }
if( m_Status.AsyncSignalMask & EV_RTS ) { ODS(L"rts\n");
( ( CLed * )GetDlgItem( IDC_ATDLG_RTS ) )->Toggle(); }
if( m_Status.AsyncSignalMask & EV_CTS ) { ODS(L"cts\n"); ( ( CLed * )GetDlgItem( IDC_ATDLG_CTS ) )->Toggle(); }
if( m_Status.AsyncSignalMask & EV_RLSD ) { ODS(L"rlsd\n");
( ( CLed * )GetDlgItem( IDC_ATDLG_DCD ) )->Toggle(); }
if( m_Status.AsyncSignalMask & EV_DSR ) { ODS(L"dsr\n");
( ( CLed * )GetDlgItem( IDC_ATDLG_DSR ) )->Toggle(); }
if( m_Status.AsyncSignalMask & EV_RING ) { ODS(L"ring\n" ); ( ( CLed * )GetDlgItem( IDC_ATDLG_RI ) )->Toggle(); }
/*
* Kill this timer event and indicate so. */
KillTimer( m_hDlg , m_LEDToggleTimer );
m_LEDToggleTimer = 0; }
} // end CAsyncTestDlg::OnTimer
/*******************************************************************************
* * OnAsyncTestError - CAsyncTestDlg member function: command * * Handle the Async Test Dialog error conditions. * * ENTRY: * wParam (input) * Contains message ID for error. * wLparam (input) * Contains error code (GetLastError or API-specific return code) * EXIT: * (LRESULT) always returns 0 to indicate error handling complete. * ******************************************************************************/ /*#define STANDARD_ERROR_MESSAGE(x) { if ( 1 ) StandardErrorMessage x ; }
LRESULT CAsyncTestDlg::OnAsyncTestError( WPARAM wParam, LPARAM lParam ) { /*
* Handle special and default errors. */
/*switch ( wParam )
{
case IDP_ERROR_MODEM_SET_INFO: case IDP_ERROR_MODEM_GET_DIAL: case IDP_ERROR_MODEM_GET_INIT: case IDP_ERROR_MODEM_GET_LISTEN: break;
case IDP_ERROR_DISABLE: StandardErrorMessage( L"Test", (HWND)LOGONID_NONE, (HINSTANCE)lParam, wParam, (UINT)m_pWSName,0 ); break;
default: StandardErrorMessage( L"Test",(HWND) LOGONID_NONE, (HINSTANCE)lParam, (UINT)wParam, lParam,0); break; }
return(0);
} // end CAsyncTestDlg::OnAsyncTestError*/
/*******************************************************************************
* * OnAsyncTestAbort - CAsyncTestDlg member function: command * * Handle the Async Test Dialog abort conditions. * * ENTRY: * wParam (input) * Contains message ID for error. * wLparam (input) * Contains error code (GetLastError) * EXIT: * (LRESULT) always returns 0 to indicate error handling complete. Will * have posted an 'Ok' (Exit) button click to cause exit. * ******************************************************************************/
LRESULT CAsyncTestDlg::OnAsyncTestAbort( WPARAM wParam, LPARAM lParam ) { UNREFERENCED_PARAMETER( lParam ); /*
* Call OnAsyncTestError() to output message. */ //OnAsyncTestError(wParam, lParam);
NotifyAbort((UINT)wParam); /*
* Post a click for 'OK' (Exit) button to exit dialog. */ PostMessage( m_hDlg , WM_COMMAND , MAKEWPARAM( IDOK, BN_CLICKED ) , (LPARAM)::GetDlgItem( m_hDlg , IDOK ) );
return(0);
} // end CAsyncTestDlg::OnAsyncTestAbort
/*******************************************************************************
* * OnAsyncTestStatusReady - CAsyncTestDlg member function: command * * Update dialog with comm status information. * * ENTRY: * wParam (input) * not used (0) * wLparam (input) * not used (0) * EXIT: * (LRESULT) always returns 0. * ******************************************************************************/
LRESULT CAsyncTestDlg::OnAsyncTestStatusReady( WPARAM wParam, LPARAM lParam ) { UNREFERENCED_PARAMETER( wParam ); UNREFERENCED_PARAMETER( lParam );
/*
* Update dialog fields with information from the input thread's * PROTOCOLSTATUS structure. */ SetInfoFields( &m_Status, &(m_pATDlgInputThread->m_Status) );
/*
* Set our working PROTOCOLSTATUS structure to the new one and signal * the thread that we're done. */ m_Status = m_pATDlgInputThread->m_Status;
m_pATDlgInputThread->SignalConsumed();
return(0);
} // end CAsyncTestDlg::OnAsyncTestStatusReady
/*******************************************************************************
* * OnAsyncTestInputReady - CAsyncTestDlg member function: command * * Update dialog with comm input data. * * ENTRY: * wParam (input) * not used (0) * wLparam (input) * not used (0) * EXIT: * (LRESULT) always returns 0. * ******************************************************************************/
LRESULT CAsyncTestDlg::OnAsyncTestInputReady( WPARAM wParam, LPARAM lParam ) { UNREFERENCED_PARAMETER( wParam ); UNREFERENCED_PARAMETER( lParam );
BYTE OutBuf[MAX_COMMAND_LEN+2];
int i, j;
/*
* Copy the thread's buffer and count locally. */ m_BufferBytes = m_pATDlgInputThread->m_BufferBytes;
CopyMemory( m_Buffer , m_pATDlgInputThread->m_Buffer , m_BufferBytes );
/*
* Always return caret to the current position before processing, and set * edit control to 'read/write' so that character overwrites can occur * properly. Finally, flag control for no redraw until all updates are completed, * and flag 'processing output' to avoid OnChar() recursion during '\b' processing. */
SendMessage( m_EditControl.m_hWnd , EM_SETSEL , m_CurrentPos , m_CurrentPos );
SendMessage( m_EditControl.m_hWnd , EM_SETREADONLY , ( WPARAM )FALSE , 0 );
SendMessage( m_EditControl.m_hWnd , WM_SETREDRAW , ( WPARAM )FALSE , 0 );
/*
* Loop to traverse the buffer, with special processing for certain * control characters. */ for ( i = 0, j = 0; m_BufferBytes; i++, m_BufferBytes-- ) { switch( m_Buffer[i] ) { case '\b': /*
* If there is data in the output buffer, write it now. */ if( j ) { OutputToEditControl(OutBuf, &j); }
/*
* Output the '\b' (will actually cut current character from buffer) */ OutBuf[j++] = '\b';
OutputToEditControl(OutBuf, &j);
continue;
case '\r': /*
* If there is data in the output buffer, write it now. */ if( j ) { OutputToEditControl(OutBuf, &j); }
/*
* Output the '\r' (will not actually output, but will special case * for caret positioning and screen update). */
OutBuf[j++] = '\r';
OutputToEditControl(OutBuf, &j);
continue;
case '\n': /*
* If there is data in the output buffer, write it now. */
if( j ) { OutputToEditControl(OutBuf, &j); }
/*
* Output the '\n' (will actually quietly output the '\r' and take * care of scolling). */ OutBuf[j++] = '\n';
OutputToEditControl(OutBuf, &j);
continue; }
/*
* Add this character to the output buffer. */ OutBuf[j++] = m_Buffer[i]; }
/*
* If there is anything remaining in the output buffer, output it now. */ if( j ) { OutputToEditControl(OutBuf, &j); }
/*
* Place edit control back in 'read only' mode, flag 'not processing output', * set redraw flag for control, and validate the entire control (updates have * already taken place). */ SendMessage( m_EditControl.m_hWnd , EM_SETREADONLY , ( WPARAM )TRUE , 0 );
SendMessage( m_EditControl.m_hWnd , WM_SETREDRAW , ( WPARAM )TRUE , 0 );
ValidateRect( m_EditControl.m_hWnd , NULL );
/*
* Signal thread that we're done with input so that it can continue. * NOTE: we don't do this at the beginning of the routine even though * we could (for more parallelism), since a constantly chatty async * line would cause WM_ASYNCTESTINPUTREADY messages to always be posted * to our message queue, effectively blocking any other message processing * (like telling the dialog to exit!). */
m_pATDlgInputThread->SignalConsumed();
return(0);
} // end CAsyncTestDlg::OnAsyncTestInputReady
/*******************************************************************************/ void CAsyncTestDlg::OutputToEditControl( BYTE *pBuffer, int *pIndex ) { RECT Rect, ClientRect;
BOOL bScroll = FALSE;
INT_PTR CurrentLine = SendMessage( m_EditControl.m_hWnd , EM_LINEFROMCHAR , ( WPARAM )m_CurrentPos , 0 );
INT_PTR FirstVisibleLine = SendMessage( m_EditControl.m_hWnd , EM_GETFIRSTVISIBLELINE , 0 , 0 );
INT_PTR CurrentLineIndex = SendMessage( m_EditControl.m_hWnd , EM_LINEINDEX , ( WPARAM )CurrentLine , 0 );
/*
* Calculate clip rectangle. */ Rect.top = ( ( int )( CurrentLine - FirstVisibleLine ) * m_EditControl.m_FontHeight ) + m_EditControl.m_FormatOffsetY;
Rect.bottom = Rect.top + m_EditControl.m_FontHeight;
Rect.left = m_EditControl.m_FormatOffsetX +( ( int )( m_CurrentPos - CurrentLineIndex ) * m_EditControl.m_FontWidth );
Rect.right = Rect.left + (*pIndex * m_EditControl.m_FontWidth);
/*
* Handle special cases. */ if ( pBuffer[0] == '\b' ) {
/*
* If we're already at the beginning of the line, clear buffer index * and return (don't do anything). */ if ( m_CurrentPos == CurrentLineIndex ) {
*pIndex = 0; return; }
/*
* Position the caret back one character and select through current character. */ SendMessage( m_EditControl.m_hWnd , EM_SETSEL , m_CurrentPos - 1 , m_CurrentPos );
/*
* Cut the character out of the edit buffer. */ m_EditControl.m_bProcessingOutput = TRUE;
SendMessage( m_EditControl.m_hWnd , WM_CUT , 0 , 0 );
m_EditControl.m_bProcessingOutput = FALSE;
/*
* Decrement current position and zero index to suppress further output. Also, * widen the clipping rectangle back one character. */ Rect.left -= m_EditControl.m_FontWidth;
m_CurrentPos--;
*pIndex = 0;
} else if( pBuffer[0] == '\r' ) {
/*
* Position the caret at the beginning of the current line. */ m_CurrentPos = CurrentLineIndex;
SendMessage( m_EditControl.m_hWnd , EM_SETSEL , m_CurrentPos, m_CurrentPos );
/*
* Zero index to keep from actually outputing to edit buffer. */ *pIndex = 0;
} else if( pBuffer[0] == '\n' ) {
/*
* Position selection point at end of the current edit buffer. */
m_CurrentPos = GetWindowTextLength( m_EditControl.m_hWnd );
SendMessage( m_EditControl.m_hWnd , EM_SETSEL , m_CurrentPos , -1 );
/*
* Cause '\r' '\n' pair to be output to edit buffer. */ pBuffer[0] = '\r'; pBuffer[1] = '\n'; *pIndex = 2;
/*
* See if scrolling needed. */ GetClientRect( m_EditControl.m_hWnd , &ClientRect );
if ( (Rect.bottom + m_EditControl.m_FontHeight) > ClientRect.bottom ) bScroll = TRUE;
} else {
/*
* Set selection from current position through *pIndex characters. This * will perform desired 'overwrite' function if current position is not at * the end of the edit buffer. */
SendMessage( m_EditControl.m_hWnd , EM_SETSEL , m_CurrentPos , m_CurrentPos + *pIndex ); }
/*
* If necessary, update the dialog's edit box with the buffer data. */ if( *pIndex ) {
#ifdef UNICODE
TCHAR OutBuffer[MAX_COMMAND_LEN+1];
mbstowcs(OutBuffer, (PCHAR)pBuffer, *pIndex); OutBuffer[*pIndex] = TEXT('\0'); SendMessage( m_EditControl.m_hWnd , EM_REPLACESEL , ( WPARAM )FALSE , ( LPARAM )OutBuffer ); #else
pBuffer[*pIndex] = BYTE('\0');
SendMessage( m_EditControl.m_hWnd , EM_REPLACESEL , ( WPARAM )FALSE , ( LPARAM )pBuffer );
#endif // UNICODE
}
/*
* Update the current line. */
SendMessage( m_EditControl.m_hWnd , WM_SETREDRAW , ( WPARAM )TRUE , 0 );
ValidateRect( m_EditControl.m_hWnd , NULL );
InvalidateRect( m_EditControl.m_hWnd , &Rect , FALSE );
UpdateWindow( m_EditControl.m_hWnd ); /*
* If scrolling is required to see the new line, do so. */ if( bScroll ) { SendMessage( m_EditControl.m_hWnd , EM_LINESCROLL , 0 , 1 ); }
SendMessage( m_EditControl.m_hWnd , WM_SETREDRAW , ( WPARAM )FALSE , 0 );
/*
* Update current position and clear buffer index. */
m_CurrentPos += *pIndex;
*pIndex = 0;
} // end CAsyncTestDlg::OutputToEditControl
/*******************************************************************************
* * OnAsyncTestWriteChar - CAsyncTestDlg member function: command * * Place the specified character in m_Buffer, set m_BufferBytes to 1, * and call DeviceWrite() to output the character to the device. * * ENTRY: * wParam (input) * Character to write. * lParam (input) * not used (0) * EXIT: * (LRESULT) always returns 0. * ******************************************************************************/
LRESULT CAsyncTestDlg::OnAsyncTestWriteChar( WPARAM wParam, LPARAM lParam ) { UNREFERENCED_PARAMETER( wParam ); UNREFERENCED_PARAMETER( lParam ); /*
* Write the byte to the device. */ m_Buffer[0] = (BYTE)wParam;
m_BufferBytes = 1;
DeviceWrite();
return(0);
} // end CAsyncTestDlg::OnAsyncTestWriteChar
/*******************************************************************************
* * OnClickedAtdlgModemDial - CAsyncTestDlg member function: command * * Send the modem dial string. * * ENTRY: * EXIT: * ******************************************************************************/
void CAsyncTestDlg::OnClickedAtdlgModemDial() { } // end CAsyncTestDlg::OnClickedAtdlgModemDial
/*******************************************************************************
* * OnClickedAtdlgModemInit - CAsyncTestDlg member function: command * * Send the modem init string. * * ENTRY: * EXIT: * ******************************************************************************/
void CAsyncTestDlg::OnClickedAtdlgModemInit() { } // end CAsyncTestDlg::OnClickedAtdlgModemInit
/*******************************************************************************
* * OnClickedAtdlgModemListen - CAsyncTestDlg member function: command * * Send the modem listen string. * * ENTRY: * EXIT: * ******************************************************************************/
void CAsyncTestDlg::OnClickedAtdlgModemListen() { lstrcpy((TCHAR *)m_Buffer, m_szModemListen);
m_BufferBytes = lstrlen((TCHAR *)m_Buffer);
DeviceWrite();
} // end CAsyncTestDlg::OnClickedAtdlgModemListen
/*******************************************************************************
* * OnNcDestroy - CAsyncTestDlg member function: command * * Clean up before deleting dialog object. * * ENTRY: * EXIT: * (Refer to CWnd::OnNcDestroy documentation) * ******************************************************************************/
void CAsyncTestDlg::OnNcDestroy() { if( m_LEDToggleTimer ) { KillTimer( m_hDlg , m_LEDToggleTimer ); }
if( m_pATDlgInputThread ) { m_pATDlgInputThread->ExitThread(); }
if( m_hDevice != INVALID_HANDLE_VALUE ) { PurgeComm(m_hDevice, PURGE_TXABORT | PURGE_TXCLEAR); }
if( m_OverlapWrite.hEvent != NULL ) { CloseHandle(m_OverlapWrite.hEvent); }
if( m_hDevice != INVALID_HANDLE_VALUE ) { CloseHandle(m_hDevice); }
if( m_bDeletedWinStation && m_pWSName ) { m_WSConfig.Create.fEnableWinStation = TRUE;
if( RegWinStationCreate( SERVERNAME_CURRENT , m_pWSName , FALSE , &m_WSConfig , sizeof(WINSTATIONCONFIG2) ) != ERROR_SUCCESS ) { _WinStationReadRegistry(SERVERNAME_CURRENT);
} }
DeleteObject(m_hRedBrush);
} // end CAsyncTestDlg::OnNcDestroy
////////////////////////////////////////////////////////////////////////////////
INT_PTR CALLBACK CAsyncTestDlg::DlgProc( HWND hwnd , UINT msg , WPARAM wp , LPARAM lp ) { CAsyncTestDlg *pDlg;
if( msg == WM_INITDIALOG ) { CAsyncTestDlg *pDlg = ( CAsyncTestDlg * )lp;
SetWindowLongPtr( hwnd , DWLP_USER, ( LONG_PTR )pDlg );
if( !IsBadReadPtr( pDlg , sizeof( CAsyncTestDlg ) ) ) { if(FALSE == pDlg->OnInitDialog( hwnd , wp , lp )) PostMessage(hwnd,WM_CLOSE,0,0); }
return 0; }
else { pDlg = ( CAsyncTestDlg * )GetWindowLongPtr( hwnd , DWLP_USER);
if( IsBadReadPtr( pDlg , sizeof( CAsyncTestDlg ) ) ) { return 0; } }
switch( msg ) {
case WM_NCDESTROY:
pDlg->OnNcDestroy( );
break;
case WM_COMMAND:
pDlg->OnCommand( HIWORD( wp ) , LOWORD( wp ) , ( HWND )lp );
break;
case WM_TIMER:
pDlg->OnTimer( ( UINT )wp );
break;
case WM_ASYNCTESTERROR:
ODS(L"TSCC:CAsyncTestDlg WM_ASYNCTESTERROR (R)\n" );
pDlg->NotifyAbort((UINT)wp);
break;
case WM_ASYNCTESTABORT:
ODS(L"TSCC:CAsyncTestDlg WM_ASYNCTESTABORT (R)\n" );
pDlg->OnAsyncTestAbort( wp , lp );
break;
case WM_ASYNCTESTSTATUSREADY:
ODS(L"TSCC:CAsyncTestDlg WM_ASYNCTESTSTATUSREADY (R)\n" );
pDlg->OnAsyncTestStatusReady( wp , lp );
break;
case WM_ASYNCTESTINPUTREADY:
ODS(L"TSCC:CAsyncTestDlg WM_ASYNCTESTINPUTREADY (R)\n" );
pDlg->OnAsyncTestInputReady( wp , lp );
break;
case WM_ASYNCTESTWRITECHAR:
ODS(L"TSCC:CAsyncTestDlg WM_ASYNCTESTWRITECHAR (R)\n" );
pDlg->OnAsyncTestWriteChar( wp , lp );
break; }
return 0; }
|