使用CreateStreamOnHGlobal来显示JPG图像的古怪问题
通过网络不断接收JPG图像,当图像接收完了之后就显示出来。接收完很多图像,显示过很多图像之后,显示就出现问题了。我仔细调试过代码,发现图像的传输和接收没有问题(我把接收的图像都用文件保存在硬盘上,发现都是好的)。
编程思路:
定义一个全局句柄
HGLOBAL g_hPicBuf=NULL;//用来保存图像
BYTE *g_pPicBuf=NULL;
1 接收函数
在确定来了一幅新图像的时候,释放g_hPicBuf,然后再开辟一段新内存,新内存的大小根据数据的包头分析出来。
if(g_hPicBuf != NULL)
{
GlobalUnlock(g_hPicBuf);
GlobalFree(g_hPicBuf);
}
g_hPicBuf = GlobalAlloc(GHND, iLen);
g_pPicBuf = (BYTE *)GlobalLock(g_hPicBuf);
接下来就不断把数据复制到g_pPicBuf中。
当一幅图像接收完整的时候,就调用显示图像的函数。
2 显示函数是用双缓存的,思路 从g_hPicBuf,利用CreateStreamOnHGlobal等函数来得到CBitmap,然后从CBitmap形成一个内存DC,最后把这个内存DC传给OnPaint函数就可以了。
定义一个全局内存DC
CDC g_dc;
int g_iWidth;
int g_iHeight;
函数中:
HANDLE h;
HBITMAP hBm;
CBitmap bm;
BITMAP bwh;
IStream *pStm = NULL;
IPicture *pPic = NULL;
CreateStreamOnHGlobal(g_hPicBuf, FALSE, &pStm);
OleLoadPicture(pStm, 0, FALSE, IID_IPicture, (void **)&pPic);
pPic-> get_Handle((OLE_HANDLE *)&h);
hBm = (HBITMAP)CopyImage(h, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG);
bm.Attach(hBm);
bm.GetBitmap(&bwh);
g_iWidth = bwh.bmWidth;
g_iHeight = bwh.bmHeight;
g_dc.dc.DeleteDC();
g_dc.dc.CreateCompatibleDC(NULL);
g_dc.dc.SelectObject(bm);
bm.Detach();
pPic-> Release();
pStm-> Release();
//////////////////////////////////
我在调试过程中,发现
接收完很多图像,显示过很多图像之后,显示就出现问题了。
g_iWidth和g_iHeight完全不对了,但是我把g_pPicBuf中的数据保存为磁盘文件,又发现磁盘文件完全正确,这说明g_hPicBuf和g_pPicBuf是正确的。
请问怎么回事?是CreateStreamOnHGlobal,OleLoadPicture等函数使用有问题么?
谢谢!
[解决办法]
显示出问题很有可能是资源泄漏造成的。
看了你的程序,问题应该出在CopyImage拷贝出来的BITMAP没有释放。CopyImage拷贝出来的是一份新的Bitmap,因此需要释放,而在你的代码中调用了bm.Detach,所以hBm最后没有被释放掉。可以去掉bm.Detach或者调DeleteObject(hBm)试一下看看。