This page was last modified 12:24, 13 December 2007.
在文本(CEikRichTextEditor)中插入带背景的图片
From Forum Nokia Wiki
适用版本:
Series 60 2nd , Series 60 3rd
更多关于在文本中插入图片参见这里: [1]
一般情况下,在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; }
best regards
davey_2
| Related Discussions | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| 求助:关于gtxted中的文本问题??? | FreeStyle521 | Symbian | 4 | 2005-06-13 03:48 |
| Change Font in CEikRichTextEditor | Holler | Symbian User Interface | 2 | 2006-08-06 18:11 |
| why MFormCustomDraw::DrawBackground() can not be called? | yql | General Symbian C++ | 8 | 2007-08-09 11:09 |
| CEikRichTextEditor - StoreL & RestoreL | ronald29 | General Symbian C++ | 3 | 2007-04-27 06:25 |
| 如何让CEikRichTextEditor初始显示最开始的数据 | cyyy824 | Symbian | 3 | 2007-07-23 10:25 |
