×
Namespaces

Variants
Actions

在文本(CEikRichTextEditor)中插入带背景的图片

From Nokia Developer Wiki
Jump to: navigation, search
Article Metadata

兼容于
平台:
Symbian

文章
User:Davey 2 在 13 Dec 2007 创建
最后由 hamishwillee 在 08 May 2013 编辑

适用版本:

Series 60 2nd , Series 60 3rd

更多关于在文本中插入图片参见这里: 使用CPicture在文本(RichTextEditor)中插入图像

一般情况下,在CEikRichTextEditor中插入的图片都是绘制在白色的背景上的,包括Forum Nokia提供的示例也是如此,如果在带有背景的Editor中使用会很别扭,下面将演示如何在文本中插入带背景的图片。


方案思路:

首先CRTxPicture是一个继承自CPicture的图片类,在该类的Draw()函数中首先绘制背景,然后在其之上绘制实际的图片。

 void CRTxPicture::Draw(CGraphicsContext& aGc, const TPoint& aTopLeft,   const TRect& aClipRect, MGraphicsDeviceMap* aMap) const
{
CBitmapContext& gc = static_cast<CBitmapContext &>(aGc);
TRect bmpPieceRect(TPoint(0,0),iBitmap->SizeInPixels());
 
// here is the skin background drawn
iControl.RTxDrawBackground(aTopLeft, bmpPieceRect, gc);
 
// then the picture itself
gc.BitBltMasked(aTopLeft, iBitmap, bmpPieceRect, iBitmapMask, ETrue);
}

背景实际是在容器(Container)中绘制的,因此Container必须继承自MRTxBackgroundDrawer类,而且必须实现其中的RTxDrawBackground ()函数。

 class MRTxBackgroundDrawer
{
public:
virtual void RTxDrawBackground(const TPoint& aDstPos, const TRect& aRect, CBitmapContext& gc) = 0;
};
class CMyAppContainer : public CCoeControl, public MRTxBackgroundDrawer
void CMyAppContainer::RTxDrawBackground(const TPoint& aDstPos, const TRect& aRect, CBitmapContext& gc)
{
#ifdef USE_SKIN
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
MAknsControlContext* cc = AknsDrawUtils::ControlContext(this);
AknsDrawUtils::DrawBackground(skin, cc, this, gc, TPoint(0, 0), aRect, KAknsDrawParamDefault);
#else
gc.SetPenStyle(CGraphicsContext::ENullPen);
gc.SetBrushColor(KRgbBlue);
gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
gc.DrawRect(aRect);
#endif
}
 
然后我们就可以通过以下 InsertPictureL()函数进行插入图片了。
 
void CRTx::InsertPictureL(MRTxBackgroundDrawer& aControl, TInt aPos, CFbsBitmap& aBitmap, CFbsBitmap& aBitmapMask)
{
CRTxPicture* picture;
 
picture = new(ELeave) CRTxPicture(iTextBox->GetSystemGc(), aControl, aBitmap, aBitmapMask);
 
CleanupStack::PushL(picture);
TPictureHeader header;
header.iPicture = TSwizzle<CPicture>(picture);
 
iTextBox->RichText()->InsertL(aPos, header);
 
CleanupStack::Pop();
}

在绘制背景时(RTxDrawBackground函数)使用了USE_SKIN来判断应用程序中的Editor是否使用了背景,因此如果使用了背景,需要在.mmp文件中加入以下语句:

 MACRO USE_SKIN

完整的示例代码如下:

 ///////////////////////////////
// MyAppContainer.cpp (parts)
///////////////////////////////
 
#include <eikclbd.h>
#include <akniconarray.h>
#include <gulicon.h>
#include <AknIconUtils.h>
#include "RTx.h"
#include <MyAppmif.mbg>
#include "MyAppDocument.h"
#include "MyAppViewDevices.h"
#include "MyAppContainer.h"
 
#ifdef USE_SKIN
#include <AknsDrawUtils.h>
#include <AknsBasicBackgroundControlContext.h>
#endif
 
#define LKMyAppMIF L"\\resource\\apps\\myapp.mif"
 
CMyAppContainer::CMyAppContainer(CMyAppViewDevices* aView) : iView(aView)
{
}
 
CMyAppContainer::~CMyAppContainer()
{
delete iRTx;
delete iTextBox;
for(int i = 0; i < iBitmap->Count(); i++)
delete iBitmap->At(i);
delete iBitmap;
for(int i = 0; i < iBitmapMask->Count(); i++)
delete iBitmapMask->At(i);
delete iBitmapMask;
#ifdef USE_SKIN
delete iBackGround;
#endif
}
 
void CMyAppContainer::LoadBitmapListL()
{
_LIT(KMyAppMif, KMyAppMIF);
PrepareBitmapL(KMyAppMif, EMbmMyAppmifImage, EMbmMyAppmifImage_mask); // the image (bitmap or svg)
}
 
void CMyAppContainer::AddSomeTextAndImageL()
{
_LIT(KText1, "Hello World!");
 
iRTx->AddTextL(KText1);
iRTx->AddCarriageReturnL();
iRTx->AddPictureL(*this, *(iBitmap->At(0)), *(iBitmapMask->At(0)));
}
 
void CMyAppContainer::ConstructL(const TRect& aRect)
{
CreateWindowL();
 
iBitmap = new (ELeave) CArrayFixFlat<CFbsBitmap *>(1);
iBitmapMask = new (ELeave) CArrayFixFlat<CFbsBitmap *>(1);
 
LoadBitmapListL();
 
iTextBox = new (ELeave) CRTxEditor(TGulBorder::ENone);
iTextBox->SetMopParent(this);
iRTx = new (ELeave) CRTx(iTextBox);
 
TInt edwinFlags = EEikEdwinInclusiveSizeFixed|EEikEdwinNoAutoSelection|EEikEdwinDisplayOnly|EEikEdwinReadOnly|
EEikEdwinLineCursor|EEikEdwinNoHorizScrolling|EEikEdwinAvkonDisableCursor;
 
iTextBox->ConstructL(this, 0, 0, edwinFlags,EGulFontControlAll, EGulAllFonts);
iTextBox->SetAknEditorFlags(edwinFlags);
 
iTextBox->SetContainerWindowL(*this);
iTextBox->SetFocus(ETrue);
 
AddSomeTextAndImageL();
 
SetRect(aRect);
#ifdef USE_SKIN
iBackGround = CAknsBasicBackgroundControlContext::NewL( KAknsIIDQsnBgAreaMain, Rect(), EFalse );
#endif
ActivateL();
}
 
void CMyAppContainer::SizeChanged()
{
TRect r = Rect();
if (iTextBox)
{
TSize scr = CEikonEnv::Static()->ScreenDevice()->SizeInPixels();
iTextBox->SetExtent(TPoint(0, 0), TSize(r.Width(), r.Height()));
}
}
 
void CMyAppContainer::HandleResourceChange(TInt aType)
{
CCoeControl::HandleResourceChange(aType);
if (aType == KEikDynamicLayoutVariantSwitch)
{
SetRect(iView->ClientRect());
}
}
 
void CMyAppContainer::Draw(const TRect& aRect) const
{
CWindowGc& gc = SystemGc();
#ifdef USE_SKIN
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
MAknsControlContext* cc = AknsDrawUtils::ControlContext(this);
AknsDrawUtils::Background(skin, cc, this, gc, aRect);
#else
gc.SetPenStyle(CGraphicsContext::ENullPen);
gc.SetBrushColor(KRgbBlue);
gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
gc.DrawRect(aRect);
#endif
}
 
TInt CMyAppContainer::CountComponentControls() const
{
return 1;
}
 
CCoeControl* CMyAppContainer::ComponentControl(TInt aIndex) const
{
switch (aIndex)
{
case 0:
return iTextBox;
default:
return NULL;
}
}
 
TKeyResponse CMyAppContainer::OfferKeyEventL(const TKeyEvent& keyEvent, TEventCode type)
{
if (type != EEventKey )
return EKeyWasNotConsumed;
 
switch (keyEvent.iCode)
{
case EKeyLeftArrow:
case EKeyRightArrow:
return EKeyWasNotConsumed;
}
return iRTx->OfferKeyEventL(keyEvent, type);
}
 
// from MRTxBackgroundDrawer
void CMyAppContainer::RTxDrawBackground(const TPoint& aDstPos, const TRect& aRect, CBitmapContext& gc)
{
#ifdef USE_SKIN
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
MAknsControlContext* cc = AknsDrawUtils::ControlContext(this);
AknsDrawUtils::DrawBackground(skin, cc, this, gc, TPoint(0, 0), aRect, KAknsDrawParamDefault);
#else
gc.SetPenStyle(CGraphicsContext::ENullPen);
gc.SetBrushColor(KRgbBlue);
gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
gc.DrawRect(aRect);
#endif
}
 
#ifdef USE_SKIN
TTypeUid::Ptr CMyAppContainer::MopSupplyObject(TTypeUid aId)
{
if (aId.iUid == MAknsControlContext::ETypeId && iBackGround)
return MAknsControlContext::SupplyMopObject(aId, iBackGround);
return CCoeControl::MopSupplyObject(aId);
}
#endif
 
void CMyAppContainer::PrepareBitmapL(const TDesC& aFileName, TInt aId, TInt aIdMask)
{
CFbsBitmap* bitmap, *bitmap_mask;
AknIconUtils::CreateIconL(bitmap, bitmap_mask, aFileName, aId, aIdMask);
TSize scr = CEikonEnv::Static()->ScreenDevice()->SizeInPixels();
TSize iconSize(scr.iWidth / 2, scr.iWidth / 3); // sample resizing - depends on the image
AknIconUtils::SetSize(bitmap, iconSize, EAspectRatioNotPreserved);
AknIconUtils::SetSize(bitmap_mask, iconSize, EAspectRatioNotPreserved);
iBitmap->AppendL(bitmap);
iBitmapMask->AppendL(bitmap_mask);
}
 ///////////////////////////////
// RTxBackgroundDrawer.h
///////////////////////////////
 
/* Leszek Buczkowski, Ingraal 2006 */
 
#ifndef __RTX_BACKGROUND_DRAWER_H__
#define __RTX_BACKGROUND_DRAWER_H__
 
class MRTxBackgroundDrawer
{
public:
virtual void RTxDrawBackground(const TPoint& aDstPos, const TRect& aRect, CBitmapContext& gc) = 0;
};
 
#endif
 ///////////////////////////////
// RTxPicture.h
///////////////////////////////
 
/* Leszek Buczkowski, Ingraal 2006 */
 
#ifndef __RTX_PICTURE_H__
#define __RTX_PICTURE_H__
 
#include <gdi.h>
 
class CWindowGc;
class TSize;
class CFbsBitmap;
class MRTxBackgroundDrawer;
 
class CRTxPicture : public CPicture
{
public: // no destructor - bitmap not owned
CRTxPicture(CWindowGc& gc, MRTxBackgroundDrawer& aControl, CFbsBitmap& aBitmap, CFbsBitmap& aBitmapMask);
 
public:
TBool LineBreakPossible(TUint aClass, TBool aBeforePicture, TBool aHaveSpaces) const {return EFalse;};
void Draw(CGraphicsContext& aGc, const TPoint& aTopLeft, const TRect& aClipRect, MGraphicsDeviceMap* aMap) const;
void ExternalizeL(RWriteStream& aStream) const {};
void GetOriginalSizeInTwips(TSize& aSize) const {aSize = iSizeInTwips;};
 
protected:
TSize iSizeInTwips;
MRTxBackgroundDrawer& iControl;
CFbsBitmap* iBitmap;
CFbsBitmap* iBitmapMask;
};
 
#endif
 ///////////////////////////////
// RTxPicture.cpp
///////////////////////////////
 
/* Leszek Buczkowski, Ingraal 2006 */
 
#include <fbs.h>
#include <w32std.h>
#include "RTxPicture.h"
#include "RTxBackgroundDrawer.h"
 
#ifdef USE_SKIN
#include <AknsDrawUtils.h>
#include <AknsBasicBackgroundControlContext.h>
#endif
 
CRTxPicture::CRTxPicture(CWindowGc& gc, MRTxBackgroundDrawer& aControl, CFbsBitmap& aBitmap, CFbsBitmap& aBitmapMask) : iControl(aControl), iBitmap(&aBitmap), iBitmapMask(&aBitmapMask)
{
TSize sizeInPixels = gc.Device()->SizeInPixels();
TSize sizeInTwips = gc.Device()->SizeInTwips();
TSize bitmapSizeInPixels = aBitmap.SizeInPixels();
iSizeInTwips = TSize(sizeInTwips.iWidth * bitmapSizeInPixels.iWidth / sizeInPixels.iWidth, sizeInTwips.iHeight * bitmapSizeInPixels.iHeight / sizeInPixels.iHeight);
}
 
void CRTxPicture::Draw(CGraphicsContext& aGc, const TPoint& aTopLeft, const TRect& aClipRect, MGraphicsDeviceMap* aMap) const
{
CBitmapContext& gc = static_cast<CBitmapContext &>(aGc);
TRect bmpPieceRect(TPoint(0,0),iBitmap->SizeInPixels());
 
// here is the skin background drawn
iControl.RTxDrawBackground(aTopLeft, bmpPieceRect, gc);
 
// then the picture itself
gc.BitBltMasked(aTopLeft, iBitmap, bmpPieceRect, iBitmapMask, ETrue);
}
 ///////////////////////////////                 
// RTx.h
///////////////////////////////
 
/* Leszek Buczkowski, Ingraal 2006 */
 
#ifndef __RTX_H__
#define __RTX_H__
 
#include <e32base.h>
#include <gdi.h>
#include <coedef.h>
#include <w32std.h>
#include <txtfrmat.h>
#include <eikrted.h>
#include <txtrich.h>
#include "RTxBackgroundDrawer.h"
 
class CWindowGc;
class CFbsBitmap;
 
// CRTxEditor is derived from CEikRichTextEditor in order to make protected GetSystemGc available
// as public (used in CRTx::InsertPictureL)
class CRTxEditor : public CEikRichTextEditor
{
public:
CRTxEditor(const TGulBorder& aBorder) { iBorder = aBorder; };
CWindowGc& GetSystemGc() const { return SystemGc(); };
};
 
class CRTx : public CBase
{
public:
CRTx(CRTxEditor* aTextBox);
~CRTx();
TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType);
void AddCarriageReturnL();
void AddTextL (const TDesC& aText);
void InsertPictureL(MRTxBackgroundDrawer& aControl, TInt aPos, CFbsBitmap& aBitmap, CFbsBitmap& aBitmapMask);
void AddPictureL(MRTxBackgroundDrawer& aControl, CFbsBitmap& aBitmap, CFbsBitmap& aBitmapMask);
 
private:
CRTxEditor* iTextBox;
TCharFormatMask iCharFormatMask;
TCharFormat iCharFormat;
};
 
#endif
 ///////////////////////////////
// RTx.cpp
///////////////////////////////
 
/* Leszek Buczkowski, Ingraal 2006 */
 
#include "RTx.h"
#include "RTxPicture.h"
#include <eikrted.h>
#include <txtrich.h>
 
CRTx::CRTx(CRTxEditor* aTextBox)
{
iTextBox = aTextBox;
}
 
CRTx::~CRTx()
{
}
 
void CRTx::AddCarriageReturnL()
{
CRichText* richText = iTextBox->RichText();
richText->InsertL(richText->DocumentLength(), CEditableText::ELineBreak);
iTextBox->HandleTextChangedL();
}
 
void CRTx::AddTextL(const TDesC& aText)
{
CRichText* richText = iTextBox->RichText();
TInt documentLength = richText->DocumentLength();
richText->InsertL (documentLength, aText);
richText->ApplyCharFormatL(iCharFormat, iCharFormatMask,documentLength,aText.Length());
iTextBox->HandleTextChangedL();
}
 
void CRTx::InsertPictureL(MRTxBackgroundDrawer& aControl, TInt aPos, CFbsBitmap& aBitmap, CFbsBitmap& aBitmapMask)
{
CRTxPicture* picture;
picture = new(ELeave) CRTxPicture(iTextBox->GetSystemGc(), aControl, aBitmap, aBitmapMask);
CleanupStack::PushL(picture);
TPictureHeader header;
header.iPicture = TSwizzle<CPicture>(picture);
iTextBox->RichText()->InsertL(aPos, header);
CleanupStack::Pop();
}
 
void CRTx::AddPictureL(MRTxBackgroundDrawer& aControl, CFbsBitmap& aBitmap, CFbsBitmap& aBitmapMask)
{
CRichText* richText = iTextBox->RichText();
TInt documentLength = richText->DocumentLength();
InsertPictureL(aControl, documentLength, aBitmap, aBitmapMask);
}
 
TKeyResponse CRTx::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
{
if (aType == EEventKey)
{
if (aKeyEvent.iCode == EKeyDownArrow)
{
iTextBox->MoveCursorL (TCursorPosition::EFPageDown, EFalse);
return EKeyWasConsumed;
}
else if (aKeyEvent.iCode == EKeyUpArrow)
{
iTextBox->MoveCursorL (TCursorPosition::EFPageUp, EFalse);
return EKeyWasConsumed;
}
else
{
return iTextBox->OfferKeyEventL(aKeyEvent, aType);
}
}
return EKeyWasNotConsumed;
}
This page was last modified on 8 May 2013, at 03:05.
137 page views in the last 30 days.
×