在Symbian exe 程序中显示图形
2007-03-07 23:04
211 查看
Displaying graphics in Symbian exe programs.
在 Symbian exe 程序中显示图形
Generally, exe programs are used to implement servers (exedll, epocexe target type) or
simple console programs. This may lead to believe that graphical features are not available
for exe programs. This is not the case, and even though it might take some extra work to
set up an appropriate environment, this is quite straight forward to achieve, as the
following snippet will illustrate. This way, we can make use of graphics without having to
resort on a full blown application.
通常,通常EXE程序(exedll, epocexe 类型)被用来实现服务器端或者是简单的控制台程序。所以使大家
认为图形化的特性对于exe程序是不必要的。事实上并非如此,甚至它需要做一些额外的工作来设置一个
适当的环境,就像下面将举例提到的,是十分方便的。
Our aim is to simply emulate the minimum set up provided by the framework when an
application (.app) is loaded. Being a dll, an application needs a process to attach to.
This is provided by AppRun.exe, which besides catering its own process and thread, calls
EikDll::RunAppInsideThread(), which -among other things- creates a CONE environment
(CCoeEnv)
我们的目标很简单,就是模拟当应用程序(.app)被加载时框架所提供的最小配置。作为一个DLL,应用程
序是需要一个进程去加载它的,AppRun.exe就是用来做这个的。AppRun.exe不仅为自己的进程和线程提
高资源,它还调用EikDll::RunAppInsideThread() ,建立一个CONE环境(CCoeEnv) 。
When a CONE Environment is created, it sets up a cleanup stack, active scheduler
(CCoeScheduler), and sessions to the file and window server (which can be later retrived by
calling CCoeEnv::FsSession() and CCoeEnv::WsSession()). Then it creates a screen, a window
group and a graphic context, among other things. Later, after the NewApplication() factory
function is called by the framework, the CCoeAppUi (from where the application's AppUi
derives) creates the control stack, view manager, etc. and the CCoeControl derived class
will create a window (RWindow) to provide a basic view. As you can see, this snippet
provides all this basic functionality at once, without extra bloat such as a control stack,
etc. which aren't needed in this simple case. I haven't included comments, as most of the
code speaks by itself.
当CONE环境建立后设置清理栈活动对象规划器(CCoeScheduler),建立和文件,窗口服务器的会话(以后
会在调用CCoeEnv::FsSession() 和 CCoeEnv::WsSession()时用到)。接着创建屏幕,窗口组和图形上
下文。再下来,在工厂函数NewApplication()被框架调用后,CCoeAppUi (来自应用程序的AppUi驱动)
建立控件栈,视图管理器等等。CCoeControl的继承类将建立窗口(RWindow)来提供基本的视图。就像你
所看到的,这个程序片断只提供了所以基本的功能,并没有像控件栈等这些多余的东西,它们是这个简
单例子程序中所不需要的。我们并没有注释,因为代码本身已经说明问题了。
LOCAL_C void ExeMainL()
{
RWsSession ws;
User::LeaveIfError(ws.Connect());
CleanupClosePushL(ws);
CWsScreenDevice* screen = new(ELeave) CWsScreenDevice(ws);
CleanupStack::PushL(screen);
screen->Construct();
RWindowGroup wg(ws);
User::LeaveIfError(wg.Construct(reinterpret_cast<TUint32>(&wg), EFalse));
CleanupClosePushL(wg);
wg.SetOrdinalPosition(10, ECoeWinPriorityAlwaysAtFront);
CWindowGc* gc;
User::LeaveIfError(screen->CreateContext(gc));
CleanupStack::PushL(gc);
RWindow window(ws);
User::LeaveIfError(window.Construct(wg, reinterpret_cast<TUint32>(&wg) + 1));
CleanupClosePushL(window);
window.SetBackgroundColor(TRgb(0x90, 0x90, 0x90));
window.Activate();
window.SetExtent(TPoint(0, 0), TSize(screenWidth, screenHeight));
window.SetVisible(ETrue);
gc->Activate(window);
TRect rect = TRect(window.Size());
window.Invalidate(rect);
window.BeginRedraw(rect);
gc->SetBrushStyle(CGraphicsContext::ESolidBrush);
gc->Clear();
TInt64 seed = User::TickCount();
TRgb color[] = { KRgbRed, KRgbGreen, KRgbBlue, KRgbYellow, KRgbCyan };
for (TUint i = 0; i < 10000; ++i)
{
TInt x = Math::Rand(seed) % screenWidth;
TInt y = Math::Rand(seed) % screenHeight;
TInt w = Math::Rand(seed) % 50;
TInt h = Math::Rand(seed) % 25;
TRect rect(TPoint(x, y), TSize(w, h));
gc->SetBrushColor(color[i % sizeof color]);
gc->DrawRect(rect);
}
window.EndRedraw();
gc->Deactivate();
ws.Flush();
CleanupStack::PopAndDestroy(5, &ws); // window, gc, wg, screen, ws
}
Let's see now the entry point of the program. If we tried something like this
现在我们来看入口程序。如果我们这样做:
GLDEF_C TInt E32Main()
{
__UHEAP_MARK;
CTrapCleanup* cleanup = CTrapCleanup::New();
TRAPD(error, ExeMainL());
__ASSERT_ALWAYS(!error, User::Panic(_L("EXEUI"), error));
delete cleanup;
__UHEAP_MARKEND;
return 0;
}
it would work on the device only. On the emulator, you'd get a panic, as
RWsSession::Connect() would fail. The reason for this is that when an exe is executed, the
emulator doesn't launch the window server as part of its initialization, whereas on the
device the server is already loaded.
它只能在真机(手机)上运行。在模拟器上你会得到一个严重错误,因为RWsSession::Connect() 会失
败。原因是当一个exe程序在模拟器上运行的时候,它(模拟器)是不会启动窗口服务器作为其初始化的
一部分的。但是在手机上窗口服务器总是运行着的。
There're a couple of ways to solve this. On Series 60 SDK v1.2, there's an undocumented
function which does exactly this for us. RegisterWsExe() is provided by wserv.lib. So now
our entry point function is:
有许多方法解决这个问题。在Series 60 SDK v1.2,有一个未公开的函数为我们解决了这个问题。
wserv.lib提供了RegisterWsExe()这个函数。现在我们的入口函数:
void RegisterWsExe(const TDesC&);
GLDEF_C TInt E32Main()
{
__UHEAP_MARK;
CTrapCleanup* cleanup = CTrapCleanup::New();
#if defined(__WINS__)
RegisterWsExe(_L("ExeUI.exe"));
#endif
TRAPD(error, ExeMainL());
__ASSERT_ALWAYS(!error, User::Panic(_L("EXEUI"), error));
delete cleanup;
__UHEAP_MARKEND;
return 0;
}
The problem with this solution is that it's not as generic as we might want. There's
another way, which requires some more bit of work, that consists of changing the target
type to exedll or epocexe. This means that on WINS (emulator) we get a .dll, and on MARM
(target) we get the .exe as usual. Note that all changes will be made to the startup code,
that is, no changes are made to ExeMainL() code.
这个解决方案并不是我们所通常所希望的。有另外一种方式,只需要多做一点儿工作,包括把目标类型
改为exedll 或 epocexe。这意味着在模拟器上我们得到的是 .dll,在ARM(手机)上是通常的.exe。要
注意所需要修改的仅仅是启动代码上,ExeMainL()使没有变化的。
This is how our new startup code looks, with the two functions required by the exedll type
(epocexe is analogous, except the exported function InitEmulator() is replaced by WinsMain
()):
我们的启动代码看起来是这样的,下面是exedll所必须的两个函数(epocexe是类似的,除非导出函数
InitEmulator()被WinsMain()所取代):
GLDEF_C TInt E32Main()
{
__UHEAP_MARK;
CTrapCleanup* cleanup = CTrapCleanup::New();
TRAPD(error, ExeMainL());
__ASSERT_ALWAYS(!error, User::Panic(_L("EXEUI"), error));
delete cleanup;
__UHEAP_MARKEND;
return 0;
}
// If using exedll target type
#if defined(__WINS__)
EXPORT_C TInt InitEmulator()
{
E32Main();
User::Exit(0);
return KErrNone;
}
TInt E32Dll(TDllReason)
{
return KErrNone;
}
#endif
Now the idea is renaming ExeUI.dll to ExeUI.app, and copying it to an application directory
on the emulator tree to make it look like an ordinary application. So we create the ExeUI
directory in Epoc32/Wins/c/system/Apps (or Epoc32/Release/wins/udeb/z/system/apps if you
wish). As we're creating an application, we also need to provide it of a proper UID, so
don't forget to add the corresponding line in the .mmp
Now you may launch the emulator, that will show the ExeUI program's default icon.
现在所要做的工作就是把把ExeUI.dll改名为ExeUI.app,并拷贝到模拟器的一个应用程序目录下。我们
建立ExeUI目录Epoc32/Wins/c/system/Apps (或 Epoc32/Release/wins/udeb/z/system/apps只要你愿意
)我们这不是建立了一个应用程序吗,所以我们还要提供一个合适的UID,别忘了在.mmp文件相应的地方
添加它。好了,你启动模拟器,它会显示ExeUI程序的默认图标了。
在 Symbian exe 程序中显示图形
Generally, exe programs are used to implement servers (exedll, epocexe target type) or
simple console programs. This may lead to believe that graphical features are not available
for exe programs. This is not the case, and even though it might take some extra work to
set up an appropriate environment, this is quite straight forward to achieve, as the
following snippet will illustrate. This way, we can make use of graphics without having to
resort on a full blown application.
通常,通常EXE程序(exedll, epocexe 类型)被用来实现服务器端或者是简单的控制台程序。所以使大家
认为图形化的特性对于exe程序是不必要的。事实上并非如此,甚至它需要做一些额外的工作来设置一个
适当的环境,就像下面将举例提到的,是十分方便的。
Our aim is to simply emulate the minimum set up provided by the framework when an
application (.app) is loaded. Being a dll, an application needs a process to attach to.
This is provided by AppRun.exe, which besides catering its own process and thread, calls
EikDll::RunAppInsideThread(), which -among other things- creates a CONE environment
(CCoeEnv)
我们的目标很简单,就是模拟当应用程序(.app)被加载时框架所提供的最小配置。作为一个DLL,应用程
序是需要一个进程去加载它的,AppRun.exe就是用来做这个的。AppRun.exe不仅为自己的进程和线程提
高资源,它还调用EikDll::RunAppInsideThread() ,建立一个CONE环境(CCoeEnv) 。
When a CONE Environment is created, it sets up a cleanup stack, active scheduler
(CCoeScheduler), and sessions to the file and window server (which can be later retrived by
calling CCoeEnv::FsSession() and CCoeEnv::WsSession()). Then it creates a screen, a window
group and a graphic context, among other things. Later, after the NewApplication() factory
function is called by the framework, the CCoeAppUi (from where the application's AppUi
derives) creates the control stack, view manager, etc. and the CCoeControl derived class
will create a window (RWindow) to provide a basic view. As you can see, this snippet
provides all this basic functionality at once, without extra bloat such as a control stack,
etc. which aren't needed in this simple case. I haven't included comments, as most of the
code speaks by itself.
当CONE环境建立后设置清理栈活动对象规划器(CCoeScheduler),建立和文件,窗口服务器的会话(以后
会在调用CCoeEnv::FsSession() 和 CCoeEnv::WsSession()时用到)。接着创建屏幕,窗口组和图形上
下文。再下来,在工厂函数NewApplication()被框架调用后,CCoeAppUi (来自应用程序的AppUi驱动)
建立控件栈,视图管理器等等。CCoeControl的继承类将建立窗口(RWindow)来提供基本的视图。就像你
所看到的,这个程序片断只提供了所以基本的功能,并没有像控件栈等这些多余的东西,它们是这个简
单例子程序中所不需要的。我们并没有注释,因为代码本身已经说明问题了。
LOCAL_C void ExeMainL()
{
RWsSession ws;
User::LeaveIfError(ws.Connect());
CleanupClosePushL(ws);
CWsScreenDevice* screen = new(ELeave) CWsScreenDevice(ws);
CleanupStack::PushL(screen);
screen->Construct();
RWindowGroup wg(ws);
User::LeaveIfError(wg.Construct(reinterpret_cast<TUint32>(&wg), EFalse));
CleanupClosePushL(wg);
wg.SetOrdinalPosition(10, ECoeWinPriorityAlwaysAtFront);
CWindowGc* gc;
User::LeaveIfError(screen->CreateContext(gc));
CleanupStack::PushL(gc);
RWindow window(ws);
User::LeaveIfError(window.Construct(wg, reinterpret_cast<TUint32>(&wg) + 1));
CleanupClosePushL(window);
window.SetBackgroundColor(TRgb(0x90, 0x90, 0x90));
window.Activate();
window.SetExtent(TPoint(0, 0), TSize(screenWidth, screenHeight));
window.SetVisible(ETrue);
gc->Activate(window);
TRect rect = TRect(window.Size());
window.Invalidate(rect);
window.BeginRedraw(rect);
gc->SetBrushStyle(CGraphicsContext::ESolidBrush);
gc->Clear();
TInt64 seed = User::TickCount();
TRgb color[] = { KRgbRed, KRgbGreen, KRgbBlue, KRgbYellow, KRgbCyan };
for (TUint i = 0; i < 10000; ++i)
{
TInt x = Math::Rand(seed) % screenWidth;
TInt y = Math::Rand(seed) % screenHeight;
TInt w = Math::Rand(seed) % 50;
TInt h = Math::Rand(seed) % 25;
TRect rect(TPoint(x, y), TSize(w, h));
gc->SetBrushColor(color[i % sizeof color]);
gc->DrawRect(rect);
}
window.EndRedraw();
gc->Deactivate();
ws.Flush();
CleanupStack::PopAndDestroy(5, &ws); // window, gc, wg, screen, ws
}
Let's see now the entry point of the program. If we tried something like this
现在我们来看入口程序。如果我们这样做:
GLDEF_C TInt E32Main()
{
__UHEAP_MARK;
CTrapCleanup* cleanup = CTrapCleanup::New();
TRAPD(error, ExeMainL());
__ASSERT_ALWAYS(!error, User::Panic(_L("EXEUI"), error));
delete cleanup;
__UHEAP_MARKEND;
return 0;
}
it would work on the device only. On the emulator, you'd get a panic, as
RWsSession::Connect() would fail. The reason for this is that when an exe is executed, the
emulator doesn't launch the window server as part of its initialization, whereas on the
device the server is already loaded.
它只能在真机(手机)上运行。在模拟器上你会得到一个严重错误,因为RWsSession::Connect() 会失
败。原因是当一个exe程序在模拟器上运行的时候,它(模拟器)是不会启动窗口服务器作为其初始化的
一部分的。但是在手机上窗口服务器总是运行着的。
There're a couple of ways to solve this. On Series 60 SDK v1.2, there's an undocumented
function which does exactly this for us. RegisterWsExe() is provided by wserv.lib. So now
our entry point function is:
有许多方法解决这个问题。在Series 60 SDK v1.2,有一个未公开的函数为我们解决了这个问题。
wserv.lib提供了RegisterWsExe()这个函数。现在我们的入口函数:
void RegisterWsExe(const TDesC&);
GLDEF_C TInt E32Main()
{
__UHEAP_MARK;
CTrapCleanup* cleanup = CTrapCleanup::New();
#if defined(__WINS__)
RegisterWsExe(_L("ExeUI.exe"));
#endif
TRAPD(error, ExeMainL());
__ASSERT_ALWAYS(!error, User::Panic(_L("EXEUI"), error));
delete cleanup;
__UHEAP_MARKEND;
return 0;
}
The problem with this solution is that it's not as generic as we might want. There's
another way, which requires some more bit of work, that consists of changing the target
type to exedll or epocexe. This means that on WINS (emulator) we get a .dll, and on MARM
(target) we get the .exe as usual. Note that all changes will be made to the startup code,
that is, no changes are made to ExeMainL() code.
这个解决方案并不是我们所通常所希望的。有另外一种方式,只需要多做一点儿工作,包括把目标类型
改为exedll 或 epocexe。这意味着在模拟器上我们得到的是 .dll,在ARM(手机)上是通常的.exe。要
注意所需要修改的仅仅是启动代码上,ExeMainL()使没有变化的。
This is how our new startup code looks, with the two functions required by the exedll type
(epocexe is analogous, except the exported function InitEmulator() is replaced by WinsMain
()):
我们的启动代码看起来是这样的,下面是exedll所必须的两个函数(epocexe是类似的,除非导出函数
InitEmulator()被WinsMain()所取代):
GLDEF_C TInt E32Main()
{
__UHEAP_MARK;
CTrapCleanup* cleanup = CTrapCleanup::New();
TRAPD(error, ExeMainL());
__ASSERT_ALWAYS(!error, User::Panic(_L("EXEUI"), error));
delete cleanup;
__UHEAP_MARKEND;
return 0;
}
// If using exedll target type
#if defined(__WINS__)
EXPORT_C TInt InitEmulator()
{
E32Main();
User::Exit(0);
return KErrNone;
}
TInt E32Dll(TDllReason)
{
return KErrNone;
}
#endif
Now the idea is renaming ExeUI.dll to ExeUI.app, and copying it to an application directory
on the emulator tree to make it look like an ordinary application. So we create the ExeUI
directory in Epoc32/Wins/c/system/Apps (or Epoc32/Release/wins/udeb/z/system/apps if you
wish). As we're creating an application, we also need to provide it of a proper UID, so
don't forget to add the corresponding line in the .mmp
Now you may launch the emulator, that will show the ExeUI program's default icon.
现在所要做的工作就是把把ExeUI.dll改名为ExeUI.app,并拷贝到模拟器的一个应用程序目录下。我们
建立ExeUI目录Epoc32/Wins/c/system/Apps (或 Epoc32/Release/wins/udeb/z/system/apps只要你愿意
)我们这不是建立了一个应用程序吗,所以我们还要提供一个合适的UID,别忘了在.mmp文件相应的地方
添加它。好了,你启动模拟器,它会显示ExeUI程序的默认图标了。
相关文章推荐
- 在Symbian exe 程序中显示图形
- VS2012下基于Glut OpenGL显示一些立体图形示例程序:
- Symbian游戏编程入门 (四)图形显示
- symbian 程序的cpp文件的第一个函数老显示没有定义 undefined identifier 'CZFirstTest_Login_Form'
- windows+xshell+xming 显示远程linux服务器的图形程序窗口
- Symbian图形显示
- Symbian 程序隐藏到后台,返回到主页面,按下特定的键值显示程序。
- PHP图形计数器程序显示网站用户浏览量
- PHP图形计数器程序显示网站用户浏览量
- Qt For Symbian 程序标题显示中文的方法
- 如何使Symbian C++程序全屏显示
- Symbian游戏编程入门 (四)图形显示
- 一个图形显示IP的PHP程序代码
- Java图形程序中的对话逐字显示实现
- Symbian程序中显示资源中定义的中文
- VC++设计图形显示CPU内存利用率程序
- vs开发的程序在xp下显示 xxx.exe不是有效的win32程序问题解决
- 显示远程主机图形窗口程序-------SSH的强大功能
- C#窗体内嵌外部程序(cmd.exe)的显示
- 系统服务显示EXE程序(C++)