Windows CE嵌入式导航系统研究(应用程序相关)

1.1.1 TCPMP多媒体播放器

本系统中采用的多媒体播放器是TCPMP,TCPMP播放器播放速度很快且支持多达几十中多媒体格式。TCPMP开源项目,同时支持Windows CE操作系统,而且提供很好的扩展性,例如需要重新编写TCPMP界面只需重新编写interface.plg即可。TCPMP提供全部的源代码,移植非常方便,只需编译后将生成的文件拷贝到目标机器运行即可。TCPMP多媒体播放器界面非常简洁,如图 5.35所示。

Windows CE嵌入式导航系统研究(应用程序相关)_第1张图片

图 5.37 TCPMP软件界面

另外、TCPMP还支持应用集成,可以将TCPMP播放的核心移入到指定应用程序的指定界面位置,实现多媒体播放和其他任务同时工作的效果,常用于电梯广告播放器平台上。

1.1.2 凯立德导航软件

本系统的导航软件采用凯立德公司的导航软件,凯立德导航软件经历数10多年的发展,已经发展成为一款成熟的导航软件平台。凯立德公司推出很多嵌入式、手机等平台的导航软件版本,有支持Windows Mobile平台的、Symbian平台的,当然也有Windows CE平台。凯立德导航软件界面如图 57所示。

另外,同行相比,凯立德导航软件提示信息比较全,高速公路上,前方的主要出入口距离有多少,服务区距离多少,全部有提示,而且可以根据前方服务区的距离,计划你可以在哪儿休息,在哪儿加油。

Windows CE嵌入式导航系统研究(应用程序相关)_第2张图片

图 5.38 凯立德导航软件

1.1.3 TQSHELL界面设计
1. 设计说明

为了提供系统的交互性、可操作性,在本系统集成之际,还需要设计一个可用交互的界面软件,并开机启动该软件,320×240分辨率显示。考虑系统本身功能比较独立,在界面分块的时候,主要提供了GPS导航、Internet、TCPMP、游戏、常用工具和我的设备等几个调用功能,这样界面清爽和简洁,如图 5.39所示;

Windows CE嵌入式导航系统研究(应用程序相关)_第3张图片

图 5.39 TQSHELL界面

不仅如此,在我们开发板上还支持KEY键(如图 5.40所示),提供左右上下切换等功能。因此、在TASHELL界面设计的时候,我们同样支持了KEY按键功能。支持KEY按键功能其实很简单,只需响应OnKeyDown事件即可。

Windows CE嵌入式导航系统研究(应用程序相关)_第4张图片

图 5.40 KEY按键原理图

2. 图片绘制

整个TQSHELL界面采用的BMP图片绘制的方式进行设计的,其中每个按键的效果展示都是由一张张图片切换产生的效果。图片绘制是TQSHELL界面设计的关键,如下详细介绍图片绘制的代码实现,首先介绍CreateCompatibleDC[7]和BitBlt这两个重要的函数。

(1) CreateCompatibleDC函数

该函数用于创建一个与pDC所指向的设备环境兼容的内存设备环境——也称内存设备上下文。内存设备环境是一块用以显示的内存块,在复制内存图像到实际的显示设备前用来存储图像,这也正是避免闪屏的原因之所在,其函数原型如下;

virtual BOOL CreateCompatibleDC( CDC* pDC );

其中pDC指向一个设备环境,在MFC中常用GetDC()获取。如果pDC为空,函数会创建一个与系统显示兼容的内存设备环境。

调用该函数,当内存设备环境创建后,GDI会自动为它装载一个黑白位图。GDI的输出函数只有当内存设备环境上有了位图画布之后,才能进行输出。但是用该函数时,有一点需要注意,即该函数只能用来为支持光栅操作的设备创建兼容的设备环境。

(2) BitBlt函数

如上所述,CreateCompatibleDC函数用于创建设备上下文兼容的内存设备环境,BitBlt函数则用于从源设备上下文(即内存设备环境)拷贝位图到这个当前设备上下文,该函数原型如下;

BOOL BitBlt( int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop );

l x 指定目标矩形左上角的逻辑x坐标。

l y 指定目标矩形左上角的逻辑y坐标。

l nWidth 指定目标矩形和源位图的宽度(逻辑单位)。

l nHeight 指定目标矩形和源位图的高度(逻辑单位)。

l pSrcDC 指向CDC对象的指针,标识待拷贝位图的设备上下文。假如dwRop指定不包括源的光栅操作,则它必须为NULL。

l xSrc 指定源位图左上角的逻辑X坐标。

l ySrc 指定源位图左上角的逻辑Y坐标。

l dwRop 指定要执行的光栅操作。光栅操作代码定义GDC如何合并输出操作中的颜色,包括当前画刷、可能的源位图和目标位图。

使用BitBlt函数,应用可以在字节边界上对齐窗口或客户区域,保证BitBlt操作发生在以字节对齐的矩形上。

在字节对齐矩形上的BitBlt操作比未经字节对齐的矩形上的BitBlt操作快许多。假如想对自己的设备上下文指定字节对齐类风格,必须登记窗口类而不要依靠Microsoft基本类,可使用全局函数AfxRegisterWndClass。

一旦使用目标设备上下文和使用源设备上下文,GDI变形nWidth和nHeight。假如结果延伸不匹配,必要时GDI使用Windows StretchBlt函数压缩或拉伸源位图。假如目标、源和特征位图颜色格式不同,BitBlt转换源和特征位图以匹配目标,转换中使用目标位图的前景和背景色。

BitBlt函数把单色位图转换为彩色时,它设置白色(1)为背景色,黑色(0)作为前景色。使用目标设备上下文的背景和前景色。要把彩色转换为单色,BitBlt把与背景色匹配的像素设置为白色,其余所有像素设置为黑色。在从彩色到单色的转换中,BitBlt使用彩色设备上下文的前景和背景色。

注意,并非所有的设备上下文都支持BitBlt。为检查给定设备上下文是否支持BitBlt,使用GetDeviceCaps成员函数并指定RASTERCAPS索引。

了解这两个函数的作用之后,编写绘图程序就相当简单了,TQSHELL界面中绘图程序如程序清单 5‑55所示;

程序清单 5‑55 绘制图片代码

CDC* pDC = GetDC () ;

CDC memDC ;

memDC.CreateCompatibleDC ( pDC ) ;

CBitmap bmp,bmp1 ;

CBitmap* pOldBitmap ;

bmp1.LoadBitmap ( m_map) ;

pOldBitmap = memDC.SelectObject ( &bmp1 ) ;

pDC->BitBlt ( m_rect[i].TopLeft().x, m_rect[i].TopLeft().y, m_rect[i].Width(),

m_rect[i].Height(), &memDC, 0, 0, SRCCOPY ) ;

memDC.SelectObject ( pOldBitmap ) ;

memDC.DeleteDC () ;

ReleaseDC ( pDC ) ;

3. 按键模仿

在系统中,考虑到如果TQSHELL所有的事件都是硬实现而没有动态效果的话未免有失系统交互性,因此在TQSHELL中,我们采用了双图片切换的方式来模拟按键触发,如图 5.41、图 5.42所示。

clip_image010

图 5.41 按键之前

clip_image012

图 5.42 按键之后

按键模仿需要响应两个事件,一个OnLButtonDown、另一个是OnLButtonUp。当OnLButtonDown事件发生之后,图片切换,当OnLButtonUp事件发生之后,图片恢复,代码如程序清单 5‑56、程序清单 5‑57所示。

程序清单 5‑56 OnLButtonDown事件

bmp.LoadBitmap ( IDB_GPS_W ) ;

CBitmap* pOldBitmap = memDC.SelectObject ( &bmp ) ;

pDC->BitBlt ( m_rect[m_prePick].TopLeft().x, m_rect[m_prePick].TopLeft().y, m_rect[m_prePick].Width(),

m_rect[m_prePick].Height(), &memDC, 0, 0, SRCCOPY ) ;

memDC.SelectObject ( pOldBitmap ) ;

程序清单 5‑57 OnLButtonUp事件

CopyBMP(IDB_GPS_W,0);

4. KEY按键响应

硬件平台的设计过程当中,考虑到操作的方便,增加了KEY按键的实现,主要针对上下左右等几个功能。在TQSHELL为很好的利用这样的条件,以增加系统的可交互性,在实现的过程当中,响应KEY按键事件。支持KEY按键其实很简单,只需实现OnKeyDown事件即可,事件的实现的时候,有一点需要注意,KEY按下之后,前一个KEY应当恢复,KEY按键响应函数如程序清单 5‑58所示。

程序清单 5‑58 OnKeyDown事件

void CGPSDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)

{

m_prePick=m_currentPick ;

if ( nChar == VK_UP|| nChar == VK_LEFT )

{

switch (m_prePick)

{

case 0:

//GPS黑别的白

CopyBMP(IDB_GPS_B,0);

CopyBMP(IDB_MP3_W,1);

CopyBMP(IDB_MP4_W,2);

CopyBMP(IDB_PICTURE_W,3);

CopyBMP(IDB_TOOL_W,4);

CopyBMP(IDB_SET_W,5);

m_currentPick = 0 ;

break ;

......

}

}

if ( nChar == VK_DOWN || nChar == VK_RIGHT)

{

switch (m_prePick)

{

case 0:

//MP3黑别的白

CopyBMP(IDB_GPS_W,0);

CopyBMP(IDB_MP3_B,1);

CopyBMP(IDB_MP4_W,2);

CopyBMP(IDB_PICTURE_W,3);

CopyBMP(IDB_TOOL_W,4);

CopyBMP(IDB_SET_W,5);

m_currentPick = 1 ;

break ;

......

default:

break;

}

}

CDialog::OnKeyDown(nChar, nRepCnt, nFlags);

}

5. 进程调用

TQSHELL界面程序是一个系统集成界面程序,为保证系统能运行,TQSHELL必须实现进程调用,调用子软件运行,实现如GPS导航、多媒体播放等方面的操作。在MFC中,进程调用的函数有很多中,但是在本系统中支持ShellExecuteEx函数,如下介绍ShellExecuteEx函数,介绍ShellExecuteEx之前,我先介绍SHELLEXECUTEINFO结构体[8]

(1) SHELLEXECUTEINFO结构体

该结构体作为参数辅助ShellExecuteEx函数的调用进程,指定需要调用的进程相关的参数,该结构体原型如程序清单 5‑59所示;

程序清单 5‑59 SHELLEXECUTEINFO 结构体

typedef struct _SHELLEXECUTEINFO {

DWORD cbSize;

ULONG fMask;

HWND hwnd;

LPCTSTR lpVerb;

LPCTSTR lpFile;

LPCTSTR lpParameters;

LPCTSTR lpDirectory;

int nShow;

HINSTANCE hInstApp;

LPVOID lpIDList;

LPCTSTR lpClass;

HKEY hkeyClass;

DWORD dwHotKey;

union {

HANDLE hIcon;

HANDLE hMonitor;

} DUMMYUNIONNAME;

HANDLE hProcess;} SHELLEXECUTEINFO, *LPSHELLEXECUTEINFO;

在进程调用的过程当中,SHELLEXECUTEINFO结构体中的这些参数是可以选择性的设置,如下一一介绍。

l lpDirectory:可选。指明工作目录的名字,成员没有说明,则默认为当前目录

l nShow:必须。指定打开的程序的显示方式,为SW_值中的一个。

l hInstApp:用于输出,如果设置SEE_MASK_NOCLOSEPROCESS S值并且ShellExecuteEx 调用成功,则该项的值大于32,如果调用失败,则将设置为 SE_ERR_XXX 的错误值。

l lpIDList:一个ITEMIDLIST结构的地址,用来存储成员的特别标识符,当fMask不包括SEE_MASK_IDLIST或SEE_MASK_INVOKEIDLIST时该项被忽略

l lpClass:用以指明文件类别的名字或GUID,当fMask不包括SEE_MASK_CLASSNAME时该项被忽略

l hkeyClass:获得已在系统注册的文件类型的Handle,当fMask不包括SEE_MASK_HOTKEY时该项被忽略

l dwHotKey:程序的热键关联,低位存储虚拟关键码(Key Code),高位存储修改标志位(HOTKEYF_),修改标志为(modifier flags)的详细列表请看WM_SETHOTKEY消息的描述,当fmask不包括SEE_MASK_HOTKEY时该项被忽略

l hIcon :取得对应文件类型的图标的Handle,当fMask不包括SEE_MASK_ICON时该项被忽略

l hMonitor :将文档显示在显示器上的Handle,当fMask不包括SEE_MASK_HMONITOR时该项被忽略

l hProcess:指向新启动的程序的句柄。若fMask不设为SEE_MASK_NOCLOSEPROCESS则该项值为NULL。但若程序没有启动,即使fMask设为SEE_MASK_NOCLOSEPROCESS,该值也仍为NULL。

(2) ShellExecuteEx函数

ShellExecuteEx函数以SHELLEXECUTEINFO结构体为参数,用于调用SHELLEXECUTEINFO结构体中指定的进程,该函数原型如下;

BOOL ShellExecuteEx(LPSHELLEXECUTEINFO lpExecInfo);

了解SHELLEXECUTEINFO结构体和ShellExecuteEx函数之后,TQSHELL中调用ShellExecuteEx函数实现进程调用,代码实现其实很简单,如程序清单 5‑60所示;

程序清单 5‑60 进程调用

tem = L"//Storage Card//KLD//NaviOne.exe";

exeshell.cbSize = sizeof(SHELLEXECUTEINFO);

exeshell.lpFile = tem;

exeshell.hwnd = NULL;

exeshell.nShow = SW_SHOW;

ShellExecuteEx(&exeshell);

DesktopBar=::FindWindow(L"HHTaskBar",NULL);

::ShowWindow(DesktopBar,SW_HIDE);

6. 内核加载

TQSHELL编译完成之后,获得TQSHELL.EXE和TQSHELL.LIB文件之后,为了方便开机就启动本界面,我们需要将这两个文件加入到内核中,加载到内核中的步骤如下;

(1) 编辑LNK文件

该文件其实就是一个快捷文件,点击可直接运行指定目录下的应用程序。该文件的内容如图 5.43所示;

Windows CE嵌入式导航系统研究(应用程序相关)_第5张图片

图 5.43 LNK文件内容

(2) 加载到内核当中

在Windows CE中,需要将应用程序加载到内核当中,只需编辑Pratfrom.bib文件即可,如图 5.44所示;

clip_image016

图 5.44 加载TQSHEEL.exe到内核

(3) Windows CE启动后直接运行TQSHELL.exe程序

Windows CE支持启动直接运行用户程序,设置很简单,因为Windows CE启动后默认是启动explorer.exe程序,如果要替换成指定的应用程序,只需设置相关的注册表即可,如程序清单 5‑60所示;

程序清单 5‑61 启动注册表

[HKEY_LOCAL_MACHINE/init]

"Launch50"="Windows//TQSHELL.EXE"

"Depend50"=hex:14,00,1e,00

Windows CE启动之后,TQSHELL.EXE运行的界面比起原始Windows CE界面要清爽很多,如图 5.45、图 5.46所示;

Windows CE嵌入式导航系统研究(应用程序相关)_第6张图片

图 5.45 主界面

Windows CE嵌入式导航系统研究(应用程序相关)_第7张图片

图 5.46 常用工具界面

你可能感兴趣的:(windows,Microsoft,null,嵌入式,mfc,平台)