函数替换的代码如下。
IDisplay* pIDisplay = ((AEEApplet*) GETAPPINSTANCE() )->m_pIDisplay;
IDisplayVtbl* pIDisplayVtbl = (IDisplayVtbl*)MALLOC(sizeof(IDisplayVtbl*));
MEMCPY(pIDisplayVtbl, *(( IDisplayVtbl**) pIDisplay), sizeof(IDisplayVtbl));
//在这里保存原来的Update函数指针
SaveOldUpdate(pIDisplayVtbl->Update);
//替换
pIDisplayVtbl->Update = IDISPLAY_MyUpdateEx;
*(( IDisplayVtbl**) pIDisplay) = pIDisplayVtbl;
这样IDISPLAY_UpdateEx就替换成自己定义的函数了。下面看一下IDISPLAY_ MyUpdateEx这个函数怎么实现。直接修改显示缓冲区的方法在过去已经有人讨论过,在这里就不详细说明了,直接给出IDISPLAY_ MyUpdateEx函数的参考实现。在参考实现中没有做任何错误处理,请注意。
void IDISPLAY_MyUpdateEx(IDisplay * po, boolean bDefer)
{
IBitmap* pScrBitmap;
IDIB* pScrDIB;
IBitmap* pBgBitmap;
IDID* pBgDIB;
IImage* pBgImage;
// 获取显示器位图
IDISPLAY_GetDeviceBitmap(po, &pScrBitmap);
// 获取显示缓冲区
IBITMAP_QueryInterface(pScrBitmap, AEECLSID_DIB, (void**)& pScrDIB);
// 创建背景位图
IBITMAP_CreateCompatibleBitmap(pScrBitmap, &pBgBitmap,pDIB->cx,pDIB->cy);
// 获取背景位图的缓冲区
IBITMAP_QueryInterface(pBgBitmap, AEECLSID_DIB, (void**)&pBgDIB);
// 载入背景图片
pBgImage = ISHELL_LoadImage(
((AEEApplet*)GETAPPINSTANCE() )->m_pIShell,
“bg.png”
);
// 替换IDisplay接口的目标位图
IDISPLAY_SetDestination(po, pBgBitmap);
IBITMAP_Release(pScrBitmap); // 引用计数减1
// 贴背景图
IIMAGE_Draw(pBgImage);
// 还原IDisplay接口的目标位图
IDISPLAY_SetDestination(po, pScrBitmap);
IBITMAP_Release(pBgBitmap); // 引用计数减1
IIMAGE_Release(pBgImage);
// 这时,pScrDIB里面是原来IHtmlViewer载入的页面的位图数据,pBgDIB里是背景图片
// 的位图数据,我们pScrDIB里白色的点用pBgDIB对应的点来替换。这里假设设备的颜色
// 深度为16bit
{
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;
}
}
// 调用真正的屏幕刷新函数
(GetOldUpdate())(po, bDefer);
// 释放资源
IDIB_Release(pBgDIB);
IBITMAP_Release(pBgBitmap);
}
好了,到此这篇文章也该结束了。最好我想狗尾续貂一下。上面讲的我想应该是一种较具普篇性的,应该不只限于为IHtmlViewer控件添加背景图(包括背景色),通过举一反三,还可以用于其它目的。希望大家可以共同探讨一下。