// CUSTOM.H
//
//
// Copyright (c) 2000 Symbian Ltd. All rights reserved.
//
//
// UI Control Framework example application
//
//这是
//http://www.symbian.com/developer/techlib/v9.2docs/doc_source/examples/coneEx/UICFrameworkExampleCode.guide.html#ApplicationFrameworkEx%2euic%2ecustom
//上的一个例子程序.
#if !defined(__COSMILEY_H__)
#define __COSMILEY_H__
//
//
// Include files containing:(头文件)
//
// 1. Symbol definitions used by C++ code and resource scripts (the *.hrh)
// 2. Resource ids generated by resource compilation of
// resource scripts (the *.rsg)
// 3. Class definitions required by this app (the *.h)
//
//
// 1.
#include <eikon.hrh>
#include "custom.hrh"
// 2.
#include <eikon.rsg>
#include <custom.rsg>
// 3.
#include <eikenv.h>
#include <eikappui.h>
#include <eikproc.h>
#include <eikdialg.h>
#include <eikmenub.h>
#include <eikapp.h>
#include <eikdoc.h>
#include <coeutils.h>
#include <barsread.h>
#include <eikfctry.h>
// The unique identifier for this application.
// NOTE that the number has been arbitrarily chosen for the purpose of
// of the example.
const TUid KUidExampleApp={0x01000d00};
//
//
// -----> CSmileyDialog(definition)
//
//
class CSmileyDialog : public CEikDialog
{
public:
// Construct and run
static TBool RunDlgLD();
private:
SEikControlInfo CreateCustomControlL(TInt aControlType);
};
//
//
// -----> CSmiley (definition)
//
//
class CSmiley : public CCoeControl
{
public:
CSmiley(TBool aSmiling);
~CSmiley();
public:
TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType);
TBool IsSmiling();
private:
void Draw(const TRect& aRect) const;
void SizeChanged();
protected:
void HandlePointerEventL(const TPointerEvent& aPointerEvent);
void FocusChanged(TDrawNow aDrawNow);
private:
TBool iSmiling;
TRect iSmileyRect;
TInt iSmileyWidth;
TInt iSmileyHeight;
TRect iSmileRect;
TRect iFrownRect;
};
//
//
// -----> CSmileyContainer(definition)
//
//
class CSmileyContainer : public CCoeControl,
public MCoeControlObserver
{
public:
// Construction
CSmileyContainer();
void ConstructL(const TRect& aRect);
// Destruction
~CSmileyContainer();
void ConstructFromResourceL(TResourceReader& aReader);
void PrepareForFocusLossL();
TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType);
protected:
void FocusChanged(TDrawNow aDrawNow);
private:
// Virtual, defined by CCoeControl; replaces the default implementation
// provided by CCoeControl.
void Draw(const TRect& aRect) const;
// Virtual, defined by CCoeControl; replaces the default implementation
// provided by CCoeControl.
TInt CountComponentControls() const;
// Virtual, defined by CCoeControl; replaces the default implementation
// provided by CCoeControl.
CCoeControl* ComponentControl(TInt aIndex) const;
// Virtual, defined by CCoeControl; empty implementation provided by
// CCoeControl; full implementation provided by this class
void SizeChanged();
// Defined as pure virtual by the mixin class MCoeControlObserver
// inherited by CCoeControl. An empty implementation provided by
// this class (its containees do not report events).
void HandleControlEventL(CCoeControl* aControl,
TCoeEvent aEventType);
private:
// Member functions defined and used by this class
void SwapFocus(CCoeControl* aControl);
private:
// Data members defined and used by this class.
CSmiley* iSmiley1;
CSmiley* iSmiley2;
};
//
//
// -----> CMainWinControl (definition)
//
//
class CMainWinControl : public CCoeControl
{
public:
CMainWinControl();
~CMainWinControl();
void ConstructL(const TRect& rect);
TInt CountComponentControls() const;
CCoeControl* ComponentControl(TInt aIndex) const;
TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType);
private:
void Draw(const TRect& aRect) const;
private:
CSmileyContainer* iContainer;
};
//
//
// -----> CExampleAppUi (definition)
//
//
class CExampleAppUi : public CEikAppUi
{
public:
// Destruction.
~CExampleAppUi();
public:
// Virtual, defined by CEikAppUi; replaces the implementation
// provided by CEikAppUi.
void ConstructL();
private:
// Virtual, defined by CEikAppUi; empty implementation
// provided by CEikAppUi; full implementation provided
// by this class.
void HandleCommandL(TInt aCommand);
// Virtual, defined by CEikAppUi; empty implementation
// provided by CEikAppUi; full implementation provided
// by this class.
void HandleModelChangeL();
private:
void OnCmdExit();
private:
// Data members defined by this class.
CMainWinControl* iMainWinControl;
};
//
//
// -----> CExampleDocument (definition)
//
//
class CExampleDocument : public CEikDocument
{
public:
// Construction.
static CExampleDocument* NewL(CEikApplication& aApp);
CExampleDocument(CEikApplication& aApp);
// Destruction.
~CExampleDocument();
private:
// Defined as pure virtual by CEikDocument; full implementation
// provided by this class
CEikAppUi* CreateAppUiL(); // Construct an app.user interface
// Defined as pure virtual by CApaDocument; empty implementation
// provided by CEikDocument; full implementation provided
// by this class.
void NewDocumentL(); // Build a new document
// Defined as pure virtual by CApaDocument; empty implementation
// provided by CEikDocument; full implementation provided
// by this class.
void StoreL(CStreamStore& aStore,
CStreamDictionary& aStreamDic
) const;
void RestoreL(const CStreamStore& aStore,
const CStreamDictionary& aStreamDic
);
public:
// Member functions defined by this class
void DoNewFileL(const TFileName& aFileName);
void DoOpenFileL(const TFileName& aFileName);
void DoSaveToNewFileL(const TFileName& aNewFileName);
TBool FileNameExists(const TFileName& aFileName) const;
private:
// Member functions defined by this class
void CreateModelL();
void ResetModelL();
};
//
//
// -----> CExampleApplication (definition)
//
//
class CExampleApplication : public CEikApplication
{
private:
// Defined as pure virtual by CApaApplication; implementation
// provided by this class
TUid AppDllUid() const; // Returns Uid associated with app
// Defined as pure virtual by CEikApplication; implementation
// provided by this class.
CApaDocument* CreateDocumentL(); // Construct new document
};
#endif
Custom.cpp
// CUSTOM.CPP
//
// Copyright (c) 2000 Symbian Ltd. All rights reserved.
//
//
// UI Control Framework example program
//
// This example demonstrates how to write new control classes.
//
// The example creates three new control classes:
// 1. CSmiley - a simple control which displays a
// smiley face that can have two moods,
// happy and sad. The user can change
// the smiley's mood by pressing the
// space bar.
// 2. CSmileyContainer - a compound control which contains
// two CSmiley controls, side by side.
// The user can move the keyboard focus
// from one CSmiley to the other using
// the arrow keys, or the pointer.
// 3. CMainWinControl - a compound control which does nothing
// except act as a background window and a
// container for other controls in the
// application.
//
//
// When the application starts up, it creates a CMainWinControl to cover
// the entire screen, and a CSmileyContainer inside this main window.
// The application's menu contains just two options. One of them closes
// the application; the other creates a dialog which contains a
// CSmileyContainer. CSmileyContainer therefore illustrates how to write
// a control that can be created both in a dialog and within the
// application's main view.
//
#include "custom.h"
#include <eikstart.h>
//
//
// -----> CMainWinControl(implementation)
//
//
CMainWinControl::CMainWinControl()
{
}
CMainWinControl::~CMainWinControl()
{
delete iContainer;
}
// CMainWinControl needs a ConstructL(), because it is a compound control
// (and a window-owning control).
void CMainWinControl::ConstructL(const TRect& rect)
{
// Make this a window-owning control.
CreateWindowL();
SetRect(rect);
// Create its only component, a CSmileyContainer
iContainer = new(ELeave) CSmileyContainer;
iContainer->SetContainerWindowL(*this);
TRect containerRect=Rect();
iContainer->ConstructL(containerRect);
// Activate the main window control - this will also activate the
// CSmileyContainer and its components.
ActivateL();
DrawNow();
}
// The following two functions have to be implemented for all compound controls.
TInt CMainWinControl::CountComponentControls() const
{
return 1;
}
CCoeControl* CMainWinControl::ComponentControl(TInt /*aIndex*/) const
{
return iContainer;
}
// Draw the main window.
void CMainWinControl::Draw(const TRect& /*aRect*/) const
{
CWindowGc& gc=SystemGc();
gc.SetBrushColor(KRgbWhite);
gc.Clear(Rect());
}
// CSmileyContainer can't be put on the control stack, because it's a component of this
// control. The main window control goes on the stack and passes on any key events it gets
// to the CSmileyContainer.
TKeyResponse CMainWinControl::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType)
{
return (iContainer->OfferKeyEventL(aKeyEvent, aType));
}
//
//
// -----> CSmileyContainer (implementation)
//
//
CSmileyContainer::CSmileyContainer()
{}
CSmileyContainer::~CSmileyContainer()
{
// Delete all the contained controls
delete iSmiley1;
delete iSmiley2;
}
// Because CSmileyContainer is a compound control, it needs a
// ConstructL() for when it's created outside a dialog, and a
// ConstructFromResourceL() for when it's created inside a dialog.
void CSmileyContainer::ConstructL(const TRect& aRect)
{
TBool isSmiling=ETrue;
// Create the two CSmileys. Their size and position is
// set in CSmileyContainer::SizeChangedL().
iSmiley1 = new(ELeave) CSmiley(isSmiling);
iSmiley1->SetContainerWindowL(*this);
isSmiling=EFalse;
iSmiley2 = new(ELeave) CSmiley(isSmiling);
iSmiley2->SetContainerWindowL(*this);
iSmiley1->SetFocus(ETrue);
// Set the container as the observer of the two CSmileys. This
// is for handling keyboard focus. When an arrow key is pressed
// or the pointer is clicked on one of the CSmileys, an
// EEventRequestFocus event is sent to the container, and the
// container changes the focus if applicable.
iSmiley1->SetObserver(this);
iSmiley2->SetObserver(this);
// Set the bounding rectangle of this control (this will result in
// a call to SizeChangedL(). The component controls must be
// created before calling this, because SizeChangedL() sets their
// sizes.
SetRect(aRect);
}
// This function is used when the CSmileyContainer is created inside a dialog.
void CSmileyContainer::ConstructFromResourceL(TResourceReader& aReader)
{
// Read the smiley mood from the resource file
TBool isSmiling=(TBool)aReader.ReadInt8();
// Read the width of the smiley container from the resource file.
TInt width=aReader.ReadInt16();
// Set the height of the container to be half its width
TSize containerSize (width, width/2);
iSmiley1 = new(ELeave) CSmiley(isSmiling);
iSmiley1->SetContainerWindowL(*this);
iSmiley2 = new(ELeave) CSmiley(isSmiling);
iSmiley2->SetContainerWindowL(*this);
iSmiley1->SetFocus(ETrue);
iSmiley1->SetObserver(this);
iSmiley2->SetObserver(this);
SetSize(containerSize);
ActivateL();
}
// The following two functions have to be implemented for all compound controls.
TInt CSmileyContainer::CountComponentControls() const
{
return 2;
}
CCoeControl* CSmileyContainer::ComponentControl(TInt aIndex) const
{
if (aIndex==0)
return iSmiley1;
else
return iSmiley2;
}
// This function gets called whenever one of the size-setting functions is called.
// As this is a compound control, this function calculates and sets the size and
// position for its components, based on its own size.
void CSmileyContainer::SizeChanged()
{
TInt containerWidth=Size().iWidth;
TInt containerHeight=Size().iHeight;
// Find half of the greater - width or height
TInt length=containerHeight>containerWidth ? containerWidth/4 : containerHeight/4;
TSize smileySize(length,length);
// Do some preliminary calculations so that Draw() is as short
// as possible.
TInt xOffset=smileySize.iWidth/4; // x offset from the center
TInt yOffset=(containerHeight - smileySize.iHeight) / 2;
iSmiley1->SetPosition(Position() +
TPoint(containerWidth/2 - smileySize.iWidth - xOffset, yOffset));
iSmiley2->SetPosition(Position() +
TPoint(containerWidth/2 + xOffset, yOffset));
// Calling SetSizeL() causes the components' SizeChanged() to be called.
iSmiley1->SetSize(smileySize);
iSmiley2->SetSize(smileySize);
}
void CSmileyContainer::Draw(const TRect& aRect) const
{
// Just draw a rectangle round the edge of the control.
CWindowGc& gc=SystemGc();
gc.Clear(aRect);
gc.SetClippingRect(aRect);
gc.DrawRect(Rect());
}
// This function is defined by MCoeControlObserver. It gets called whenever
// a control that this control is observing calls ReportEventL().
// In this example, the CSmileyContainer is the observer for both of the
// CSmileys. CCoeControl::ProcessPointerEventL() calls ReportEvent(),
// sending an event of type EEventRequestFocus, whenever an EButton1Down event
// occurs in the CSmiley that doesn't currently have focus.
void CSmileyContainer::HandleControlEventL(CCoeControl* aControl,
TCoeEvent aEventType)
{
switch (aEventType)
{
case EEventRequestFocus:
{
if (aControl->IsFocused())
return;
SwapFocus(aControl);
}
break;
default:
break;
}
}
// This function is called by the framework whenever a component in a dialog is
// about to lose focus. It checks that the data in ithe component is valid. In
// this example, there's a "rule" that both the CSmileys in the container can't
// be miserable! If they are, the function leaves. The framework issues the message
// we give it, and doesn't move focus away from the CSmileyContainer.
void CSmileyContainer::PrepareForFocusLossL()
{
if (!iSmiley1->IsSmiling() && !iSmiley2->IsSmiling())
{
CEikonEnv::Static()->LeaveWithInfoMsg(R_EXAMPLE_TEXT_VALIDATE);
}
}
// This function gets called whenever the application calls SetFocus().
// It redraws the CSmileyContainer, so that they are updated to show
// which one now has focus.
void CSmileyContainer::FocusChanged(TDrawNow aDrawNow)
{
if (IsFocused())
{
iSmiley1->SetFocus(ETrue, EDrawNow);
}
else
{
if (iSmiley1->IsFocused())
iSmiley1->SetFocus(EFalse, EDrawNow);
else
iSmiley2->SetFocus(EFalse, EDrawNow);
}
if (aDrawNow)
DrawNow();
}
void CSmileyContainer::SwapFocus(CCoeControl* aControl)
{
if (aControl==iSmiley1)
{
iSmiley2->SetFocus(EFalse, EDrawNow);
iSmiley1->SetFocus(ETrue, EDrawNow);
}
else
{
iSmiley1->SetFocus(EFalse, EDrawNow);
iSmiley2->SetFocus(ETrue, EDrawNow);
}
}
TKeyResponse CSmileyContainer::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
{
// Use the arrow keys to move focus between the two CSmileys.
switch (aKeyEvent.iScanCode)
{
case EStdKeySpace:
if (iSmiley1->IsFocused())
return iSmiley1->OfferKeyEventL(aKeyEvent, aType);
else if (iSmiley2->IsFocused())
return iSmiley2->OfferKeyEventL(aKeyEvent, aType);
break;
case EStdKeyRightArrow:
if (iSmiley1->IsFocused())
SwapFocus(iSmiley2);
return EKeyWasConsumed;
break;
case EStdKeyLeftArrow:
if (iSmiley2->IsFocused())
SwapFocus(iSmiley1);
return EKeyWasConsumed;
break;
default:
break;
}
// If the CSmileyContainer didn't use the key event, it must return EKeyWasNotConsumed,
// so that the key event is passed to other controls on the stack.
return EKeyWasNotConsumed;
}
//
//
// -----> CSmiley (implementation)
//
//
// CSmiley doesn't need a ConstructL() because it's a simple control.
CSmiley::CSmiley(TBool aSmiling) : iSmiling(aSmiling)
{
}
CSmiley::~CSmiley()
{
}
TBool CSmiley::IsSmiling()
{
return iSmiling;
}
void CSmiley::Draw(const TRect& aRect) const
{
CWindowGc& gc=SystemGc();
if (IsFocused())
{
gc.SetPenColor(KRgbBlack);
}
else
{
gc.SetPenColor(KRgbWhite);
}
gc.SetBrushColor(KRgbWhite);
gc.Clear(Rect());
gc.DrawRect(Rect());
gc.SetClippingRect(aRect);
// Draw the smiley face, smiling or looking sad
gc.SetPenColor(KRgbBlack);
// Draw a circle for the face
gc.DrawEllipse(iSmileyRect);
// Draw the eyes
TPoint leftEye(iSmileyWidth/3, iSmileyHeight/3);
TPoint rightEye(iSmileyWidth*2/3, iSmileyHeight/3);
gc.SetPenSize(TSize(5,5));
gc.Plot(iSmileyRect.iTl+leftEye);
gc.Plot(iSmileyRect.iTl+rightEye);
//Draw the mouth, smiling or looking sad.
gc.SetPenSize(TSize(1,1));
gc.SetPenColor(KRgbWhite);
if (iSmiling)
gc.DrawArc(iFrownRect, iFrownRect.iTl+TPoint(iSmileyWidth/2,iFrownRect.Height()/2),
iFrownRect.iTl+TPoint(0,iFrownRect.Height()/2));
else
gc.DrawArc(iSmileRect, iSmileRect.iTl+TPoint(0,iSmileRect.Height()/2),
iSmileRect.iTl+TPoint(iSmileyWidth/2,iSmileRect.Height()/2));
gc.SetPenColor(KRgbBlack);
if (iSmiling)
gc.DrawArc(iSmileRect, iSmileRect.iTl+TPoint(0,iSmileRect.Height()/2),
iSmileRect.iTl+TPoint(iSmileyWidth/2,iSmileRect.Height()/2));
else
gc.DrawArc(iFrownRect, iFrownRect.iTl+TPoint(iSmileyWidth/2,iFrownRect.Height()/2),
iFrownRect.iTl+TPoint(0,iFrownRect.Height()/2));
}
void CSmiley::SizeChanged()
{
// Calculate sizes of rectangles for drawing face and mouth
iSmileyRect=Rect();
// Allow room for the focus rectangle round the outside
iSmileyRect.Shrink(3,3);
iSmileyWidth=iSmileyRect.Width();
iSmileyHeight=iSmileyRect.Height();
iSmileRect.SetRect(iSmileyRect.iTl+TPoint(iSmileyWidth/4, iSmileyHeight/2),
TSize(iSmileyWidth/2, iSmileyHeight/3));
iFrownRect.SetRect(iSmileyRect.iTl+TPoint(iSmileyWidth/4, iSmileyHeight*2/3),
TSize(iSmileyWidth/2, iSmileyHeight/3));
}
void CSmiley::FocusChanged(TDrawNow aDrawNow)
{
if (aDrawNow)
DrawNow();
}
void CSmiley::HandlePointerEventL(const TPointerEvent& aPointerEvent)
{
if (aPointerEvent.iType==TPointerEvent::EButton1Down)
{
iSmiling = !iSmiling;
DrawNow();
}
}
TKeyResponse CSmiley::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
{
// The space bar changes the "mood" of the CSmiley.
if (aType==EEventKey && aKeyEvent.iScanCode==EStdKeySpace)
{
iSmiling = !iSmiling;
DrawNow();
return EKeyWasConsumed;
}
else
{
return EKeyWasNotConsumed;
}
}
//
//
// -----> CSmileyDialog(implementation)
//
//
TBool CSmileyDialog::RunDlgLD()
{
CEikDialog* dialog = new (ELeave) CSmileyDialog();
return (dialog->ExecuteLD(R_SMILEY_DIALOG));
}
// This function is used by CEikForm::ConstructByTypeL() to create the custom
// control within the dialog.
SEikControlInfo CSmileyDialog::CreateCustomControlL(TInt aControlType)
{
SEikControlInfo controlInfo;
controlInfo.iControl = NULL;
controlInfo.iTrailerTextId = 0;
controlInfo.iFlags = 0;
switch (aControlType)
{
case ESmileyControl:
controlInfo.iControl = new(ELeave) CSmileyContainer;
break;
default:
break;
}
return controlInfo;
}
//
//
// -----> CExampleAppUi (implementation)
//
//
void CExampleAppUi::ConstructL()
{
// Allow base class (CEikAppUi) to perform necessary construction
BaseConstructL();
// Construct the CMainWinControl which forms the main view
// for this application.
iMainWinControl=new(ELeave) CMainWinControl;
iMainWinControl->ConstructL(ClientRect());
// The main window is added to the control stack (for key event
// handling).
AddToStackL(iMainWinControl);
}
CExampleAppUi::~CExampleAppUi()
{
RemoveFromStack(iMainWinControl);
// Delete the main window
delete iMainWinControl;
}
void CExampleAppUi::HandleCommandL(TInt aCommand)
{
// Handle the command generated by:
// 1. menu item selection
// 2. short-cut key press
switch (aCommand)
{
// EXIT comand
case EEikCmdExit:
OnCmdExit();
break;
case ECreateSmileyDialog:
CSmileyDialog::RunDlgLD();
break;
default :
break;
}
}
void CExampleAppUi::OnCmdExit()
{
CBaActiveScheduler::Exit();
}
void CExampleAppUi::HandleModelChangeL()
{
}
/
//
// -----> CExampleDocument (implementation)
//
/
CExampleDocument::CExampleDocument(CEikApplication& aApp)
: CEikDocument(aApp)
{}
CExampleDocument::~CExampleDocument()
{
}
CExampleDocument* CExampleDocument::NewL(CEikApplication& aApp)
{
CExampleDocument* self=new(ELeave) CExampleDocument(aApp);
CleanupStack::PushL(self);
self->CreateModelL();
CleanupStack::Pop();
return self;
}
void CExampleDocument::ResetModelL()
{
CreateModelL();
}
void CExampleDocument::CreateModelL()
{
}
CEikAppUi* CExampleDocument::CreateAppUiL()
{
return(new(ELeave) CExampleAppUi);
}
void CExampleDocument::NewDocumentL()
{
ResetModelL();
}
void CExampleDocument::StoreL(CStreamStore& /*aStore*/,CStreamDictionary& /*aStreamDic*/) const
{
}
void CExampleDocument::RestoreL(const CStreamStore& /*aStore*/,const CStreamDictionary& /*aStreamDic*/)
{
}
//
//
// -----> CExampleApplication (implementation)
//
//
TUid CExampleApplication::AppDllUid() const
{
return(KUidExampleApp);
}
CApaDocument* CExampleApplication::CreateDocumentL()
{
return CExampleDocument::NewL(*this);
}
//
// EXPORTed functions
//
LOCAL_C CApaApplication* NewApplication()
{
return new CExampleApplication;
}
GLDEF_C TInt E32Main()
{
return EikStart::RunApplication(NewApplication);
}
#if defined(__WINS__) && !defined(EKA2)
GLDEF_C TInt E32Dll(TDllReason)
{
return KErrNone;
}
EXPORT_C TInt WinsMain(TDesC* aCmdLine)
{
return EikStart::RunApplication(NewApplication, aCmdLine);
}
#endif
Custom.hrh
// Custom.HRH
//
// Copyright (c) 2000 Symbian Ltd. All rights reserved.
//
//
//
// Definitions
//
// Maximum length of text item on the application data dialog
//
//
#define KExampleMaxlenTextData 16
//
//
// Command ids
// Identify all commands defined by this application.
//
//
//
#define ECreateSmileyDialog 0x800
//
//
// Control ids
// Identify all controls defined and used by this application.
//
//
enum {ESmileyControlIdData};
//
//
// Define the CSmileyContainer control so it can be created as a component in a dialog
//
//
// Assume there are less than 1000 framework controls, and they can't be defined anywhere else.
enum {ESmileyControl=1000};
//
//
// Define the values for the "mood" resource.
//
//
enum TSmileyMood {ESad, EHappy};
Custom.rss
// COSMILEY.RSS
//
// Copyright (c) 1997-1999 Symbian Ltd. All rights reserved.
//
NAME COSM
// Include definitions of resource STRUCTS used by this
// resource script
#include <eikon.rh>
// Include the standard resource ids
#include <eikon.rsg>
// Include the symbol definitions used by C++ code and
// this resource script.
#include <eikon.hrh>
#include "custom.hrh"
#include "custom.rh"
RESOURCE RSS_SIGNATURE
{
}
RESOURCE TBUF { buf=""; } // default document name
RESOURCE EIK_APP_INFO
{
hotkeys=r_example_hotkeys;
menubar=r_example_main_menubar;
}
//
//
// Dialog containing smileys
//
//
RESOURCE DIALOG r_smiley_dialog
{
title="Smileys";
buttons=R_EIK_BUTTONS_CANCEL_OK;
items=
{
DLG_LINE
{
type=ESmileyControl;
id=ESmileyControlIdData;
control=SMILEYCONTROL
{
mood=EHappy;
width=200;
};
}
};
}
//
//
// Short cut keys
//
//
RESOURCE HOTKEYS r_example_hotkeys
{
control=
{
HOTKEY {command=EEikCmdExit; key='e';},
HOTKEY {command=ECreateSmileyDialog; key='d';}
};
}
//
//
// The menu bar
//
//
RESOURCE MENU_BAR r_example_main_menubar
{
titles=
{
MENU_TITLE { menu_pane=r_example_file_menu; txt="File"; }
};
}
//
//
// The "file" menu pane hung directly from the menu bar
//
//
RESOURCE MENU_PANE r_example_file_menu
{
items=
{
MENU_ITEM
{
command=ECreateSmileyDialog;
txt="Create Smiley Dialog";
},
MENU_ITEM
{
command=EEikCmdExit;
txt="Exit";
}
};
}
//
//
// Text resources for info messages
//
//
RESOURCE TBUF r_example_text_validate { buf="They can't both be miserable!";}
Custom.rh
// COSMILEY.RH
//
// Copyright (c) 1997-1999 Symbian Ltd. All rights reserved.
//
STRUCT SMILEYCONTROL
{
BYTE mood=EHappy;
WORD width=300;
}
Custom_reg.rss
#include <appinfo.rh>
UID2 KUidAppRegistrationResourceFile
UID3 0x01000d00 // application UID
RESOURCE APP_REGISTRATION_INFO
{
app_file = "Custom";
}
Bld.inf
// BLD.INF
// Component description file
//
// Copyright (c) 2000 Symbian Ltd. All rights reserved.
PRJ_MMPFILES
Custom.MMP
Custom.mmp
// Custom.MMP
//
// Copyright (c) 2000 Symbian Ltd. All rights reserved.
//
TARGET Custom.exe
TARGETTYPE exe
UID 0x100039ce 0x01000d00
VENDORID 0x70000001
EPOCSTACKSIZE 0x5000
SOURCEPATH .
SOURCE Custom.cpp
START RESOURCE Custom.rss
TARGETPATH /Resource/Apps
HEADER
END
START RESOURCE Custom_reg.rss
TARGETPATH /private/10003a3f/apps
END
USERINCLUDE .
SYSTEMINCLUDE /epoc32/include
SYSTEMINCLUDE /epoc32/include/techview
LIBRARY euser.lib cone.lib apparc.lib bafl.lib
LIBRARY eikcore.lib eikcoctl.lib eikdlg.lib
Description
CustomControls demonstrates customised simple and compound UI Control Framework control classes. Compound controls are used as on-screen containers for other controls, either simple or compound. The custom controls are subclasses of the class CCoeControl, with implementations of its virtual functions for construction, drawing, and accepting user input.
Note that the CustomControls example has dependencies on GUI components that may not be present on all Symbian OS licensee SDKs.
Usage
When the application starts, it displays two smiling faces (smiley) controls. The mood of the smileys can be changed by selecting a smiley using the left/right keys or pointer, and pressing space/clicking. A dialog containing the smiley controls can be started from the application’s menu.
Class summary
All of the examples use the following classes:
*
CCoeControl: control base class, implemented by CSmiley, CSmileyContainer, and CMainWindowControl.
*
MCoeControlObserver: interface class for classes interested in events reported by controls. Implemented by CSmileyContainer.
*
CEikDialog: dialog base class, implemented by CSmileyDialog. This is used to show how controls can be added to dialogs.
*
CEikAppUi, CEikDocument, CEikApplication: application framework base classes. Implemented by CExampleAppUi, CExampleDocument, and CExampleApplication respectively.
//
//
// Copyright (c) 2000 Symbian Ltd. All rights reserved.
//
//
// UI Control Framework example application
//
//这是
//http://www.symbian.com/developer/techlib/v9.2docs/doc_source/examples/coneEx/UICFrameworkExampleCode.guide.html#ApplicationFrameworkEx%2euic%2ecustom
//上的一个例子程序.
#if !defined(__COSMILEY_H__)
#define __COSMILEY_H__
//
//
// Include files containing:(头文件)
//
// 1. Symbol definitions used by C++ code and resource scripts (the *.hrh)
// 2. Resource ids generated by resource compilation of
// resource scripts (the *.rsg)
// 3. Class definitions required by this app (the *.h)
//
//
// 1.
#include <eikon.hrh>
#include "custom.hrh"
// 2.
#include <eikon.rsg>
#include <custom.rsg>
// 3.
#include <eikenv.h>
#include <eikappui.h>
#include <eikproc.h>
#include <eikdialg.h>
#include <eikmenub.h>
#include <eikapp.h>
#include <eikdoc.h>
#include <coeutils.h>
#include <barsread.h>
#include <eikfctry.h>
// The unique identifier for this application.
// NOTE that the number has been arbitrarily chosen for the purpose of
// of the example.
const TUid KUidExampleApp={0x01000d00};
//
//
// -----> CSmileyDialog(definition)
//
//
class CSmileyDialog : public CEikDialog
{
public:
// Construct and run
static TBool RunDlgLD();
private:
SEikControlInfo CreateCustomControlL(TInt aControlType);
};
//
//
// -----> CSmiley (definition)
//
//
class CSmiley : public CCoeControl
{
public:
CSmiley(TBool aSmiling);
~CSmiley();
public:
TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType);
TBool IsSmiling();
private:
void Draw(const TRect& aRect) const;
void SizeChanged();
protected:
void HandlePointerEventL(const TPointerEvent& aPointerEvent);
void FocusChanged(TDrawNow aDrawNow);
private:
TBool iSmiling;
TRect iSmileyRect;
TInt iSmileyWidth;
TInt iSmileyHeight;
TRect iSmileRect;
TRect iFrownRect;
};
//
//
// -----> CSmileyContainer(definition)
//
//
class CSmileyContainer : public CCoeControl,
public MCoeControlObserver
{
public:
// Construction
CSmileyContainer();
void ConstructL(const TRect& aRect);
// Destruction
~CSmileyContainer();
void ConstructFromResourceL(TResourceReader& aReader);
void PrepareForFocusLossL();
TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType);
protected:
void FocusChanged(TDrawNow aDrawNow);
private:
// Virtual, defined by CCoeControl; replaces the default implementation
// provided by CCoeControl.
void Draw(const TRect& aRect) const;
// Virtual, defined by CCoeControl; replaces the default implementation
// provided by CCoeControl.
TInt CountComponentControls() const;
// Virtual, defined by CCoeControl; replaces the default implementation
// provided by CCoeControl.
CCoeControl* ComponentControl(TInt aIndex) const;
// Virtual, defined by CCoeControl; empty implementation provided by
// CCoeControl; full implementation provided by this class
void SizeChanged();
// Defined as pure virtual by the mixin class MCoeControlObserver
// inherited by CCoeControl. An empty implementation provided by
// this class (its containees do not report events).
void HandleControlEventL(CCoeControl* aControl,
TCoeEvent aEventType);
private:
// Member functions defined and used by this class
void SwapFocus(CCoeControl* aControl);
private:
// Data members defined and used by this class.
CSmiley* iSmiley1;
CSmiley* iSmiley2;
};
//
//
// -----> CMainWinControl (definition)
//
//
class CMainWinControl : public CCoeControl
{
public:
CMainWinControl();
~CMainWinControl();
void ConstructL(const TRect& rect);
TInt CountComponentControls() const;
CCoeControl* ComponentControl(TInt aIndex) const;
TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType);
private:
void Draw(const TRect& aRect) const;
private:
CSmileyContainer* iContainer;
};
//
//
// -----> CExampleAppUi (definition)
//
//
class CExampleAppUi : public CEikAppUi
{
public:
// Destruction.
~CExampleAppUi();
public:
// Virtual, defined by CEikAppUi; replaces the implementation
// provided by CEikAppUi.
void ConstructL();
private:
// Virtual, defined by CEikAppUi; empty implementation
// provided by CEikAppUi; full implementation provided
// by this class.
void HandleCommandL(TInt aCommand);
// Virtual, defined by CEikAppUi; empty implementation
// provided by CEikAppUi; full implementation provided
// by this class.
void HandleModelChangeL();
private:
void OnCmdExit();
private:
// Data members defined by this class.
CMainWinControl* iMainWinControl;
};
//
//
// -----> CExampleDocument (definition)
//
//
class CExampleDocument : public CEikDocument
{
public:
// Construction.
static CExampleDocument* NewL(CEikApplication& aApp);
CExampleDocument(CEikApplication& aApp);
// Destruction.
~CExampleDocument();
private:
// Defined as pure virtual by CEikDocument; full implementation
// provided by this class
CEikAppUi* CreateAppUiL(); // Construct an app.user interface
// Defined as pure virtual by CApaDocument; empty implementation
// provided by CEikDocument; full implementation provided
// by this class.
void NewDocumentL(); // Build a new document
// Defined as pure virtual by CApaDocument; empty implementation
// provided by CEikDocument; full implementation provided
// by this class.
void StoreL(CStreamStore& aStore,
CStreamDictionary& aStreamDic
) const;
void RestoreL(const CStreamStore& aStore,
const CStreamDictionary& aStreamDic
);
public:
// Member functions defined by this class
void DoNewFileL(const TFileName& aFileName);
void DoOpenFileL(const TFileName& aFileName);
void DoSaveToNewFileL(const TFileName& aNewFileName);
TBool FileNameExists(const TFileName& aFileName) const;
private:
// Member functions defined by this class
void CreateModelL();
void ResetModelL();
};
//
//
// -----> CExampleApplication (definition)
//
//
class CExampleApplication : public CEikApplication
{
private:
// Defined as pure virtual by CApaApplication; implementation
// provided by this class
TUid AppDllUid() const; // Returns Uid associated with app
// Defined as pure virtual by CEikApplication; implementation
// provided by this class.
CApaDocument* CreateDocumentL(); // Construct new document
};
#endif
Custom.cpp
// CUSTOM.CPP
//
// Copyright (c) 2000 Symbian Ltd. All rights reserved.
//
//
// UI Control Framework example program
//
// This example demonstrates how to write new control classes.
//
// The example creates three new control classes:
// 1. CSmiley - a simple control which displays a
// smiley face that can have two moods,
// happy and sad. The user can change
// the smiley's mood by pressing the
// space bar.
// 2. CSmileyContainer - a compound control which contains
// two CSmiley controls, side by side.
// The user can move the keyboard focus
// from one CSmiley to the other using
// the arrow keys, or the pointer.
// 3. CMainWinControl - a compound control which does nothing
// except act as a background window and a
// container for other controls in the
// application.
//
//
// When the application starts up, it creates a CMainWinControl to cover
// the entire screen, and a CSmileyContainer inside this main window.
// The application's menu contains just two options. One of them closes
// the application; the other creates a dialog which contains a
// CSmileyContainer. CSmileyContainer therefore illustrates how to write
// a control that can be created both in a dialog and within the
// application's main view.
//
#include "custom.h"
#include <eikstart.h>
//
//
// -----> CMainWinControl(implementation)
//
//
CMainWinControl::CMainWinControl()
{
}
CMainWinControl::~CMainWinControl()
{
delete iContainer;
}
// CMainWinControl needs a ConstructL(), because it is a compound control
// (and a window-owning control).
void CMainWinControl::ConstructL(const TRect& rect)
{
// Make this a window-owning control.
CreateWindowL();
SetRect(rect);
// Create its only component, a CSmileyContainer
iContainer = new(ELeave) CSmileyContainer;
iContainer->SetContainerWindowL(*this);
TRect containerRect=Rect();
iContainer->ConstructL(containerRect);
// Activate the main window control - this will also activate the
// CSmileyContainer and its components.
ActivateL();
DrawNow();
}
// The following two functions have to be implemented for all compound controls.
TInt CMainWinControl::CountComponentControls() const
{
return 1;
}
CCoeControl* CMainWinControl::ComponentControl(TInt /*aIndex*/) const
{
return iContainer;
}
// Draw the main window.
void CMainWinControl::Draw(const TRect& /*aRect*/) const
{
CWindowGc& gc=SystemGc();
gc.SetBrushColor(KRgbWhite);
gc.Clear(Rect());
}
// CSmileyContainer can't be put on the control stack, because it's a component of this
// control. The main window control goes on the stack and passes on any key events it gets
// to the CSmileyContainer.
TKeyResponse CMainWinControl::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType)
{
return (iContainer->OfferKeyEventL(aKeyEvent, aType));
}
//
//
// -----> CSmileyContainer (implementation)
//
//
CSmileyContainer::CSmileyContainer()
{}
CSmileyContainer::~CSmileyContainer()
{
// Delete all the contained controls
delete iSmiley1;
delete iSmiley2;
}
// Because CSmileyContainer is a compound control, it needs a
// ConstructL() for when it's created outside a dialog, and a
// ConstructFromResourceL() for when it's created inside a dialog.
void CSmileyContainer::ConstructL(const TRect& aRect)
{
TBool isSmiling=ETrue;
// Create the two CSmileys. Their size and position is
// set in CSmileyContainer::SizeChangedL().
iSmiley1 = new(ELeave) CSmiley(isSmiling);
iSmiley1->SetContainerWindowL(*this);
isSmiling=EFalse;
iSmiley2 = new(ELeave) CSmiley(isSmiling);
iSmiley2->SetContainerWindowL(*this);
iSmiley1->SetFocus(ETrue);
// Set the container as the observer of the two CSmileys. This
// is for handling keyboard focus. When an arrow key is pressed
// or the pointer is clicked on one of the CSmileys, an
// EEventRequestFocus event is sent to the container, and the
// container changes the focus if applicable.
iSmiley1->SetObserver(this);
iSmiley2->SetObserver(this);
// Set the bounding rectangle of this control (this will result in
// a call to SizeChangedL(). The component controls must be
// created before calling this, because SizeChangedL() sets their
// sizes.
SetRect(aRect);
}
// This function is used when the CSmileyContainer is created inside a dialog.
void CSmileyContainer::ConstructFromResourceL(TResourceReader& aReader)
{
// Read the smiley mood from the resource file
TBool isSmiling=(TBool)aReader.ReadInt8();
// Read the width of the smiley container from the resource file.
TInt width=aReader.ReadInt16();
// Set the height of the container to be half its width
TSize containerSize (width, width/2);
iSmiley1 = new(ELeave) CSmiley(isSmiling);
iSmiley1->SetContainerWindowL(*this);
iSmiley2 = new(ELeave) CSmiley(isSmiling);
iSmiley2->SetContainerWindowL(*this);
iSmiley1->SetFocus(ETrue);
iSmiley1->SetObserver(this);
iSmiley2->SetObserver(this);
SetSize(containerSize);
ActivateL();
}
// The following two functions have to be implemented for all compound controls.
TInt CSmileyContainer::CountComponentControls() const
{
return 2;
}
CCoeControl* CSmileyContainer::ComponentControl(TInt aIndex) const
{
if (aIndex==0)
return iSmiley1;
else
return iSmiley2;
}
// This function gets called whenever one of the size-setting functions is called.
// As this is a compound control, this function calculates and sets the size and
// position for its components, based on its own size.
void CSmileyContainer::SizeChanged()
{
TInt containerWidth=Size().iWidth;
TInt containerHeight=Size().iHeight;
// Find half of the greater - width or height
TInt length=containerHeight>containerWidth ? containerWidth/4 : containerHeight/4;
TSize smileySize(length,length);
// Do some preliminary calculations so that Draw() is as short
// as possible.
TInt xOffset=smileySize.iWidth/4; // x offset from the center
TInt yOffset=(containerHeight - smileySize.iHeight) / 2;
iSmiley1->SetPosition(Position() +
TPoint(containerWidth/2 - smileySize.iWidth - xOffset, yOffset));
iSmiley2->SetPosition(Position() +
TPoint(containerWidth/2 + xOffset, yOffset));
// Calling SetSizeL() causes the components' SizeChanged() to be called.
iSmiley1->SetSize(smileySize);
iSmiley2->SetSize(smileySize);
}
void CSmileyContainer::Draw(const TRect& aRect) const
{
// Just draw a rectangle round the edge of the control.
CWindowGc& gc=SystemGc();
gc.Clear(aRect);
gc.SetClippingRect(aRect);
gc.DrawRect(Rect());
}
// This function is defined by MCoeControlObserver. It gets called whenever
// a control that this control is observing calls ReportEventL().
// In this example, the CSmileyContainer is the observer for both of the
// CSmileys. CCoeControl::ProcessPointerEventL() calls ReportEvent(),
// sending an event of type EEventRequestFocus, whenever an EButton1Down event
// occurs in the CSmiley that doesn't currently have focus.
void CSmileyContainer::HandleControlEventL(CCoeControl* aControl,
TCoeEvent aEventType)
{
switch (aEventType)
{
case EEventRequestFocus:
{
if (aControl->IsFocused())
return;
SwapFocus(aControl);
}
break;
default:
break;
}
}
// This function is called by the framework whenever a component in a dialog is
// about to lose focus. It checks that the data in ithe component is valid. In
// this example, there's a "rule" that both the CSmileys in the container can't
// be miserable! If they are, the function leaves. The framework issues the message
// we give it, and doesn't move focus away from the CSmileyContainer.
void CSmileyContainer::PrepareForFocusLossL()
{
if (!iSmiley1->IsSmiling() && !iSmiley2->IsSmiling())
{
CEikonEnv::Static()->LeaveWithInfoMsg(R_EXAMPLE_TEXT_VALIDATE);
}
}
// This function gets called whenever the application calls SetFocus().
// It redraws the CSmileyContainer, so that they are updated to show
// which one now has focus.
void CSmileyContainer::FocusChanged(TDrawNow aDrawNow)
{
if (IsFocused())
{
iSmiley1->SetFocus(ETrue, EDrawNow);
}
else
{
if (iSmiley1->IsFocused())
iSmiley1->SetFocus(EFalse, EDrawNow);
else
iSmiley2->SetFocus(EFalse, EDrawNow);
}
if (aDrawNow)
DrawNow();
}
void CSmileyContainer::SwapFocus(CCoeControl* aControl)
{
if (aControl==iSmiley1)
{
iSmiley2->SetFocus(EFalse, EDrawNow);
iSmiley1->SetFocus(ETrue, EDrawNow);
}
else
{
iSmiley1->SetFocus(EFalse, EDrawNow);
iSmiley2->SetFocus(ETrue, EDrawNow);
}
}
TKeyResponse CSmileyContainer::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
{
// Use the arrow keys to move focus between the two CSmileys.
switch (aKeyEvent.iScanCode)
{
case EStdKeySpace:
if (iSmiley1->IsFocused())
return iSmiley1->OfferKeyEventL(aKeyEvent, aType);
else if (iSmiley2->IsFocused())
return iSmiley2->OfferKeyEventL(aKeyEvent, aType);
break;
case EStdKeyRightArrow:
if (iSmiley1->IsFocused())
SwapFocus(iSmiley2);
return EKeyWasConsumed;
break;
case EStdKeyLeftArrow:
if (iSmiley2->IsFocused())
SwapFocus(iSmiley1);
return EKeyWasConsumed;
break;
default:
break;
}
// If the CSmileyContainer didn't use the key event, it must return EKeyWasNotConsumed,
// so that the key event is passed to other controls on the stack.
return EKeyWasNotConsumed;
}
//
//
// -----> CSmiley (implementation)
//
//
// CSmiley doesn't need a ConstructL() because it's a simple control.
CSmiley::CSmiley(TBool aSmiling) : iSmiling(aSmiling)
{
}
CSmiley::~CSmiley()
{
}
TBool CSmiley::IsSmiling()
{
return iSmiling;
}
void CSmiley::Draw(const TRect& aRect) const
{
CWindowGc& gc=SystemGc();
if (IsFocused())
{
gc.SetPenColor(KRgbBlack);
}
else
{
gc.SetPenColor(KRgbWhite);
}
gc.SetBrushColor(KRgbWhite);
gc.Clear(Rect());
gc.DrawRect(Rect());
gc.SetClippingRect(aRect);
// Draw the smiley face, smiling or looking sad
gc.SetPenColor(KRgbBlack);
// Draw a circle for the face
gc.DrawEllipse(iSmileyRect);
// Draw the eyes
TPoint leftEye(iSmileyWidth/3, iSmileyHeight/3);
TPoint rightEye(iSmileyWidth*2/3, iSmileyHeight/3);
gc.SetPenSize(TSize(5,5));
gc.Plot(iSmileyRect.iTl+leftEye);
gc.Plot(iSmileyRect.iTl+rightEye);
//Draw the mouth, smiling or looking sad.
gc.SetPenSize(TSize(1,1));
gc.SetPenColor(KRgbWhite);
if (iSmiling)
gc.DrawArc(iFrownRect, iFrownRect.iTl+TPoint(iSmileyWidth/2,iFrownRect.Height()/2),
iFrownRect.iTl+TPoint(0,iFrownRect.Height()/2));
else
gc.DrawArc(iSmileRect, iSmileRect.iTl+TPoint(0,iSmileRect.Height()/2),
iSmileRect.iTl+TPoint(iSmileyWidth/2,iSmileRect.Height()/2));
gc.SetPenColor(KRgbBlack);
if (iSmiling)
gc.DrawArc(iSmileRect, iSmileRect.iTl+TPoint(0,iSmileRect.Height()/2),
iSmileRect.iTl+TPoint(iSmileyWidth/2,iSmileRect.Height()/2));
else
gc.DrawArc(iFrownRect, iFrownRect.iTl+TPoint(iSmileyWidth/2,iFrownRect.Height()/2),
iFrownRect.iTl+TPoint(0,iFrownRect.Height()/2));
}
void CSmiley::SizeChanged()
{
// Calculate sizes of rectangles for drawing face and mouth
iSmileyRect=Rect();
// Allow room for the focus rectangle round the outside
iSmileyRect.Shrink(3,3);
iSmileyWidth=iSmileyRect.Width();
iSmileyHeight=iSmileyRect.Height();
iSmileRect.SetRect(iSmileyRect.iTl+TPoint(iSmileyWidth/4, iSmileyHeight/2),
TSize(iSmileyWidth/2, iSmileyHeight/3));
iFrownRect.SetRect(iSmileyRect.iTl+TPoint(iSmileyWidth/4, iSmileyHeight*2/3),
TSize(iSmileyWidth/2, iSmileyHeight/3));
}
void CSmiley::FocusChanged(TDrawNow aDrawNow)
{
if (aDrawNow)
DrawNow();
}
void CSmiley::HandlePointerEventL(const TPointerEvent& aPointerEvent)
{
if (aPointerEvent.iType==TPointerEvent::EButton1Down)
{
iSmiling = !iSmiling;
DrawNow();
}
}
TKeyResponse CSmiley::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
{
// The space bar changes the "mood" of the CSmiley.
if (aType==EEventKey && aKeyEvent.iScanCode==EStdKeySpace)
{
iSmiling = !iSmiling;
DrawNow();
return EKeyWasConsumed;
}
else
{
return EKeyWasNotConsumed;
}
}
//
//
// -----> CSmileyDialog(implementation)
//
//
TBool CSmileyDialog::RunDlgLD()
{
CEikDialog* dialog = new (ELeave) CSmileyDialog();
return (dialog->ExecuteLD(R_SMILEY_DIALOG));
}
// This function is used by CEikForm::ConstructByTypeL() to create the custom
// control within the dialog.
SEikControlInfo CSmileyDialog::CreateCustomControlL(TInt aControlType)
{
SEikControlInfo controlInfo;
controlInfo.iControl = NULL;
controlInfo.iTrailerTextId = 0;
controlInfo.iFlags = 0;
switch (aControlType)
{
case ESmileyControl:
controlInfo.iControl = new(ELeave) CSmileyContainer;
break;
default:
break;
}
return controlInfo;
}
//
//
// -----> CExampleAppUi (implementation)
//
//
void CExampleAppUi::ConstructL()
{
// Allow base class (CEikAppUi) to perform necessary construction
BaseConstructL();
// Construct the CMainWinControl which forms the main view
// for this application.
iMainWinControl=new(ELeave) CMainWinControl;
iMainWinControl->ConstructL(ClientRect());
// The main window is added to the control stack (for key event
// handling).
AddToStackL(iMainWinControl);
}
CExampleAppUi::~CExampleAppUi()
{
RemoveFromStack(iMainWinControl);
// Delete the main window
delete iMainWinControl;
}
void CExampleAppUi::HandleCommandL(TInt aCommand)
{
// Handle the command generated by:
// 1. menu item selection
// 2. short-cut key press
switch (aCommand)
{
// EXIT comand
case EEikCmdExit:
OnCmdExit();
break;
case ECreateSmileyDialog:
CSmileyDialog::RunDlgLD();
break;
default :
break;
}
}
void CExampleAppUi::OnCmdExit()
{
CBaActiveScheduler::Exit();
}
void CExampleAppUi::HandleModelChangeL()
{
}
/
//
// -----> CExampleDocument (implementation)
//
/
CExampleDocument::CExampleDocument(CEikApplication& aApp)
: CEikDocument(aApp)
{}
CExampleDocument::~CExampleDocument()
{
}
CExampleDocument* CExampleDocument::NewL(CEikApplication& aApp)
{
CExampleDocument* self=new(ELeave) CExampleDocument(aApp);
CleanupStack::PushL(self);
self->CreateModelL();
CleanupStack::Pop();
return self;
}
void CExampleDocument::ResetModelL()
{
CreateModelL();
}
void CExampleDocument::CreateModelL()
{
}
CEikAppUi* CExampleDocument::CreateAppUiL()
{
return(new(ELeave) CExampleAppUi);
}
void CExampleDocument::NewDocumentL()
{
ResetModelL();
}
void CExampleDocument::StoreL(CStreamStore& /*aStore*/,CStreamDictionary& /*aStreamDic*/) const
{
}
void CExampleDocument::RestoreL(const CStreamStore& /*aStore*/,const CStreamDictionary& /*aStreamDic*/)
{
}
//
//
// -----> CExampleApplication (implementation)
//
//
TUid CExampleApplication::AppDllUid() const
{
return(KUidExampleApp);
}
CApaDocument* CExampleApplication::CreateDocumentL()
{
return CExampleDocument::NewL(*this);
}
//
// EXPORTed functions
//
LOCAL_C CApaApplication* NewApplication()
{
return new CExampleApplication;
}
GLDEF_C TInt E32Main()
{
return EikStart::RunApplication(NewApplication);
}
#if defined(__WINS__) && !defined(EKA2)
GLDEF_C TInt E32Dll(TDllReason)
{
return KErrNone;
}
EXPORT_C TInt WinsMain(TDesC* aCmdLine)
{
return EikStart::RunApplication(NewApplication, aCmdLine);
}
#endif
Custom.hrh
// Custom.HRH
//
// Copyright (c) 2000 Symbian Ltd. All rights reserved.
//
//
//
// Definitions
//
// Maximum length of text item on the application data dialog
//
//
#define KExampleMaxlenTextData 16
//
//
// Command ids
// Identify all commands defined by this application.
//
//
//
#define ECreateSmileyDialog 0x800
//
//
// Control ids
// Identify all controls defined and used by this application.
//
//
enum {ESmileyControlIdData};
//
//
// Define the CSmileyContainer control so it can be created as a component in a dialog
//
//
// Assume there are less than 1000 framework controls, and they can't be defined anywhere else.
enum {ESmileyControl=1000};
//
//
// Define the values for the "mood" resource.
//
//
enum TSmileyMood {ESad, EHappy};
Custom.rss
// COSMILEY.RSS
//
// Copyright (c) 1997-1999 Symbian Ltd. All rights reserved.
//
NAME COSM
// Include definitions of resource STRUCTS used by this
// resource script
#include <eikon.rh>
// Include the standard resource ids
#include <eikon.rsg>
// Include the symbol definitions used by C++ code and
// this resource script.
#include <eikon.hrh>
#include "custom.hrh"
#include "custom.rh"
RESOURCE RSS_SIGNATURE
{
}
RESOURCE TBUF { buf=""; } // default document name
RESOURCE EIK_APP_INFO
{
hotkeys=r_example_hotkeys;
menubar=r_example_main_menubar;
}
//
//
// Dialog containing smileys
//
//
RESOURCE DIALOG r_smiley_dialog
{
title="Smileys";
buttons=R_EIK_BUTTONS_CANCEL_OK;
items=
{
DLG_LINE
{
type=ESmileyControl;
id=ESmileyControlIdData;
control=SMILEYCONTROL
{
mood=EHappy;
width=200;
};
}
};
}
//
//
// Short cut keys
//
//
RESOURCE HOTKEYS r_example_hotkeys
{
control=
{
HOTKEY {command=EEikCmdExit; key='e';},
HOTKEY {command=ECreateSmileyDialog; key='d';}
};
}
//
//
// The menu bar
//
//
RESOURCE MENU_BAR r_example_main_menubar
{
titles=
{
MENU_TITLE { menu_pane=r_example_file_menu; txt="File"; }
};
}
//
//
// The "file" menu pane hung directly from the menu bar
//
//
RESOURCE MENU_PANE r_example_file_menu
{
items=
{
MENU_ITEM
{
command=ECreateSmileyDialog;
txt="Create Smiley Dialog";
},
MENU_ITEM
{
command=EEikCmdExit;
txt="Exit";
}
};
}
//
//
// Text resources for info messages
//
//
RESOURCE TBUF r_example_text_validate { buf="They can't both be miserable!";}
Custom.rh
// COSMILEY.RH
//
// Copyright (c) 1997-1999 Symbian Ltd. All rights reserved.
//
STRUCT SMILEYCONTROL
{
BYTE mood=EHappy;
WORD width=300;
}
Custom_reg.rss
#include <appinfo.rh>
UID2 KUidAppRegistrationResourceFile
UID3 0x01000d00 // application UID
RESOURCE APP_REGISTRATION_INFO
{
app_file = "Custom";
}
Bld.inf
// BLD.INF
// Component description file
//
// Copyright (c) 2000 Symbian Ltd. All rights reserved.
PRJ_MMPFILES
Custom.MMP
Custom.mmp
// Custom.MMP
//
// Copyright (c) 2000 Symbian Ltd. All rights reserved.
//
TARGET Custom.exe
TARGETTYPE exe
UID 0x100039ce 0x01000d00
VENDORID 0x70000001
EPOCSTACKSIZE 0x5000
SOURCEPATH .
SOURCE Custom.cpp
START RESOURCE Custom.rss
TARGETPATH /Resource/Apps
HEADER
END
START RESOURCE Custom_reg.rss
TARGETPATH /private/10003a3f/apps
END
USERINCLUDE .
SYSTEMINCLUDE /epoc32/include
SYSTEMINCLUDE /epoc32/include/techview
LIBRARY euser.lib cone.lib apparc.lib bafl.lib
LIBRARY eikcore.lib eikcoctl.lib eikdlg.lib
Description
CustomControls demonstrates customised simple and compound UI Control Framework control classes. Compound controls are used as on-screen containers for other controls, either simple or compound. The custom controls are subclasses of the class CCoeControl, with implementations of its virtual functions for construction, drawing, and accepting user input.
Note that the CustomControls example has dependencies on GUI components that may not be present on all Symbian OS licensee SDKs.
Usage
When the application starts, it displays two smiling faces (smiley) controls. The mood of the smileys can be changed by selecting a smiley using the left/right keys or pointer, and pressing space/clicking. A dialog containing the smiley controls can be started from the application’s menu.
Class summary
All of the examples use the following classes:
*
CCoeControl: control base class, implemented by CSmiley, CSmileyContainer, and CMainWindowControl.
*
MCoeControlObserver: interface class for classes interested in events reported by controls. Implemented by CSmileyContainer.
*
CEikDialog: dialog base class, implemented by CSmileyDialog. This is used to show how controls can be added to dialogs.
*
CEikAppUi, CEikDocument, CEikApplication: application framework base classes. Implemented by CExampleAppUi, CExampleDocument, and CExampleApplication respectively.