自己用API(非MFC)写了个窗口UI,窗口皮肤和按钮都是自己绘制的,有如下功能:当光标移过按钮的时候,按钮是一种样式,光标不在按钮上时,按钮是另一种样式。现在有如下问题:执行程序时,前几次都很正常,到第十次光标放到按钮上的时候,按钮样式改变,之后不管怎样移动光标,按钮的样式都不会改变,好像是窗口不再重绘了。但是调试的时候没有这个问题,哪位高手可以指点一下,不胜感激!代码:
//int buNo=0;全局变量,用来存储ifButtonMove函数的返回值(即按钮区域的编号)
//这是ifButtonMove的实现
int ifButtonMove(int x,int y,int &cx,int &cy,int &ex,int &ey)
{
if(x>58 && x<246 && y>218 && y<259)
{
cx=58;ex=246;cy=218;ey=259;
return 4;//单词模式
}
if(x>58 && x<246 && y>262 && y<303)
{
cx=58;ex=246;cy=262;ey=303;
return 5;//百科模式
}
if(x>58 && x<246 && y>304 && y<345)
{
cx=58;ex=246;cy=304;ey=345;
return 6;//故事模式
}
if(x>58 && x<246 && y>347 && y<388)
{
cx=58;ex=246;cy=347;ey=388;
return 7;//歌曲模式
}
if(x>58 && x<246 && y>390 && y<431)
{
cx=58;ex=246;cy=390;ey=431;
return 8;//游戏模式
}
return 0;
}
//buttonWord1,buttonWord2等变量都是HBITMAP句柄,用来加载按钮图片
//skinBmp是加载窗口背景的图片句柄
//这是消息处理函数涉及这部分的代码
case WM_MOUSEMOVE:
mousePt.x=LOWORD(lParam);
mousePt.y=HIWORD(lParam);
buNo=ifButtonMove(mousePt.x,mousePt.y,cx,cy,ex,ey);
if(buNo!=0)//不等于0为在按钮上,等于0不在按钮上
{
frashRect1.left=frashRect2.left;
frashRect1.right=frashRect2.right;
frashRect1.top=frashRect2.top;
frashRect1.bottom=frashRect2.bottom;
frashRect2.left=cx;
frashRect2.right=ex;
frashRect2.top=cy;
frashRect2.bottom=ey;
InvalidateRect(hWnd,&frashRect1,FALSE);
InvalidateRect(hWnd,&frashRect2,FALSE);
}
else if(frashRect2.left!=0)
{
InvalidateRect(hWnd,&frashRect2,FALSE);
frashRect2.left=0;
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: 在此添加任意绘图代码... //绘制窗口皮肤
HDC memoryDC,skinDC,bwDC,bbDC,bstDC,bsoDC,bgDC;
HBITMAP bmp; memoryDC=CreateCompatibleDC(hdc);
skinDC=CreateCompatibleDC(hdc);
bwDC=CreateCompatibleDC(hdc);
bbDC=CreateCompatibleDC(hdc);
bstDC=CreateCompatibleDC(hdc);
bsoDC=CreateCompatibleDC(hdc);
bgDC=CreateCompatibleDC(hdc);
bmp = CreateCompatibleBitmap(hdc, 1050, 610);
SelectObject(memoryDC, bmp); SelectObject(skinDC,skinBmp);
//绘制按钮
if(buNo==4)
{
SelectObject(bwDC,buttonWord2);
}
else
{
SelectObject(bwDC,buttonWord1);
}
if(buNo==5)
{
SelectObject(bbDC,buttonBaike2);
}
else
{
SelectObject(bbDC,buttonBaike1);
}
if(buNo==6)
{
SelectObject(bstDC,buttonStroy2);
}
else
{
SelectObject(bstDC,buttonStroy1);
}
if(buNo==7)
{
SelectObject(bsoDC,buttonSong2);
}
else
{
SelectObject(bsoDC,buttonSong1);
}
if(buNo==8)
{
SelectObject(bgDC,buttonGame2);
}
else
{
SelectObject(bgDC,buttonGame1);
}
//-----------------缓冲区结束 //------绘图代码
BitBlt(memoryDC,0,0,1050,610,skinDC,0,0,SRCCOPY);//皮肤
TransparentBlt(memoryDC,58,218,188,41,bwDC,0,0,188,41,RGB(0,0,0));//单词按钮
TransparentBlt(memoryDC,58,262,188,41,bbDC,0,0,188,41,RGB(0,0,0));//百科按钮
TransparentBlt(memoryDC,58,304,188,41,bstDC,0,0,188,41,RGB(0,0,0));//故事按钮
TransparentBlt(memoryDC,58,347,188,41,bsoDC,0,0,188,41,RGB(0,0,0));//儿歌按钮
TransparentBlt(memoryDC,58,390,188,41,bgDC,0,0,188,41,RGB(0,0,0));//游戏按钮 DeleteDC(skinDC);
DeleteDC(bwDC);
DeleteDC(bbDC);
DeleteDC(bstDC);
DeleteDC(bsoDC);
DeleteDC(bgDC);
ReleaseDC(hWnd,hdc);
EndPaint(hWnd, &ps);
break;

解决方案 »

  1.   

    不好意思,上面有一个错误。DeleteDC上应该还有一个输出缓冲区图形的
    BitBlt(hdc,0,0,1050,610,memoryDC,0,0,SRCCOPY);
    不过这个没什么影响。
      

  2.   

    感觉是内存泄露啊,而且你的图像申请的非常之大呢。
    注意使用DeleteObject
      

  3.   

    另外你的DeleteDC和ReleaseDC
    返回值查一下,确定都释放了么CreateCompatibleBitmap这个消耗内存太厉害了,一定要用DeleteObject释放。
    能折腾10下,说明你机器内存配置真心不错
      

  4.   

    刚才网断了,不好意思!这会儿正在试验加上DeleteObject行不行,先谢了!
      

  5.   

    真心感谢tiger9991,果然是我忘了释放memoryDC和bmp了。不过我在想,因为我的界面是全图片的,这么频繁的创建和释放是不是太折腾了,能不能做成全局的,只创建和释放一次?