首 页 | 新 闻 | Symbian | Android| Windows Mobile | J2ME | 下载中心 | 游戏策划招聘与求职 | 购书指南 | 视频教程
您现在的位置: 开发视界 >> Symbian >> Symbian开发 >> 正文
关于exe形式编程的一点心得(下)
作者:allyfeng    文章来源:Nokia论坛    更新时间:2006-1-4 15:58:27
4.如何防止exe运行多个实例
和app不同的是,exe可以运行多个实例,在某些情况下,这是有用的。但是如果我们不需要这个特性,那么如何才能阻止exe运行多个实例以减少资源占用呢?这就需要用TFindProcess。
将MainL写成:
Code:
LIT(KPROCESSNAME, "MyExe*");  // 线程名称
void MainL()
{
CActiveScheduler* scheduler = new(ELeave) CActiveScheduler();
CleanupStack::PushL(scheduler);
CActiveScheduler::Install(scheduler);

// 寻找符合条件的线程
TInt pcount = 0;
TFullName processName;
TFindProcess findProcess(KPROCESSNAME);
while (ETrue)
{
findProcess.Next(processName);
if (processName != KNullDesC)
{
pcount ++;
CONSOLEPRINTINFO(processName);
}
else
break;
}

if (pcount <= 1) // 只有本线程运行
{
// 具体的处理
// ......
}

CONSOLEPRINTINFO(_L("Exe End"));
CleanupStack::PopAndDestroy(scheduler);
}
注意,KPROCESSNAME是线程主名称,后面*是一个通佩符,因为具体的线程名称后面还跟着一串数字,我们只要定位前面的关键字就可以了。
这里判断线程的数量用了 if (pcount <= 1),而不是<1,因为当前在做判断的线程也算一个。
当发现有其他相同的线程在运行时,本线程就跳过具体的处理,直接结束了。这样就达到了我们的目的。
5. 如何让exe程序显示信息窗口
exe是后台的程序,通常是没有窗口界面的,但是我们有时候需要让使用者获得一些信息。比如一个闹钟提醒程序,平时在后台运行,到时间后除了要播放闹铃,可能还需要在屏幕上显示一些用户预先设置的提示信息,如"XXX生日"之类的。这时候就需要来构造一个窗口。
Code:
// ================= Start of Window.h =======================
//

#if !defined(__MY_WINDOW_H__)
#define __MY_WINDOW_H__

class CWindow;

/////////////////////////////////////////////////////////////////////////
////////////////////// Declaration of CWsClient /////////////////////////
/////////////////////////////////////////////////////////////////////////

// Base class for all windows
class CWsClient : public CActive
{
protected:
//construct
CWsClient(const TRect& aRect);

public:
static CWsClient* NewL(const TRect& aRect);
void ConstructL();
// destruct
~CWsClient();

public:
// terminate cleanly
void Exit();
// active object protocol
void IssueRequest(); // request an event
void DoCancel(); // cancel the request

virtual void RunL(); // handle completed request

private:
CWsScreenDevice* iScreen;
CWindowGc* iGc;

CWindow *iWindow;

RWsSession iWs;
RWindowGroup iGroup;

const TRect& iRect;

friend class CWindow; // needs to get at session
};

//////////////////////////////////////////////////////////////////////////////
///////////////////////// CWindow declaration ////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

class CWindow : public CBase
{
public:
CWindow(CWsClient* aClient);
void ConstructL (const TRect& aRect);
~CWindow();

public:
// access
RWindow& Window(); // our own window
// drawing
void Draw(const TRect& aRect);

private:
CWindowGc* SystemGc(); // system graphics context

private:
RWindow iWindow; // window server window
TRect iRect; // rectangle re owning window
private:
CWsClient* iClient; // client including session and group
};

#endif  // __MY_WINDOW_H__

// ================= End of Window.h =======================



// ================= Start of Window.cpp =======================
// Window.cpp
//

#include <w32std.h>
#include <coedef.h>
#include "Window.h"

///////////////////////////////////////////////////////////////////////////////
////////////////////////// CWindow implementation /////////////////////////////
///////////////////////////////////////////////////////////////////////////////

CWindow::CWindow(CWsClient* aClient)
: iClient(aClient)
{
}

void CWindow::ConstructL (const TRect& aRect)
{
// Use the window group for parent window
RWindowTreeNode* parent= &(iClient->iGroup);
iWindow=RWindow(iClient->iWs); // use app's session to window server
User::LeaveIfError(iWindow.Construct(*parent,(TUint32)this));
iRect = aRect;
iWindow.SetExtent(iRect.iTl, iRect.Size()); // set extent relative to group coords
iWindow.Activate(); // window is now active
}

CWindow::~CWindow()
{
iWindow.Close(); // close our window
}

RWindow& CWindow::Window()
{
return iWindow;
}

CWindowGc* CWindow::SystemGc()
{
return iClient->iGc;
}

/****************************************************************************\
| Function: CWindow::Draw
| Purpose: Redraws the contents of CSmallWindow within a given
| rectangle.  CSmallWindow displays a square border around
| the edges of the window, and two diagonal lines between the
| corners.
| Input: aRect Rectangle that needs redrawing
| Output: None
\****************************************************************************/
void CWindow::Draw(const TRect& aRect)
{
// Drawing to a window is done using functions supplied by
// the graphics context (CWindowGC), not the window.
CWindowGc* gc = SystemGc(); // get a gc
gc->SetClippingRect(aRect); // clip outside this rect
gc->Clear(aRect); // clear
TSize size=iWindow.Size();
TInt width=size.iWidth;
TInt height=size.iHeight;
// Draw a square border
gc->DrawLine(TPoint(0,0),TPoint(0,height-1));
gc->DrawLine (TPoint (0, height-1), TPoint (width-1, height-1));
gc->DrawLine(TPoint(width-1,height-1),TPoint(width-1,0));
gc->DrawLine (TPoint (width-1, 0), TPoint (0, 0));
// Draw a line between the corners of the window
gc->DrawLine(TPoint(0,0),TPoint(width, height));
gc->DrawLine (TPoint (0, height), TPoint (width, 0));
}


/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////// CWsClient implementation ////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
CWsClient* CWsClient::NewL(const TRect& aRect)
{
// make new client
CWsClient* client=new (ELeave) CWsClient(aRect);
CleanupStack::PushL(client); // push, just in case
client->ConstructL(); // construct and run
CleanupStack::Pop();
return client;
}

CWsClient::CWsClient(const TRect& aRect)
: CActive(CActive::EPriorityHigh),
iRect(aRect)
{
}

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)); // meaningless handle; enable focus
// 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

iWindow = new (ELeave) CWindow (this);
iWindow->ConstructL(iRect);

// 窗口始终在最上层
iGroup.SetOrdinalPosition(0, ECoeWinPriorityAlwaysAtFront);
// 禁止接受焦点
iGroup.EnableReceiptOfFocus(EFalse);
// Set the window is non-fading
iGroup.SetNonFading(ETrue);

// 将窗口提到前面
TApaTask task(iWs);
task.SetWgId(iGroup.Identifier());
task.BringToForeground();

// 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 iWindow;

// destroy window group
iGroup.Close();
// finish with window server
iWs.Close();
}

void CWsClient::IssueRequest()
{
iWs.RedrawReady(&iStatus); // request redraw
SetActive(); // so we're now active
}

void CWsClient::DoCancel()
{
iWs.RedrawReadyCancel(); // cancel redraw request
}

/****************************************************************************\
| Function: CWsClient::RunL()
| Called by active scheduler when an even occurs
| Purpose: do Redraw
\****************************************************************************/
void CWsClient::RunL()
{
// find out what needs to be done
TWsRedrawEvent redrawEvent;
    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
iGc->Activate(window->Window());
window->Window().BeginRedraw(rect);
window->Draw(rect);
window->Window().EndRedraw();
iGc->Deactivate();
}
// maintain outstanding request
IssueRequest(); // maintain outstanding request
}
// ================= End of Window.cpp =======================
上面的代码只是一个最基础的框架,你可以自己添更多的东西。比如显示一些文字。不过要显示文字就要先设定字体,具体操作如下:
先要建立一个CWsScreenDevice:
Code:
iScreen = new (ELeave) CWsScreenDevice(iWs);

然后可以用GetNearestFontInTwips通过字体名字获得CFont:
Code:
LIT(FONT_CH16, "CombinedChinesePlain16");
TFontSpec myFontSpec(FONT_CH16, 200);
iScreen->GetNearestFontInTwips(iFont, myFontSpec);


相关文章:
在没有ui的程序中捕获所有的key事件
Symbian类里的extension和reserved
Symbian绘图全过程
Symbian应用程序中如何备份和载入
播放WAV文件
CCoeControl类中Draw()函数的调试
Symbian程序中的观察者模式
S60平台:Bluetooth API开发伙伴指南——搜索和发布
 

站点地图 | 加入收藏 | 联系站长 | 广告服务 |
QQ:280529124  Tel:0592-8271361 辽ICP备05021703号