Click here to Skip to main content
15,886,199 members
Articles / Programming Languages / C++

Windows Switcher Add-In

Rate me:
Please Sign up or sign in to vote.
3.50/5 (2 votes)
4 Jan 20042 min read 45.3K   388   11  
How to speed-up navigating in big workspace using keyboard
// WindowsListDialog.cpp : implementation file
//

#include "stdafx.h"
#include "WindowsSwitcher.h"
#include "WindowsListDialog.h"
#include "KeyBindingsDialog.h"
#include "AboutDialog.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CWindowsListDialog dialog

CString CWindowsListDialog::m_oActiveProjectNameString;

CWindowsListDialog::CWindowsListDialog( IApplication* pIApplication, CWnd* pParent /*=NULL*/ )
	: CDialog(CWindowsListDialog::IDD, pParent), m_pIApplication( pIApplication )
{
	//{{AFX_DATA_INIT(CWindowsListDialog)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
}

CWindowsListDialog::~CWindowsListDialog()
{
	DeleteWindowsDescriptions();
}


void CWindowsListDialog::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CWindowsListDialog)
	DDX_Control(pDX, IDC_EDIT_FILTER, m_oFilterEdit);
	DDX_Control(pDX, IDC_LIST_WINDOWS, m_oWindowsListCtrl);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CWindowsListDialog, CDialog)
	//{{AFX_MSG_MAP(CWindowsListDialog)
	ON_EN_CHANGE(IDC_EDIT_FILTER, OnChangeEditFilter)
	ON_BN_CLICKED(IDC_BUTTON_ACVITATE, OnButtonAcvitate)
	ON_BN_CLICKED(IDC_BUTTON_CLOSE_WND, OnButtonCloseWnd)
	ON_NOTIFY(NM_DBLCLK, IDC_LIST_WINDOWS, OnDblclkListWindows)
	ON_WM_DESTROY()
	ON_WM_CONTEXTMENU()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CWindowsListDialog message handlers

BOOL CWindowsListDialog::OnInitDialog() 
{
	CDialog::OnInitDialog();

	// change style
	DWORD dwStyle = 0;
	m_oWindowsListCtrl.GetExtendedStyle();
	dwStyle |= LVS_EX_FULLROWSELECT;
	m_oWindowsListCtrl.SetExtendedStyle( dwStyle );

	m_oWindowsListCtrl.InsertColumn( eColumnIndexContent, "Content", LVCFMT_LEFT, 200 );	
	m_oWindowsListCtrl.InsertColumn( eColumnIndexProject, "Project", LVCFMT_LEFT, 150 );
	m_oWindowsListCtrl.InsertColumn( eColumnIndexFullPath, "Full path", LVCFMT_LEFT, 500 );

	LoadDialogSettings();

	try
	{
		m_pIProjects = m_pIApplication->Projects;
		m_pIWindows = m_pIApplication->Windows;

		try
		{	
			::DSSharedObjects::IGenericProjectPtr	pIActiveProject = m_pIApplication->ActiveProject;
			pIActiveProject = m_pIApplication->ActiveProject;
			m_oActiveProjectNameString = (CComBSTR)(BSTR)pIActiveProject->Name;
		}
		catch( _com_error & )	// don't generate an error if none project is available
		{
		}

		ReadProjectNames();
		GetWindowsDescriptions();
		PopulateWindowsListCtrl();
	}
	catch( _com_error &oComError )
	{
		AfxMessageBox( oComError.Description() );
		return FALSE;
	}	
	
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

int __cdecl CompareProjectByPathLength( const void *elem1, const void *elem2 )
{
	CProject *poProject1 = (CProject *)elem1;
	CProject *poProject2 = (CProject *)elem2;

	return poProject2->m_oPathString.GetLength() - poProject1->m_oPathString.GetLength();
}

void CWindowsListDialog::ReadProjectNames()
{	
	m_aoProjectsArray.SetSize( m_pIProjects->Count );

	for( int iIndex = 1; iIndex <= m_pIProjects->Count; iIndex++ )
	{
		CString oFullNameString = (BSTR) m_pIProjects->Item( CComVariant( iIndex ) )->FullName;
		int iLastBackSlashIndex = oFullNameString.ReverseFind( '\\' );

		m_aoProjectsArray[iIndex - 1].m_oNameString = (CString)(BSTR) m_pIProjects->Item( CComVariant( iIndex ) )->Name;
		
		if( iLastBackSlashIndex > -1 )
		{
			m_aoProjectsArray[iIndex - 1].m_oPathString = oFullNameString.Left( iLastBackSlashIndex );
		}
		else
		{
			m_aoProjectsArray[iIndex - 1].m_oPathString = oFullNameString;
		}

		m_aoProjectsArray[iIndex - 1].m_oPathString.MakeLower();
	}

	// sort projects by path length descending in order to assure correctly recognize project to which the file belongs
	// in case when one path name includes path name from other project
	qsort( m_aoProjectsArray.GetData(), m_aoProjectsArray.GetSize(), sizeof( CProject ), CompareProjectByPathLength );
}

int __cdecl CompareWindows( const void *elem1, const void *elem2 )
{
	CWindowDescription *poWindow1 = (*(CWindowDescription **)elem1);
	CWindowDescription *poWindow2 = (*(CWindowDescription **)elem2);
	bool bWin1InActualProject = poWindow1->m_oProjectNameString.Compare( CWindowsListDialog::m_oActiveProjectNameString ) == 0;
	bool bWin2InActualProject = poWindow2->m_oProjectNameString.Compare( CWindowsListDialog::m_oActiveProjectNameString ) == 0;

	if( bWin1InActualProject )
	{
		if( bWin2InActualProject )
		{
			return poWindow1->m_oWindowContentString.Compare( poWindow2->m_oWindowContentString );
		}
		else
		{
			return -1;
		}
	}
	else if( bWin2InActualProject )
	{
		return 1;
	}
	else
	{
		bool bWin1HasEmptyProject = ( poWindow1->m_oProjectNameString.IsEmpty() == TRUE );
		bool bWin2HasEmptyProject = ( poWindow2->m_oProjectNameString.IsEmpty() == TRUE );

		if( bWin1HasEmptyProject )
		{
			if( !bWin2HasEmptyProject )
			{
				return 1;
			}
		}
		else
		{
			if( bWin2HasEmptyProject )
			{
				return -1;
			}
		}

		int bProjectCompare = poWindow1->m_oProjectNameString.Compare( poWindow2->m_oProjectNameString );

		if( bProjectCompare != 0 )
		{
			return bProjectCompare;
		}
		else
		{
			return poWindow1->m_oWindowContentString.Compare( poWindow2->m_oWindowContentString );
		}		
	}
}

void CWindowsListDialog::GetWindowsDescriptions()
{
	int iItemIndex = 0;
	long lTmpWindowsListCount = m_pIWindows->Count;
		
	m_aoWindowsDescriptionsArray.SetSize( lTmpWindowsListCount );
	memset( m_aoWindowsDescriptionsArray.GetData(), 0, sizeof( CWindowDescription *) * lTmpWindowsListCount );
	
	for( int iIndex = 1; iIndex <= lTmpWindowsListCount; iIndex++ )
	{
		::DSSharedObjects::IGenericWindowPtr pIWindow = m_pIWindows->Item( CComVariant( iIndex ) );
		CString oCaptionString = (BSTR)pIWindow->Caption;

		if( oCaptionString != "Disassembly" )// dissasebly window have no document
		{
			::DSSharedObjects::IGenericDocumentPtr pIDocument = pIWindow->Parent;
			CWindowDescription *poWindowDescription = new CWindowDescription;
			
			CString oWindowNameString = RemovePathAndDecorationsFromCaption( oCaptionString, pIDocument );
			
			poWindowDescription->m_oFullPathString = (BSTR)pIDocument->FullName;
			poWindowDescription->m_oProjectNameString = GetProjectNameForWindow( poWindowDescription->m_oFullPathString );
			poWindowDescription->m_oWindowContentString = ReadWindowContent( poWindowDescription->m_oFullPathString, oWindowNameString, pIDocument );
			poWindowDescription->m_iWindowIndex = iIndex;
			m_aoWindowsDescriptionsArray[iItemIndex++] = poWindowDescription;
		}
	}

	qsort( m_aoWindowsDescriptionsArray.GetData(), iItemIndex, sizeof( CWindowDescription* ), CompareWindows );

	m_aoWindowsDescriptionsArray.SetSize( iItemIndex );
}

void CWindowsListDialog::DeleteWindowsDescriptions()
{
	for( int iIndex = 0; iIndex < m_aoWindowsDescriptionsArray.GetSize(); iIndex++ )
	{
		if( m_aoWindowsDescriptionsArray[iIndex] )
		{
			delete m_aoWindowsDescriptionsArray[iIndex];
			m_aoWindowsDescriptionsArray[iIndex] = NULL;
		}
	}
}

CString CWindowsListDialog::RemovePathAndDecorationsFromCaption( const CString &oWindowCaption, ::DSSharedObjects::IGenericDocumentPtr pIDocument )
{
	CString oWindowNameString = oWindowCaption;
	CString oWindowTypeString = (CString)(BSTR)pIDocument->Type;

	int iBackslashIndex = oWindowNameString.ReverseFind( '\\' );

	// remove file path
	if( iBackslashIndex > -1 )
	{
		oWindowNameString.Delete( 0, iBackslashIndex + 1 );
	}	

	// for opened resource windows remove resource file name
	if( oWindowTypeString == "Generic" )
	{
		int iMinusIndex = oWindowNameString.Find( '-' );

		if( iMinusIndex > 0
			&& iMinusIndex + 1 < oWindowNameString.GetLength() )
		{
			oWindowNameString.Delete( 0, iMinusIndex + 2 );
			
			for( int iIndex = 0; iIndex < oWindowNameString.GetLength(); iIndex++ )
			{
				if( oWindowNameString[iIndex] == ' ' )
				{
					oWindowNameString.Delete( iIndex, oWindowNameString.GetLength() - iIndex );
					break;
				}
			}
		}
	}

	return oWindowNameString;
}

CString CWindowsListDialog::GetProjectNameForWindow( const CString &oWindowFullPathString )
{
	CString oLowerFileNameString = oWindowFullPathString;
	
	oLowerFileNameString.MakeLower();

	for( int iProjIndex = 0; iProjIndex < m_aoProjectsArray.GetSize(); iProjIndex++ )
	{
		if( m_aoProjectsArray[iProjIndex].m_oPathString == oLowerFileNameString.Left( m_aoProjectsArray[iProjIndex].m_oPathString.GetLength() ) )
		{
			return m_aoProjectsArray[iProjIndex].m_oNameString;
		}
	}

	return "";
}

CString CWindowsListDialog::ReadWindowContent( const CString &oWindowFullPathString, const CString &oWindowCaptionString, ::DSSharedObjects::IGenericDocumentPtr pIDocument )
{
	CString oWindowTypeString = (CString)(BSTR)pIDocument->Type;
	CString oLineString;
	EFileTypes eFileExtension = GetFileExtensionType( oWindowFullPathString );
	CString oFileContentString = oWindowCaptionString;	// get window caption as default window content
	bool bContentWasFound = false;

	if( oWindowTypeString != "Generic" )
	{
		switch( eFileExtension )
		{
		case eFileTypeCpp:
		case eFileTypeHeader:
			TRY
			{
				CStdioFile oFile( oWindowFullPathString, CFile::modeRead );
				
				// analyse window content line by line
				while( oFile.ReadString( oLineString ) && !bContentWasFound )
				{
					switch( eFileExtension )
					{
					case eFileTypeCpp:
						if( FindFileContentInCppLine( oLineString, &oFileContentString ) )
						{
							bContentWasFound = true;
						}
						break;
						
					case eFileTypeHeader:					
						if( FindFileContentInHeaderLine( oLineString, &oFileContentString ) )
						{
							bContentWasFound = true;
						}
						break;
					}
				}
			}
			CATCH( CFileException, poFileException )
			{
				
			}
			END_CATCH
		}
	}

	return oFileContentString;
}

CWindowsListDialog::EFileTypes CWindowsListDialog::GetFileExtensionType( const CString &oFileNameString )
{
	EFileTypes eFileExtension = eFileTypeOther;
	int iExtIndex = oFileNameString.ReverseFind( '.' );

	if( iExtIndex > -1 )
	{
		CString oExtensionString = oFileNameString.Mid( iExtIndex );

		if( oExtensionString.CompareNoCase( ".cpp" ) == 0 )
		{
			eFileExtension = eFileTypeCpp;
		}
		else if( oExtensionString.CompareNoCase( ".h" ) == 0 )
		{
			eFileExtension = eFileTypeHeader;
		}
	}

	return eFileExtension;
}

bool CWindowsListDialog::FindFileContentInCppLine( const CString &oLineString, CString *poFileContentString )
{
	int iDotIndex = oLineString.Find( "::" );	// look for class name in any method e.g. CString::CString()

	if( iDotIndex > -1 )
	{	
		int iRemIndex = oLineString.Find( "//" );	// omit commented class name

		if( iRemIndex == -1 || iRemIndex > iDotIndex )
		{
			int iParanthesisIndex = oLineString.Find( '(', iDotIndex );	// find for paranthesis

			if( iParanthesisIndex > -1 )
			{
				// class name is between '::' or white-space and '('
				for( int iStartIndex = iDotIndex; iStartIndex > 0; iStartIndex-- )
				{
					if( isspace( oLineString[iStartIndex] ) )
					{
						iStartIndex++;
						break;
					}
				}
				
				CString oContentString = oLineString.Mid( iStartIndex, iDotIndex - iStartIndex );
				
				if( IsItIdentifier( oContentString ) )
				{					
					*poFileContentString = oContentString +" (.cpp)";
					return true;
				}
			}
		}
	}

	return false;
}

bool CWindowsListDialog::FindFileContentInHeaderLine( const CString &oLineString, CString *poFileContentString )
{
	int iClassIndex = oLineString.Find( "class" );

	if( iClassIndex > -1 )
	{
		int iRemIndex = oLineString.Find( "//" );

		// ommit commented class name
		if( iRemIndex == -1 || iClassIndex < iRemIndex  )
		{
			int iSemicolonIndex = oLineString.Find( ';', iClassIndex );

			// class name should not be finished by ';'
			if( iSemicolonIndex == -1 )
			{
				*poFileContentString = "";
				
				for( int iIndex = iClassIndex + sizeof( "class" ); iIndex < oLineString.GetLength(); iIndex++ )
				{
					char cCharacter = oLineString[iIndex];
					
					if( !poFileContentString->IsEmpty() )
					{
						if( cCharacter == ':' )	// stop on ':' for inherited classes
						{
							break;
						}				
					}
					
					*poFileContentString += cCharacter;
				}

				// get only last word from content in order to ommit AFX_CLASS_EXPORT and other decorations
				CutToLastWord( poFileContentString );
								
				*poFileContentString += " (.h)";

				return true;
			}
		}

	}

	return false;
}

void CWindowsListDialog::PopulateWindowsListCtrl()
{
	CString oFilterString;
	int iAddIndex = 0;
	int iCurrentWindowData = -1, iCurrentWindowIndex = 0;
	POSITION pFirstSelItemPosition = m_oWindowsListCtrl.GetFirstSelectedItemPosition();	

	if( pFirstSelItemPosition )
	{
		iCurrentWindowData = m_oWindowsListCtrl.GetItemData( m_oWindowsListCtrl.GetNextSelectedItem( pFirstSelItemPosition ) );
	}
	
	m_oWindowsListCtrl.SetRedraw( FALSE );
	m_oWindowsListCtrl.DeleteAllItems();
	m_oFilterEdit.GetWindowText( oFilterString );

	for( int iIndex = 0; iIndex < m_aoWindowsDescriptionsArray.GetSize(); iIndex++ )
	{
		if( oFilterString.IsEmpty() 
			|| m_aoWindowsDescriptionsArray[iIndex]->IsContainFilteredWord( oFilterString ) )
		{
			m_oWindowsListCtrl.InsertItem( iAddIndex, "" );
			m_oWindowsListCtrl.SetItemText( iAddIndex, eColumnIndexProject, m_aoWindowsDescriptionsArray[iIndex]->m_oProjectNameString );
			m_oWindowsListCtrl.SetItemText( iAddIndex, eColumnIndexContent, m_aoWindowsDescriptionsArray[iIndex]->m_oWindowContentString );
			m_oWindowsListCtrl.SetItemText( iAddIndex, eColumnIndexFullPath, m_aoWindowsDescriptionsArray[iIndex]->m_oFullPathString );
			m_oWindowsListCtrl.SetItemData( iAddIndex, m_aoWindowsDescriptionsArray[iIndex]->m_iWindowIndex );

			if( iCurrentWindowData == m_aoWindowsDescriptionsArray[iIndex]->m_iWindowIndex )
			{
				iCurrentWindowIndex = iAddIndex;
			}

			iAddIndex++;
		}
	}

	if( m_oWindowsListCtrl.GetItemCount() > 0 )
	{
		m_oWindowsListCtrl.SetItemState( iCurrentWindowIndex, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED );
	}

	m_oWindowsListCtrl.SetRedraw( TRUE );
}


void CWindowsListDialog::OnChangeEditFilter() 
{
	PopulateWindowsListCtrl();
}

void CWindowsListDialog::OnButtonAcvitate() 
{
	POSITION pSelPosition = m_oWindowsListCtrl.GetFirstSelectedItemPosition();

	if( pSelPosition )
	{
		int iSelIndex = m_oWindowsListCtrl.GetNextSelectedItem( pSelPosition );
		int iWindowIndex = m_oWindowsListCtrl.GetItemData( iSelIndex );
		::DSSharedObjects::IGenericWindowPtr pIWindow = m_pIWindows->Item( CComVariant( iWindowIndex ) );

		CDialog::OnOK();
		pIWindow->Active = VARIANT_BOOL( -1 );
	}	
}

void CWindowsListDialog::OnButtonCloseWnd() 
{
	try
	{
		POSITION pSelPosition = m_oWindowsListCtrl.GetFirstSelectedItemPosition();
		
		if( pSelPosition )
		{
			CArray <int,int> aiSelectedWindowIndex;
			int iIndex = 0;
			aiSelectedWindowIndex.SetSize( m_oWindowsListCtrl.GetSelectedCount() );
			
			for( int iItemIndex = m_oWindowsListCtrl.GetItemCount() - 1; iItemIndex >= 0; iItemIndex-- )
			{
				if( m_oWindowsListCtrl.GetItemState( iItemIndex, LVIS_SELECTED ) == LVIS_SELECTED )
				{
					aiSelectedWindowIndex[iIndex++] = m_oWindowsListCtrl.GetItemData( iItemIndex );
				}
			}		
			
			int iMaxWndIndex = 0, iMaxIndex = -1;
			do
			{
				iMaxWndIndex = 0, iMaxIndex = -1;
				
				for( iIndex = aiSelectedWindowIndex.GetSize() - 1; iIndex >= 0 ; iIndex-- )
				{
					if( iMaxWndIndex < aiSelectedWindowIndex[iIndex] )
					{
						iMaxWndIndex = aiSelectedWindowIndex[iIndex];
						iMaxIndex = iIndex;
					}
				}
				
				if( iMaxIndex > -1 )
				{
					::DSSharedObjects::IGenericWindowPtr pIWindow = m_pIWindows->Item( CComVariant( iMaxWndIndex ) );
					pIWindow->Close( CComVariant( dsSaveChangesPrompt ) );
					aiSelectedWindowIndex[iMaxIndex] = 0;
				}
			}while( iMaxIndex > -1 );
		}
		
		GetWindowsDescriptions();
		PopulateWindowsListCtrl();
	}
	catch( _com_error &oComError )
	{
		AfxMessageBox( oComError.Description() );
	}
	
}

void CWindowsListDialog::OnDblclkListWindows(NMHDR* pNMHDR, LRESULT* pResult) 
{
	OnButtonAcvitate();
	
	*pResult = 0;
}

void CWindowsListDialog::SaveDialogSettings()
{
	CRegKey oRegKey;	

	if( oRegKey.Create( HKEY_LOCAL_MACHINE, oSettingsRegistryKey ) == ERROR_SUCCESS )
	{
		oRegKey.SetValue( m_oWindowsListCtrl.GetColumnWidth( eColumnIndexContent ), oSettingsValNameColWndContent );
		oRegKey.SetValue( m_oWindowsListCtrl.GetColumnWidth( eColumnIndexProject ), oSettingsValNameColWndProject );
		oRegKey.SetValue( m_oWindowsListCtrl.GetColumnWidth( eColumnIndexFullPath ), oSettingsValNameColWndFullPath );
		oRegKey.Close();
	}
}

void CWindowsListDialog::LoadDialogSettings()
{
	CRegKey oRegKey;
	CRect oRect;

	if( oRegKey.Open( HKEY_LOCAL_MACHINE, oSettingsRegistryKey ) == ERROR_SUCCESS )
	{
		DWORD dwWidth = 0;

		if( oRegKey.QueryValue( dwWidth, oSettingsValNameColWndContent ) == ERROR_SUCCESS )
		{
			m_oWindowsListCtrl.SetColumnWidth( eColumnIndexContent, dwWidth );
		}

		if( oRegKey.QueryValue( dwWidth, oSettingsValNameColWndProject ) == ERROR_SUCCESS )
		{
			m_oWindowsListCtrl.SetColumnWidth( eColumnIndexProject, dwWidth );
		}

		if( oRegKey.QueryValue( dwWidth, oSettingsValNameColWndFullPath ) == ERROR_SUCCESS )
		{
			m_oWindowsListCtrl.SetColumnWidth( eColumnIndexFullPath, dwWidth );
		}
	}
}

void CWindowsListDialog::OnDestroy() 
{
	CDialog::OnDestroy();

	SaveDialogSettings();
	
}

BOOL CWindowsListDialog::PreTranslateMessage(MSG* pMsg)
{
	if( pMsg->message == WM_KEYDOWN
		&& pMsg->hwnd == m_oFilterEdit.GetSafeHwnd() )
	{
		switch( pMsg->wParam )
		{
		case VK_DOWN:
		case VK_UP:
		case VK_PRIOR:
		case VK_NEXT:
			m_oWindowsListCtrl.PostMessage( WM_KEYDOWN, pMsg->wParam, pMsg->lParam );
			return TRUE;
		}
	}
	
	return CDialog::PreTranslateMessage(pMsg);
}

void CWindowsListDialog::CutToLastWord( CString *poString )
{
	ASSERT( poString );

	poString->TrimRight();

	for( int iIndex = poString->GetLength() - 1; iIndex >= 0; iIndex-- )
	{
		if( ::isspace( poString->GetAt( iIndex ) ) )
		{
			poString->Delete( 0, iIndex + 1 );
			return;
		}
	}
}

void CWindowsListDialog::OnContextMenu(CWnd* pWnd, CPoint point) 
{	
	CMenu oMenu;
   
	if( oMenu.LoadMenu( IDR_MENU_POPUP ) )
	{
		CMenu* poPopupMenu = oMenu.GetSubMenu( 0 );

		ASSERT( poPopupMenu != NULL );

		poPopupMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
		point.x, point.y,
		AfxGetMainWnd() );
	}	
}

BOOL CWindowsListDialog::OnCommand(WPARAM wParam, LPARAM lParam)
{
	switch( LOWORD( wParam ) )
	{
	case IDM_KEYBINDINGS:
		OnKeyBindingsDialog();
		return TRUE;

	case IDM_ABOUT:
		OnAbout();
		return TRUE;
	}
	
	return CDialog::OnCommand(wParam, lParam);
}

void CWindowsListDialog::OnKeyBindingsDialog()
{
	CKeyBindingsDialog oKeyBindingsDialog( m_pIApplication, this );

	oKeyBindingsDialog.DoModal();	
}

void CWindowsListDialog::OnAbout()
{
	CAboutDialog oAboutDialog;

	oAboutDialog.DoModal();

}

bool CWindowsListDialog::IsItIdentifier( const CString &oString )
{
	if( !oString.IsEmpty()
		&& 
		( oString[0] >= 'A' && oString[0] <= 'Z'
		|| oString[0] >= 'a' && oString[0] <= 'z'
		|| oString[0] == '_'
			)
		)
	{
		for( int iIndex = 1; iIndex < oString.GetLength(); iIndex++ )
		{
			if( oString[0] >= 'A' && oString[0] <= 'Z'
				|| oString[0] >= 'a' && oString[0] <= 'z'
				|| oString[0] >= '0' && oString[0] <= '9'
				|| oString[iIndex] == '_' )
			{
				continue;
			}
			else
			{
				return false;
			}
		}

		return true;
	}

	return false;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Poland Poland
Mariusz Wojtysiak started his career as coder on ZX-Spectrum demo-scene under nickname Maniu. He graduated Poznan University of Technology. His skills are: project/develop/maintenance of Oracle and MS SQL databases, programming in C++ (including MFC, ATL, Soap), Oracle Forms, and Assembler.
Currently works in IN-Software as developer. Live in Poznan/Poland.

Comments and Discussions