Drawing to the screen outside application framework
Article Metadata
The CWindowDrawer class illustrates how to construct a drawable screen outside the standard application framework. You usually use this kind of code when constructing a background server that normally needs to be hidden and only requires an UI in some parts of its operations.
As with this example the CWindowDrawer will not take focus which means that the current focused application still receives all key input. To disable this call the EnableReceiptOfFocus() method with ETrue.
For key catching you can also use CKeyCapturer
The active object implementation used in this example uses RWsSession's RedrawReady() method to receive redraw events. To get your own drawing code into it you only need to change the content of the Draw() method.
Also if you don't want to take the whole screen for your window you can change the values given in iWindow's SetExtent() method inside the ConstructL() method.
Library required:
LIBRARY gdi.lib //CFont
LIBRARY ws32.lib //RWindowGroup ,CWsScreenDevice, CWindowGc
LIBRARY apgrfx.lib //CApaWindowGroupName
WindowDrawer.cpp
#include <apgwgnam.h> //CApaWindowGroupName
#include "WindowDrawer.h"
#include <coedef.h> //for ECoeWinPriorityAlwaysAtFront
CWindowDrawer* CWindowDrawer::NewL(void)
{
CWindowDrawer* self = CWindowDrawer::NewLC(void);
CleanupStack::Pop(self);
return self;
}
CWindowDrawer* CWindowDrawer::NewLC(void)
{
CWindowDrawer* self = new (ELeave) CWindowDrawer(void);
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
// the active object priority should be relatively low
CWindowDrawer::CWindowDrawer(void):CActive(EPriorityLow)
{
}
CWindowDrawer::~CWindowDrawer()
{
Cancel();
if(iMyFont)
{
iScreenDevice->ReleaseFont(iMyFont);
iMyFont = NULL;
}
delete iWindowGc;
iWindowGc = NULL;
delete iScreenDevice;
iScreenDevice = NULL;
iWindow.Close();
iWindowGroup.Close();
iWsSession.Close();
}
void CWindowDrawer::ConstructL(void)
{
CActiveScheduler::Add(this);
User::LeaveIfError(iWsSession.Connect());
iScreenDevice=new (ELeave) CWsScreenDevice(iWsSession);
User::LeaveIfError(iScreenDevice->Construct());
User::LeaveIfError(iScreenDevice->CreateContext(iWindowGc));
TFontSpec MyeFontSpec (KFontArial, 12*15);
MyeFontSpec.iTypeface.SetIsProportional(ETrue);
User::LeaveIfError(iScreenDevice->GetNearestFontInTwips(iMyFont,MyeFontSpec));
iWindowGroup=RWindowGroup(iWsSession);
User::LeaveIfError(iWindowGroup.Construct((TUint32)&iWindowGroup, EFalse));
// iWindowGroup.SetOrdinalPosition(0,ECoeWinPriorityNormal);
iWindowGroup.SetOrdinalPosition(0,ECoeWinPriorityAlwaysAtFront);
iWindowGroup.EnableReceiptOfFocus(EFalse);
CApaWindowGroupName* winGroupName=CApaWindowGroupName::NewLC(iWsSession);
winGroupName->SetHidden(ETrue);
winGroupName->SetWindowGroupName(iWindowGroup);
CleanupStack::PopAndDestroy();
iWindow=RWindow(iWsSession);
User::LeaveIfError(iWindow.Construct(iWindowGroup, (TUint32)&iWindow));
TPixelsTwipsAndRotation SizeAndRotation;
iScreenDevice->GetDefaultScreenSizeAndRotation(SizeAndRotation);
iWindow.Activate();
iWindow.SetExtent(TPoint(0,0),SizeAndRotation.iPixelSize);
iWindow.SetBackgroundColor(KRgbBlue);
// iWindow.SetOrdinalPosition(0,ECoeWinPriorityNormal);
iWindow.SetOrdinalPosition(0, ECoeWinPriorityAlwaysAtFront);
iWindow.SetNonFading(ETrue);
iWindow.SetVisible(ETrue);
Draw();
iWsSession.RedrawReady(&iStatus);
SetActive();
}
void CWindowDrawer::RunL()
{
if (iStatus != KErrCancel)
{
TWsRedrawEvent e;
iWsSession.GetRedraw(e);
// if Windows Server does not want a redraw the window handle is 0
if (e.Handle() != 0)
{
// draw our only window
Draw();
}
iWsSession.RedrawReady(&iStatus);
SetActive();
}
}
void CWindowDrawer::Draw(void)
{
iWindowGc->Activate(iWindow);
TRect DrwRect(TPoint(0,0), iWindow.Size());
iWindow.Invalidate(DrwRect);
iWindow.BeginRedraw();
iWindowGc->Clear(DrwRect);
if(iMyFont)
{
iWindowGc->UseFont(iMyFont);
TInt StartY ((DrwRect.Height() - iMyFont->HeightInPixels()) / 2);
iWindowGc->DrawText(KtxHelloThere,TRect(0,StartY,DrwRect.Width(),(StartY + iMyFont->HeightInPixels())),iMyFont->AscentInPixels(), CGraphicsContext::ECenter, 0);
}
iWindow.EndRedraw();
iWindowGc->Deactivate();
iWsSession.Flush();
}
void CWindowDrawer::DoCancel()
{
iWsSession.RedrawReadyCancel();
}
WindowDrawer.h
#include <gdi.h> // CFont
#include <w32std.h> //RWindowGroup, CWsScreenDevice, CWindowGc
_LIT(KtxHelloThere ,"Hi there !");
_LIT(KFontArial ,"Arial");
class CWindowDrawer : public CActive
{
public:
static CWindowDrawer* NewL(void);
static CWindowDrawer* NewLC(void);
~CWindowDrawer();
protected:
void DoCancel();
void RunL();
private:
CWindowDrawer();
void ConstructL(void);
void Draw(void);
private:
RWsSession iWsSession;
CWindowGc* iWindowGc;
CWsScreenDevice* iScreenDevice;
RWindowGroup iWindowGroup;
RWindow iWindow;
CFont* iMyFont;
};
Related Links:
- How to get ReDraw event in exe from window server?
- How to capture Keyevents in thread or exe
- Archived:How to launch an Exe and pass command line arguments
- How to start EXE from an EXE in 3rd Edition
- Archived:Displaying UI controls in Symbian console exe programs
- How to use graphics in a non-GUI Symbian exe


(no comments yet)