cardrgnmouse.cpp

来自「一个类似windows」· C++ 代码 · 共 643 行 · 第 1/2 页

CPP
643
字号
        //
        //add the cards to the destination stack
        //
        CardStack temp = pDestStack->GetCardStack();
        temp.Push(dragstack);
        
        pDestStack->SetCardStack(temp);
//        pDestStack->Update();        //Update this stack's card count + size
//        pDestStack->UpdateFaceDir(temp);
        
        //    Call the remove callback on THIS stack, if one is specified
        //
        if(RemoveCallback)
            RemoveCallback(*this, iNumDragCards);

        //    Call the add callback, if one is specified
        //
        if(pDestStack->AddCallback)
            pDestStack->AddCallback(*pDestStack, pDestStack->cardstack);//index, deststack->numcards);
        
        RedrawIfNotDim(pDestStack, true);
        TRACE ( "done dropping card\n" );
    }

    //
    //    Otherwise, let the cards snap back onto this stack
    //
    else
    {
        TRACE ( "no, putting card back\n" );
        hdc = GetDC((HWND)parentWnd);
        TRACE ( "calling ZoomCard()\n" );
        ZoomCard(hdc, x - mousexoffset, y - mouseyoffset, this);
        TRACE ( "cardstack += dragstack\n" );
        cardstack += dragstack;
        TRACE ( "calling ReleaseDC()\n" );
        ReleaseDC((HWND)parentWnd, hdc);

        TRACE ( "calling Update()\n" );
        Update();        //Update this stack's card count + size
        TRACE ( "done putting card back\n" );
    }
    
    ReleaseDragBitmaps();
    ReleaseCapture();
    
    TRACE ( "OnLButtonUp() done\n" );
    return true;
}

bool CardRegion::OnMouseMove(int x, int y)
{
    HDC hdc;

    hdc = GetDC((HWND)parentWnd);
        
    x -= mousexoffset;
    y -= mouseyoffset;
        
    MoveDragCardTo(hdc, x, y);

    //BitBlt(hdc, nDragCardWidth+10, 0, nDragCardWidth, nDragCardHeight, hdcBackGnd, 0, 0, SRCCOPY);
    //BitBlt(hdc, 0, 0, nDragCardWidth, nDragCardHeight, hdcDragCard, 0, 0, SRCCOPY);
    
    ReleaseDC((HWND)parentWnd, hdc);
        
    oldx = x;
    oldy = y;
    
    return true;
}

//
//    There is a bug in BitBlt when the source x,y
//    become < 0. So this wrapper function simply adjusts
//    the coords so that we never try to blt in from this range
//
BOOL ClippedBitBlt(HDC hdcDest, int x, int y, int width, int height, HDC hdcSrc, int srcx, int srcy, DWORD dwROP)
{
    if(srcx < 0)
    {
        x = 0 - srcx;
        width = width + srcx;
        srcx = 0;
    }

    if(srcy < 0)
    {
        y = 0 - srcy;
        height = height + srcy;
        srcy = 0;
    }

    return BitBlt(hdcDest, x, y, width, height, hdcSrc, srcx, srcy, dwROP);
}

void CardRegion::MoveDragCardTo(HDC hdc, int x, int y)
{
    RECT inter, rect1, rect2;

    //mask off the new position of the drag-card, so
    //that it will not be painted over
    ClipCard(hdc, x, y, nDragCardWidth, nDragCardHeight);
    
    //restore the area covered by the card at its previous position
    BitBlt(hdc, oldx, oldy, nDragCardWidth, nDragCardHeight, hdcBackGnd, 0, 0, SRCCOPY);

    //remove clipping so we can draw the card at its new place
    SelectClipRgn(hdc, NULL);
    
    //if the card's old and new positions overlap, then we
    //need some funky code to update the "saved background" image,
    SetRect(&rect1, oldx, oldy, oldx+nDragCardWidth, oldy+nDragCardHeight);
    SetRect(&rect2,    x,    y,    x+nDragCardWidth,    y+nDragCardHeight);
    
    if(IntersectRect(&inter, &rect1, &rect2))
    {
        int interwidth = inter.right-inter.left;
        int interheight = inter.bottom-inter.top;
        int destx, desty, srcx, srcy;
        
        if(rect2.left > rect1.left) 
        {    
            destx = 0; srcx = nDragCardWidth - interwidth; 
        }
        else
        {
            destx = nDragCardWidth  - interwidth; srcx = 0;
        }
        
        if(rect2.top  > rect1.top) 
        {
            desty = 0; srcy = nDragCardHeight - interheight;
        }
        else 
        {
            desty = nDragCardHeight - interheight; srcy = 0;
        }
        
        //shift the bit we didn't use for the restore (due to the clipping)
        //into the opposite corner
        BitBlt(hdcBackGnd, destx,desty, interwidth, interheight, hdcBackGnd, srcx, srcy, SRCCOPY);
        
        ExcludeClipRect(hdcBackGnd, destx, desty, destx+interwidth, desty+interheight);
        
        //this bit requires us to clip the BitBlt (from screen to background)
        //as BitBlt is a bit buggy it seems
        ClippedBitBlt(hdcBackGnd, 0,0, nDragCardWidth, nDragCardHeight, hdc, x, y, SRCCOPY);
        SelectClipRgn(hdcBackGnd, NULL);
    }
    else
    {
        BitBlt(hdcBackGnd, 0,0, nDragCardWidth, nDragCardHeight, hdc, x, y, SRCCOPY);
    }
    
    //finally draw the card to the screen
    DrawCard(hdc, x, y, hdcDragCard, nDragCardWidth, nDragCardHeight);
}


//extern "C" int _fltused(void) { return 0; }
//extern "C" int _ftol(void) { return 0; }

//
//    Better do this in fixed-point, to stop
//    VC from linking in floatingpoint-long conversions
//
//#define FIXED_PREC_MOVE
#ifdef  FIXED_PREC_MOVE
#define PRECISION 12
void ZoomCard(HDC hdc, int xpos, int ypos, CARDSTACK *dest)
{
    long dx, dy, x , y;

    
    int apparentcards;
    x = xpos << PRECISION; y = ypos << PRECISION;

    oldx = (int)xpos;
    oldy = (int)ypos;

    apparentcards=dest->numcards/dest->threedcount;

    int idestx = dest->xpos + dest->xoffset * (apparentcards);// - iNumDragCards); 
    int idesty = dest->ypos + dest->yoffset * (apparentcards);// - iNumDragCards);

    //normalise the motion vector
    dx = (idestx<<PRECISION) - x;
    dy = (idesty<<PRECISION) - y;
    long recip = (1 << PRECISION) / 1;//sqrt(dx*dx + dy*dy);

    dx *= recip * 16;//CARDZOOMSPEED; 
    dy *= recip * 16;//CARDZOOMSPEED;

    //if(dx < 0) dxinc = 1.001; else

    for(;;)
    {
        int ix, iy;
        x += dx;
        y += dy;

        ix = (int)x>>PRECISION;
        iy = (int)y>>PRECISION;
        if(dx < 0 && ix < idestx) ix = idestx;
        else if(dx > 0 && ix > idestx) ix = idestx;

        if(dy < 0 && iy < idesty) iy = idesty;
        else if(dy > 0 && iy > idesty) iy = idesty;

        MoveDragCardTo(hdc, ix, iy);

        if(ix == idestx && iy == idesty)
            break;

        oldx = (int)x >> PRECISION;
        oldy = (int)y >> PRECISION;

        //dx *= 1.2;
        //dy *= 1.2;

        Sleep(10);
    }
}
#else
void CardRegion::ZoomCard(HDC hdc, int xpos, int ypos, CardRegion *pDestStack)
{
    TRACE ( "ENTER ZoomCard()\n" );
    double dx, dy, x ,y;
    int apparentcards;
    x = (double)xpos; y = (double)ypos;

    oldx = (int)x;
    oldy = (int)y;

    apparentcards = pDestStack->cardstack.NumCards() / pDestStack->nThreedCount;

    int idestx = pDestStack->xpos + pDestStack->xoffset * (apparentcards);
    int idesty = pDestStack->ypos + pDestStack->yoffset * (apparentcards);

    if(pDestStack->yoffset < 0)
        idesty += pDestStack->yoffset * (iNumDragCards-1);

    if(pDestStack->xoffset < 0)
        idestx += pDestStack->xoffset * (iNumDragCards-1);

    //normalise the motion vector
    dx = idestx - x;
    dy = idesty - y;
    if ( fabs(dx) + fabs(dy) < 0.001f )
    {
        MoveDragCardTo(hdc, idestx, idesty);
        return;
    }
    double recip = 1.0 / sqrt(dx*dx + dy*dy);
    dx *= recip * __CARDZOOMSPEED; dy *= recip * __CARDZOOMSPEED;

    //if(dx < 0) dxinc = 1.001; else

    for(;;)
    {
        bool attarget = true;
        int ix, iy;
        x += dx;
        y += dy;

        ix = (int)x;
        iy = (int)y;

        if(dx < 0.0 && ix < idestx) ix = idestx;
        else if(dx > 0.0 && ix > idestx) ix = idestx;
        else attarget = false;

        if(dy < 0.0 && iy < idesty) iy = idesty;
        else if(dy > 0.0 && iy > idesty) iy = idesty;
        else attarget = false;

        //if the target stack wants the drag cards drawn differently
        //to how they are, then redraw the drag card image just before
        //the cards land
        /*if(attarget == true)
        {
            for(int i = 0; i < iNumDragCards; i++)
            {
                int xdraw = pDestStack->xoffset*i;
                int ydraw = pDestStack->yoffset*i;

                if(pDestStack->yoffset < 0)
                    ydraw = -pDestStack->yoffset * (iNumDragCards-i-1);
                if(pDestStack->xoffset < 0)
                    xdraw = -pDestStack->xoffset * (iNumDragCards-i-1);

                if(pDestStack->facedirection == CS_FACEUP && 
                    pDestStack->numcards+i >= dest->numfacedown)
                {
                    //cdtDraw(hdcDragCard, xdraw, ydraw, iDragCards[i], ectFACES, 0);
                }
                else
                {
                    //cdtDraw(hdcDragCard, xdraw, ydraw, CARDSTACK::backcard, ectBACKS, 0);
                }
            }
        }*/

        MoveDragCardTo(hdc, ix, iy);

        if(attarget || ix == idestx && iy == idesty)
            break;

        oldx = (int)x;
        oldy = (int)y;

        //dx *= 1.2;
        //dy *= 1.2;

        Sleep(10);
    }
    TRACE ( "EXIT ZoomCard()\n" );
}
#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?