在很多时间,我们并不满足于BREW API提供那个简单的IMenuCtl控件,其实自己做一个标准菜单是很方便的一件事情。今天我们就来讨论一下。
要实现的菜单比较简单,只支持列表视图,也就是IMenuCtl中的AEECLSID_MENUCTL 模式。
但是我们需要考虑两个要求:
1.菜单需要一个背景图,并且在每一个选中项的背景不仅仅是简单地填充色,而应该是一个图片(这样我们就可以方便地实现渐变、光晕、立体等效果了)。
2.它应该在调用接口方面与原有的IMenuCtl基本一致,这样便于我们移植原来的代码。
首先,在h文件中对菜单各个实体先做个定义如下:
GMenuItem很好理解,明显是模仿着CtlAddItem来作的,只是省掉了一些东西罢了。
另外,关键的问题在于整个菜单结构的定义,如下:
前面的AEEVTBL就不说了,因为我们整个扩展GUI都是采用BREW的扩展类机制来实现的,具体方法可以参考相关资料。在这个菜单中,关键点是我们定义了一个背景图m_pImageBk和选中项的背景图m_pImageSe。其它几个字段象index/pagesize等等都是控制菜单行为的。用一个TQueueList来保存菜单项的链表(这个TQueueList也是自已实现的一个链表结构)。
好了,在实现中如何处理呢?先来看看看我们都需要些什么函数?
要实现的菜单比较简单,只支持列表视图,也就是IMenuCtl中的AEECLSID_MENUCTL 模式。
但是我们需要考虑两个要求:
1.菜单需要一个背景图,并且在每一个选中项的背景不仅仅是简单地填充色,而应该是一个图片(这样我们就可以方便地实现渐变、光晕、立体等效果了)。
2.它应该在调用接口方面与原有的IMenuCtl基本一致,这样便于我们移植原来的代码。
首先,在h文件中对菜单各个实体先做个定义如下:
//
自定义菜单项
typedef struct
{
const AECHAR * pText; // Text
IImage * pImage; // Image
const char * pszResImage;
const char * pszResText;
uint16 wText;
uint16 wImage;
uint16 wItemID;
uint32 dwData;
} GMenuItem;
typedef struct
{
RGBVAL cText;
RGBVAL cSelText;
} GMenuColors;
typedef struct
{
const AECHAR * pText; // Text
IImage * pImage; // Image
const char * pszResImage;
const char * pszResText;
uint16 wText;
uint16 wImage;
uint16 wItemID;
uint32 dwData;
} GMenuItem;
typedef struct
{
RGBVAL cText;
RGBVAL cSelText;
} GMenuColors;
另外,关键的问题在于整个菜单结构的定义,如下:
struct
_IGMenuCtl
{
const AEEVTBL(IGMenuCtl) * pvt;
uint32 m_nRefs;
IShell *m_pIShell;
IDisplay *m_pIDisplay;
IModule *m_pIModule;
IImage *m_pImageBk;
IImage *m_pImageSe;
TQueueList *m_pDataList;
int m_Index;
int m_startIndex;
int m_pageSize;
int m_textPos;
boolean m_isActive;
AEERect m_Rect;
GMenuColors m_Colors;
uint32 m_Properties;
} ;
const AEEVTBL(IGMenuCtl) * pvt;
uint32 m_nRefs;
IShell *m_pIShell;
IDisplay *m_pIDisplay;
IModule *m_pIModule;
IImage *m_pImageBk;
IImage *m_pImageSe;
TQueueList *m_pDataList;
int m_Index;
int m_startIndex;
int m_pageSize;
int m_textPos;
boolean m_isActive;
AEERect m_Rect;
GMenuColors m_Colors;
uint32 m_Properties;
} ;
好了,在实现中如何处理呢?先来看看看我们都需要些什么函数?
AEEINTERFACE(IGMenuCtl)