Copy Link
Add to Bookmark
Report
5x01 Writing Basic Symbian Application
...................
...::: phearless zine #5 :::...
...............>---[ Writing Basic Symbian Application ]---<................
...........................>---[ by argv ]---<..............................
argv[at]gmail[dot]com
Sadrzaj:
[1] Starting
[2] Sources
[3] Headers
[4] Project Group
[5] Compiled
////////////////////////////////////////////////////////////////////////////
--==<[ 1. Starting
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
U ovom tutoru cu vam pokazati kako da napisete kostur za bilo koju
aplikaciju. Ovaj kostur mozete koristiti za neke projekte koje cete kasnije
raditi jer koristi sve potrebno za basic app. Sekcije sam podijelio po
folderima koje projekt treba sadrzavati tako da se lako mozete snaci ako
vam nesto kasnije zatreba. Ako ovaj app pisete rucno, morat cete staviti
neke prefixe u sufixe u ime sourcea i headera, a ako koristite neko okruzje
koje vec ima predefinirane, onda netrebate. Iako ta okruzja su uglavnom
potpuno nepotrebna jer stvaraju dosta stvari koje uopce nisu potrebne i samo
"zagusuju" foldere projekata.
////////////////////////////////////////////////////////////////////////////
--==<[ 1. Sources
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
Napravite folder "MyApp" i unutar tog foldera napravite slijedeca 4:
src, inc, group i sis. Sve .cpp fajlove stavljate u src folder, headere u
inc folder, compile info u group dok se compilani fajlovi buildaju u sis.
Zapocet cemo sa osnovnim sourceom koji ce sluziti kao handle za pozivanje
svih ostalih. Nazovimo ga MyApp.cpp i unutra stavimo:
--
// MyApp.cpp
#include "MyApp.h"
// entry point za DLL
GLDEF_C TInt E32Dll(TDllReason)
{
return KErrNone;
}
// napravi aplikaciju i pointaj
EXPORT_C CApaApplication* NewApplication()
{
return (new CMyApp);
}
--
Ovaj kostur se koristi startanje 95% aplikacija, i uvijek ga mozete koristiti.
Postoji jos nekoliko metoda, ali sve se svodi na isto, a ovaj je najjednostavniji.
Sada moramo napraviti UID i pointer na "document" file od naseg projekta.
UID ce se u vecini slucajeva sam generirati pa nije potrebno mozgati oko njega.
Potrebno je staviti nesto samo pre-compile, a ostalo ce compiler sam napravit.
Ovaj source ce se zvati "MyAppapplication.cpp".
--
// MyApplication.cpp
#include "MyAppDocument.h"
#include "MyAppApplication.h"
// UID za app
static const TUid KUidMyApp = {0x1000000};
CApaDocument* CMyAppApplication::CreateDocumentL()
{
// stvaranje documenta i pointanje
CApaDocument* document = CMyAppDocument::NewL(*this);
return document;
}
TUid CMyAppApplication::AppDllUid() const
{
// vracanje UIDa za app
return KUidMyApp;
}
--
Naravno, aplikacija mora imati i neki UI. Koristit cemo osnovni UI koji
nam SDK pruza. Ako bas zelite neki fancy UI onda ce vam okruzja prilagodjena
za to pomoci, ali kome to treba? :) Slijedeci source cemo nazvati "MyAppUi.cpp".
Koristimo Avkon UI i Avkon wrappere. Source od menua koristi varijable iz
resource fajlova, ali o tome nesto kasnije.
--
// MyAppUi.cpp
#include <avkon.hrh>
#include <aknnotewrappers.h>
#include "MyApp.pan"
#include "MyAppUi.h"
#include "MyAppView.h"
#include "MyApp.hrh"
// ConstructL - pokretanje aplikacije (Avkon)
void CMyAppAppUi::ConstructL()
{
BaseConstructL();
iAppView = CMyAppView::NewL(ClientRect());
AddToStackL(iAppView);
}
CMyAppUi::CMyAppUi()
{
// ne radimo nikakve fancy stvari pa nam ovo netreba
}
CMyAppUi::~CMyAppUi()
{
if (iAppView)
{
RemoveFromStack(iAppView);
delete iAppView;
iAppView = NULL;
}
}
// nas menu
void CMyAppAppUi::HandleCommandL(TInt aCommand)
{
switch(aCommand)
{
case EEikCmdExit:
case EAknSoftkeyExit:
Exit();
break;
case EMyAppCommand1:
{
_LIT(message,"MyApp Message :)");
CAknInformationNote* informationNote = new (ELeave) CAknInformationNote;
informationNote->ExecuteLD(message);
}
break;
default:
Panic(EMyAppBasicUi);
break;
}
}
--
Slijedece cemo pokazati nas interface. U proslom sourceu smo ga izgradili.
Takodjer cemo koristiti Avkon, ali ovaj put moramo koristiti i interne kontrole
iz coemain.h (ala buttoni i stuff u Win32). Nazovimo ovaj fajl "MyAppView.cpp".
--
// MyAppView.cpp
#include <coemain.h>
#include "MyAppView.h"
// standardna izgradnja iz Avkona - uvijek ovo mozete koristiti
CMyAppView* CMyAppView::NewL(const TRect& aRect)
{
CMyAppView* self = CMyAppView::NewLC(aRect);
CleanupStack::Pop(self);
return self;
}
CMyAppView* CMyAppView::NewLC(const TRect& aRect)
{
CMyAppView* self = new (ELeave) CMyAppView;
CleanupStack::PushL(self);
self->ConstructL(aRect);
return self;
}
CMyAppView::CMyAppView()
{
// ovo je za fancy UI, nama netreba
}
CMyAppView::~CMyAppView()
{
// isto
}
void CMyAppView::ConstructL(const TRect& aRect)
{
// stvaranje prvog prozora
CreateWindowL();
// velicina prozora (ovo se automatski generira)
SetRect(aRect);
// aktivacija prozora
ActivateL();
}
// pokazivanje naseg prozora na zaslonu
void CMyAppView::Draw(const TRect&) const
{
// standardna grafika iz coe.h kontrola
CWindowGc& gc = SystemGc();
TRect rect = Rect();
// clear za ciscenje messagea
gc.Clear(rect);
}
--
I zadnje sto name je potrebno je dokument. Ovo je mandatorno jer koristi
Symbianove construct metode i program se nece pokrenuti bez toga. Nazovimo fajl
"MyAppDocument.cpp"
--
// MyAppDocument.cpp
#include "MyAppUi.h"
#include "MyAppDocument.h"
// pokretanje bilo koje Symbian aplikacije
CMyAppDocument* CMyAppDocument::NewL(CEikApplication& aApp)
{
CMyAppDocument* self = NewLC(aApp);
CleanupStack::Pop(self);
return self;
}
CMyAppDocument* CMyAppDocument::NewLC(CEikApplication& aApp)
{
CMyAppDocument* self = new (ELeave) CMyAppDocument(aApp);
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
void CMyAppDocument::ConstructL()
}
}
CMyAppDocument::CMyAppDocument(CEikApplication& aApp) : CAknDocument(aApp)
{
}
CMyAppDocument::~CMyAppDocument()
{
}
CEikAppUi* CMyAppDocument::CreateAppUiL()
{
// stvaranje interfacea
CEikAppUi* appUi = new (ELeave) CMyAppAppUi;
return appUi;
}
--
////////////////////////////////////////////////////////////////////////////
--==<[ 3. Headers
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
Headere stavljate u inc folder. Prvo cemo napraviti resource fajlove
koje ce nas interface koristit. Napravite fajl "MyApp.hrh" i ubacite unutra:
--
// MyApp.hrh
#ifndef __MyApp_HRH__
#define __MyApp_HRH__
enum TMyAppIds
{
EMyAppCommand1 = 1
};
#endif
--
Zatim napravite fajl "MyApp.pan" (panic modul) i ubacite:
--
// MyApp.pan
#ifndef __MyApp_PAN__
#define __MyApp_PAN__
enum TMyAppPanics
{
EMyAppBasicUi = 1
};
inline void Panic(TMyAppPanics aReason)
{
_LIT(applicationName,"MyApp Message :)");
User::Panic(applicationName, aReason);
}
#endif
--
Sada krecemo sa headerima. Headeri nece koristi nista svemirsko =) nego
najobicnije callove iz vec predefiniranih Symbianovih fajlova. Moramo napraviti
header za svaki source u kojem smo ga zvali. Pocet cemo sa "MyAppApplication.h":
--
// MyAppApplication.h
#ifndef __MyApp_APPLICATION_H__
#define __MyApp_APPLICATION_H__
#include <aknapp.h>
class CMyAppApplication : public CAknApplication
{
public:
TUid AppDllUid() const;
protected:
CApaDocument* CreateDocumentL();
};
#endif
--
Zatim idemo na "MyAppUi.h":
--
// MyAppUi.h
#ifndef __MyApp_UI_H__
#define __MyApp_UI_H__
#include <aknappui.h>
class CMyAppAppView;
class CMyAppAppUi : public CAknAppUi
{
public:
void ConstructL();
CMyAppAppUi();
~CMyAppAppUi();
public:
void HandleCommandL(TInt aCommand);
private:
CMyAppAppView* iAppView;
};
#endif
--
Slijedece dolaze coe.h kontrole (iscrtavanje prozora). "MyAppView.h":
--
// MyAppView.h
#ifndef __MyApp_VIEW_H__
#define __MyApp_VIEW_H__
#include <coecntrl.h>
class CMyAppAppView : public CCoeControl
{
public:
static CMyAppAppView* NewL(const TRect& aRect);
static CMyAppAppView* NewLC(const TRect& aRect);
~CMyAppAppView();
public:
void Draw(const TRect& aRect) const;
private:
void ConstructL(const TRect& aRect);
CMyAppAppView();
};
#endif
--
I zadnje nam je ostalo "MyAppDocument.h":
--
// MyAppDocument.h
#ifndef __MyApp_DOCUMENT_H__
#define __MyApp_DOCUMENT_H__
#include <akndoc.h>
class CMyAppAppUi;
class CEikApplication;
class CMyAppDocument : public CAknDocument
{
public:
static CMyAppDocument* NewL(CEikApplication& aApp);
static CMyAppDocument* NewLC(CEikApplication& aApp);
~CMyAppDocument();
public:
CEikAppUi* CreateAppUiL();
private:
void ConstructL();
CMyAppDocument(CEikApplication& aApp);
};
#endif
////////////////////////////////////////////////////////////////////////////
--==<[ 4. Project Group
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
Da bi uspjesno compilali program, potrebno je napraviti grupe koje ce
compiler koristit da bi pronasao fajlove potrebne za compile. Prvo napravite
fajl "bld.inf" i unutra ubacite:
--
// bld.inf
PRJ_MMPFILES
MyApp.mmp
--
Ovo nam sluzi kao pointer compileru da koristi informacije iz MyApp.mmp
fajla. Zatim napravite "MyApp.mmp" file koji ce sadrzavati pathove do nasih
fajlova i instrukcije gdje i sta da compiler napravit.
--
// MyApp.mpp
TARGET MyApp.app
TARGETTYPE app
UID 0x10000000 0x10000001
TARGETPATH \system\apps\myapp
LANG SC
SOURCEPATH ..\src
SOURCE MyApp.cpp
SOURCE MyAppApplication.cpp
SOURCE MyAppAppView.cpp
SOURCE MyAppAppUi.cpp
SOURCE MyAppDocument.cpp
SOURCEPATH ..\group
RESOURCE MyApp.rss
USERINCLUDE ..\inc
SYSTEMINCLUDE \epoc32\include
LIBRARY euser.lib
LIBRARY apparc.lib
LIBRARY cone.lib
LIBRARY eikcore.lib
LIBRARY avkon.lib
--
Jos nam je samo potreban resource fajl. Nazovimo da "MyApp.rss":
--
// MyApp.rss
NAME MAPP
#include <eikon.rh>
#include <eikon.rsg>
#include <avkon.rh>
#include <avkon.rsg>
#include "MyApp.hrh"
RESOURCE RSS_SIGNATURE { }
RESOURCE TBUF r_default_document_name { buf=""; }
RESOURCE EIK_APP_INFO
{
menubar = r_MyApp_menubar;
cba = R_AVKON_SOFTKEYS_OPTIONS_EXIT;
}
RESOURCE MENU_BAR r_MyApp_menubar
{
titles =
{
MENU_TITLE {menu_pane = r_MyApp_menu;}
};
}
RESOURCE MENU_PANE r_MyApp_menu
{
items =
{
MENU_ITEM {command = EMyAppCommand1; txt = "Start";},
MENU_ITEM {command = EAknSoftkeyExit; txt = "Exit";}
};
}
--
////////////////////////////////////////////////////////////////////////////
--==<[ 5. Compiled
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
U sis folderu napravite file "MyApp.pkg" koji ce posluziti kao pointer
gdje se i koji fajlovi trebaju compilati:
--
// MyApp.pkg
&EN
#{"MyApp"},(0x10000000),1,0,0
(0x101F6F88), 0, 0, 0, {"Series60ProductID"}
"..\..\..\epoc32\release\thumb\urel\MyApp.APP"-"C:\system\apps\MyApp\MyApp.app"
"..\..\..\epoc32\release\thumb\urel\MyApp.rsc"-"C:\system\apps\MyApp\MyApp.rsc"
--
Nakon compilea dobit cete MyApp.app i MyApp.rsc. Napravite direktorij na
telefonu na C:\system\apps\MyApp\ i kopirajte ta 2 filea unutra. U glavnom
meniju ce se pokazati MyApp s ikonom puzzle i kad ga pokrenete dobit cete
osnovni interface sa 2 opcije - Start i Exit. Start ispisuje message dok Exit
izlazi (d0h=).