如何将控件绘制到位图上
Article Metadata
Tested with
Devices(s): S60 Emulator
Compatibility
Platform(s): Symbian
Article
Keywords: CWindowToBitmapMappingGc CCoeControl CFbsBitmap SetCustomGc CWsScreenDevice CFbsBitmapDevice CFbsBitGc
Created: chenziteng
(08 Nov 2009)
Last edited: hamishwillee
(26 Jul 2011)
Contents |
概述
直接或间接继承自CCoeControl的控件在默认情况下使用系统GC(Graphics Context,图形上下文)将自己绘制到屏幕上,但在有些情况下开发人员需要将控件绘制到位图上,比如在实现视图切换特效时需要当前视图和目标视图的截图。本文展示了如何强制将控件绘制到位图上。
方案
CCoeControl::SetGc()和CCoeControl::SetCustomGc()可以将控件的绘制重定向到一个定制的图形GC上,但是这两个函数只接受窗口GC的指针,也就是说不能直接将位图GC作为它们的参数。Symbian OS 7.0中引入的CWindowToBitmapMappingGc可以解决这个问题,这个类可以将所有对窗口GC的操作映射到位图GC上。
// .mmp
...
// begin by chen
LIBRARY egul.lib // CWindowToBitmapMappingGc
LIBRARY bitgdi.lib // CFbsBitmapDevice
LIBRARY imageconversion.lib // CImageEncoder
// end by chen
...
// .cpp
...
// begin by chen
#include <gulgcmap.h> // CWindowToBitmapMappingGc
#include <ImageConversion.h> // CImageEncoder
// end by chen
...
TBool CGoodbyeHellAppUi::HandleDummyDrawNowMenuItemSelectedL( TInt aCommand )
{
// TODO: implement selected event handler
// begin by chen
RFs& fs = iCoeEnv->FsSession();
CCoeControl* control = iGoodbyeHellContainer; // 待绘制的控件
CWsScreenDevice* wsScreenDevice = iCoeEnv->ScreenDevice();
CFbsBitmap* bitmap = new(ELeave) CFbsBitmap; // 绘制控件的位图
CleanupStack::PushL(bitmap);
TInt err = bitmap->Create(control->Size(), wsScreenDevice->DisplayMode());
User::LeaveIfError(err);
CFbsBitmapDevice* bitDevice = CFbsBitmapDevice::NewL(bitmap);
CleanupStack::PushL(bitDevice);
CFbsBitGc* bitGc = NULL;
err = bitDevice->CreateContext(bitGc);
User::LeaveIfError(err);
CleanupStack::PushL(bitGc);
CWindowToBitmapMappingGc* w2bGc = CWindowToBitmapMappingGc::NewL(*wsScreenDevice, *bitGc);
CleanupStack::PushL(w2bGc);
control->SetCustomGc(w2bGc); // 将控件的GC替换成位图GC
control->DrawNow(); // 将控件绘制到位图上
control->SetCustomGc(NULL); // 恢复控件的GC
// 在本例中将位图保存成一个.bmp文件以方便查看效果
_LIT(KFileName, "c:\\data\\control.bmp");
_LIT8(KMIME, "image/bmp");
CImageEncoder* encoder = CImageEncoder::FileNewL(fs, KFileName, KMIME, CImageEncoder::EOptionAlwaysThread);
CleanupStack::PushL(encoder);
TRequestStatus status = KRequestPending;
encoder->Convert(&status, *bitmap);
User::WaitForRequest(status);
User::LeaveIfError(status.Int());
CleanupStack::PopAndDestroy(encoder);
CleanupStack::PopAndDestroy(w2bGc);
CleanupStack::PopAndDestroy(bitGc);
CleanupStack::PopAndDestroy(bitDevice);
CleanupStack::PopAndDestroy(bitmap);
// end by chen
return ETrue;
}
...
更多细节请查看完整的示例程序。
注:如果想将列表框控件绘制到位图上请参照论坛中的讨论
Source Code
完整的示例程序:
GoodbyeHell(DrawControlsOnBitmap).zip
模拟器截图:
示例程序绘制的位图(由于wiki不允许上传.bmp文件因此将它转换成了.png文件):



(no comments yet)