none
使用 SelectClipRgn 碰到的问题 RRS feed

  • 问题

  • 我想在一个CScrollView中画一个椭圆,然后用GradientFill进行渐变填充,如果椭圆比较大,超出窗口尺寸,拖动滚动条时发现图形有重叠现象,不拖动滚动条椭圆显示正常。以下是代码

    void CABView::OnDraw(CDC* pDC)
    {
     CABDoc* pDoc = GetDocument();
     ASSERT_VALID(pDoc);
     // TODO: add draw code for native data here
     CRect rect=CRect(0,0,200,500);
     CRgn hRgn;
     hRgn.CreateEllipticRgnIndirect (rect);
      pDC->SelectClipRgn(&hRgn,RGN_COPY);
     GradientRectangle(pDC,rect,RGB(255,255,255),RGB(0,0,0),90,1);
     hRgn.DeleteObject();
     pDC->SelectClipRgn(NULL);
    }

    inline COLOR16 R16(COLORREF c) { return GetRValue(c)<<8; }
    inline COLOR16 G16(COLORREF c) { return GetGValue(c)<<8; }
    inline COLOR16 B16(COLORREF c) { return GetBValue(c)<<8; }

    inline COLOR16 R16(COLORREF c0, COLORREF c1) { return ((GetRValue(c0)+GetRValue(c1))/2)<<8; }
    inline COLOR16 G16(COLORREF c0, COLORREF c1) { return ((GetGValue(c0)+GetGValue(c1))/2)<<8; }
    inline COLOR16 B16(COLORREF c0, COLORREF c1) { return ((GetBValue(c0)+GetBValue(c1))/2)<<8; }

    BOOL CABView::GradientRectangle(CDC* dc, CRect rect, COLORREF c0, COLORREF c1, int angle,int dirct)
    {
     TRIVERTEX vert[4] = {
      { rect.left, rect.top,  R16(c0), G16(c0), B16(c0), 0 },    //  0:c0         3:(c0+c1)/2
      { rect.right, rect.bottom,  R16(c1), G16(c1), B16(c1), 0 },
      { rect.left, rect.bottom,  R16(c0, c1), G16(c0, c1), B16(c0, c1), 0 }, //
      { rect.right, rect.top,  R16(c0, c1), G16(c0, c1), B16(c0, c1), 0 } //  2:(c0+c1)/2  1: c1
     };
     
     ULONG Index[] = { 0, 1, 2, 0, 1, 3};
     
     switch ( angle % 180 )
     {
     case   0:
      if (dirct == 1)
      {
       vert[0].Red=R16(c1);vert[0].Green=G16(c1);vert[0].Blue=B16(c1);
       vert[1].Red=R16(c0);vert[1].Green=G16(c0);vert[1].Blue=B16(c0);
      }
      return GradientFill(dc->GetSafeHdc(), vert, 2, &Index, 1, GRADIENT_FILL_RECT_H);
      break;
     case  45:
      if (dirct == 1)
      {
       vert[2].Red= R16(c0);vert[2].Green=G16(c0);vert[2].Blue=B16(c0) ;
       vert[0].Red= R16(c0, c1);vert[0].Green=G16(c0, c1);vert[0].Blue=B16(c0, c1);
       vert[3].Red=R16(c1);vert[3].Green=G16(c1);vert[3].Blue=B16(c1);
       vert[1].Red=R16(c0, c1);vert[1].Green=G16(c0, c1);vert[1].Blue=B16(c0, c1);
      }
      else
      {
       vert[1].Red= R16(c0);vert[1].Green=G16(c0);vert[1].Blue=B16(c0) ;
       vert[3].Red= R16(c0, c1);vert[3].Green=G16(c0, c1);vert[3].Blue=B16(c0, c1);
       vert[0].Red=R16(c1);vert[0].Green=G16(c1);vert[0].Blue=B16(c1);
       vert[2].Red=R16(c0, c1);vert[2].Green=G16(c0, c1);vert[2].Blue=B16(c0, c1);
      }
      return GradientFill(dc->GetSafeHdc(), vert, 4, &Index, 2, GRADIENT_FILL_TRIANGLE);
            break;
     case  90:
      if (dirct == 1)
      {
       vert[0].Red=R16(c1);vert[0].Green=G16(c1);vert[0].Blue=B16(c1);
       vert[1].Red=R16(c0);vert[1].Green=G16(c0);vert[1].Blue=B16(c0);
      }
      return GradientFill(dc->GetSafeHdc(), vert, 2, Index, 1, GRADIENT_FILL_RECT_V);
      break;
     case 135:
      vert[0].x = rect.right;
      vert[3].x = rect.left;
      vert[1].x = rect.left;
      vert[2].x = rect.right;
      if (dirct == 0)
      {
       vert[3].Red= R16(c0);vert[3].Green=G16(c0);vert[3].Blue=B16(c0) ;
       vert[0].Red= R16(c0, c1);vert[0].Green=G16(c0, c1);vert[0].Blue=B16(c0, c1);
       vert[2].Red=R16(c1);vert[2].Green=G16(c1);vert[2].Blue=B16(c1);
       vert[1].Red=R16(c0, c1);vert[1].Green=G16(c0, c1);vert[1].Blue=B16(c0, c1);
      }
      return GradientFill(dc->GetSafeHdc(), vert, 4, Index, 2, GRADIENT_FILL_TRIANGLE);
      break;
     }
     
     return FALSE;
     }

     

    2011年7月28日 9:37

答案