⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chtextinput.cpp

📁 Windows上的MUD客户端程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*----------------------------------------------------------------------------
                        _                              _ _       
        /\             | |                            | (_)      
       /  \   _ __   __| |_ __ ___  _ __ ___   ___  __| |_  __ _ 
      / /\ \ | '_ \ / _` | '__/ _ \| '_ ` _ \ / _ \/ _` | |/ _` |
     / ____ \| | | | (_| | | | (_) | | | | | |  __/ (_| | | (_| |
    /_/    \_\_| |_|\__,_|_|  \___/|_| |_| |_|\___|\__,_|_|\__,_|

    The contents of this file are subject to the Andromedia Public
	License Version 1.0 (the "License"); you may not use this file
	except in compliance with the License. You may obtain a copy of
	the License at http://www.andromedia.com/APL/

    Software distributed under the License is distributed on an
	"AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
	implied. See the License for the specific language governing
	rights and limitations under the License.

    The Original Code is Pueblo client code, released November 4, 1998.

    The Initial Developer of the Original Code is Andromedia Incorporated.
	Portions created by Andromedia are Copyright (C) 1998 Andromedia
	Incorporated.  All Rights Reserved.

	Andromedia Incorporated                         415.365.6700
	818 Mission Street - 2nd Floor                  415.365.6701 fax
	San Francisco, CA 94103

    Contributor(s):
	--------------------------------------------------------------------------
	   Chaco team:  Dan Greening, Glenn Crocker, Jim Doubek,
	                Coyote Lussier, Pritham Shetty.

					Wrote and designed original codebase.

------------------------------------------------------------------------------

	Implementation for the ChTextInputBar class.

----------------------------------------------------------------------------*/

// $Header: /home/cvs/chaco/modules/client/msw/ChWorld/ChTextInput.cpp,v 2.21 1996/09/23 17:10:50 pritham Exp $

#include "headers.h"

#include <ChConst.h>
#include <ChCore.h>
#include <ChSplit.h>
#include <ChUtil.h>
#include <ChHtpCon.h>

#include "World.h"
#include "ChTextInput.h"
#include "ChTextOutput.h"


/*----------------------------------------------------------------------------
	Constants
----------------------------------------------------------------------------*/

#define INPUT_BANNER_TITLE		"_TEXT_INPUT_BANNER_"
#define MAX_MENU_STRING_LEN		30

#define TEXT_INPUT_EDIT_ID		12345


/*----------------------------------------------------------------------------
	Forward declarations
----------------------------------------------------------------------------*/

CH_GLOBAL_FUNC( void )
TruncateMenuString( string& strText );


/*----------------------------------------------------------------------------
	ChTextInput class
----------------------------------------------------------------------------*/

ChTextInput::ChTextInput( ChWorldMainInfo* pMainInfo ) :
				m_pMainInfo( pMainInfo ),
				m_pBanner( 0 ),
				m_pEdit( 0 ),
				m_pPasswordEdit( 0 ),
				m_boolShown( false ),
				m_boolLoginRecognized( false ),
				m_sEditLines( 2 )
{
	Reset();

	UpdatePreferences();
	CreateEditField();
}


ChTextInput::~ChTextInput()
{
	if (IsShown())
	{
		Show( false );
	}

	if (m_pBanner)
	{
		ChSplitter*		pSplitter = GetMainInfo()->GetCore()->GetSplitter();

											/* Disassociate and destroy the
												edit field */
		m_pBanner->SetChild( 0 );
		if (m_pEdit)
		{
			delete m_pEdit;
			m_pEdit = 0;
		}
		if (m_pPasswordEdit)
		{
			delete m_pPasswordEdit;
			m_pPasswordEdit = 0;
		}
											// Destroy the banner
		pSplitter->DestroyBanner( m_pBanner );
		m_pBanner = 0;
	}
}


void ChTextInput::Show( bool boolShow )
{
	if (boolShow && !IsShown())
	{										// Show the banner
		if (m_pBanner)
		{
			Reset();
			m_pBanner->ShowWindow( SW_SHOW );
			SetFocus();
		}

		m_boolShown = true;
	}
	else if (!boolShow && IsShown())
	{										// Hide the banner
		if (m_pBanner)
		{
			m_pBanner->ShowWindow( SW_HIDE );
		}

		m_boolShown = false;
	}
}


void ChTextInput::SetFocus()
{
	ASSERT( 0 != GetEdit() );

	GetEdit()->PostMessage( WM_CHACO_GRABFOCUS );
}


void ChTextInput::Reset()
{
	m_boolLoginRecognized = false;

	if (m_pEdit && m_pPasswordEdit)
	{
		SetEcho( true, false );
	}
}


void ChTextInput::Clear()
{
	ASSERT( 0 != GetEdit() );

	GetEdit()->EraseText();
}


void ChTextInput::SetEcho( bool boolEcho, bool boolPreserve )
{
	if (boolEcho)
	{
		if (boolPreserve)
		{								/* Preserve what's already in the
											password edit field */
			string		strText;
			DWORD		dwSel;

			m_pPasswordEdit->GetWindowText( strText );
			m_pEdit->SetWindowText( strText );

			dwSel = m_pPasswordEdit->GetSel();
			m_pEdit->SetSel( dwSel );
		}
		else
		{								/* Not preserving, so empty the
											edit field */
			m_pEdit->EraseText();
		}
										// Set the new child into the banner
		m_pBanner->SetChild( m_pEdit );
		SizeEditField();

		m_pPasswordEdit->ShowWindow( SW_HIDE );
		m_pEdit->ShowWindow( SW_SHOW );
	}
	else
	{
		if (boolPreserve)
		{								/* Preserve what's already in the
											non-password edit field */
			string		strText;
			DWORD		dwSel;

			m_pEdit->GetWindowText( strText );
			m_pPasswordEdit->SetWindowText( strText );

			dwSel = m_pEdit->GetSel();
			m_pPasswordEdit->SetSel( dwSel );
		}
		else
		{								/* Not preserving, so empty the
											edit field */
			m_pPasswordEdit->EraseText();
		}
										// Set the new child into the banner

		m_pBanner->SetChild( m_pPasswordEdit );
		SizeEditField();

		m_pEdit->ShowWindow( SW_HIDE );
		m_pPasswordEdit->ShowWindow( SW_SHOW );
	}
}


void ChTextInput::SetInputLines( int iCount )
{
	ChRegistry	reg( WORLD_PREFS_GROUP );
	chint16		sOldEditLines = GetEditLines();

	if (iCount < 1)
	{
		iCount = 1;
	}
	else if (iCount > WORLD_EDIT_LINES_MAX)
	{
		iCount = WORLD_EDIT_LINES_MAX;
	}

	m_sEditLines = (chint16)iCount;

	if (sOldEditLines != GetEditLines())
	{										// Save the number of edit lines

		reg.Write( WORLD_EDIT_LINES, m_sEditLines );

											// Size the banner pane
		SizeEditField();
	}
}


void ChTextInput::UpdatePreferences()
{
	ChRegistry	reg( WORLD_PREFS_GROUP );
	chint16		sOldEditLines = GetEditLines();

											// Read in the number of edit lines

	reg.Read( WORLD_EDIT_LINES, m_sEditLines, WORLD_EDIT_LINES_DEF );

	if (GetEdit())
	{										/* Tell the edit field to update
												itself as well */
		GetEdit()->UpdatePreferences();
	}

	if (m_pBanner && (sOldEditLines != GetEditLines()))
	{
		SizeEditField();
	}
}


#if !defined( CH_PUEBLO_PLUGIN )
bool ChTextInput::CheckEditMenuItem( EditMenuItem item )
{
	bool	boolEnable;

	switch( item )
	{
		case editMenuCut:
		case editMenuCopy:
		{
			int		iStart;
			int		iEnd;

			GetEdit()->GetSel( iStart, iEnd );
			boolEnable = (iStart != iEnd);
			break;
		}

		case editMenuPaste:
		{
			if (GetEdit()->OpenClipboard())
			{
				boolEnable = (0 != ::GetClipboardData( CF_TEXT ));
				::CloseClipboard();
			}
			break;
		}

		default:
		{
			boolEnable = false;
			break;
		}
	}

	return boolEnable;
}


void ChTextInput::DoEditMenuItem( EditMenuItem item )
{
	switch( item )
	{
		case editMenuCut:
		{
			GetEdit()->Cut();
			break;
		}

		case editMenuCopy:
		{
			GetEdit()->Copy();
			break;
		}

		case editMenuPaste:
		{
			GetEdit()->Paste();
			break;
		}

		default:
		{
			break;
		}
	}
}

#endif // #if !defined( CH_PUEBLO_PLUGIN )


void ChTextInput::CheckForPasswordProtection()
{
	ChWorldInfo*	pWorldInfo = GetMainInfo()->GetWorldInfo();

	if (pWorldInfo && (unamePwLogin != pWorldInfo->GetLoginType()) &&
			!m_boolLoginRecognized)
	{
		ChTextInputEdit*	pEdit = GetEdit();

		if (pEdit)
		{
			EchoState	echo = GetMainInfo()->GetEchoState();
			string		strText;

			pEdit->GetWindowText( strText );

			if (echoAutoOff == echo)
			{
				if (!MatchMushLogin( strText ))
				{
					GetMainInfo()->SetEchoState( echoOn, true );
				}
			}
			else
			{
				if (echoOn == echo)
				{
					if (MatchMushLogin( strText ))
					{
						GetMainInfo()->SetEchoState( echoAutoOff, true );
					}
				}
			}
		}
	}
}


/*----------------------------------------------------------------------------
	ChTextInput protected methods
----------------------------------------------------------------------------*/

void ChTextInput::CreateEditField()
{
	ChSplitter*	pSplitter =  GetMainInfo()->GetCore()->GetSplitter();
	chint16		sClientHeight = 30;
	CSize		editSize;
											/* Get the edit size for the number
												of lines desired */

	ChTextInputEdit::GetSize( GetEditLines(), editSize );

											/* Create the banner and the edit
												fields */
	m_pEdit = new ChTextInputEdit( false );
	m_pPasswordEdit = new ChTextInputEdit( true );

	m_pBanner = pSplitter->CreateBanner( 0, INPUT_BANNER_TITLE, false, true,
											(chint16)editSize.cx,
											(chint16)editSize.cy );

	m_pEdit->Create( m_pBanner, GetMainInfo() );
	m_pPasswordEdit->Create( m_pBanner, GetMainInfo() );

											// Set the banner information
	m_pBanner->SetChild( m_pEdit );
}


void ChTextInput::SizeEditField()
{
	ChSize	editSize;
											// Size the banner pane

	ChTextInputEdit::GetSize( GetEditLines(), editSize );
	m_pBanner->SetChildSize( (chint16)editSize.cx, (chint16)editSize.cy );
}


bool ChTextInput::MatchMushLogin( const string& strText )
{
	const char*		pstrText = strText;
	bool			boolMatch = false;
											/* This function will return
												true if the specified text
												matches the form:
													'c[o|r]* * ?' */
	if (*pstrText == 'c' || *pstrText == 'C')
	{										// Found 'c'
		pstrText++;

		if ((*pstrText == 'o') || (*pstrText == 'O'))
		{
											// Found 'co'
			pstrText++;

			boolMatch = true;
		}
		else if ((*pstrText == 'r') || (*pstrText == 'R'))
		{
											// Found 'cr'
			pstrText++;

			boolMatch = true;
		}

		if (boolMatch)
		{
			boolMatch = false;

			while (*pstrText && !isspace( *pstrText ))
			{
											/* Eat everything after 'c?'
												up to a space */
				pstrText++;
			}

			if (isspace( *pstrText ))
			{								// Found 'c* '
				while (isspace( *pstrText ))
				{
					pstrText++;
				}

				while (*pstrText && !isspace( *pstrText ))
				{
					pstrText++;
				}

				if (*pstrText)
				{							// Found 'c* *'

					while (isspace( *pstrText ))
					{
						pstrText++;
					}

					if (*pstrText)
					{						// Found 'c* * ?'
						boolMatch = true;
					}
				}
			}
		}
	}

	return boolMatch;
}


/*----------------------------------------------------------------------------
	ChTextInputEdit constants
----------------------------------------------------------------------------*/

#define NUM_EDIT_CHARS_PER_LINE		80

#define INPUT_EDIT_STYLE			(WS_CHILD | WS_BORDER | WS_VISIBLE | \
										ES_AUTOVSCROLL | ES_MULTILINE)

#define INPUT_EDIT_PW_STYLE			(WS_CHILD | WS_BORDER | ES_AUTOVSCROLL | \
										ES_PASSWORD)


/*----------------------------------------------------------------------------
	ChTextInputEdit class
----------------------------------------------------------------------------*/

ChTextInputEdit::ChTextInputEdit( bool boolPassword ) :
					m_boolPassword( boolPassword ),
					m_h3dLib( 0 ),
					m_pprocSubclassCtl3d( 0 ),
					m_boolBrowsingHistory( false ),
					m_tabCompletionMode( tabModeReset ),
					m_posTabCompletion( 0 )
{
	const ChClientInfo*	pClientInfo = ChCore::GetClientInfo();
	OSType				osType = pClientInfo->GetPlatform();

	m_boolWindows95 = (osWin95 == osType);

	if (!m_boolWindows95 && (m_h3dLib = LoadLibrary( "Ctl3d32.dll" )))
	{
		m_pprocSubclassCtl3d =
			(SubclassCtl3dProc)GetProcAddress( m_h3dLib, "Ctl3dSubclassCtl" );
	}
											// Init registry values
	UpdatePreferences();
}


ChTextInputEdit::~ChTextInputEdit()
{
	if (m_h3dLib)
	{
		FreeLibrary( m_h3dLib );
		m_h3dLib = 0;
		m_pprocSubclassCtl3d = 0;
	}
}


bool ChTextInputEdit::Create( ChWnd* pParent, ChWorldMainInfo* pMainInfo )
{
	CRect		rtEdit( 0, 0, 100, 100 );
	chflag32	flStyle;
											// Cache the pMainInfo
	m_pMainInfo = pMainInfo;
											// Create the window

	flStyle = IsPassword() ? INPUT_EDIT_PW_STYLE : INPUT_EDIT_STYLE;

	return CEdit::CreateEx( WS_EX_CLIENTEDGE, "edit", "_Text_In_Module_Edit_",
							flStyle, rtEdit.left, rtEdit.top,
							rtEdit.Width(), rtEdit.Height(),
							pParent->GetSafeHwnd(),
							(HMENU)TEXT_INPUT_EDIT_ID );
}


void ChTextInputEdit::GetSize( int iLines, CSize& size )
{
	CWindowDC	dc( CWnd::GetDesktopWindow() );
	TEXTMETRIC	tm;

	dc.GetTextMetrics( &tm );

	size.cy = (chint16)(tm.tmHeight + tm.tmExternalLeading) * iLines;
	size.cx = (chint16)(tm.tmAveCharWidth * NUM_EDIT_CHARS_PER_LINE);

	size.cx += (3 * GetSystemMetrics( SM_CXFRAME ));
	size.cy += (3 * GetSystemMetrics( SM_CYFRAME ));

	if (INPUT_EDIT_STYLE & WS_VSCROLL)
	{
		size.cx += GetSystemMetrics( SM_CXVSCROLL );
	}

	if (INPUT_EDIT_STYLE & WS_HSCROLL)
	{
		size.cy += GetSystemMetrics( SM_CYHSCROLL );
	}
}


bool ChTextInputEdit::OnChildNotify( UINT message, WPARAM wParam,
										LPARAM lParam, LRESULT* pResult )
{
	if ((WM_COMMAND == message) && (EN_UPDATE == HIWORD( wParam )))
	{
		ChTextInput*	pTextInput = GetMainInfo()->GetTextInput();

		if (pTextInput)
		{
			pTextInput->CheckForPasswordProtection();
		}
	}

	return CEdit::OnChildNotify( message, wParam, lParam, pResult );
}


void ChTextInputEdit::EraseText()
{
	SetWindowText( "" );
}


void ChTextInputEdit::UpdatePreferences()
{
	ChRegistry	reg( WORLD_PREFS_GROUP );
	string		strKeyMap;

	reg.Read( WORLD_PREFS_KEYMAP, strKeyMap, WORLD_PREFS_KEYMAP_DEF );
	m_keyMapType.Set( strKeyMap );
	m_keyMapType.CreateMap( m_keyMap );

	reg.ReadBool( WORLD_PREFS_CLEAR, m_boolClearOnSend,
					WORLD_PREFS_CLEAR_DEF );
}


BEGIN_MESSAGE_MAP( ChTextInputEdit, CEdit )
	//{{AFX_MSG_MAP(ChTextInputEdit)
	ON_WM_KILLFOCUS()
	ON_WM_SETFOCUS()
	ON_WM_RBUTTONDOWN()
	ON_WM_CREATE()
	ON_WM_SHOWWINDOW()
	//}}AFX_MSG_MAP
#if defined( CH_PUEBLO_PLUGIN )
	ON_WM_KEYUP()
#endif
	ON_MESSAGE( WM_CHACO_GRABFOCUS, OnGrabFocus )
END_MESSAGE_MAP()


/*----------------------------------------------------------------------------
	ChTextInputEdit protected methods
----------------------------------------------------------------------------*/

void ChTextInputEdit::OnSendKey()
{
	string				strText;
	ChWorldMainInfo*	pMainInfo = GetMainInfo();

	GetWindowText( strText );
	pMainInfo->GetTinTin()->ParseInput( strText );

											/* Scroll to the end of the
												output buffer */

	GetMainInfo()->GetTextOutput()->GetOutputWnd()->End();

	if (pMainInfo->GetEchoState() == echoAutoOff)
	{
		pMainInfo->GetTextInput()->SetLoginRecognized();
	}
											/* Don't add blank lines or passwords
												to the history */

	if (!IsPassword() && (strText.GetLength() > 0))
	{
		m_history.Add( strText );			// Add to the history
	}

	if (m_boolClearOnSend || IsPassword())
	{
		EraseText();
	}
	else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -