screenshot.cpp
来自「Symbian_OS_code 初学Symbian_OS学习代码, 屏幕截图软」· C++ 代码 · 共 739 行 · 第 1/2 页
CPP
739 行
TRAPD(err, DoSaveL());
if (KErrNone != err)
{
iScreenShotStatus = EIdle;
iIsCapturing = EFalse;
iObserver.OnSaveCompleted(err);
}
else
{
iObserver.OnCaptureCompleted(KErrNone);
iScreenShotStatus = EConverting;
SetActive();
}
break;
}
// The saving is done.
case EConverting:
{
iObserver.OnSaveCompleted(iStatus.Int());
// Check whether the user has stopped the capturing or not.
// If iIsCapturing is EFalse, the user hasn't stopped it.
if ((iIsCapturing) && (KErrNone == iStatus.Int()))
{
switch (iScreenShotData.Mode())
{
// If the mode is one shot only, then it is in idle state now.
case CScreenShotData::EModeOneShot:
iScreenShotStatus = EIdle;
break;
// Otherwise, request another screenshot capture.
case CScreenShotData::EMode2Seconds:
FireCapture(2 * KOneSecond);
break;
case CScreenShotData::EMode5Seconds:
FireCapture(5 * KOneSecond);
break;
case CScreenShotData::EMode10Seconds:
FireCapture(10 * KOneSecond);
break;
default:
User::Invariant();
} // switch
} // if
else
{
iIsCapturing = EFalse;
iScreenShotStatus = EIdle;
}
break;
}
default:
User::Invariant();
}
}
// --------------------------------------------------------------------------
// Cancel any outstanding request.
// --------------------------------------------------------------------------
void CScreenShot::DoCancel()
{
if (iImageEncoder)
{
iImageEncoder->Cancel();
delete iImageEncoder;
iImageEncoder = 0;
}
iTimer.Cancel();
iScreenShotStatus = EIdle;
}
// --------------------------------------------------------------------------
// Captures the screenshot and store it to a buffer.
// --------------------------------------------------------------------------
void CScreenShot::DoCaptureL()
{
iOverlay->MakeVisible(ETrue);
iOverlay->SetRect(TRect(TPoint(0, 0), TSize(1, 1)));
const CWsScreenDevice* screenDevice = iCoeEnv.ScreenDevice();
TPixelsTwipsAndRotation sizeAndRotation;
screenDevice->GetScreenModeSizeAndRotation(
screenDevice->CurrentScreenMode(), sizeAndRotation);
// Creates a bitmap used to retrieve the screen pixels.
delete iBitmap;
iBitmap = 0;
iBitmap = new (ELeave) CFbsBitmap();
iBitmap->Create(sizeAndRotation.iPixelSize, screenDevice->DisplayMode());
iBitmap->SetSizeInTwips(screenDevice);
screenDevice->CopyScreenToBitmap(iBitmap);
iOverlay->MakeVisible(ETrue);
iOverlay->SetRect(TRect(TPoint(1, 1), TSize(1, 1)));
CFbsBitmap* bitmap2 = new (ELeave) CFbsBitmap();
bitmap2->Create(sizeAndRotation.iPixelSize, screenDevice->DisplayMode());
bitmap2->SetSizeInTwips(screenDevice);
screenDevice->CopyScreenToBitmap(bitmap2);
TUint32* dataAddress1 = iBitmap->DataAddress();
TUint32* dataAddress2 = bitmap2->DataAddress();
*dataAddress1 = *dataAddress2;
delete bitmap2;
iOverlay->MakeVisible(EFalse);
iOverlay->SetRect(TRect(TPoint(-1, -1), TSize(0, 0)));
}
// --------------------------------------------------------------------------
// Saves captured screenshot to a file.
// --------------------------------------------------------------------------
void CScreenShot::DoSaveL()
{
// Deletes the old encoder first.
delete iImageEncoder;
iImageEncoder = 0;
// Gets the next available file name.
// Although the file name will be assigned iDefaultFileName, here
// I use local variable. The reason is that we cannot push
// any member variables to the cleanup stack (Symbian convention).
HBufC* fileName = GetNextFileNameLC();
iCoeEnv.FsSession().MkDirAll(*fileName);
// Gets the MIME type
TPtrC8 mimeType = GetMimeType(iScreenShotData.ImageFormat());
// Prepares the image data (if applied).
CFrameImageData* frameImageData = CreateFrameImageDataLC(
iScreenShotData.ImageFormat());
// Creates a new encoder and then convert the bitmap.
iImageEncoder = CImageEncoder::FileNewL(
iCoeEnv.FsSession(), *fileName, mimeType);
iImageEncoder->Convert(&iStatus, *iBitmap, frameImageData);
CleanupStack::PopAndDestroy(); // frameImageData
CleanupStack::Pop(); // fileName
// Resets current file name.
delete iCurrentFileName;
iCurrentFileName = 0;
iCurrentFileName = fileName;
}
// --------------------------------------------------------------------------
// Returns MIME type based on aImageFormat.
// --------------------------------------------------------------------------
const TDesC8& CScreenShot::GetMimeType(
CScreenShotData::TImageFormat aImageFormat)
{
switch (aImageFormat)
{
case CScreenShotData::EFormatJpgHigh:
case CScreenShotData::EFormatJpgNormal:
case CScreenShotData::EFormatJpgLow:
return KMimeTypeJpg;
case CScreenShotData::EFormatPngDefault:
case CScreenShotData::EFormatPngSpeed:
case CScreenShotData::EFormatPngSize:
return KMimeTypePng;
case CScreenShotData::EFormatBmp:
case CScreenShotData::EFormatBmp8bpp:
return KMimeTypeBmp;
case CScreenShotData::EFormatMbm:
case CScreenShotData::EFormatMbm8bpp:
return KMimeTypeMbm;
default:
User::Invariant(); // panic if the format is unknown
}
return KMimeTypeUnknown;
}
#if (__S60__ >= 200)
// --------------------------------------------------------------------------
// Creates frame image data based on aImageFormat.
// --------------------------------------------------------------------------
CFrameImageData* CScreenShot::CreateFrameImageDataLC(
CScreenShotData::TImageFormat aImageFormat)
{
CFrameImageData* frameImageData = CFrameImageData::NewL();
CleanupStack::PushL(frameImageData);
switch (aImageFormat)
{
case CScreenShotData::EFormatJpgHigh:
case CScreenShotData::EFormatJpgNormal:
case CScreenShotData::EFormatJpgLow:
{
TJpegImageData* imageData = new (ELeave) TJpegImageData();
imageData->iSampleScheme = TJpegImageData::EColor444;
if (CScreenShotData::EFormatJpgHigh == aImageFormat)
{
imageData->iQualityFactor = 100;
}
else if (CScreenShotData::EFormatJpgNormal == aImageFormat)
{
imageData->iQualityFactor = 90;
}
else if (CScreenShotData::EFormatJpgLow == aImageFormat)
{
imageData->iQualityFactor = 80;
}
User::LeaveIfError(frameImageData->AppendImageData(imageData));
break;
}
case CScreenShotData::EFormatPngDefault:
case CScreenShotData::EFormatPngSpeed:
case CScreenShotData::EFormatPngSize:
{
TPngEncodeData* encodeData = new (ELeave) TPngEncodeData();
encodeData->iPaletted = EFalse;
encodeData->iColor = ETrue;
encodeData->iBitsPerPixel = 24;
if (CScreenShotData::EFormatPngDefault == aImageFormat)
{
encodeData->iLevel = TPngEncodeData::EDefaultCompression;
}
else if (CScreenShotData::EFormatPngSpeed == aImageFormat)
{
encodeData->iLevel = TPngEncodeData::EBestSpeed;
}
else if (CScreenShotData::EFormatPngSize == aImageFormat)
{
encodeData->iLevel = TPngEncodeData::EBestCompression;
}
User::LeaveIfError(frameImageData->AppendFrameData(encodeData));
break;
}
case CScreenShotData::EFormatBmp:
{
TBmpImageData* imageData = new (ELeave) TBmpImageData();
imageData->iBitsPerPixel = 24;
User::LeaveIfError(frameImageData->AppendImageData(imageData));
break;
}
case CScreenShotData::EFormatBmp8bpp:
{
TBmpImageData* imageData = new (ELeave) TBmpImageData();
imageData->iBitsPerPixel = 8;
User::LeaveIfError(frameImageData->AppendImageData(imageData));
break;
}
case CScreenShotData::EFormatMbm:
{
TMbmEncodeData* imageData = new (ELeave) TMbmEncodeData();
imageData->iDisplayMode = EColor16M;
User::LeaveIfError(frameImageData->AppendFrameData(imageData));
break;
}
case CScreenShotData::EFormatMbm8bpp:
{
TMbmEncodeData* imageData = new (ELeave) TMbmEncodeData();
imageData->iDisplayMode = EColor256;
User::LeaveIfError(frameImageData->AppendFrameData(imageData));
break;
}
case CScreenShotData::EFormatGif:
break;
default:
User::Invariant(); // panic if the format is unknown
}
return frameImageData;
}
#else
// --------------------------------------------------------------------------
// Creates frame image data based on aImageFormat.
// --------------------------------------------------------------------------
CFrameImageData* CScreenShot::CreateFrameImageDataLC(
CScreenShotData::TImageFormat aImageFormat)
{
CFrameImageData* frameImageData = new (ELeave) CFrameImageData();
CleanupStack::PushL(frameImageData);
switch (aImageFormat)
{
case CScreenShotData::EFormatJpgHigh:
frameImageData->iQualityFactor = 100;
break;
case CScreenShotData::EFormatJpgNormal:
frameImageData->iQualityFactor = 67;
break;
case CScreenShotData::EFormatJpgLow:
frameImageData->iQualityFactor = 33;
break;
case CScreenShotData::EFormatPngDefault:
frameImageData->iQualityFactor = 75;
break;
case CScreenShotData::EFormatPngSpeed:
frameImageData->iQualityFactor = 100;
break;
case CScreenShotData::EFormatPngSize:
frameImageData->iQualityFactor = 50;
break;
case CScreenShotData::EFormatBmp:
frameImageData->iBitsPerPixel = 24;
break;
case CScreenShotData::EFormatBmp8bpp:
frameImageData->iBitsPerPixel = 8;
break;
case CScreenShotData::EFormatGif:
break;
case CScreenShotData::EFormatMbm:
frameImageData->iBitsPerPixel = 24;
break;
case CScreenShotData::EFormatMbm8bpp:
frameImageData->iBitsPerPixel = 8;
break;
default:
User::Invariant(); // panic if the format is unknown
}
return frameImageData;
}
#endif
// --------------------------------------------------------------------------
// Fires an event. It means set this active object to active, but completes
// the request immediately.
// --------------------------------------------------------------------------
void CScreenShot::Fire(TScreenShotStatus aStatus)
{
iScreenShotStatus = aStatus;
SetActive();
TRequestStatus* status = &iStatus;
User::RequestComplete(status, KErrNone);
}
// --------------------------------------------------------------------------
// Fires an event after aTime microseconds.
// --------------------------------------------------------------------------
void CScreenShot::FireCapture(TTimeIntervalMicroSeconds32 aTime)
{
iScreenShotStatus = EWaiting;
iTimer.After(iStatus, aTime);
SetActive();
}
// End of File
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?