如何通过直接访问屏幕内存来直接绘制屏幕并更新
2010-05-09 13:34
363 查看
[打印本页]
--------------------------------------------------------------------------------
作者: freebird 时间: 2009-9-14 23:13 标题: 如何通过直接访问屏幕内存来直接绘制屏幕并更新
有三个方法可以跳过window server来直接绘制屏幕(这里称为Direct drawing),这通常用在游戏程序中使得屏幕绘制更加快速。
其中一个直接访问的方法就是直接访问屏幕内存,并通过编辑内存来绘制屏幕。
这里可以使用UserSvr::ScreenInfo()这个API来获取屏幕地址,结果放在TScreenInfoV01包中,下面的代码片段可以获得内存地址,并绘制一个简单的矩形到屏幕上:
TPckgBuf<TScreenInfoV01> infoPckg;
TScreenInfoV01& screenInfo = infoPckg();
UserSvr::ScreenInfo(infoPckg);
TUint16* screenMemory = (TUint16*) screenInfo.iScreenAddress + 16;
for (int j = 80; j < 140; j++)
{
for (int i = 0; i < 176; i++)
{
*(screenMemory + 2*(16 + i + j*176)) = i/8 + j;
}
}
当绘制完成后,屏幕将会被更新,变化后的内容直接反映在屏幕上,
我们可以通过向系统队列增加一个重绘事件来完成TRawEvent::ERedraw(通过UserSvr::AddEvent()),
它将立刻更新屏幕,下列代码演示了如何处理:
TRawEvent redraw;
redraw.Set(TRawEvent::ERedraw);
UserSvr::AddEvent(redraw);
但TRawEvent::ERedraw是由主机系统生成的,如模拟器环境的WM_PAINT事件。
S60第二版中,屏幕更新可以通过增加系统队列完成,但第三版中却无法立刻展现系统队列中重绘指令的效果。
屏幕只能通过手机屏幕关于超出数据区域的通知事件才能更新。 所以通过UserSvr::ScreenInfo()来修改显示内存的方法在S60第三版后是不建议使用的。
作为一个解决方案,可以通过使用老的绘制方法强制屏幕更新,
通过使用CFbsScreenDevice的Update()方法来指明超出数据区域,这个代码示例如下:
CFbsScreenDevice* iMyScreenDev = CFbsScreenDevice::NewL(0 ,EColor64K); // the screennumber will be 0 if phone supports single screen where as the
// displaymode can be as per your choice
RRegion iMyregion;
iMyregion.AddRect(TRect(0,0,240,320)); // the out of date rect region.
iMyScreenDev->Update(iMyregion);
iMyregion.Close();
--------------------------------------------------------------------------------
作者: freebird 时间: 2009-9-14 23:13 标题: 如何通过直接访问屏幕内存来直接绘制屏幕并更新
有三个方法可以跳过window server来直接绘制屏幕(这里称为Direct drawing),这通常用在游戏程序中使得屏幕绘制更加快速。
其中一个直接访问的方法就是直接访问屏幕内存,并通过编辑内存来绘制屏幕。
这里可以使用UserSvr::ScreenInfo()这个API来获取屏幕地址,结果放在TScreenInfoV01包中,下面的代码片段可以获得内存地址,并绘制一个简单的矩形到屏幕上:
TPckgBuf<TScreenInfoV01> infoPckg;
TScreenInfoV01& screenInfo = infoPckg();
UserSvr::ScreenInfo(infoPckg);
TUint16* screenMemory = (TUint16*) screenInfo.iScreenAddress + 16;
for (int j = 80; j < 140; j++)
{
for (int i = 0; i < 176; i++)
{
*(screenMemory + 2*(16 + i + j*176)) = i/8 + j;
}
}
当绘制完成后,屏幕将会被更新,变化后的内容直接反映在屏幕上,
我们可以通过向系统队列增加一个重绘事件来完成TRawEvent::ERedraw(通过UserSvr::AddEvent()),
它将立刻更新屏幕,下列代码演示了如何处理:
TRawEvent redraw;
redraw.Set(TRawEvent::ERedraw);
UserSvr::AddEvent(redraw);
但TRawEvent::ERedraw是由主机系统生成的,如模拟器环境的WM_PAINT事件。
S60第二版中,屏幕更新可以通过增加系统队列完成,但第三版中却无法立刻展现系统队列中重绘指令的效果。
屏幕只能通过手机屏幕关于超出数据区域的通知事件才能更新。 所以通过UserSvr::ScreenInfo()来修改显示内存的方法在S60第三版后是不建议使用的。
作为一个解决方案,可以通过使用老的绘制方法强制屏幕更新,
通过使用CFbsScreenDevice的Update()方法来指明超出数据区域,这个代码示例如下:
CFbsScreenDevice* iMyScreenDev = CFbsScreenDevice::NewL(0 ,EColor64K); // the screennumber will be 0 if phone supports single screen where as the
// displaymode can be as per your choice
RRegion iMyregion;
iMyregion.AddRect(TRect(0,0,240,320)); // the out of date rect region.
iMyScreenDev->Update(iMyregion);
iMyregion.Close();
相关文章推荐
- ThinkPHP如何禁止直接通过路径访问
- 如何用C 让ASII码在屏幕中央显示。通过修改B800这段内存完成
- 如何通过输入域名直接访问项目地址
- SAP ABAP/4学习---如何给写好的一个程序分配事务代码,用户可以直接通过事务码来访问程序.或者加入收藏夹(9)
- ssh如何通过跳板机直接访问到后端服务器(Mac&Linux&Windows解决方案)
- 如何通过手机直接访问本地电脑中的网站
- weblogic服务器部署的程序,如何直接通过IP访问(即URL中去掉工程名)
- ASP.NET如何禁止直接通过Url访问某个类型的文件(非权限),不定时补充
- 如何让局域网其他电脑通过IP直接访问自己电脑的网站
- tomcat设置如何通过ip直接访问项目
- Tomcat部署web项目,如何直接通过域名访问,不加项目名称
- 装饰者模式的学习(c#) EF SaveChanges() 报错(转载) C# 四舍五入 保留两位小数(转载) DataGridView样式生成器使用说明 MSSQL如何将查询结果拼接成字符串 快递查询 C# 通过smtp直接发送邮件 C# 带参访问接口,WebClient方式 C# 发送手机短信 文件 日志 写入 与读取
- Tomcat部署web项目,如何直接通过域名访问,不加项目名称
- HttpServletRequest的getServletPath、getServletURI、getServletURL等区别 &&如何防止用户通过直接输入URL访问网页
- 在apache下如何禁止通过URL直接访问文件夹
- php如何判断用户通过手机wap访问还是电脑直接访问
- 如何将javaweb打包的war包发布到tomcat的根目录直接通过域名访问,而不是在二级目录
- VB编程的一些小技巧 - vb直接访问dx7屏幕内存的例子
- 如何通过Pyqt 或者PySide 在电脑上直接显示手机屏幕。
- php如何判断用户通过手机wap访问还是电脑直接访问