《深入brew接口机制》的补充

接口替换技术实例

这是对一篇文章《深入BREW接口机制》文中代码的补充,经过我的调试,对IMENU、ISTATIC接口都是有效的,大家一起探讨一下,会不会存在什么问题。

在AEEAppGen.h中加入
typedef void (*UpdateFun)(IDisplay * po, boolean bDefer); //数据请求的回调函数指针
在结构_AEEApplet中加入变量
        UpdateFun m_pOldUpdate; //用来保存原来的UPDATE函数的地址
        IDIB*    m_pBgDIB; //用来保存要显示的背景图片的DIB位图

在你的程序的主结构中加入变量保存
        IDisplay* m_pOldIDisplay; //原来的IDISPLAY结构的地址
        IDisplayVtbl * m_pOldDisplayVtbl; //原来的DISPLAYVTBL地址
        uint16 m_nColorDepth;  //手机颜色深度,AEEDeviceInfo.nColorDepth

//初始化一些变量
void InitDisplay(APPFRAME * pApp)
{
        pApp->a.m_pBgDIB = NULL;
        if(pApp->m_nColorDepth == 16) //判断手机的颜色深度是否是16位,因为背景图片是256色的,这里我们假设只对手机色深为16的有效
        {
                IBitmap* pScrBitmap = NULL;
                IDIB*    pScrDIB = NULL;
                IBitmap* pBgBitmap = NULL;
                IDIB*    pBgDIB = NULL;
                IImage*  pBgImage = NULL;
                IDisplay* pIDisplay = pApp->a.m_pIDisplay;

                // 获取显示器位图
                IDISPLAY_GetDeviceBitmap(pApp->a.m_pIDisplay, &pScrBitmap);
                // 获取显示缓冲区
                IBITMAP_QueryInterface(pScrBitmap, AEECLSID_DIB, (void**)&pScrDIB);
                // 创建背景位图
                IBITMAP_CreateCompatibleBitmap(pScrBitmap, &pBgBitmap, pScrDIB->cx, pScrDIB->cy);
                // 获取背景位图的缓冲区
                IBITMAP_QueryInterface(pBgBitmap, AEECLSID_DIB, (void**)&pBgDIB);
                // 载入背景图片
                pBgImage = ISHELL_LoadImage(pApp->a.m_pIShell, "bg.png"); //载入背景图片

                // 替换IDisplay接口的目标位图
                IDISPLAY_SetDestination(pApp->a.m_pIDisplay, pBgBitmap);
                IBITMAP_Release(pScrBitmap); // 引用计数减1
                pScrBitmap = NULL;
                // 贴背景图
                if(pBgImage)
                        IIMAGE_Draw(pBgImage, 0, 0);//pApp->m_nTitleHeight);
                // 还原IDisplay接口的目标位图
                IDISPLAY_SetDestination(pApp->a.m_pIDisplay, pScrBitmap);
                IBITMAP_Release(pBgBitmap); // 引用计数减1
                pBgBitmap = NULL;
                pApp->a.m_pBgDIB = pBgDIB;
                IDIB_Release(pScrDIB);
                pScrDIB = NULL;
                RELEASEIF(pBgImage);
                pApp->m_pOldDisplayVtbl = *(( IDisplayVtbl**) pIDisplay);//将原来的pIDisplay指针保存
        }
}

//改变IDISPLAY_UPDATE()的地址指向
void ChangeDisplay(APPFRAME * pApp)
{
        if(pApp->m_nColorDepth == 16)
        {
                IDisplay* pIDisplay = pApp->a.m_pIDisplay;
                IDisplayVtbl* pIDisplayVtbl = (IDisplayVtbl*)MALLOC(sizeof(IDisplayVtbl));
                pApp->m_pOldDisplayVtbl = *(( IDisplayVtbl**) pIDisplay);
                MEMCPY(pIDisplayVtbl, *(( IDisplayVtbl**) pIDisplay), sizeof(IDisplayVtbl));
                //在这里保存原来的Update函数指针
                pApp->a.m_pOldUpdate = pIDisplayVtbl->Update;
                //替换
                pIDisplayVtbl->Update = IDISPLAY_MyUpdate;
                *((IDisplayVtbl**) pIDisplay) = pIDisplayVtbl;
        }
}

//还原IDISPLAY_UPDATE()的地址指向
void RevertDisplay(APPFRAME * pApp)
{
        if(pApp->m_nColorDepth == 16)
        {
                IDisplay* pIDisplay = pApp->a.m_pIDisplay;
                IDisplayVtbl* pIDisplayVtbl = *(( IDisplayVtbl**) pIDisplay);
                if(pIDisplayVtbl == pApp->m_pOldDisplayVtbl)
                        return;
                pIDisplayVtbl->Update = pApp->a.m_pOldUpdate;
                FREEIF(pIDisplayVtbl);
                *((IDisplayVtbl**) pIDisplay) = pApp->m_pOldDisplayVtbl;
        }
}

void IDISPLAY_MyUpdate(IDisplay * po, boolean bDefer)
{
        IBitmap* pScrBitmap = NULL;
        IDIB*    pScrDIB = NULL;
        IDIB*    pBgDIB = ((AEEApplet*)GETAPPINSTANCE())->m_pBgDIB;
       
        // 获取显示器位图
        IDISPLAY_GetDeviceBitmap(po, &pScrBitmap);
        // 获取显示缓冲区
        IBITMAP_QueryInterface(pScrBitmap, AEECLSID_DIB, (void**)& pScrDIB);
        IBITMAP_Release(pScrBitmap); // 引用计数减1
        pScrBitmap = NULL;
        // 这时,pScrDIB里面是原来IHtmlViewer载入的页面的位图数据,pBgDIB里是背景图片
        // 的位图数据,我们pScrDIB里白色的点用pBgDIB对应的点来替换。这里假设设备的颜色
        // 深度为16bit
        if(pBgDIB)
        {
                uint16* pixel = (uint16*)pScrDIB->pBmp;
                uint16* bgpixel = (uint16*)pBgDIB->pBmp;
                int pcount = pScrDIB->cx * pScrDIB->cy;
               
                for(; pcount; --pcount)
                {
                        if(*pixel == 0xffff)
                        {
                                *pixel = *bgpixel;
                        }
                        ++pixel;
                        ++bgpixel;
                }
        }
       
        // 调用真正的屏幕刷新函数
        ((AEEApplet*)GETAPPINSTANCE())->m_pOldUpdate(po, bDefer);
       
        IDIB_Release(pScrDIB);
        pScrDIB = NULL;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值