📄 chtxtin.cpp
字号:
/*----------------------------------------------------------------------------
_ _ _
/\ | | | (_)
/ \ _ __ __| |_ __ ___ _ __ ___ ___ __| |_ __ _
/ /\ \ | '_ \ / _` | '__/ _ \| '_ ` _ \ / _ \/ _` | |/ _` |
/ ____ \| | | | (_| | | | (_) | | | | | | __/ (_| | | (_| |
/_/ \_\_| |_|\__,_|_| \___/|_| |_| |_|\___|\__,_|_|\__,_|
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/ChText/ChTxtIn.cpp,v 2.36 1996/02/17 01:46:42 coyote Exp $
#include "headers.h"
#include <ChCore.h>
#include <ChSplit.h>
#include <ChUtil.h>
#include <ChWorld.h>
#include "ChTxtIn.h"
#include "ChPrefs.h"
#include "ChKeyMapType.h"
#include "resource.h"
#if defined( CH_MSW )
#include <ctl3d.h>
#endif // defined( CH_MSW )
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/*----------------------------------------------------------------------------
Handler declarations
----------------------------------------------------------------------------*/
CH_DECLARE_MESSAGE_HANDLER( textInInitHandler )
CH_DECLARE_MESSAGE_HANDLER( textInShowModuleHandler )
CH_DECLARE_MESSAGE_HANDLER( textInGetPageCountHandler )
CH_DECLARE_MESSAGE_HANDLER( TextInGetPagesHandler )
CH_DECLARE_MESSAGE_HANDLER( TextInGetPageDataHandler )
CH_DECLARE_MESSAGE_HANDLER( TextInReleasePagesHandler )
CH_DECLARE_MESSAGE_HANDLER( textInSetFocusHandler )
CH_DECLARE_MESSAGE_HANDLER( textInTextHandler )
CH_DECLARE_MESSAGE_HANDLER( textInClearTextHandler )
CH_DECLARE_MESSAGE_HANDLER( textInInstallHookHandler )
CH_DECLARE_MESSAGE_HANDLER( textInPromoteHookHandler )
CH_DECLARE_MESSAGE_HANDLER( textInUninstallHookHandler )
CH_DECLARE_MESSAGE_HANDLER( textInSetPasswordHandler )
static ChMsgHandlerDesc textInHandlers[] =
{ {CH_MSG_INIT, textInInitHandler},
{CH_MSG_SHOW_MODULE, textInShowModuleHandler},
{CH_MSG_GET_PAGE_COUNT, textInGetPageCountHandler},
{CH_MSG_GET_PAGES, TextInGetPagesHandler},
{CH_MSG_GET_PAGE_DATA, TextInGetPageDataHandler},
{CH_MSG_RELEASE_PAGES, TextInReleasePagesHandler},
{CH_MSG_SET_FOCUS, textInSetFocusHandler},
{CH_MSG_TEXT, textInTextHandler},
{CH_MSG_CLEAR_TEXT, textInClearTextHandler},
{CH_MSG_INSTALL_HOOK, textInInstallHookHandler},
{CH_MSG_PROMOTE_HOOK, textInPromoteHookHandler},
{CH_MSG_UNINSTALL_HOOK, textInUninstallHookHandler},
{CH_TXT_MSG_SET_PASSWORD, textInSetPasswordHandler} };
/*----------------------------------------------------------------------------
Chaco menu handlers
----------------------------------------------------------------------------*/
CH_DECLARE_MESSAGE_HANDLER( stdEditMenuHandler )
CH_DECLARE_MESSAGE_HANDLER( OnStdEditCopy )
CH_DECLARE_MESSAGE_HANDLER( OnStdEditCut )
CH_DECLARE_MESSAGE_HANDLER( OnStdEditPaste )
CH_DECLARE_MESSAGE_HANDLER( OnStdEditClear )
CH_DECLARE_MESSAGE_HANDLER( stdWindowMenuHandler )
CH_DECLARE_MESSAGE_HANDLER( OnStdWindowCommand )
/*----------------------------------------------------------------------------
ChTextInTinTin class
----------------------------------------------------------------------------*/
ChTextInTinTin::ChTextInTinTin( ChTextInMainInfo* pMainInfo ) :
m_pMainInfo( pMainInfo )
{
}
void ChTextInTinTin::SendToWorld( const string& strOutput )
{
if (IsOnline())
{ /* This function doesn't apply
any tintin processing to the
string that it is sending */
GetMainInfo()->Send( strOutput );
}
}
void ChTextInTinTin::Display( const string& strOutput )
{
if (IsOnline())
{ /* This function doesn't apply
any tintin processing to the
string that it is sending */
GetMainInfo()->Display( strOutput );
}
}
/*----------------------------------------------------------------------------
ChTextInMainInfo class
----------------------------------------------------------------------------*/
ChTextInMainInfo::ChTextInMainInfo( const ChModuleID& idModule,
const ChModuleID& idServerModule ) :
ChMainInfo( idModule ),
m_idServerModule( idServerModule ),
m_textInDispatcher( idModule, defTextInHandler ),
m_pBanner( 0 ),
m_pEdit( 0 ),
m_stdEditMenu( stdEditMenuHandler ),
m_stdWindowMenu( stdWindowMenuHandler ),
m_boolShown( false ),
m_boolMenus( false ),
m_boolMenusInstalled( false ),
m_sEditLines( 2 ),
m_pTinTinProcessor( 0 )
{
// Init registry values
UpdatePreferences();
/* Create the tintin processor
object */
m_pTinTinProcessor = new ChTextInTinTin( this );
ASSERT( m_pTinTinProcessor );
}
ChTextInMainInfo::~ChTextInMainInfo()
{
if (IsShown())
{
ShowModule( false );
}
if (m_pTinTinProcessor)
{ /* Delete the tintin processor
object */
delete m_pTinTinProcessor;
m_pTinTinProcessor = 0;
}
if (m_pBanner)
{
ChSplitter* pSplitter = ChSplitter::GetSplitter();
/* Disassociate and destroy the
edit field */
m_pBanner->SetChild( 0 );
if (m_pEdit)
{
delete m_pEdit;
m_pEdit = 0;
}
// Destroy the banner
pSplitter->DestroyBanner( INPUT_BANNER_TITLE );
m_pBanner = 0;
}
DestroyMenus();
}
void ChTextInMainInfo::RegisterDispatchers()
{
chint16 sHandlerCount = sizeof( textInHandlers ) /
sizeof( ChMsgHandlerDesc );
m_textInDispatcher.AddHandler( textInHandlers, sHandlerCount );
}
void ChTextInMainInfo::ShowModule( bool boolShow )
{
if (boolShow && !IsShown())
{ // Show the banner
if (m_pBanner)
{
m_pBanner->ShowWindow( SW_SHOW );
}
m_pTinTinProcessor->Reset();
if (!m_strTinTinFile.IsEmpty())
{
m_pTinTinProcessor->ReadInitFile( "{" + m_strTinTinFile + "}" );
}
InstallMenus();
m_boolShown = true;
}
else if (!boolShow && IsShown())
{ // Hide the banner
if (m_pBanner)
{
m_pBanner->ShowWindow( SW_HIDE );
}
UninstallMenus();
m_boolShown = false;
}
}
void ChTextInMainInfo::Send( const string& strText )
{
/* This function doesn't apply
any tintin processing to the
string that it is sending */
ChHookManager* pHookMgr = GetHookMgr();
bool boolProcessed;
ChTextMsg msg( strText, TEXT_SEND_TO_WORLD );
pHookMgr->Dispatch( msg, boolProcessed );
if (!boolProcessed)
{ // If not processed, ignore it...
}
}
void ChTextInMainInfo::Display( const string& strText )
{
/* This function doesn't apply
any tintin processing to the
string that it is sending */
ChHookManager* pHookMgr = GetHookMgr();
bool boolProcessed;
ChTextMsg msg( strText, TEXT_DISPLAY_ONLY );
pHookMgr->Dispatch( msg, boolProcessed );
if (!boolProcessed)
{ // If not processed, ignore it...
}
}
void ChTextInMainInfo::UpdatePreferences()
{
ChRegistry reg( TEXT_IN_PREFS_GROUP );
chint16 sOldEditLines = GetEditLines();
// Read in the number of edit lines
reg.Read( TEXT_IN_EDIT_LINES, m_sEditLines, TEXT_IN_EDIT_LINES_DEF );
if (GetEdit())
{ /* Tell the edit field to update
itself as well */
GetEdit()->UpdatePreferences();
}
if (m_pBanner && (sOldEditLines != GetEditLines()))
{
ChSize editSize;
// Size the banner pane
ChTextInputEdit::GetSize( GetEditLines(), editSize );
m_pBanner->SetChildSize( (chint16)editSize.cx, (chint16)editSize.cy );
}
reg.Read( TEXT_IN_TINTIN_FILE, m_strTinTinFile, TEXT_IN_TINTIN_FILE_DEF );
}
/*----------------------------------------------------------------------------
ChTextInMainInfo protected methods
----------------------------------------------------------------------------*/
void ChTextInMainInfo::Initialize()
{
ChSplitter* pSplitter = ChSplitter::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
field */
m_pEdit = new ChTextInputEdit( GetServerModule() );
m_pBanner = pSplitter->CreateBanner( 0, INPUT_BANNER_TITLE, false, true,
(chint16)editSize.cx,
(chint16)editSize.cy );
m_pEdit->Create( m_pBanner, this );
// Set the banner information
m_pBanner->SetChild( m_pEdit );
// Create menus for this module
CreateMenus();
}
/*----------------------------------------------------------------------------
ChTextInMainInfo private methods
----------------------------------------------------------------------------*/
void ChTextInMainInfo::CreateMenus()
{
ChMenuItem* pItem;
string strText;
/* Add our menu hooks to the
standard Edit menu */
m_stdEditMenu.GetCutItem()->
SetHandler( OnStdEditCut )->SetData( (chparam)this );
m_stdEditMenu.GetCopyItem()->
SetHandler( OnStdEditCopy )->SetData( (chparam)this );
m_stdEditMenu.GetPasteItem()->
SetHandler( OnStdEditPaste )->SetData( (chparam)this );
/* Add our item to the standard
Window menu */
ChUtil::Load( (chparam)hTextDLL, IDS_WND_MENU_INPUT, strText );
pItem = m_stdWindowMenu.InsertItem( strText, OnStdWindowCommand );
ChUtil::Load( (chparam)hTextDLL, IDS_WND_MENU_INPUT_TXT,
strText );
pItem->SetHelpText( strText );
ChUtil::Load( (chparam)hTextDLL, IDS_WND_MENU_INPUT_ACC,
strText );
pItem->SetAccelerator( strText[0], CH_ACC_CONTROL | CH_ACC_VIRTKEY );
pItem->SetData( (chparam)this );
m_boolMenus = true;
}
void ChTextInMainInfo::InstallMenus()
{
m_stdEditMenu.Install( CH_MODULE_TEXT_INPUT );
m_stdWindowMenu.Install( CH_MODULE_TEXT_INPUT );
m_boolMenusInstalled = true;
}
void ChTextInMainInfo::UninstallMenus()
{
m_stdEditMenu.Uninstall();
m_stdWindowMenu.Uninstall();
m_boolMenusInstalled = false;
}
void ChTextInMainInfo::DestroyMenus()
{
m_boolMenus = false;
m_boolMenusInstalled = false;
}
/*----------------------------------------------------------------------------
ChTextInputBar constants
----------------------------------------------------------------------------*/
#define NUM_EDIT_CHARS_PER_LINE 80
#define INPUT_EDIT_STYLE (WS_CHILD | WS_VISIBLE | WS_BORDER | \
ES_AUTOVSCROLL | ES_MULTILINE | \
ES_LEFT)
/*----------------------------------------------------------------------------
ChTextInputEdit class
----------------------------------------------------------------------------*/
ChTextInputEdit::ChTextInputEdit( const ChModuleID& idServerModule ) :
m_serverCore( idServerModule ),
m_boolPassword( false ),
m_h3dLib( 0 ),
m_pprocSubclassCtl3d( 0 ),
m_boolBrowsingHistory( false ),
m_tabCompletionMode( tabModeReset ),
m_posTabCompletion( 0 )
{
ChCore* pCore = ChCore::GetCore();
const ChClientInfo* pClientInfo = pCore->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, ChTextInMainInfo* pMainInfo )
{
CRect rtEdit( 0, 0, 100, 100 );
// Cache the pMainInfo
m_pMainInfo = pMainInfo;
// Create the window
return CEdit::CreateEx( WS_EX_CLIENTEDGE, "edit", "_Text_In_Module_Edit_",
INPUT_EDIT_STYLE, rtEdit.left, rtEdit.top,
rtEdit.Width(), rtEdit.Height(),
pParent->GetSafeHwnd(), 0 );
}
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 );
}
}
void ChTextInputEdit::Send()
{ /* This function doesn't apply
any tintin processing to the
string that it is sending */
string strText;
GetWindowText( strText );
GetMainInfo()->Send( strText );
}
void ChTextInputEdit::EraseText()
{
SetWindowText( "" );
}
void ChTextInputEdit::UpdatePreferences()
{
ChRegistry reg( TEXT_IN_PREFS_GROUP );
string strKeyMap;
reg.Read( TEXT_IN_PREFS_KEYMAP, strKeyMap, TEXT_IN_PREFS_KEYMAP_DEF );
m_keyMapType.Set( strKeyMap );
m_keyMapType.CreateMap( m_keyMap );
reg.ReadBool( TEXT_IN_PREFS_CLEAR, m_boolClearOnSend,
TEXT_IN_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_CHAR()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/*----------------------------------------------------------------------------
ChTextInputEdit protected methods
----------------------------------------------------------------------------*/
void ChTextInputEdit::OnSendKey()
{
string strText;
GetWindowText( strText );
/* 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
{
SetSel( 0, -1 ); // Select all text
}
/* We're no longer browsing the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -