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

📄 console.cpp

📁 在手机操作系统symbina上使用的一个脚本扩展语言的代码实现,可以参考用于自己的开发
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// CONSOLE.CPP
//
// Copyright (c) 1997-2002 Symbian Ltd. All rights reserved.

#include <bldvariant.hrh>
#include <w32std.h>
#include <e32hal.h>
#if !defined(__SERIES60__)
#include <fontids.h>
#endif
#include <gdi.h>
#include <e32math.h>
#include <eikenv.h>

#include "iomain.h"
#include "console.h"
#include <oplerr.h>
#include "oplr.h"

#if defined(__SERIES60__)||defined(__UIQ__)
#include "oplutil.h"
#endif

COplConsole::COplConsole(RWsSession& aSession)
	:iWindow(aSession),iCurrentPos(1,1)
#if defined(__SERIES60__)||defined(__UIQ__)
	,iIsFontToBeReleased(ETrue) // Assume font is to be released
#endif
	{
	}

COplConsole::~COplConsole()
	{
	// Drop the loaded font.
	if (iLoadedConsoleFontId)
		iDevice->RemoveFile(iLoadedConsoleFontId);
	iWindow.Close();
	delete iGc;
	}

void COplConsole::ConstructL(CWsScreenDevice* aDevice,CWsEventHandler* aEventHandler,RWindowGroup& aParent,TDisplayMode aDisplayMode)
	{
	iEventHandler=aEventHandler;
	iDevice=aDevice;
	iRootWin=&aParent;
#if defined(__SERIES60__)
	// Fix defect 817867 "reset the default window" by making the Series 60 status pane 
	// invisible at startup.
	CEikStatusPane* statusPane=CEikonEnv::Static()->AppUiFactory()->StatusPane();
	if (statusPane)
		statusPane->MakeVisible(EFalse);
#endif
	User::LeaveIfError(iWindow.Construct(aParent,aDisplayMode,1));
	User::LeaveIfError(iDevice->CreateContext(iGc));
	iGc->Activate(iWindow);
	iGc->SetDrawMode(CGraphicsContext::EDrawModePEN);
	iGc->SetPenStyle(CGraphicsContext::ESolidPen);
	iGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
	SetInverseAndUnderline(EFalse,EFalse);
	TAlgStyle style;
	style.SetWidthFactor(1);
	style.SetHeightFactor(1);

#if defined(__SERIES60__)
	User::LeaveIfError(SetStandardFont((CFont*)CEikonEnv::Static()->DenseFont(),style,EFalse,EFalse));
#elif defined(__UIQ__)
	User::LeaveIfError(SetStandardFont((CFont*)CEikonEnv::Static()->LegendFont(),style,EFalse,EFalse));
#else
	// Attempt to load the font by UID. If that fails, install it into FBSERV and try again.
	TInt error=SetFontByUid(TUid::Uid(KScreenFontUidCourierNormal11),style,EFalse,EFalse); //HAS FontByName pair
	if (error)
		{
		_LIT(KConsoleFontFileName,"Eon14.gdr");
		TFindFile fontFile(TheRuntime()->ConEnv()->FsSession());
		// First attempt to look for it in \System\Libs\. We now install it there by default
		// because on Crystal EON14.GDR causes problems with checkboxes used in other
		// applications. It also causes problems for backup/install because it is constantly
		// marked as "In use". If we can't find it there, fall back to \System\Fonts\ which
		// allows us to still run on WINS by default.
		error=fontFile.FindByDir(KConsoleFontFileName,KSystemLibsPath);
		if (error)
			{
			_LIT(KSystemFontsPath,"\\System\\Fonts\\");
			User::LeaveIfError(fontFile.FindByDir(KConsoleFontFileName,KSystemFontsPath));
			}
		// If we get to here, should be OK to Add to FBSERV
		User::LeaveIfError(iDevice->AddFile(fontFile.File(),iLoadedConsoleFontId));
		// Now FBSERV is aware of it, try to load it once more...
		User::LeaveIfError(SetFontByUid(TUid::Uid(KScreenFontUidCourierNormal11),style,EFalse,EFalse));
		}
#endif
	iWindow.Activate();
	}

#if defined(__SERIES60__)||defined(__UIQ__)
TInt COplConsole::SetStyle(TAlgStyle aAlgStyle,TBool aInverse,TBool aUnderline)
	{
	TAlgStyle style=iFontStyle;
	style.SetIsItalic(aAlgStyle.IsItalic());
	if (!(iFontStyle==style))
		{
		const CFont* font;
		TBool standardFont=OplUtil::IsStandardFontUid(iFontUid);
		if (standardFont)
			font=OplUtil::MapFontUidToStandardFontL(iFontUid);
		else
			{
			TInt ret=iDevice->GetFontById((CFont*&)font,iFontUid,aAlgStyle); //NEEDS FontByName
			if (ret!=KErrNone)
				{
				if (ret==KErrNotFound || ret==KErrGeneral)
					ret=KOplErrFontNotLoaded;
				return ret;
				}
			}
		ReleaseCurrentFontIfNecessary();
		iGc->UseFont(font);
		iIsFontToBeReleased=(standardFont)?EFalse:ETrue;
		iFont=(CFont*)font;
		iFontStyle=style;
		// char size unchanged !?!
		}
	SetInverseAndUnderline(aInverse,aUnderline);
	return KErrNone;
	}


void COplConsole::ReleaseCurrentFontIfNecessary()
	{
	if (iFont)
		{
		if (iIsFontToBeReleased!=EFalse)
			{
			iDevice->ReleaseFont(iFont);
			iFont=NULL;
			iIsFontToBeReleased=EFalse;
			}
		}
	}
#else
TInt COplConsole::SetStyle(TAlgStyle aAlgStyle,TBool aInverse,TBool aUnderline)
	{
	TAlgStyle style=iFontStyle;
	style.SetIsItalic(aAlgStyle.IsItalic());
	if (!(iFontStyle==style))
		{
		CFont* font;
		TInt ret=iDevice->GetFontById(font,iFontUid,style);
		if (ret!=KErrNone)
			{
			if (ret==KErrGeneral)
				ret=KOplErrFontNotLoaded;
			return ret;
			}
		if (iFont)
			iDevice->ReleaseFont(iFont);
		iGc->UseFont(font);
		iFont=font;
		iFontStyle=style;
		// char size unchanged !?!
		}
	SetInverseAndUnderline(aInverse,aUnderline);
	return KErrNone;
	}
#endif

void COplConsole::SetInverseAndUnderline(TBool aInverse,TBool aUnderline)
	{
	if ((aInverse&&!(iFlags&EConsoleInverse))||((!aInverse)&&(iFlags&EConsoleInverse)))
		{ // need to set gc to aInverse
		if (aInverse)
			{
			iGc->SetBrushColor(KRgbBlack);
			iGc->SetPenColor(KRgbWhite);
			iFlags|=EConsoleInverse;
			}
		else
			{
			iGc->SetBrushColor(KRgbWhite);
			iGc->SetPenColor(KRgbBlack);
			iFlags&=~EConsoleInverse;
			}
		}
	if ((aUnderline&&!(iFlags&EConsoleUnderline))||((!aUnderline)&&(iFlags&EConsoleUnderline)))
		{ // need to set gc to use underline
		iGc->SetUnderlineStyle((aUnderline)?EUnderlineOn:EUnderlineOff);
		if (aUnderline)
			iFlags|=EConsoleUnderline;
		else
			iFlags&=~EConsoleUnderline;
		}
	}


#ifdef ___NOT_YET____
CFont* COplConsole::GetFontByNameL(TPtrC aFontName,TAlgStyle /*aAlgStyle*/,TBool aInverse,TBool aUnderline)
	{
	TFontSpec fontSpec(aFontName,200);
	CFont* font;
	TInt err=((CWsScreenDevice*)iDevice)->GetNearestFontInTwips(font,fontSpec);
	if (err!=KErrNone)
		{
		if (err==KErrNotFound)
			err=KOplErrFontNotLoaded;
		User::Leave(err);
		}
	return font;	
	}
#endif

#ifdef _NOT_YET_
// FontByName not currently used by OPLT.
TInt COplConsole::SetFontByName(TPtrC aFontName,TAlgStyle /*aAlgStyle*/,TBool aInverse,TBool aUnderline) //IS FontByName pair
	{
	TInt ret=ResizeWindow();
	if (ret!=KErrNone)
		return ret;
	TFontSpec fontSpec(aFontName,200);
	TFontStyle myStyle;
	fontSpec.iFontStyle=myStyle;
	//is it a standard font?
//	TBool standardFont=test if font is standard();
	CFont* font;
	TInt err=((CWsScreenDevice*)iDevice)->GetNearestFontInTwips(font,fontSpec);
	if (err!=KErrNone)
		{
		if (err==KErrNotFound)
			err=KOplErrFontNotLoaded;
		return err;
		}
	ReleaseCurrentFontIfNecessary();
	iGc->UseFont(font); //pukka because unused
	iFont=font;
//	iIsFontToBeReleased=(standardFont)?EFalse:ETrue;
//	iFontUid=aUid;
//	iFontStyle=aAlgStyle;
	TInt charWidth=iFont->MaxNormalCharWidthInPixels();
	if (charWidth==0)
		charWidth=iFont->MaxCharWidthInPixels();
	iCharSizeInPixels=TSize(charWidth,iFont->HeightInPixels());
	ResetScreenSize();
	SetCursorToFont();

	SetInverseAndUnderline(aInverse,aUnderline);
	iCurrentPos=TPoint(1,1);
	DrawCursorIfOn(iCurrentPos);
	return KErrNone;
	}
#endif


#if defined(__SERIES60__)||defined(__UIQ__)
TInt COplConsole::SetFontByUidL(TUid aUid,TAlgStyle aAlgStyle,TBool aInverse,TBool aUnderline) //NEEDS FontByName pair?
	{
	TInt ret=ResizeWindow();
	if (ret!=KErrNone)
		return ret;
	if (iFontUid!=aUid || !(aAlgStyle==iFontStyle))
		{ // need to change font
		const CFont* font;
		TBool standardFont=OplUtil::IsStandardFontUid(iFontUid);
		if (standardFont)
			font=OplUtil::MapFontUidToStandardFontL(iFontUid);
		else
			{
			ret=iDevice->GetFontById((CFont*&)font,aUid,aAlgStyle); //NEEDS FontByName
			if (ret!=KErrNone)
				{
				if (ret==KErrNotFound)
					ret=KOplErrFontNotLoaded;
				return ret;
				}
			}
		ReleaseCurrentFontIfNecessary();
		iGc->UseFont(font); //pukka
		iIsFontToBeReleased=(standardFont)?EFalse:ETrue;
		iFont=(CFont*)font;
		iFontUid=aUid;
		iFontStyle=aAlgStyle;
		TInt charWidth=iFont->MaxNormalCharWidthInPixels();
		if (charWidth==0)
			charWidth=iFont->MaxCharWidthInPixels();
		iCharSizeInPixels=TSize(charWidth,iFont->HeightInPixels());
		ResetScreenSize();
		SetCursorToFont();
		}
	SetInverseAndUnderline(aInverse,aUnderline);
	iCurrentPos=TPoint(1,1);
	DrawCursorIfOn(iCurrentPos);
	return KErrNone;
	}

/*
 * Use one of the CEikonEnv "built-in" fonts:
 */
TInt COplConsole::SetStandardFont(const CFont* aFont,TAlgStyle /*aAlgStyle*/,TBool aInverse,TBool aUnderline) //IS FontByName pair
	{
	TInt ret=ResizeWindow();
	if (ret!=KErrNone)
		return ret;
	ReleaseCurrentFontIfNecessary();
	iGc->UseFont(aFont); //pukka
	iIsFontToBeReleased=EFalse;//This is a standard font.
	iFont=(CFont*)aFont;
//	TInt charWidth=iFont->MaxNormalCharWidthInPixels();
	TInt charWidth=iFont->WidthZeroInPixels();
	if (charWidth==0)
		charWidth=iFont->MaxCharWidthInPixels();
	iCharSizeInPixels=TSize(charWidth,iFont->HeightInPixels());
	ResetScreenSize();
	SetCursorToFont();

	SetInverseAndUnderline(aInverse,aUnderline);
	iCurrentPos=TPoint(1,1);
	DrawCursorIfOn(iCurrentPos);
	return KErrNone;
	}
#else
TInt COplConsole::SetFontByUid(TUid aUid,TAlgStyle aAlgStyle,TBool aInverse,TBool aUnderline) //NEEDS FontByName pair?
	{
	TInt ret=ResizeWindow();
	if (ret!=KErrNone)
		return ret;
	if (iFontUid!=aUid || !(aAlgStyle==iFontStyle))
		{ // need to change font
		CFont* font;
		ret=iDevice->GetFontById(font,aUid,aAlgStyle);
		if (ret!=KErrNone)
			{
			if (ret==KErrNotFound)
				ret=KOplErrFontNotLoaded;
			return ret;
			}
		if (iFont)
			iDevice->ReleaseFont(iFont);
		iGc->UseFont(font);
		iFont=font;
		iFontUid=aUid;
		iFontStyle=aAlgStyle;
		TInt charWidth=iFont->MaxNormalCharWidthInPixels();
		if (charWidth==0)
			charWidth=iFont->MaxCharWidthInPixels();
		iCharSizeInPixels=TSize(charWidth,iFont->HeightInPixels());
		ResetScreenSize();
		SetCursorToFont();
		}
	SetInverseAndUnderline(aInverse,aUnderline);
	iCurrentPos=TPoint(1,1);
	DrawCursorIfOn(iCurrentPos);
	return KErrNone;
	}
#endif

TInt COplConsole::ResizeWindow()
	{
	TMachineInfoV1Buf machInfo;
	UserHal::MachineInfo(machInfo);
	TRect rect(TPoint(0,0),machInfo().iDisplaySizeInPixels);

	TInt ret=iWindow.SetExtentErr(rect.iTl,machInfo().iDisplaySizeInPixels);
	if (ret==KErrNone)
		DoClearRect(rect);
	return ret;
	}

void COplConsole::ResetScreenSize()
	{
	TSize windowSize(iWindow.Size());
	iScreenSizeInChars=windowSize;
	iScreenSizeInChars.iWidth/=iCharSizeInPixels.iWidth;
	iScreenSizeInChars.iHeight/=iCharSizeInPixels.iHeight;
	iTopLeft.iX=(windowSize.iWidth-(iScreenSizeInChars.iWidth*iCharSizeInPixels.iWidth))/2;
	iTopLeft.iY=(windowSize.iHeight-(iScreenSizeInChars.iHeight*iCharSizeInPixels.iHeight))/2;
	SetScreen(iScreenSizeInChars,TPoint(1,1)); // will not fail in this case
	}

TInt COplConsole::SetScreen(TSize aSizeInChars,TPoint aPosInChars)
	{
	if (aPosInChars==TPoint(0,0))
		{
		TSize size=(iScreenSizeInChars-aSizeInChars);
		aPosInChars.iX=size.iWidth/2+1;
		aPosInChars.iY=size.iHeight/2+1;
		}
	TRect rect=TRect(aPosInChars,aSizeInChars);
	if (aPosInChars.iX<1 || aPosInChars.iY<1 || aSizeInChars.iWidth<1 || aSizeInChars.iHeight<1 ||
		iScreenSizeInChars.iWidth<rect.iBr.iX-1 ||
		iScreenSizeInChars.iHeight<rect.iBr.iY-1)
		return KErrArgument;
	iScreenRectInChars=rect;
	iGc->SetClippingRect(CharsToPixels(TRect(TPoint(1,1),aSizeInChars))); // only allow drawing to screen area
	return KErrNone;
	}

TRect COplConsole::CharsToPixels(const TRect& aCharRect)
	{
	TInt charWidth=iCharSizeInPixels.iWidth;
	TInt charHeight=iCharSizeInPixels.iHeight;
	TPoint topLeft(iTopLeft.iX+(iScreenRectInChars.iTl.iX-1)*charWidth,iTopLeft.iY+(iScreenRectInChars.iTl.iY-1)*charHeight);
	TPoint tl((topLeft.iX+(aCharRect.iTl.iX-1)*charWidth),(topLeft.iY+(aCharRect.iTl.iY-1)*charHeight));
	TPoint br((topLeft.iX+(aCharRect.iBr.iX-1)*charWidth),(topLeft.iY+(aCharRect.iBr.iY-1)*charHeight));
	return TRect(tl,br);
	}

void COplConsole::ScreenInfo(SScreenInfo& aScreenInfo)
	{
	aScreenInfo.iLeftInPixels=(TUint16)iTopLeft.iX;
	aScreenInfo.iTopInPixels=(TUint16)iTopLeft.iY;
	TSize size=iScreenRectInChars.Size();
	aScreenInfo.iTextWidth=(TUint16)size.iWidth;
	aScreenInfo.iTextHeight=(TUint16)size.iHeight;
	aScreenInfo.iWindowId=1;
	aScreenInfo.iNotUsed=0;
	aScreenInfo.iCharWidth=(TUint16)iCharSizeInPixels.iWidth;
	aScreenInfo.iCharHeight=(TUint16)iCharSizeInPixels.iHeight;
	aScreenInfo.iFontUid=iFontUid.iUid;
	}

void COplConsole::DoClearRect(const TRect& aRectInPixels)
	{
	if (iFlags&EConsoleInverse)
		iGc->SetBrushColor(KRgbWhite);
	iGc->Clear(aRectInPixels);
	if (iFlags&EConsoleInverse)
		iGc->SetBrushColor(KRgbBlack);
	}

void COplConsole::Cls()
	{
	DoClearRect(CharsToPixels(TRect(TPoint(1,1),iScreenRectInChars.Size())));
	iCurrentPos=TPoint(1,1);
	DrawCursorIfOn(iCurrentPos);
	}

void COplConsole::ClearRect(const TRect& aRectInChars)
	{
	DoClearRect(CharsToPixels(aRectInChars));
	}

TPoint COplConsole::CurrentPos() const
	{
	return iCurrentPos;
	}

TInt COplConsole::At(const TPoint& aPos)
	{
	if (aPos.iX<1 || aPos.iX>iScreenRectInChars.Size().iWidth || aPos.iY<1 || aPos.iY>iScreenRectInChars.Size().iHeight)
		return KErrArgument;
	iCurrentPos=aPos;
	DrawCursorIfOn(iCurrentPos);
	return KErrNone;
	}

void COplConsole::BackSpace()
	{
	if (iCurrentPos.iX>1)
		iCurrentPos.iX--;
	}

void COplConsole::Cr()
	{
	iCurrentPos.iX=1;
	}

void COplConsole::Lf()
	{
	ScrollIfNeeded();
	iCurrentPos.iY++;
	}

void COplConsole::Tab()
	{
	ScrollIfNeeded();
	iCurrentPos.iX=((iCurrentPos.iX+(KTabStop-1))&~(KTabStop-1))+1;
	WrapIfNeeded();
	}

void COplConsole::ScrollIfNeeded()
	{

⌨️ 快捷键说明

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