4672 lines
123 KiB
C++
4672 lines
123 KiB
C++
//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;
|
|
}
|
|
|