可以缩放的异形窗口一个矩形裁剪区(rgn),4个角裁剪区(rgnlt,rgnrt,rgnrb,rgnlb).
矩形裁剪区大小可以变化,4个角裁剪区大小不变,假定都是10*10,位置对应于矩形裁剪区(rgn)的4个角.1.  生成rgnlt,rgnrt,rgnrb,rgnlb2.在onsize中
         CRgn rgn;
rgn.CreateRectRgn (0, 0, rcClient.Width0, rcClient.Height0);
        //不知道怎么弄了
rgn.CombineRgn(&rgn, rgnlt, RGN_AND);//?

解决方案 »

  1.   

    假定4个角裁剪区大小不变,假定都是10*10
    在onsize中 CRect rect, rect2;
    CRgn rgn[4];
    CRgn rgnWnd; GetClientRect(rect);
    GetWindowRect(rect2);
    rect.right = rect.left + rect2.Width();
    rect.bottom = rect.top + rect2.Height();
    rgn[0].CreateRectRgn(rect.left, rect.top, rect.left + 10, rect.top + 10);
    rgn[1].CreateRectRgn(rect.right - 10, rect.top, rect.right, rect.top + 10);
    rgn[2].CreateRectRgn(rect.left, rect.bottom - 10, rect.left + 10, rect.bottom);
    rgn[3].CreateRectRgn(rect.right - 10, rect.bottom - 10, rect.right, rect.bottom); rgnWnd.CreateRectRgn(rect.left, rect.top, rect.right, rect.bottom);
    rgnWnd.CombineRgn(&rgnWnd, &rgn[0], RGN_XOR);
    rgnWnd.CombineRgn(&rgnWnd, &rgn[1], RGN_XOR);
    rgnWnd.CombineRgn(&rgnWnd, &rgn[2], RGN_XOR);
    rgnWnd.CombineRgn(&rgnWnd, &rgn[3], RGN_XOR); SetWindowRgn((HRGN)rgnWnd.Detach(), TRUE);
      

  2.   

    生成rgnlt,rgnrt,rgnrb,rgnlb 的代价比较高,就是流行的Bmp2Rgn 
    这4个区域怎么和rgn[4]产生反应?
      

  3.   

    rgnlt,rgnrt,rgnrb,rgnlb  只生成一次
    不多次生成
      

  4.   

    rgnWnd的4个角形状同rgnlt,rgnrt,rgnrb,rgnlb
    rgnlt,rgnrt,rgnrb,rgnlb只生成一次
      

  5.   

    如果rgnlt,rgnrt,rgnrb,rgnlb是复杂的区域, 用位图抠像创建他们的rgn, 在初始化时只创建一次即可, 这个可以自己组织
    下面的代码是根据位图创建rgnbool CxxDlg::CreateBitmapRgn(HBITMAP hBitmap, COLORREF clrTrans, CRgn &rgnOut)
    {
    CDC memDC, *pDC = NULL;
    CBitmap bmp, *pOldBitmap = NULL;
    COLORREF clr;
    long x, y;
    CRgn rgnTemp;
    BITMAP bm; if (!hBitmap)
    {
    return false;
    }
    bmp.Attach(hBitmap); //获取位图尺寸
    bmp.GetBitmap(&bm); pDC = new CClientDC(this);
    memDC.CreateCompatibleDC(pDC);
    pOldBitmap = memDC.SelectObject(&m_bmp);
    //首先创建位图大小的矩形区域区域
    rgnOut.CreateRectRgn(0, 0, bm.bmWidth, bm.bmHeight);
    //下面的两层循环为检查背景位图象素颜色,进行透明区域处理;
    //当象素颜色为指定的透明值时,即将该点从区域中剪裁掉。
    for(x=0; x<=bm.bmWidth; x++)
    {
    for(y=0; y<=bm.bmHeight; y++)
    {
    //取得坐标处象素的颜色值
    clr = memDC.GetPixel(x, y);
    if(clr == clrTrans) //透明色
    {
    //象素颜色为指定的透明色,创建透明“微区域”
    rgnTemp.CreateRectRgn(x, y, x+1, y+1);
    //“扣像”,从完整的区域中“扣除”透明的“微区域”
    rgnOut.CombineRgn(&rgnOut, &rgnTemp, RGN_XOR);
    //删除刚创建的透明“微区域”,释放资源
    rgnTemp.DeleteObject(); 
    }
    }
    }
    memDC.SelectObject(pOldBitmap);

    delete pDC; bmp.Detach(); return true;
    }
    用成员变量保存rgnlt,rgnrt,rgnrb,rgnlb
    如:m_rgnlt,m_rgnrt,m_rgnrb,m_rgnlb
    在对话框初始化的时候创建他们
    CreateBitmapRgn(bmp1, clrTrans, m_rgnlt);
    CreateBitmapRgn(bmp2, clrTrans, m_rgnrt);
    CreateBitmapRgn(bmp3, clrTrans, m_rgnrb);
    CreateBitmapRgn(bmp4, clrTrans, m_rgnlb);在onsize中 :
        CRect        rect, rect2;
        CRgn        rgnWnd;    GetClientRect(rect);
        GetWindowRect(rect2);
        rect.right = rect.left + rect2.Width();
        rect.bottom = rect.top + rect2.Height();    rgnWnd.CreateRectRgn(rect.left, rect.top, rect.right, rect.bottom);
        rgnWnd.CombineRgn(&rgnWnd, &m_rgnlt, RGN_XOR);
        rgnWnd.CombineRgn(&rgnWnd, &m_rgnrt, RGN_XOR);
        rgnWnd.CombineRgn(&rgnWnd, &m_rgnrb, RGN_XOR);
        rgnWnd.CombineRgn(&rgnWnd, &m_rgnlb, RGN_XOR);    SetWindowRgn((HRGN)rgnWnd.Detach(), TRUE);
      

  6.   

    我已经弄出来了
    Onsize中,以右上角为例:RECT rect;
    CRgn rgnRT;
    CRgn rgnWnd;
    GetClientRect(rect);
    int a1=rect.right - m_szRT.cx,a2=rect.top,a3=rect.right,a4=rect.top+m_szRT.cy;
    rgnRT.CreateRectRgn(a1,a2 , a3, a4 );//创建右上角区域
    int nOffsetx=rect.right - m_szRT.cx;
    m_cRgnRT.OffsetRgn(nOffsetx,0);//将右上角图片区域移动到右上角,XOR
    rgnRT.CombineRgn(&rgnRT,m_cRgnRT,RGN_XOR);//裁剪右上角
    rgnWnd.CreateRectRgnIndirect(&rect);
    rgnWnd.CombineRgn(&rgnWnd,&rgnRT, RGN_XOR);//将裁剪后的右上角合并到主区域,XOR
    rgnRT.DeleteObject();
    rgnWnd.DeleteObject();
    m_cRgnRT.OffsetRgn(-nOffsetx,0);//返回原来的位置
      

  7.   

    按比例缩放就了啊,和CRect差不多吧.