⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 didevimg.cpp

📁 VC游戏编程基础
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            aptArrow[0] = aptArrow[1] = p1;
            bDrawArrow = TRUE;

            aptArrow[0].x -= 1;
            aptArrow[0].y -= 1;
            aptArrow[1].x += 1;
            aptArrow[1].y += 1;
            
            // Adjust arrow points based on line orientation
            if( p1.y == p2.y )
            {
                if( p2.x < p1.x )
                    aptArrow[1].x -= 2;
                else
                    aptArrow[0].x += 2;
            }
            else if( p1.x == p2.x )
            {
                if( p2.y < p1.y )
                    aptArrow[1].y -= 2;
                else
                    aptArrow[0].y += 2;
            }
            else
            {
                // This is a diagonal line. Skip the arrow endpoint.
                bDrawArrow = FALSE;
            }

            if( bDrawArrow )
            {
                MoveToEx( hdcRender, aptArrow[0].x, aptArrow[0].y, NULL );
                LineTo(   hdcRender, aptArrow[1].x, aptArrow[1].y );

                MoveToEx( hdcAlpha, aptArrow[0].x, aptArrow[0].y, NULL );
                LineTo(   hdcAlpha, aptArrow[1].x, aptArrow[1].y );
            }
        }

        // Select a new pen into the DC based on current color
        DeleteObject( SelectObject( hdcRender, CreatePen( PS_SOLID, 1, crCur ) ) ); 
        DeleteObject( SelectObject( hdcAlpha, GetStockObject( WHITE_PEN ) ) ); 
        

        // Draw callout lines
        MoveToEx( hdcRender, pCallout->aptLineScaled[0].x, pCallout->aptLineScaled[0].y, NULL );
        MoveToEx( hdcAlpha, pCallout->aptLineScaled[0].x, pCallout->aptLineScaled[0].y, NULL );
        for( j=1; j < pCallout->dwNumPoints; j++ )
        {
            LineTo( hdcRender, pCallout->aptLineScaled[j].x, pCallout->aptLineScaled[j].y );
            LineTo( hdcAlpha, pCallout->aptLineScaled[j].x, pCallout->aptLineScaled[j].y );
        }

        // Draw arrow ends
        if( bDrawArrow )
        {
            DWORD dwEnd = pCallout->dwNumPoints-1;

            SetPixel( hdcRender, aptArrow[0].x, aptArrow[0].y, crCur );
            SetPixel( hdcRender, aptArrow[1].x, aptArrow[1].y, crCur );
            SetPixel( hdcRender, pCallout->aptLineScaled[ dwEnd ].x, 
                                 pCallout->aptLineScaled[ dwEnd ].y, crCur );

            SetPixel( hdcAlpha, aptArrow[0].x, aptArrow[0].y, RGB(255, 255, 255) );
            SetPixel( hdcAlpha, aptArrow[1].x, aptArrow[1].y, RGB(255, 255, 255) );
            SetPixel( hdcAlpha, pCallout->aptLineScaled[ dwEnd ].x, 
                                 pCallout->aptLineScaled[ dwEnd ].y, RGB(255, 255, 255) );
        }

        
    }
    
    // Free the pen resource
    DeleteObject( SelectObject( hdcRender, GetStockObject( WHITE_PEN ) ) );
    DeleteObject( SelectObject( hdcAlpha, GetStockObject( WHITE_PEN ) ) );

    // Draw callout text
    for( i=0; i < m_dwNumObjects; i++ )
    {
        COLORREF crNorm, crHigh, crCur;
        RECT     rcFill;
        
        DIDICallout *pCallout = m_apObject[i]->GetCallout( m_dwActiveView );
        MAXSTRING    strCallout = {0};
        
        // Callout may be invisible
        if( DIDICOS_INVISIBLE & m_apObject[i]->GetCalloutState() )
            continue;

        m_apObject[i]->GetCalloutText( strCallout, MAX_PATH-4 );
        m_apObject[i]->GetCalloutColors( &crNorm, &crHigh );
        
        
        

        if( IsRectEmpty( &pCallout->rcScaled ) )
            continue;

        // Draw callouts
        DWORD dwFormat = DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOCLIP;

        // Get text dimensions
        rcFill = pCallout->rcScaled;
        DrawText( hdcRender, strCallout, lstrlen( strCallout ),
                  &rcFill, dwFormat | DT_CALCRECT | DT_MODIFYSTRING );

      
        // Horizontal alignment
        if( pCallout->dwTextAlign & DIDAL_CENTERED      ) 
        {
            dwFormat |= DT_CENTER;
            OffsetRect( &rcFill, (pCallout->rcScaled.right - rcFill.right) / 2, 0 );
        }
        else if( pCallout->dwTextAlign & DIDAL_RIGHTALIGNED  ) 
        {
            dwFormat |= DT_RIGHT;
            OffsetRect( &rcFill, (pCallout->rcScaled.right - rcFill.right ), 0 );
        }
        else
        {
            dwFormat |= DT_LEFT;
        }

        // Vertical alignment
        if( pCallout->dwTextAlign & DIDAL_MIDDLE        ) 
        {
            dwFormat |= DT_VCENTER;
            OffsetRect( &rcFill, 0, (pCallout->rcScaled.bottom - rcFill.bottom) / 2 );
        }
        else if( pCallout->dwTextAlign & DIDAL_BOTTOMALIGNED ) 
        {
            dwFormat |= DT_BOTTOM;
            OffsetRect( &rcFill, 0, (pCallout->rcScaled.bottom - rcFill.bottom) );
        }
        else
        {
            dwFormat |= DT_TOP;
        }

        // First replace the background area behind the text to cover up
        // intersecting lines
        
        // Pad the returned rect
        InflateRect( &rcFill, 5, 5 );

        // But make sure the rect still fits on the screen
        rcFill.left   = max( rcFill.left,   0 );
        rcFill.top    = max( rcFill.top,    0 );
        rcFill.right  = min( rcFill.right,  info.dsBm.bmWidth );
        rcFill.bottom = min( rcFill.bottom, info.dsBm.bmHeight );

        RestoreRect( m_ahImages[ m_dwActiveView ], &rcFill, pCleanPixels );
        if( hdcAlpha )
            FillRect( hdcAlpha, &rcFill, (HBRUSH) GetStockObject( BLACK_BRUSH ) );

        // Fill behind the text
        SetTextColor( hdcRender, CRFromColor(m_BkColor) );
        for( int x = -1; x <= 1; x++ )
        {
            for( int y = -1; y <= 1; y++ )
            {
                RECT rcText = pCallout->rcScaled;
                OffsetRect( &rcText, x, y );

                DrawText( hdcRender, strCallout, lstrlen( strCallout ),
                  &rcText, dwFormat );

                DrawText( hdcAlpha, strCallout, lstrlen( strCallout ),
                  &rcText, dwFormat );
            }
        }

        // Now draw the actual text
        crCur = ( DIDICOS_HIGHLIGHTED & m_apObject[i]->GetCalloutState() ) ? crHigh : crNorm;     
        SetTextColor( hdcRender, crCur );

        DrawText( hdcRender, strCallout, lstrlen( strCallout ),
                  &(pCallout->rcScaled), dwFormat );
        
        DrawText( hdcAlpha, strCallout, lstrlen( strCallout ),
                  &(pCallout->rcScaled), dwFormat );
        


        // If the TOOLTIP flag is set and the callout text doesn't fit within
        // the scaled rect, we need to draw the full text
        if( DIDICOS_TOOLTIP & m_apObject[i]->GetCalloutState() )
        {
            SIZE TextSize = {0};
            
            // This string was modified by the first call to draw text, so we
            // need to get a fresh copy
            m_apObject[i]->GetCalloutText( strCallout, MAX_PATH-4 );
            GetTextExtentPoint32( hdcRender, strCallout, lstrlen( strCallout ), &TextSize );

            if( TextSize.cx > ( pCallout->rcScaled.right - pCallout->rcScaled.left ) )
            {
                // Yep, the text is too big and is marked as a tooltip candidate.
                RECT rcBitmap = { 0, 0, info.dsBm.bmWidth, info.dsBm.bmHeight };
                DrawTooltip( hdcRender, hdcAlpha, strCallout, &rcBitmap, &(pCallout->rcScaled),
                             CRFromColor( m_BkColor ), crNorm, crHigh );
                
            }

        }

    }

    

    // Finalize all rendering
    GdiFlush();

    // Copy the freshly rendered image to the render target
    switch( eTarget )
    {
        case DIDIRT_SURFACE:
            // Since the image is being transfered to a Direct3D surface, the stored
            // alpha information could be used.
            ApplyAlphaChannel( m_ahImages[ m_dwActiveView ], hbmpAlpha, ( (m_BkColor & ALPHA_MASK) == ALPHA_MASK ) );
            rcBitmap.right  = info.dsBm.bmWidth;
            rcBitmap.bottom = info.dsBm.bmHeight;

            hr = D3DXLoadSurfaceFromMemory( (LPDIRECT3DSURFACE9) pvTarget,
                                             NULL, NULL, info.dsBm.bmBits,
                                             D3DFMT_A8R8G8B8, 
                                             info.dsBm.bmWidthBytes,
                                             NULL, &rcBitmap, 
                                             D3DX_FILTER_NONE, 0 );
            break;

        case DIDIRT_DC:
            BitBlt( (HDC) pvTarget, 0, 0, info.dsBm.bmWidth, info.dsBm.bmHeight,
                          hdcRender, 0, 0, SRCCOPY );
            break;
    
        default:
            // Invalid render target
            hr = DIERR_INVALIDPARAM;
            goto LCleanReturn;
    }   

    

LCleanReturn:
    
    // Restore the background
    if( pSavedPixels )
        CopyMemory( info.dsBm.bmBits, pSavedPixels, info.dsBm.bmWidthBytes * info.dsBm.bmHeight );
  
    DeleteDC( hdcRender );
    DeleteDC( hdcAlpha );
    DeleteObject( hbmpAlpha );

    delete [] pSavedPixels;
    delete [] pCleanPixels;
    return hr;
}





//-----------------------------------------------------------------------------
// Name: AddObject
// Desc: Adds an object to the current list according to object ID. If an 
//       object with the given ID already exists, a pointer to it returned. 
//       Otherwise, a new object is created and a pointer to the new object
//       is returned. Returns NULL if memory couldn't be allocated.
//-----------------------------------------------------------------------------
HRESULT CDIDevImage::AddObject( DWORD dwID )
{
    CDIDIObject* pObject = NULL;

    // Search through current objects
    if( GetObject( dwID ) )
        return DI_OK;

    // Did not find object. Create a new object, and store pointer
    pObject = new CDIDIObject( dwID, m_dwNumViews );
    if( NULL == pObject )
        return DIERR_OUTOFMEMORY;

    m_apObject[m_dwNumObjects++] = pObject;
    
    return DI_OK;
}




//-----------------------------------------------------------------------------
// Name: GetObject
// Desc: If an object with given ID exist, a pointer to it is returned
//-----------------------------------------------------------------------------
CDIDIObject* CDIDevImage::GetObject( DWORD dwID )
{
    for( UINT i=0; i < m_dwNumObjects; i++ )
    {
        if( m_apObject[i]->GetID() == dwID )
            return m_apObject[i];
    }

    return NULL;
}




//-----------------------------------------------------------------------------
// Name: LoadImageInfo
// Desc: helper function to retrieve callout / image data from
//       DirectInput
//-----------------------------------------------------------------------------
HRESULT CDIDevImage::LoadImageInfo( LPDIRECTINPUTDEVICE8 pDIDevice )
{
    HRESULT hr;
    DWORD   dwBufferCount = 0;
    DIDEVICEIMAGEINFOHEADER dihImageHeader = {0};
    DIDEVICEIMAGEINFO *pInfo = NULL;

    // properly initialize the structure before it can be used
    dihImageHeader.dwSize = sizeof( DIDEVICEIMAGEINFOHEADER );
    dihImageHeader.dwSizeImageInfo = sizeof( DIDEVICEIMAGEINFO );
    
    // since m_dihImageHeader.dwBufferSize is 0, this call serves to determine
    // the minimum buffer size required to hold information for all the images
    hr = pDIDevice->GetImageInfo( &dihImageHeader );
    if( FAILED(hr) )
        return hr;

    // at this point, m_lpDidImgHeader->dwBufferUsed has been set by
    // the GetImageInfo method to minimum buffer size needed, so allocate.
    dihImageHeader.dwBufferSize = dihImageHeader.dwBufferUsed;
    dihImageHeader.lprgImageInfoArray = (DIDEVICEIMAGEINFO*) new BYTE[dihImageHeader.dwBufferSize];

    // make sure memory has been allocated
    if( NULL == dihImageHeader.lprgImageInfoArray )
        return DIERR_OUTOFMEMORY;

    // now that the dwBufferSize has been filled, and lprgImageArray allocated,
    // we call GetImageInfo again to get the image data
    hr = pDIDevice->GetImageInfo( &dihImageHeader );
    if( FAILED(hr) )
        goto LCleanReturn;
    
    // Allocate space for all the object/callouts/overlays
    m_apObject = new CDIDIObject* [dihImageHeader.dwcButtons + 
                                   dihImageHeader.dwcAxes +
                                   dihImageHeader.dwcPOVs];

    if( NULL == m_apObject )
    {
        hr = DIERR_OUTOFMEMORY;
        goto LCleanReturn;
    }

    m_dwNumViews = dihImageHeader.dwcViews;

    // Allocate space for background images
    m_atszImagePath = new TCHAR[m_dwNumViews][MAX_PATH];
    if( NULL == m_atszImagePath )
    {
        hr = DIERR_OUTOFMEMORY;
        goto LCleanReturn;
    }

    ZeroMemory( m_atszImagePath, sizeof(m_atszImagePath) );

    m_ahImages = new HBITMAP[m_dwNumViews];
    if( NULL == m_ahImages )
    {
        hr = DIERR_OUTOFMEMORY;
        goto LCleanReturn;
    }

    ZeroMemory( m_ahImages, sizeof(m_ahImages) );

⌨️ 快捷键说明

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