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

📄 chtextinput.cpp

📁 Windows上的MUD客户端程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	{
		SetSel( 0, -1 );					// Select all text
	}
											/* We're no longer browsing the
												history, if we were before... */
	SetBrowsingHistory( false );

	if (pMainInfo->GetEchoState() == echoAutoOff)
	{
		pMainInfo->SetEchoState( echoOn );
	}
}


void ChTextInputEdit::MoveInHistory( bool boolUp )
{
	string		strLine;

	if (boolUp)
	{
		if (!IsBrowsingHistory())
		{									/* When we start browsing the
												history, we save the current
												text and use it as the 'end'
												text for browsing */
			GetWindowText( m_strEndText );
			SetBrowsingHistory( true );
		}

		if (m_history.GetPrevious( strLine ))
		{
			bool	boolNewText;
			string	strCurrent;

			GetWindowText( strCurrent );
											/* We haven't modified since
												we sent the text -- skip the
												last stored line */
			if (strLine == strCurrent)
			{
				boolNewText = m_history.GetPrevious( strLine );
			}
			else
			{
				boolNewText = true;
			}

			if (boolNewText)
			{
				SetHistoryText( strLine );
			}
		}
	}
	else
	{
		if (m_history.GetNext( strLine ))
		{
			SetHistoryText( strLine );
		}
		else
		{									/* We're at the end of the history
												again... */
			SetHistoryText( m_strEndText );
			SetBrowsingHistory( false );
		}
	}
}


void ChTextInputEdit::SetBrowsingHistory( bool boolBrowsing )
{
	if (m_boolBrowsingHistory != boolBrowsing)
	{
		m_boolBrowsingHistory = boolBrowsing;

		if (!m_boolBrowsingHistory)
		{									// Reset the history to the end
			m_history.Reset();
		}
	}
}


void ChTextInputEdit::DoTabCompletion()
{
	string		strText;

	if (tabModeReset == m_tabCompletionMode)
	{										// Reset the expansion string
		GetWindowText( m_strTabCompletion );
	}

	if ((tabModeReset == m_tabCompletionMode) ||
		(tabModeStart == m_tabCompletionMode))
	{										// Start from the beginning
		m_posTabCompletion = 0;
		m_tabCompletionMode = tabModeHistory;
	}

	strText = m_strTabCompletion;

	switch( m_tabCompletionMode )
	{
		case tabModeHistory:
		{
			if (m_history.GetExpansion( strText, m_posTabCompletion ))
			{
				int		iPos = m_strTabCompletion.GetLength();

				SetWindowText( strText );
				SetSel( iPos, iPos );

				if (0 == m_posTabCompletion)
				{							// We're at the end of the list

					m_tabCompletionMode = tabModeEnd;
				}
			}
			else
			{								// We've hit the end of the list
				MessageBeep( MB_ICONASTERISK );
				m_tabCompletionMode = tabModeStart;
			}
			break;
		}

		case tabModeEnd:
		{
			MessageBeep( MB_ICONASTERISK );
			m_tabCompletionMode = tabModeStart;
			break;
		}

		case tabModeReset:
		default:
		{
			break;
		}
	}
}


void ChTextInputEdit::DoRightButtonMenu( CPoint ptMouse )
{
	CMenu	popupMenu;

	popupMenu.CreatePopupMenu();
	ConstructRightButtonMenu( popupMenu );

	popupMenu.TrackPopupMenu( TPM_LEFTALIGN | TPM_RIGHTBUTTON, ptMouse.x,
								ptMouse.y, this, 0 );
}


void ChTextInputEdit::ConstructRightButtonMenu( CMenu& menu )
{
	int		iHistoryCount = m_history.GetCount();
	string	strText;
											// Add history items
	if (iHistoryCount > 0)
	{
		int		iItem = 0;
		int		iItemsInMenu;

		iItemsInMenu = min( maxMenuHistory, iHistoryCount );

		for (iItem = iHistoryCount - iItemsInMenu; iItem < iHistoryCount; iItem++)
		{
			string		strMenu;

			strMenu = m_history.GetString( iItem );
			TruncateMenuString( strMenu );
			menu.AppendMenu( MF_STRING, popupMenuHistoryBase + iItem,
								strMenu );
		}
	}
}


int ChTextInputEdit::GetEndOfLineIndex( int iLine ) const
{
	int		iChar;

	if (iLine == GetLineCount() - 1)
	{
		iChar = GetWindowTextLength();
	}
	else
	{
		iChar = LineIndex( iLine + 1 ) - 1;
	}

	return iChar;
}


void ChTextInputEdit::SendKeyDown( UINT uiKey, LPARAM lParam,
									bool boolStripCtrl )
{
											/* This function will send a key to
												the edit control, first
												stripping off the control key
												if it is pressed */
	static BYTE	bKeyStateArray[256];

	bool		boolControlWasPressed;
	BYTE		bControlBack;

	if (boolStripCtrl)
	{
		GetKeyboardState( bKeyStateArray );

		bControlBack = bKeyStateArray[VK_CONTROL];

		if (boolControlWasPressed = !!(bControlBack & 0x80))
		{
											// Turn off the control key

			bKeyStateArray[VK_CONTROL] &= ~0x80;
			SetKeyboardState( bKeyStateArray );
		}
	}
											// Send the key
	SendMessage( WM_KEYDOWN, uiKey, lParam );

	if (boolStripCtrl && boolControlWasPressed)
	{										// Restore the control key
		
		bKeyStateArray[VK_CONTROL] = bControlBack;
		SetKeyboardState( bKeyStateArray );
	}
}


bool ChTextInputEdit::ProcessKey( UINT& uiChar, LPARAM lParam )
{
	bool		boolContinue = false;
	bool		boolInTabCompletion = false;
	ChPosition	pos;
	chflag32	flMods = 0;
	bool		boolStripControl;

	if (GetKeyState( VK_CONTROL ) & 0x8000)
	{
		boolStripControl = true;
		flMods |= ACTION_MOD_CONTROL;
	}
	else
	{
		boolStripControl = false;
	}

	pos = m_keyMap.FindItem( uiChar, flMods );
	if (pos)
	{
		ChKeyMapItem*	pItem = m_keyMap.GetItem( pos );

		ASSERT( pItem );

		switch( (KeyAction)pItem->GetUserData() )
		{
			case actSend:
			{
				OnSendKey();
				break;
			}

			case actTranspose:
			{
				int		iStart;
				int		iEnd;
				bool	boolLegal = false;

				GetSel( iStart, iEnd );

				if (iStart == iEnd)
				{
					int		iLen = GetWindowTextLength();

					if ((iEnd > 0) && (iEnd < iLen))
					{
						string		strText;
						string		strNewText;

						GetWindowText( strText );
						strNewText = strText.Left( iEnd - 1 );
						strNewText += strText[iEnd];
						strNewText += strText[iEnd - 1];
						strNewText += strText.Mid( iEnd + 1 );

						SetWindowText( strNewText );
						SetSel( iEnd, iEnd );

						boolLegal = true;
					}
				}

				if (!boolLegal)
				{							/* Transpose doesn't work here...
												beep */
					MessageBeep( MB_OK );
				}
				break;
			}

			case actHistoryPrev:
			{
				MoveInHistory( true );
				break;
			}

			case actHistoryNext:
			{
				MoveInHistory( false );
				break;
			}

			case actCursorLeft:
			{
				SendKeyDown( VK_LEFT, lParam, boolStripControl );
				break;
			}

			case actCursorRight:
			{
				SendKeyDown( VK_RIGHT, lParam, boolStripControl );
				break;
			}

			case actCursorHome:
			{
				SetSel( 0, 0 );
				break;
			}

			case actCursorEnd:
			{
				int		iChar = GetWindowTextLength();

				SetSel( iChar, iChar );
				break;
			}

			case actCursorStartLine:
			{
				SendKeyDown( VK_HOME, lParam, boolStripControl );
				break;
			}

			case actCursorEndLine:
			{
				SendKeyDown( VK_END, lParam, boolStripControl );
				break;
			}

			case actCursorUp:
			{
				if (0 == LineFromChar())
				{
					MoveInHistory( true );
				}
				else
				{
					SendKeyDown( VK_UP, lParam, boolStripControl );
				}
				break;
			}

			case actCursorDown:
			{
				int		iLastLineIndex = GetLineCount() - 1;

				if (iLastLineIndex == LineFromChar())
				{
					MoveInHistory( false );
				}
				else
				{
					SendKeyDown( VK_DOWN, lParam, boolStripControl );
				}
				break;
			}

			case actTabCompletion:
			{
				DoTabCompletion();
				boolInTabCompletion = true;
				break;
			}

			case actDeleteText:
			{
				EraseText();
				break;
			}

			case actDeleteToEndOfBuffer:
			{
				int		iStart;
				int		iEnd;

				GetSel( iStart, iEnd );

				if (iStart == iEnd)
				{							// No selection

					SetSel( iStart, GetWindowTextLength() );
				}
											// Clear the selection
				Clear();
				break;
			}

			case actDeleteNextChar:
			{
				int		iStart;
				int		iEnd;
				int		iLen = GetWindowTextLength();
				bool	boolLegal = true;

				GetSel( iStart, iEnd );

				if (iStart == iEnd)
				{							// No selection
					if (iEnd < iLen)
					{
						iEnd++;
						SetSel( iStart, iEnd );
					}
					else
					{
						MessageBeep( MB_OK );
						boolLegal = false;
					}
				}

				if (boolLegal)
				{							// Clear the selection
					Clear();
				}
				break;
			}

			case actLogPageUp:
			{
				GetMainInfo()->GetTextOutput()->GetOutputWnd()->PageUp();
				break;
			}

			case actLogPageDown:
			{
				GetMainInfo()->GetTextOutput()->GetOutputWnd()->PageDown();
				break;
			}

			case actLogHome:
			{
				GetMainInfo()->GetTextOutput()->GetOutputWnd()->Home();
				break;
			}

			case actLogEnd:
			{
				GetMainInfo()->GetTextOutput()->GetOutputWnd()->End();
				break;
			}

			default:
			{
				boolContinue = true;
				break;
			}
		}
	}
	else
	{
		boolContinue = true;
	}

	if (!boolInTabCompletion)
	{
		m_tabCompletionMode = tabModeReset;
	}

	return boolContinue;
}


/*----------------------------------------------------------------------------
	ChTextInputEdit message handlers
----------------------------------------------------------------------------*/

#if !defined( CH_PUEBLO_PLUGIN )
bool ChTextInputEdit::PreTranslateMessage( MSG* pMsg )
{
	bool boolCancel;

	if (WM_KEYDOWN == pMsg->message)
	{
		if (ProcessKey( pMsg->wParam, pMsg->lParam ))
		{
			boolCancel = CEdit::PreTranslateMessage( pMsg );
		}
		else
		{
			boolCancel = true;
		}
	}
	else if (WM_KEYUP == pMsg->message)
	{
		if (VK_RETURN == pMsg->wParam)
		{
			boolCancel = true;
		}
	}
	else
	{
		boolCancel = CEdit::PreTranslateMessage( pMsg );
	}

	return boolCancel;
}
#endif


int ChTextInputEdit::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CEdit::OnCreate(lpCreateStruct) == -1)
	{
		return -1;
	}

	if (m_pprocSubclassCtl3d)
	{
		m_pprocSubclassCtl3d( GetSafeHwnd() );
	}

	return 0;
}


bool ChTextInputEdit::OnCommand( WPARAM wParam, LPARAM lParam )
{
	bool	boolProcessed = true;
	string	strText;

	if ((wParam >= popupMenuHistoryBase) &&
				(wParam <= popupMenuHistoryBase + maxHistory))
	{
		int		iIndex = wParam - popupMenuHistoryBase;

		strText = m_history.GetString( iIndex );
	}
	else
	{
		boolProcessed = false;
	}

	if (boolProcessed && !strText.IsEmpty())
	{
		SetWindowText( strText );
		OnSendKey();
	}

	return boolProcessed;
}


void ChTextInputEdit::OnKillFocus( CWnd* pNewWnd )
{
	CEdit::OnKillFocus( pNewWnd );

	GetMainInfo()->SetFocusTarget( focusTextInput, false );
}


void ChTextInputEdit::OnSetFocus( CWnd* pOldWnd )
{
	CEdit::OnSetFocus( pOldWnd );

	GetMainInfo()->SetFocusTarget( focusTextInput, true );
}


void ChTextInputEdit::OnRButtonDown( UINT nFlags, CPoint ptMouse )
{
	ClientToScreen( &ptMouse );
	DoRightButtonMenu( ptMouse );
}


void ChTextInputEdit::OnShowWindow( BOOL boolShow, UINT nStatus )
{
	CEdit::OnShowWindow( boolShow, nStatus );

	if (boolShow)
	{
		PostMessage( WM_CHACO_GRABFOCUS );
	}
}


LONG ChTextInputEdit::OnGrabFocus( UINT wParam, LONG lParam )
{
	SetFocus();
	return 0;
}


#if defined( CH_PUEBLO_PLUGIN )

LRESULT ChTextInputEdit::WindowProc( UINT message, WPARAM wParam, LPARAM lParam )
{

	if (WM_KEYDOWN == message )
	{
		if (!ProcessKey( wParam, lParam ))
		{
			MSG msg;
			PeekMessage( &msg, GetSafeHwnd(), WM_CHAR, WM_CHAR, PM_REMOVE );
			return 0;
		}
	}
	else if (WM_KEYUP == message )
	{
		if (VK_RETURN == wParam)
		{
			return 0;
		}
	}

	return CEdit::WindowProc(  message,  wParam,  lParam );

}
  

void ChTextInputEdit::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	// TODO: Add your message handler code here and/or call default

	if ( nChar != VK_RETURN )
	{
		if ( GetKeyState( VK_CONTROL ) & 0x8000  )
		{
			if ( nChar == TEXT( 'C' ) )
			{
				Copy();
			}
			else if ( nChar == TEXT( 'V' ) )
			{
				Paste();
			}
			else if ( nChar == TEXT( 'X' ) )
			{
				Cut();
			}
			else if ( nChar == TEXT( 'Z' ) || nChar == TEXT( 'A' ))
			{
				Undo();
			}

		}
		CEdit::OnKeyUp(nChar, nRepCnt, nFlags);
	}
}
#endif

/*----------------------------------------------------------------------------
	Utility functions
----------------------------------------------------------------------------*/

CH_GLOBAL_FUNC( void )
TruncateMenuString( string& strText )
{
	if (strText.GetLength() > MAX_MENU_STRING_LEN)
	{
									/* Truncate the string to make a
										happy menu, and add ellipses */

		strText = strText.Left( MAX_MENU_STRING_LEN );
		strText += "...";
	}
}

⌨️ 快捷键说明

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