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 + -
显示快捷键?