我用SDK写的一个树控件,自己响应WM_PAINT消息,为树控件添加了一个背景图片。自认为什么GDI资源都正确释放了。另外树控件还支持拖放操作,拖放操作时创建的imagelist也正确释放了。在XP下,程序比较稳定,可是到了98/me下,经过大量操作后,就会出错,弄得拖放的位图创建不起来,背景图片也会没有掉。实在是查不出什么原因了,附代码如下: case WM_PAINT:
{
if(g_pBackPicture == NULL)
{
break;
}
PAINTSTRUCT ps;
BeginPaint(hwnd, &ps);
HDC hMemDc = CreateCompatibleDC(ps.hdc);
RECT rcWnd;
GetWindowRect(hwnd, &rcWnd);
int width = rcWnd.right - rcWnd.left;
int height = rcWnd.bottom - rcWnd.top;
HBITMAP hbmp = (HBITMAP)CreateCompatibleBitmap(ps.hdc, width, height);
HBITMAP hOldBmp = (HBITMAP)SelectObject(hMemDc, hbmp);
OldProc = (WNDPROC)GetProp(hwnd, "prevproc");
CallWindowProc(OldProc, hwnd, WM_PAINT, (WPARAM)hMemDc , lParam);
HDC hmaskdc = CreateCompatibleDC(ps.hdc);//this dc may be null, so the background may be unavailabe.I puzzled about this!
HBITMAP hmaskbmp= NULL;
HBITMAP hmaskOldBmp = NULL;
if(hmaskdc != NULL)//I don't want this statement to be true in fact!
{
hmaskbmp = CreateCompatibleBitmap(ps.hdc, width, height);
hmaskOldBmp = (HBITMAP)SelectObject(hmaskdc, hmaskbmp);
RECT rcDraw = {0, 0, width, height};
if(g_pBackPicture)
PutPicture(g_pBackPicture, hmaskdc, rcDraw);//hmaskdc
BitBlt(hMemDc , 0, 0, width, height,hmaskdc,0,0,SRCAND);
}
BitBlt(ps.hdc, 0, 0, width, height, hMemDc,0,0,SRCCOPY);
SelectObject(hMemDc, hOldBmp);
DeleteObject(hbmp);
DeleteDC(hMemDc); if(hmaskdc)
{
SelectObject(hmaskdc, hmaskOldBmp);
DeleteObject(hmaskbmp);
DeleteDC(hmaskdc);
}
EndPaint(hwnd, &ps);
}
return TRUE;
{
if(g_pBackPicture == NULL)
{
break;
}
PAINTSTRUCT ps;
BeginPaint(hwnd, &ps);
HDC hMemDc = CreateCompatibleDC(ps.hdc);
RECT rcWnd;
GetWindowRect(hwnd, &rcWnd);
int width = rcWnd.right - rcWnd.left;
int height = rcWnd.bottom - rcWnd.top;
HBITMAP hbmp = (HBITMAP)CreateCompatibleBitmap(ps.hdc, width, height);
HBITMAP hOldBmp = (HBITMAP)SelectObject(hMemDc, hbmp);
OldProc = (WNDPROC)GetProp(hwnd, "prevproc");
CallWindowProc(OldProc, hwnd, WM_PAINT, (WPARAM)hMemDc , lParam);
HDC hmaskdc = CreateCompatibleDC(ps.hdc);//this dc may be null, so the background may be unavailabe.I puzzled about this!
HBITMAP hmaskbmp= NULL;
HBITMAP hmaskOldBmp = NULL;
if(hmaskdc != NULL)//I don't want this statement to be true in fact!
{
hmaskbmp = CreateCompatibleBitmap(ps.hdc, width, height);
hmaskOldBmp = (HBITMAP)SelectObject(hmaskdc, hmaskbmp);
RECT rcDraw = {0, 0, width, height};
if(g_pBackPicture)
PutPicture(g_pBackPicture, hmaskdc, rcDraw);//hmaskdc
BitBlt(hMemDc , 0, 0, width, height,hmaskdc,0,0,SRCAND);
}
BitBlt(ps.hdc, 0, 0, width, height, hMemDc,0,0,SRCCOPY);
SelectObject(hMemDc, hOldBmp);
DeleteObject(hbmp);
DeleteDC(hMemDc); if(hmaskdc)
{
SelectObject(hmaskdc, hmaskOldBmp);
DeleteObject(hmaskbmp);
DeleteDC(hmaskdc);
}
EndPaint(hwnd, &ps);
}
return TRUE;
使用boundschecker也找不到问题根源
期待高手
HDC hMemDC = CreateCompatibleDC(hDC);
Graphics gc(hMemDC);
...
//绘图
...
DeleteDC(hMemDC);
虽然hMemDC你删除了, 实际上是没有被删除, 因为gc还在引用它;
相关的问题还有很多, 但在XP一点问题都没有, 但在98下GDI资源马上就耗光了;而且伴随着很多GDI32访问违规(GDI32 ACCESS VIOLATION)提示, 实际你根本找不到哪一句访问违规;