bencoolenappui.cpp

来自「Symbian_OS_code 初学Symbian_OS学习代码, 屏幕截图软」· C++ 代码 · 共 1,322 行 · 第 1/3 页

CPP
1,322
字号
/*
 * BencoolenAppUi.cpp
 *
 * Copyright 2005 - 2008, Antony Pranata
 * http://www.antonypranata.com
 *
 * Project: Screenshot for Symbian OS.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

// INCLUDE FILES
#include <symbianvariant.h>

#include <eikenv.h>
#include <apgcli.h>
#include <e32keys.h>
#include <eikmenup.h> // CEikMenuPane
#include <apgtask.h>
#include <StringLoader.h>
#include <screenshot.rsg>
#include <bautils.h>
#include <apgwgnam.h>

#ifdef __S60__
#include <SendUi.h> // CSendAppUi or CSendUi
#include <smut.h>   // KUidMsgTypeSMS
#if (__S60__ >= 300)
#include <CMessageData.h> // for sending data in S60 3.x
#else
#include <SendNorm.rsg> // Only available in pre S60 3.x
#endif
#include <avkon.hrh>
#include <AknGlobalNote.h>
#include "BencoolenSettingsView.h"
#include "BencoolenAboutDlg.h"
#else
#include <hal.h>	   // to check machine id
#include <bautils.h>   //  to check file exists
#include <eikdialg.h>
#include <qikSendAs.h> // Send As dialog box
#include <mtmuids.h>   // List of all MTMs
#include <eikmenub.h>  // remove this when possible
#include <qikutils.rsg>
#include "BencoolenSettingsDlg.h"
#endif

#include "BencoolenAppContainer.h"
#include "BencoolenAppui.h"
#include "BencoolenApp.h"
#include "ScreenShot.h"
#include "ScreenShotData.h"
#include "Bencoolen.hrh"
#include "FakeOverlay.h"

// CONSTANTS
const TInt KOkKeyCode           = 63557;
const TInt KOkKeyScanCode       = EStdKeyDevice3;

const TInt KAsteriskKeyCode     = 42;
const TInt KAsteriskKeyScanCode = 42;

const TInt KHashKeyCode         = 74;
const TInt KHashKeyScanCode     = EStdKeyHash; // = 127

#if (__S60__ >= 300)

// const TInt KCameraKeyCode       = EKeyApplication1A;
const TInt KCameraKeyScanCode   = EStdKeyApplication1A;

const TInt KStdKey1             = 0x31;
//const TInt KStdKey3             = 0x33;
const TInt KStdKey7             = 0x37;
//const TInt KStdKey9             = 0x39;

#else

const TInt KCameraKeyCode       = 227;
const TInt KCameraKeyScanCode   = 227;

#endif

#ifdef __UIQ__

const TInt KSonyEricssonP910i = 0x10200AC6;
const TInt KMotorolaA925      = 0x101F6B26;

_LIT(KAboutDialogImage, "Bencoolen.mbm");

#else

_LIT(KBackgroundImage,  "background.mbm");

#endif

#if (__S60__ >= 200)
#define PRIORITYCAPTUREKEY ,2
#else
#define PRIORITYCAPTUREKEY
#endif


// MEMBER FUNCTIONS

// --------------------------------------------------------------------------
// Second phase constructor
// --------------------------------------------------------------------------
void CBencoolenAppUi::ConstructL()
	{
#if (__S60__ >= 200)
	BaseConstructL(EAknEnableSkin);
#else
	BaseConstructL();
#endif

	iIsCapturing  = ETrue;
	iIsContinuous = EFalse;

	// We have to instantiate CSendUi or CSendAppUi here.
	// Otherwise it will fail in LowMem test from SymbianSigned.
	// I don't know why, but moving the call to the very beginning
	// solved the problem.
#ifdef __S60__

#if (__S60__ >= 300) // Starting from S60 3.x, we use CSendUi
	iSendUi = CSendUi::NewL();
#else
	iSendUi = CSendAppUi::NewL(EBencoolenCmdSend);
#endif // (__S60__ >= 300)

#endif // __S60__

	// Create screen shot data and load the settings from the .ini file.
	iScreenShotData = new (ELeave) CScreenShotData();
	TRAPD(err, DoLoadSettingsL()); // If this leaves, it means there's no settings yet.
								   // Use default settings then (already assigned in
								   // the constructor of CScreenShotData).
	
	// If no more memory, then propagate the error.
	// This is needed for SymbianSigned, otherwise it will failed at LowMem test.
	if (KErrNoMemory == err)
		{
		User::Leave(err);
		}

	// Create screen shot object that will be used to capture the screen
	// and save it to a file.
	iScreenShot = CScreenShot::NewL(*this, *iCoeEnv, *iScreenShotData);

	// Set the capture key
	SetCaptureKey();

#ifdef __S60__

	iAppView = CBencoolenAppView::NewL();
	iSettingsView = CBencoolenSettingsView::NewL(iScreenShotData);

	// Set the background image.
	TParse aParser;
	aParser.Set(Application()->AppFullName(), NULL, NULL);
	iBackgroundBitmap = new (ELeave) CFbsBitmap();
	TFileName result;

	#if (__S60__ >= 300)
	
	// In S60 3.x, we use private folder to store background image.
	iCoeEnv->FsSession().PrivatePath(result);
	result.Insert(0, aParser.Drive());
	
	#else
	
	// In any previous version, we use the same folder as the application
	// (\system\apps\appname).	
	TPtrC aPathLessName = aParser.DriveAndPath();	
	result.Append(aPathLessName);
	
	#endif

	result.Append(KBackgroundImage);
	TInt error = iBackgroundBitmap->Load(result);	
	if (KErrNone != error)
		{
		// If we cannot load the background image, we just use
		// text to display information to the user.
		// Thus we have to delete iBackgroundBitmap here.
		delete iBackgroundBitmap;
		iBackgroundBitmap = 0;
		}
		
	AppContainer()->SetBitmap(iBackgroundBitmap);
	AppContainer()->DrawNow();
	
	AddViewL(iAppView);
	AddViewL(iSettingsView);

	SetDefaultViewL(*iAppView);
	
	// Creates an overlay window to solve direct screen access problem.
	iWindowGroup = RWindowGroup(iCoeEnv->WsSession());
	User::LeaveIfError(iWindowGroup.Construct((TUint32)&iWindowGroup, EFalse));
	iWindowGroup.SetOrdinalPosition(0, ECoeWinPriorityAlwaysAtFront);
	iWindowGroup.SetNonFading(ETrue);
	iOverlay = CFakeOverlay::NewL(iWindowGroup);
	
	iScreenShot->SetOverlay(iOverlay);

#else

	// Constructs the main view.
	iAppContainer = new (ELeave) CBencoolenAppContainer();
	iAppContainer->ConstructL(ClientRect());
	AddToStackL(iAppContainer);

	// No bitmap is shown at the beginning.
	// This function call will sets default text message too.
	iAppContainer->ClearBitmap(ETrue);

	// The table of mime types to monitor, here just one, Images
	CDesCArray* mimeTypesArray = new (ELeave) CDesCArrayFlat(1);
	CleanupStack::PushL(mimeTypesArray);
	mimeTypesArray->AppendL(KMimeTypeImage);
	iMonitor = CQikMediaFolderMonitor::NewL(
		*this, iEikonEnv->FsSession(), * mimeTypesArray, *iEikonEnv);
	CleanupStack::PopAndDestroy();

	// Sets the current directory in the menu bar.
	// But remember that the directory name is ended with backslash.
	// That's why we have to minus 1 when setting the title.
	TPtrC directoryPtr(iScreenShotData->Directory());
	CEikMenuBar* menu = iEikonEnv->AppUiFactory()->MenuBar();
	menu->SetTitleL(directoryPtr.Left(directoryPtr.Length() - 1),
		R_BENCOOLEN_CATEGORY_PANE);
	menu->DrawNow();
	
#endif // __S60__
	}

// --------------------------------------------------------------------------
// Destructor.
// --------------------------------------------------------------------------
CBencoolenAppUi::~CBencoolenAppUi()
	{
	CancelCaptureKey();

#ifdef __S60__

	delete iBackgroundBitmap;
	delete iSendUi;

#else

	delete iMonitor;
	if (iAppContainer)
		{
		RemoveFromStack(iAppContainer);
		delete iAppContainer;
		}

#endif

	delete iScreenShot;
	delete iScreenShotData;
	
	iWindowGroup.Close();
	delete iOverlay;
	}

// --------------------------------------------------------------------------
// Sets the capture key based on the shortcut assigned in CScreenShotData.
// --------------------------------------------------------------------------
void CBencoolenAppUi::SetCaptureKey()
	{
	// In the emulator, we just simply use Yes button.
#ifdef __WINS__

	DoSetCaptureKey(EStdKeyYes);

#else

#ifdef __S60__

	switch (iScreenShotData->Shortcut())
		{
		case CScreenShotData::EShortcutConfirm:
			DoSetCaptureKey(KOkKeyScanCode, KOkKeyCode, 0, 0, EModifierShift);
			break;
		case CScreenShotData::EShortcutStar:
			DoSetCaptureKey(KAsteriskKeyScanCode, KAsteriskKeyCode, 0, 0, EModifierShift);
			break;
		case CScreenShotData::EShortcutHash:
			DoSetCaptureKey(KHashKeyScanCode, KHashKeyCode, 0, 0, EModifierShift);
			break;
		case CScreenShotData::EShortcutCamera:
			DoSetCaptureKey(KCameraKeyScanCode);
			break;
		case CScreenShotData::EShortcutC:
			DoSetCaptureKey(EStdKeyBackspace, EKeyBackspace);
			break;
		case CScreenShotData::EShortcutHashStar:
			DoSetCaptureKey(KHashKeyScanCode, 0, KAsteriskKeyCode, 0);
			break;
		case CScreenShotData::EShortcutHash1:
			// Do not handle iCode because we want to pass it to 
			// other applications.
			// For example, the phone application will hang if we handle iCode.
			DoSetCaptureKey(KHashKeyScanCode, 0, KStdKey1, 0);
			break;
		case CScreenShotData::EShortcutHash7:
			// Do not handle iCode because we want to pass it to 
			// other applications.
			// For example, the phone application will hang if we handle iCode.
			DoSetCaptureKey(KHashKeyScanCode, 0, KStdKey7, 0);
			break;
		default:
			User::Invariant();
		}

#else

	TInt machineId;
	HAL::Get(HAL::EMachineUid, machineId);

	// If we're using Code, then this is the key
	// Camera: EKeyApplication1 (63571)
	// Camera: EKeyDevice8 (63562) in Motorola A920 and A925
	// Browser: EKeyApplication0 (63570)
	switch (iScreenShotData->Shortcut())
		{
		case CScreenShotData::EShortcutCamera:
			{
			if (KMotorolaA925 == machineId)
				{
				DoSetCaptureKey(EKeyDevice8);
				}
			else
				{
				DoSetCaptureKey(EKeyApplication1);
				}
			break;
			}
		case CScreenShotData::EShortcutBrowser:
			DoSetCaptureKey(EKeyApplication0);
			break;
		default:
			User::Invariant();
		}

	// If we're using StdCode, then this is the key
	// Camera: EStdKeyApplication1
	// Browser: EStdKeyApplication0
/*	switch (iScreenShotData->Shortcut())
		{
		case CScreenShotData::EShortcutCamera:
			DoSetCaptureKey(EStdKeyApplication1);
			break;
		case CScreenShotData::EShortcutBrowser:
			DoSetCaptureKey(EStdKeyApplication0);
			break;
		default:
			User::Invariant();
		}*/

#endif // __S60__

#endif // __WINS__
	}

// --------------------------------------------------------------------------
// Cancels the capturing key.
// --------------------------------------------------------------------------
void CBencoolenAppUi::CancelCaptureKey()
	{
	if (iHandleCaptureKey > 0)
		{
#ifdef __S60__
		iCoeEnv->RootWin().CancelCaptureKeyUpAndDowns(iHandleCaptureKey);
		iHandleCaptureKey = 0;		

		iCoeEnv->RootWin().CancelCaptureKey(iHandleCaptureKey2);
		iHandleCaptureKey2 = 0;
#else
		iCoeEnv->RootWin().CancelCaptureKey(iHandleCaptureKey);
		iHandleCaptureKey = 0;
#endif		
		}
		
	if (iHandleCaptureKeySecondary > 0)
		{
#ifdef __S60__
		iCoeEnv->RootWin().CancelCaptureKeyUpAndDowns(iHandleCaptureKeySecondary);
		iHandleCaptureKeySecondary = 0;

		iCoeEnv->RootWin().CancelCaptureKey(iHandleCaptureKey2Secondary);
		iHandleCaptureKey2Secondary = 0;
#else
		iCoeEnv->RootWin().CancelCaptureKey(iHandleCaptureKeySecondary);
		iHandleCaptureKeySecondary = 0;
#endif		
		}
	}

// --------------------------------------------------------------------------
// This function is called when a screenshot has been captured.
// --------------------------------------------------------------------------
void CBencoolenAppUi::OnCaptureCompleted(TInt aError)
	{
	if (KErrNone == aError)
		{
		// Display the dialog only when the mode is one shot only.
		if (CScreenShotData::EModeOneShot == iScreenShotData->Mode())
			{
			// Before capturing screenshot, we set the bitmap to 0
			// Why do we need to set to 0? Because after we call
			// CScreenShot::CaptureL(), the instance of bitmap
			// is no longer valid. That's why, AppContainer()
			// will point to invalid pointer.
			// 
			// Don't need to call AppContainer()->DrawNow()
			// otherwise we will have flickering effect.
			AppContainer()->ClearBitmap(EFalse);
				
			const HBufC* fileName = iScreenShot->CurrentFileName();

			// When this function is called, there should be a file name.
			// If not, then there's a programming error.
			__ASSERT_DEBUG(fileName, User::Invariant());

			TParse parse;
			parse.Set(*fileName, 0, 0);

⌨️ 快捷键说明

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