vc中在某区域用黑颜色画刷绘制圆角矩形,而后用白颜色擦除时却留有黑方框?通过最小化再还原后黑方框就消失了?不知为什么? 

解决方案 »

  1.   

    代码如下:main.cpp

    int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
    {
             。。
    while(GetMessage(&Msg,NULL,0,0))
    {
    TranslateMessage(&Msg);
    DispatchMessage(&Msg);
    }
    return Msg.wParam;   
    }
    LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
    {
    int a=0;
    switch(message)
    {
       case WM_CREATE:
       DialogBox(hInst,MAKEINTRESOURCE(IDD_DIALOG2),hwnd,(DLGPROC)DlgProc);
       return 0;
       case WM_PAINT:    //显现对象,开始游戏
       a++;  
       hdc=BeginPaint(hwnd,&ps);
       if(a==1)
       {
           Name1.visible();
          // PostMessage(hwnd,WM_MY_JUDGE,0,0);
       }
       EndPaint(hwnd,&ps);
       return 0;
       case WM_COMMAND:   //处理游戏界面里菜单的消息
       switch(LOWORD(wParam))
       {
       case IDM_PAUSE:
       //..........
       break;
       case IDM_STORE:
       //.........
       break;
       case IDM_GAME_HELP:
       DialogBox(hInst,MAKEINTRESOURCE(IDD_DIALOG1),hwnd,(DLGPROC)DlgProc);
       break;
       case IDM_ABOUT:
       DialogBox(hInst,MAKEINTRESOURCE(IDD_DIALOG),hwnd,(DLGPROC)DlgProc);
       break;
       case IDM_EXIT:
       PostMessage(hwnd,WM_DESTROY,0,0);
       break;
       }
               return 0;   
       case WM_KEYDOWN:  //按键
               switch(wParam)
       {
       case VK_LEFT:  //左移
       hdc=GetDC(hwnd);   
                   Name1.left();
       ReleaseDC(hwnd,hdc);
       break;
       case VK_RIGHT:  //右移
       hdc=GetDC(hwnd);   
       Name1.right();
       ReleaseDC(hwnd,hdc);
       break;
       case VK_SPACE:  //旋转
       hdc=GetDC(hwnd);   
                   Name1.roll();
       ReleaseDC(hwnd,hdc);
       break;
       case VK_DOWN:  //快速下落
       hdc=GetDC(hwnd);   
       Name1.down(1);
       ReleaseDC(hwnd,hdc);
       break;
       }
       PostMessage(hwnd,WM_MY_JUDGE,0,0); //移动结束,判断以下是否可以继续下落
       return 0;                   
       case WM_MY_JUDGE:   //判断是否可以继续下落,不是则进行处理
               if(Name1.judge()==0)  //是
       {
           hdc=GetDC(hwnd);
       Name1.down(0);
       ReleaseDC(hwnd,hdc);
       PostMessage(hwnd,WM_MY_JUDGE,0,0);
       }
       else PostMessage(hwnd,WM_MY_DEAL,0,0);  //否,进行处理
       return 0;
       case WM_MY_DEAL:  //进行处理,看是否结束还是运行下一个对象
               Name1.deal();
       return 0;
       case WM_MY_ANOTHER: //运行下一个对象
       Name1.~Name();
               PostMessage(hwnd,WM_MY_NEW,0,0);
       return 0;
       case WM_MY_NEW://??????
       return 0;
       case WM_MY_ENDC: //结束消息,弹出统计分数对话框
               DialogBox(hInst,MAKEINTRESOURCE(IDD_DIALOG3),hwnd,(DLGPROC)DlgProc3);
       SendMessage(hwnd,WM_DESTROY,0,0);
       return 0;  
       case WM_DESTROY:
       PostQuitMessage(0);
       return 0;
           default:
       return DefWindowProc(hwnd,message,wParam,lParam);
    }
    return(0);
    }
    BOOL CALLBACK DlgProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam)
    {
    switch(message)
    {
    case WM_INITDIALOG:
    return 1;
    case WM_COMMAND:
    switch(LOWORD(wParam))
    {
    case IDOK:
    EndDialog(hdlg,0);
    return 1;
    }
    break;
    case WM_CLOSE:
    EndDialog(hdlg,0);
    return 1;
    }
    return 0;
    }
    BOOL CALLBACK DlgProc3(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam)
    {
    switch(message)
    {
    case WM_INITDIALOG:
    // SetDlgltemInt(hdlg,IDC_EDIT,(UINT)count,TRUE);  //输出count的值
    return 1;
    case WM_COMMAND:
    switch(LOWORD(wParam))
    {
    case IDOK:
    EndDialog(hdlg,0);
    return 1;
    }
    break;
    case WM_CLOSE:
    EndDialog(hdlg,0);
    return 1;
    }
    return 0;
    }
    ***************************************
    define.h

    #define color BLACK_BRUSH
    #define ms  1000class Fun  //所有对象均继承的单格绘图、旋转类
    {
    public:
        int place[4][2];   //对象单元格
    int dot[3][2];   //敏感点
    int left_to_end;  //左极点
    int right_to_end;  //右极点
    void paint(int,int,COLORREF);  //单格绘图
    void left();  //左移
    void right();  //右移
    void down(int); //下移
    int judge();   //判断底下是否有砖块
    void current();  //当前对象对应的坐标,置1,对应栈单元格加1
    void visible();  //显现对象,单格绘图
    };class Name:public Fun   //继承Fun的部分对象的行为
    {
    public:
    Name(int,int,int,int,int,int,int,int);  //构造函数,使各数据获初值
    void roll();  //旋转
    void deal();  //消息WM_MY_DEAL的内容
    ~Name();  //析构不必要数据
    };void Fun::left()
    {
    if(left_to_end!=0)
    {
    int i;
    for(i=0;i<=3;i++) if(state[place[i][1]/15][place[i][0]/15-1]==1) break;
    if(i!=4) return;
    else
    {
    for(i=0;i<=3;i++)
    {
    paint(place[i][0],place[i][1],WHITE_BRUSH);
    place[i][0]-=15;
    paint(place[i][0],place[i][1],color);
    if((i!=3)&&(dot[i][0]!=-1)) dot[i][0]-=15;
    }
    right_to_end-=15;
    left_to_end-=15;
    }
    }
    }void Fun::right()
    {
    if(right_to_end!=285)
    {
    int i;
    for(i=0;i<=3;i++) if(state[place[i][1]/15][place[i][0]/15+1]==1) break;
    if(i!=4) return;
    else
    {
    for(i=3;i>=0;i--)
    {
    paint(place[i][0],place[i][1],WHITE_BRUSH);
    place[i][0]+=15;
    paint(place[i][0],place[i][1],color);
    if((i!=3)&&(dot[i][0]!=-1)) dot[i][0]+=15;
    }
    right_to_end+=15;
    left_to_end+=15;
    }
    }
    }void Fun::down(int control)    //下移,0自由下落,1快速下落
    {
    int i,j;
    switch(control)
    {
    case 0:
    Sleep(ms);   
    for(i=3;i>=0;i--)
    {
    paint(place[i][0],place[i][1],WHITE_BRUSH);
                place[i][1]+=15;
    paint(place[i][0],place[i][1],color);
    }
    break;
    case 1:
    Sleep(ms/5);    
    for(j=23;j>=0;j--)
    {
    for(i=3;i>=0;i--)
    {
    paint(place[i][0],place[i][1],WHITE_BRUSH);
    place[i][1]+=15;
    paint(place[i][0],place[i][1],color);
    }    
    for(i=0;i<=3;i++) if(dot[i][1]!=-1) dot[i][1]+=15;
    if(judge()==1)

    SendMessage(hwnd,WM_MY_DEAL,0,0);
    break;
    }
    }
    break;
    }
    for(i=0;i<=3;i++) if(dot[i][1]!=-1) dot[i][1]+=15;
    }void Fun::visible()   //判断显示位置是否有砖块,有则中止游戏,否则予以显示
    {
       int i,x,y;
       for(i=0;i<=2;i++)
         if(dot[i][0]!=-1)
         {
            x=dot[i][1]/15;
            y=dot[i][0]/15;
            if(state[x][y]==1)     //有砖块
            {
               SendMessage(hwnd,WM_MY_ENDC,0,0);
               return;
            }
         }    
       for(i=0;i<=3;i++) paint(place[i][0],place[i][1],color);  //绘图显示
    }void Fun::current()  //将对象当前位置对应的坐标置1,对应栈单元格也加1,主要用于对象位置固定时
    {
       int i;
       for(i=0;i<=3;i++)
       {
          state[place[i][1]/15][place[i][0]/15]=1;
          flag[place[i][1]/15]++;
       }
    }int Fun::judge()  //判断对象下是否有砖块,返回0、1
    {
       int i;
       for(i=0;i<=2;i++)
          if(dot[i][1]==345) return 1;
          else if((dot[i][0]!=-1)&&state[dot[i][1]/15+1][dot[i][0]/15]==1) return 1;
       return 0;
    }void Fun::paint(int x,int y,COLORREF hbcolor)  //绘图
    {
       hB=(HBRUSH)GetStockObject(hbcolor);
       SelectObject(hdc,hB);
       switch(hbcolor)
       {
       case BLACK_BRUSH:
       RoundRect(hdc,x,y,x+15,y+15,2,2);
       break;
       case WHITE_BRUSH:
       Rectangle(hdc,x,y,x+15,y+15);
       break;
       }
       DeleteObject(hB);
    }Name::Name(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4)  //构造函数,使各数据获初值
    {
       place[0][0]=x1,place[0][1]=y1;
       place[1][0]=x2,place[1][1]=y2;
       place[2][0]=x3,place[2][1]=y3;
       place[3][0]=x4,place[3][1]=y4;   left_to_end=place[0][0];
       right_to_end=place[0][0];
       int i;
       for(i=1;i<=3;i++)
       if(left_to_end>place[i][0]) left_to_end=place[i][0];
       else if(right_to_end<place[i][0]) right_to_end=place[i][0];   int k=0,j;
       dot[0][0]=place[0][0],dot[0][1]=place[0][1];
       for(i=1;i<=2;i++)
       {
       dot[i][0]=-1;
       dot[i][1]=-1;
       }
       for(i=1;i<=3;i++)
       if(place[i][0]==dot[k][0])  
       {
       if(place[i][1]>dot[k][1]) dot[k][1]=place[i][1];
       }
       else
       for(j=k;j>=0;j--)
       if(place[i][0]==dot[j][0])
       {
       if(place[i][1]>dot[j][1]) dot[j][1]=place[i][1];
                       break;
       }
       else if((place[i][0]!=dot[j][0])&&(j==0))
       {
       k++;
       dot[k][0]=place[i][0],dot[k][1]=place[i][1];
       break;
       }
    }void Name::roll()  //部分对象的旋转
    {
    //????
    }
    void Name::deal()  //消息WM_MY_DEAL的内容
    {
    int i,x=0,pot;
    int num=0;
    for(i=0;i<=2;i++) if(x<dot[i][1]) x=dot[i][1];
    x/=15;  //下落的最低所在行
    for(i=x;i>=x-4;i--)
    {
    if(flag[i]==24) num++;
    if(num==1) pot=i;  //记录满行的最低位置
    }
    if(num==0)
    {
    if(flag[0]>0) PostMessage(hwnd,WM_MY_ENDC,0,0);  //满界,发送结束消息
    }
    else
    {
    int c=0,j;    
    count+=num;
    for(i=pot;i>=pot-num;i--) flag[i]=0;  //满行标志置0
            hdc=GetDC(hwnd);
    for(i=pot-num;i>=0;i--)  //处理底坐标和栈
    {
    for(j=0;j<=19;j++)
    {
    if(state[i][j]==1)
    {
    c++;
    paint(j*15,i*15,WHITE_BRUSH);
    state[i][j]=0;
    paint(j*15,(i+num)*15,color);
    state[i+num][j]=1;
    }
    if(flag[i]==c) break;
    }
    flag[i+num]=flag[i];
    flag[i]=0;
    }
    ReleaseDC(hwnd,hdc);
    PostMessage(hwnd,WM_MY_ANOTHER,0,0);   //发消息运行下一个对象
    }
    }Name::~Name()
    {
       int i;
       for(i=0;i<=2;i++)
       {
          dot[i][0]=-1;
          dot[i][1]=-1;
       }
       left_to_end=0;
       right_to_end=0;
    }Name Name1(135,0,150,0,150,15,150,30);
    ******************************************
    其中WM_MY_**为自定义消息。
    请看一下以上问题如何解决。
      

  2.   

    case BLACK_BRUSH: 
      RoundRect(hdc,x,y,x+15,y+15,2,2); 
      break; 
      case WHITE_BRUSH: 
      Rectangle(hdc,x,y,x+15,y+15); 
      break; 画黑的,用的是RoundRect,画白的是Rectangle,黑的后面两个参数
    nWidth 
    [in] Specifies the width of the ellipse used to draw the rounded corners. 
    nHeight 
    [in] Specifies the height of the ellipse used to draw the rounded corners. 建议两个用同一个!不要用两个!
      

  3.   

    把Rectangle的范围扩大一些应该可以覆盖掉了
    Rectangle(hdc,x-1,y-1,x+16,y+16); 
      

  4.   

    前先,我都用RoundRect(hdc,x,y,x+15,y+15,2,2),不行的;
    把范围扩大一些也不可以覆盖掉;
    至于我改的代码为
    void Fun::paint(int x,int y,COLORREF hbcolor)
    {
       hB=(HBRUSH)GetStockObject(hbcolor);
       SelectObject(hdc,hB);
       RoundRect(hdc,x,y,x+15,y+15,2,2);
       InvalidateRect(hwnd,NULL,1);
       DeleteObject(hB);
    } 也不行,不知具体如何使用InvalidateRect()才能解决问题?
      

  5.   

    调用 CRect::InflateRect或CRect::DeflateRect把Rect放大或缩小试试
      

  6.   

    void Fun::paint(int x,int y,COLORREF hbcolor)  //绘图
    {
    hB=(HBRUSH)GetStockObject(hbcolor);
    SelectObject(hdc,hB);
    switch(hbcolor)
    {
    case BLACK_BRUSH:
    RoundRect(hdc,x,y,x+15,y+15,2,2);
    break;
    case WHITE_BRUSH:
    Rectangle(hdc,x,y,x+15,y+15);
    break;
    }
    RECT rc(x,y,x+15,y+15);      //刷新区域
    InvalidateRect(hwnd,rc,TRUE);
    DeleteObject(hB);
    }
      

  7.   

    厉害,居然不用mfc写而用纯api
      

  8.   


    合不拢应该是范围计算错了吧,不介意的话把程序发给我看看:[email protected]