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

📄 didcfgview.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                        // reset the text flags
                        dwTextAlign = arr[i]->GetTextAlign();

                        // check horizontal alignment
                        if( dwTextAlign & DIDAL_LEFTALIGNED )
                            dwTextFlags |= DT_LEFT;
                        else if( dwTextAlign & DIDAL_RIGHTALIGNED )
                            dwTextFlags |= DT_RIGHT;
                        else //( dwTextAlign & DIDAL_CENTERED )
                            dwTextFlags |= DT_CENTER;

                        // check vertical alignment
                        if( dwTextAlign & DIDAL_TOPALIGNED )
                            dwTextFlags |= DT_TOP;
                        else if( dwTextAlign & DIDAL_BOTTOMALIGNED )
                            dwTextFlags |= DT_SINGLELINE | DT_BOTTOM;
                        else //( dwTextAlign & DIDAL_MIDDLE )
                            dwTextFlags |= DT_SINGLELINE | DT_VCENTER;

                    }
                    else
                    {
                        // copy and draw the default text
                        _tcscpy( szBuffer, m_tszDefaultText );
                        dwTextFlags |= DT_VCENTER | DT_SINGLELINE;
                    }

                    // make a copy
                    _tcscpy( szCopy, szBuffer );

                    // draw the text
                    DrawText( hdc, szCopy, -1,( LPRECT ) rect, dwTextFlags );

                    // rendered string truncated
                    if( pData->lpState->bDrawFullname && _tcscmp( szCopy, szBuffer ) )
                    {
                        RenderFullname( hdc, szBuffer, rect );
                    }

                    if( pData->lpState->bDrawHighlight )
                    {
                        // reset the pen
                        SelectObject( hdc, hLinePen );

                        // reset the back ground color
                        SetBkColor( hdc, m_crBack );

                        // reset the text color
                        // SetTextColor( hdc, m_crFore );
                    }
                }
            }
        }
    }

    // restore DC state
    RestoreDC( hdc, iDCStackNum );

    // clean up
    DeleteObject( hBkBrush );
    DeleteObject( hLinePen );
    DeleteObject( hHighlightPen );
    DeleteObject( hHighlightLinePen );

    return S_OK;
}




//-----------------------------------------------------------------------------
// Name: RenderFullname()
// Desc: renders a box with the full name inside
//-----------------------------------------------------------------------------
VOID DIDCfgView::RenderFullname( HDC hdc, const TCHAR* pctszFullname, 
                                 const RECT* pCalloutRect )
{
    HFONT hFont, hOldFont;
    HBRUSH hBrush, hOldBrush;
    COLORREF crOldTextColor;
    TEXTMETRIC tm;
    RECT rect;
    DWORD dwTextFlags;
    int len, width, height;

    // check the length
    len = _tcslen( pctszFullname );
    if( 0 == len )
        return;

    // create the font to use in the box to display the full name
    // we hard-code Courier to ensure we have a fix-width font
    hFont = DidcvCreateFont( hdc, TEXT( "Courier" ), 
                             DIDCV_DEFAULT_FONT_SIZE, 0, 0, FALSE );

    // use the foreground color as the background
    hBrush = CreateSolidBrush( m_crFore );
    // and vice versa
    crOldTextColor = SetTextColor( hdc, m_crBack );

    hOldFont =( HFONT ) SelectObject( hdc, hFont );
    hOldBrush =( HBRUSH ) SelectObject( hdc, hBrush );

    // get the width and height of the text
    GetTextMetrics( hdc, &tm );
    width = tm.tmAveCharWidth * len + 8;
    height = tm.tmHeight + tm.tmExternalLeading + 4;

    // for now draw over the callout rect
    rect.left = pCalloutRect->left;
    rect.top = pCalloutRect->top;
    rect.right = rect.left + width;
    rect.bottom = pCalloutRect->bottom;

    // draw the rectangle
    Rectangle( hdc, rect.left, rect.top, rect.right, rect.bottom );

    // draw the text
    dwTextFlags = DT_NOPREFIX | DT_EDITCONTROL | DT_CENTER | 
                  DT_VCENTER | DT_SINGLELINE;
    DrawText( hdc, pctszFullname, -1, &rect, dwTextFlags );

    // restore HDC objects
    SelectObject( hdc, hOldFont );
    SelectObject( hdc, hOldBrush );
    SetTextColor( hdc, crOldTextColor );

    // clean up
    DeleteObject( hFont );
    DeleteObject( hBrush );
}




//-----------------------------------------------------------------------------
// Name: InitAlloc()
// Desc: helper function to dynamically allocate memory for internal data
//       structures.
//-----------------------------------------------------------------------------
HRESULT DIDCfgView::InitAlloc()
{
    // allocate a view manager, callout manager
    m_lpViewManager = new DidcvViewManager;
    m_lpCalloutManager = new DidcvCalloutManager;

    // ensure that memory has been allocated
    if( NULL == m_lpViewManager || NULL == m_lpCalloutManager )
    {
        CleanUp();
        return DIERR_OUTOFMEMORY;
    }

    return S_OK;
}




//-----------------------------------------------------------------------------
// Name: InitImageInfoRetrieve()
// Desc: helper function to retrieve callout / image data from
//       DirectInput
//-----------------------------------------------------------------------------
HRESULT DIDCfgView::InitImageInfoRetrieve( LPDIRECTINPUTDEVICE8 lpDidev )
{
    HRESULT hr;

    // allocate a DIDEVICEIMAGEINFOHEADER
    m_lpDidImgHeader = new DIDEVICEIMAGEINFOHEADER;

    // make sure memory has been allocated
    if( NULL == m_lpDidImgHeader )
    {
        return DIERR_OUTOFMEMORY;
    }

    // zero out the DIDEVICEIMAGEINFOHEADER
    ZeroMemory( m_lpDidImgHeader, sizeof( DIDEVICEIMAGEINFOHEADER ) );

    // properly initialize the structure before it can be used
    m_lpDidImgHeader->dwSize = sizeof( DIDEVICEIMAGEINFOHEADER );
    m_lpDidImgHeader->dwSizeImageInfo = sizeof( DIDEVICEIMAGEINFO );

    // since m_lpDidImgHeader->dwBufferSize is 0, this call serves to determine
    // the minimum buffer size required to hold information for all the images
    hr = lpDidev->GetImageInfo( m_lpDidImgHeader );
    if( FAILED( hr ) )
    {
        return DIERR_INVALIDPARAM; 
    }

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

    // make sure memory has been allocated
    if( m_lpDidImgHeader->lprgImageInfoArray == NULL )
    {
        return DIERR_OUTOFMEMORY;
    }

    // now that the dwBufferSize has been filled, and lprgImageArray allocated,
    // we call GetImageInfo again to get the image data
    hr = lpDidev->GetImageInfo( m_lpDidImgHeader );
    if( FAILED( hr ) )
    {
        return DIERR_INVALIDPARAM;
    }

    return S_OK;
}




//-----------------------------------------------------------------------------
// Name: InitImageInfoProcess()
// Desc: helper function to process the image/callout information to
//       get them ready to be used.
//-----------------------------------------------------------------------------
HRESULT DIDCfgView::InitImageInfoProcess()
{
    DWORD num_elements, i;
    DidcvView* pView = NULL;
    BOOL bLoadComplete = TRUE;
    DidcvCallout* pCallout = NULL;
    DWORD dwNumViews, dwNumCallouts, dwNumUniqueObjIDs;

    // a pre-condition of this method is that m_lpDidImgHeader != NULL
    assert( m_lpDidImgHeader != NULL );

    // calcuate the number of elements in the image info array
    num_elements = m_lpDidImgHeader->dwBufferUsed / m_lpDidImgHeader->dwSizeImageInfo;

    // determines sizes ahead of time
    CalcSizes( m_lpDidImgHeader->lprgImageInfoArray, num_elements, &dwNumViews, 
               &dwNumCallouts, &dwNumUniqueObjIDs );

    // set the capacity of the managers ahead of time
    m_lpViewManager->SetCapacity( dwNumViews );
    m_lpCalloutManager->SetCapacity( dwNumCallouts, dwNumUniqueObjIDs, dwNumViews );

    // first pass to process all configuration image, in order
    for( i = 0; i < num_elements; i++ )
    {
        // check to see if the element is a configuration image
        if( m_lpDidImgHeader->lprgImageInfoArray[i].dwFlags & DIDIFT_CONFIGURATION )
        {
            pView = DidcvBitmapView::Create( m_lpDidImgHeader->lprgImageInfoArray[i].tszImagePath,
                                             m_lpDidImgHeader->lprgImageInfoArray[i].dwFlags );

            if( NULL == pView )
            {
                bLoadComplete = FALSE;
                continue;
            }
            
            // add new image to the ImageManager, along with the array index, 
            // which is referred by callout entries
            m_lpViewManager->AddImage( pView,( INT )i );
        }
    }

    // second pass to process all overlays
    for( i = 0; i < num_elements; i++ )
    {
        // check to see if the element is a control overlay entry
        if( m_lpDidImgHeader->lprgImageInfoArray[i].dwFlags & DIDIFT_OVERLAY )
        {
            pCallout = DidcvCallout::Create( &( m_lpDidImgHeader->lprgImageInfoArray[i] ) );

            if( NULL == pCallout )
            {
                bLoadComplete = FALSE;
                continue;
            }
            
            // try to get the appropriate view, by the offset in the image array
            pView = m_lpViewManager->GetImageByOffset( m_lpDidImgHeader->lprgImageInfoArray[i].dwViewID );

            if( NULL == pView )
            {
                bLoadComplete = FALSE;
                continue;
            }

            // add new image to the ImageManager, along with the array index, 
            // which is referred by callout entries
            m_lpCalloutManager->AddCallout( pCallout, pView->GetID() );
        }
    }

    // free unused dynamic memory
    m_lpCalloutManager->TrimArrays();

    // appropriate error code for bLoadComplete != TRUE is not returned at this time
    return S_OK;
}




//-----------------------------------------------------------------------------
// Name: CalcSizes()
// Desc: helper function to determine the number of views and callouts in
//       in the image info array.
//-----------------------------------------------------------------------------
VOID DIDCfgView::CalcSizes( const DIDEVICEIMAGEINFO* lprgImageInfoArray, 
                            DWORD dwNumElements, LPDWORD lpNumViews, 
                            LPDWORD lpNumCallouts, LPDWORD lpNumDistinctObjID )
{
    DWORD i, j;

    // set everything to 0
    *lpNumViews = *lpNumCallouts = *lpNumDistinctObjID = 0;

    for( i = 0; i < dwNumElements; i++ )
    {
        // figure out how many of each
        if( lprgImageInfoArray[i].dwFlags & DIDIFT_CONFIGURATION )
          ( *lpNumViews ) ++;
        else if( lprgImageInfoArray[i].dwFlags & DIDIFT_OVERLAY )
        {
          ( *lpNumCallouts ) ++;

            // find to see if dwObjID unique so far
            for( j = 0; j < i; j++ )
                if( lprgImageInfoArray[j].dwObjID == lprgImageInfoArray[i].dwObjID )
                    break;

            if( j == i ) // current id unique
              ( *lpNumDistinctObjID )++;
        }
    }
}




//-----------------------------------------------------------------------------
// Name: enum DidcvEnumDataType
// Desc: constants for the dwType member of the DidcvEnumDeviceData
//-----------------------------------------------------------------------------
enum DidcvEnumDataType
{
    DIDCV_EDT_COUNT = 1,    // count
    DIDCV_EDT_SAVE  = 2     // save each item
};




//-----------------------------------------------------------------------------
// Name: IsObjectOnExcludeList()
// Desc: Exclude these objects from the view
//-----------------------------------------------------------------------------
BOOL IsObjectOnExcludeList( DWORD dwOfs )
{
	if (dwOfs == DIK_PREVTRACK  ||
	    dwOfs == DIK_NEXTTRACK  ||
	    dwOfs == DIK_MUTE       ||
	    dwOfs == DIK_CALCULATOR ||
	    dwOfs == DIK_PLAYPAUSE  ||
	    dwOfs == DIK_MEDIASTOP  ||
	    dwOfs == DIK_VOLUMEDOWN ||
	    dwOfs == DIK_VOLUMEUP   ||
	    dwOfs == DIK_WEBHOME    ||
	    dwOfs == DIK_SLEEP      ||
	    dwOfs == DIK_WEBSEARCH  ||
	    dwOfs == DIK_WEBFAVORITES ||
	    dwOfs == DIK_WEBREFRESH ||
	    dwOfs == DIK_WEBSTOP    ||
	    dwOfs == DIK_WEBFORWARD ||
	    dwOfs == DIK_WEBBACK    ||
	    dwOfs == DIK_MYCOMPUTER ||
	    dwOfs == DIK_MAIL       ||
	    dwOfs == DIK_MEDIASELECT)
		return TRUE;

	return FALSE;
}




//-----------------------------------------------------------------------------
// Name: DidcvEnumDeviceObjectsCallback()
// Desc: enumerates the objects( keys) on an device
//-----------------------------------------------------------------------------
BOOL CALLBACK DidcvEnumDeviceObjectsCallback( LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef )
{
    // get the struct that is passed in
    DidcvCustomViewInfo* lpData =( DidcvCustomViewInfo* ) pvRef;
    if( NULL == lpData )
        return DIENUM_STOP;

    // Exclude certain keys on advanced keyboards
    if( IsObjectOnExcludeList( lpddoi->dwOfs ) )
        return DIENUM_CONTINUE;

    if( lpData->dwType == DIDCV_EDT_COUNT )
    {
        // simply count
        lpData->dwCount++;
    }
    else if( lpData->dwType == DIDCV_EDT_SAVE )
    {
        if( lpData->dwSize < lpData->dwCount )
        {
            // instantiate new object instance
            lpData->rgObjData[lpData->dwSize] = new DIDEVICEOBJECTINSTANCE;
            memcpy( lpData->rgObjData[lpData->dwSize], lpddoi, sizeof( DIDEVICEOBJECTINSTANCE ) );
            lpData->dwSize++;
        }
        else
        {
            // this should not happen
            return DIENUM_STOP;
        }
    }
    else
        return DIENUM_STOP;

    return DIENUM_CONTINUE;

⌨️ 快捷键说明

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