These examples show how to use the Window Server Client-Side API. Note that these examples create windows directly rather than going through the UI Control Framework, as standard applications would do.
The source files for each example are similiar. They can be found in:
examples\Graphics\WS\BackedUp\
AppHolder.cpp
provides the standard GUI application
framework classes. The only command handling provided is a menu with a
Close
command.
Base.cpp
provides base classes that use the window
server. CWsClient
handles the connection to the window server: it
is an active object that issues a request for window server events, and handles
them in its RunL()
. CWindow
encapsulates a basic
window.
project-name.cpp
provides most of the
code specific to a particular example. Typically, they sub-class
CWsClient
and CWindow
.
// AppHolder.cpp
//
// Copyright (c) 2005 Symbian Softwares Ltd. All rights reserved.
//
#include "AppHolder.h"
#include "BackedUp.h"
#include <EikStart.h>
//
// EXPORTed functions
//
EXPORT_C CApaApplication* NewApplication()
{
return new CAppholderApplication;
}
// updated for 9.1. not conditional as not expected to be used pre 9.1.
GLDEF_C TInt E32Main()
{
return EikStart::RunApplication(NewApplication);
}
////////////////////////////////////////////////////////////////
//
// Application class, CAppholderApplication
//
////////////////////////////////////////////////////////////////
TUid CAppholderApplication::AppDllUid() const
{
return KUidAppholder;
}
CApaDocument* CAppholderApplication::CreateDocumentL()
{
// Construct the document using its NewL() function, rather
// than using new(ELeave), because it requires two-phase
// construction.
return new (ELeave) CAppholderDocument(*this);
}
////////////////////////////////////////////////////////////////
//
// Document class, CAppholderDocument
//
////////////////////////////////////////////////////////////////
// C++ constructor
CAppholderDocument::CAppholderDocument(CEikApplication& aApp)
: CEikDocument(aApp)
{
}
CEikAppUi* CAppholderDocument::CreateAppUiL()
{
return new(ELeave) CAppholderAppUi;
}
CAppholderDocument::~CAppholderDocument()
{
}
////////////////////////////////////////////////////////////////
//
// App UI class, CAppholderAppUi
//
////////////////////////////////////////////////////////////////
void CAppholderAppUi::ConstructL()
{
BaseConstructL();
iClient=CExampleWsClient::NewL(ClientRect());
}
CAppholderAppUi::~CAppholderAppUi()
{
delete iClient;
}
void CAppholderAppUi::HandleCommandL(TInt aCommand)
{
switch (aCommand)
{
case EEikCmdExit:
Exit();
break;
}
}
// Base.CPP
//
// Copyright (c) 2005 Symbian Softwares Ltd. All rights reserved.
//
#include <w32std.h>
#include "Base.h"
///////////////////////////////////////////////////////////////////////////////
// CWindow implementation
///////////////////////////////////////////////////////////////////////////////
CWindow::CWindow(CWsClient* aClient)
: iClient(aClient)
{
}
void CWindow::ConstructL (const TRect& aRect, const TRgb& aColor, CBackedUpWindow* aParent)
{
_LIT(KFontName,"Swiss");
// If a parent window was specified, use it; if not, use the window group
// (aParent defaults to 0).
RWindowTreeNode* parent= aParent ? (RWindowTreeNode*) &(aParent->Window()) : &(iClient->iGroup);
// Allocate and construct the window
iWindow=RWindow(iClient->iWs);
User::LeaveIfError(iWindow.Construct(*parent, (TUint32)this));
// Store the window's extent
iRect = aRect;
// Set up the new window's extent
User::LeaveIfError(iWindow.SetExtentErr(iRect.iTl, iRect.Size()));
// Set its background color
iWindow.SetBackgroundColor (aColor);
// Set pointer grab to enable drag and drop
iWindow.SetPointerGrab (ETrue);
// Set up font for displaying text
TFontSpec fontSpec(KFontName,200);
User::LeaveIfError(iClient->iScreen->GetNearestFontInTwips(iFont,fontSpec));
// Activate the window
iWindow.Activate();
}
CWindow::~CWindow()
{
iWindow.FreePointerMoveBuffer();
iWindow.Close();
iClient->iScreen->ReleaseFont(iFont);
}
RWindow& CWindow::Window()
{
return iWindow;
}
CWindowGc* CWindow::SystemGc()
{
return iClient->iGc;
}
CWsScreenDevice* CWindow::Screen()
{
return iClient->iScreen;
}
CFont* CWindow::Font()
{
return iFont;
}
/////////////////////////////////////////////////////////////////////////
CBackedUpWindow::CBackedUpWindow(CWsClient* aClient)
: iClient(aClient)
{
}
void CBackedUpWindow::ConstructL (const TRect& aRect, CWindow* aParent)
{
_LIT(KFontName,"Swiss");
// If a parent window was specified, use it; if not, use the window group
// (aParent defaults to 0).
RWindowTreeNode* parent= aParent ? (RWindowTreeNode*) &(aParent->Window()) : &(iClient->iGroup);
// Allocate and construct the window
iWindow=RBackedUpWindow(iClient->iWs);
User::LeaveIfError(iWindow.Construct(*parent, EGray4, (TUint32)this));
// Store the window's extent
iRect = aRect;
// Set up the new window's extent
User::LeaveIfError(iWindow.SetExtentErr(iRect.iTl, iRect.Size()));
// Set its background color
iWindow.AllocPointerMoveBuffer(KPointerMoveBufferSize, 0);
iWindow.DisablePointerMoveBuffer();
iWindow.PointerFilter(EPointerFilterDrag, 0);
// Set pointer grab to enable drag and drop
iWindow.SetPointerGrab (ETrue);
// Set up font for displaying text
TFontSpec fontSpec(KFontName,200);
User::LeaveIfError(iClient->iScreen->GetNearestFontInTwips(iFont,fontSpec));
// Activate the window
iWindow.Activate();
}
CBackedUpWindow::~CBackedUpWindow()
{
iWindow.Close();
iClient->iScreen->ReleaseFont(iFont);
}
RBackedUpWindow& CBackedUpWindow::Window()
{
return iWindow;
}
CWindowGc* CBackedUpWindow::SystemGc()
{
return iClient->iGc;
}
CWsScreenDevice* CBackedUpWindow::Screen()
{
return iClient->iScreen;
}
CFont* CBackedUpWindow::Font()
{
return iFont;
}
///////////////////////////////////////////////////////////////////////////////
// CWsRedrawer implementation
///////////////////////////////////////////////////////////////////////////////
CWsRedrawer::CWsRedrawer()
: CActive(CActive::EPriorityLow)
{
}
void CWsRedrawer::ConstructL(CWsClient* aClient)
{
iClient=aClient; // remember WsClient that owns us
CActiveScheduler::Add(this); // add ourselves to the scheduler
IssueRequest(); // issue request to draw
}
CWsRedrawer::~CWsRedrawer()
{
Cancel();
}
void CWsRedrawer::IssueRequest()
{
iClient->iWs.RedrawReady(&iStatus);
SetActive();
}
void CWsRedrawer::DoCancel()
{
iClient->iWs.RedrawReadyCancel();
}
void CWsRedrawer::RunL()
{
// find out what needs to be done in response to the event
TWsRedrawEvent redrawEvent;
iClient->iWs.GetRedraw(redrawEvent); // get event
CWindow* window=(CWindow*)(redrawEvent.Handle()); // get window
if (window)
{
TRect rect=redrawEvent.Rect(); // and rectangle that needs redrawing
// now do drawing
iClient->iGc->Activate(window->Window());
window->Window().BeginRedraw(rect);
window->Draw(rect);
window->Window().EndRedraw();
iClient->iGc->Deactivate();
}
// maintain outstanding request
IssueRequest();
}
/////////////////////////////////////////////////////////////////////////////////////
// CWsClient implementation
/////////////////////////////////////////////////////////////////////////////////////
CWsClient::CWsClient()
: CActive(CActive::EPriorityStandard)
{
}
void CWsClient::ConstructL()
{
// add ourselves to active scheduler
CActiveScheduler::Add(this);
// get a session going
User::LeaveIfError(iWs.Connect());
// construct our one and only window group
iGroup=RWindowGroup(iWs);
User::LeaveIfError(iGroup.Construct(2,ETrue)); // '2' is a meaningless handle
// construct screen device and graphics context
iScreen=new (ELeave) CWsScreenDevice(iWs); // make device for this session
User::LeaveIfError(iScreen->Construct()); // and complete its construction
User::LeaveIfError(iScreen->CreateContext(iGc)); // create graphics context
// construct redrawer
iRedrawer=new (ELeave) CWsRedrawer;
iRedrawer->ConstructL(this);
// construct main window
ConstructMainWindowL();
// request first event and start scheduler
IssueRequest();
}
CWsClient::~CWsClient()
{
// neutralize us as an active object
Deque(); // cancels and removes from scheduler
// get rid of everything we allocated
delete iGc;
delete iScreen;
delete iRedrawer;
// destroy window group
iGroup.Close(); // what's the difference between this and destroy?
// finish with window server
iWs.Close();
}
void CWsClient::IssueRequest()
{
iWs.EventReady(&iStatus); // request an event
SetActive(); // so we're now active
}
void CWsClient::DoCancel()
{
iWs.EventReadyCancel(); // cancel event request
}
void CWsClient::ConstructMainWindowL()
{
}