📄 didcfgview.cpp
字号:
//-----------------------------------------------------------------------------
// File: didcfgview.cpp
//
// Desc: Interface for retrieving and rendering DirectInput Device
// configuration view( implemenation ). Feel free to use
// this class as a starting point for adding extra functionality.
//
//
// Copyright (c) 1999-2000 Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#include <d3d8.h>
#include <d3dx8tex.h>
#include <assert.h>
#include <tchar.h>
#include "didcfgview.h"
#include "dxutil.h"
//-----------------------------------------------------------------------------
// Name: DIDCfgView()
// Desc: constructor
//-----------------------------------------------------------------------------
DIDCfgView::DIDCfgView()
: m_lpViewManager( NULL ),
m_lpCalloutManager( NULL ),
m_bIsInit( FALSE ),
m_nView( DIDCV_INVALID_ID ),
m_lpDidImgHeader( NULL ),
m_lpCustomViewInfo( NULL ),
m_lpDIDevice( NULL ),
m_bCanBeCollapsed( FALSE ),
m_bIsCollapsed( FALSE ),
m_lpDiaf( NULL ),
m_crFore( RGB( 0xff, 0xff, 0xff ) ),
m_crBack( RGB( 0x0, 0x0, 0x0 ) ),
m_crHighlight( RGB( 0x33, 0x33, 0x33 ) ),
m_crHighlightLine( RGB( 0x99, 0xff, 0x0 ) ),
m_hFont( NULL )
{
_tcscpy( m_tszDefaultText, TEXT( "- - -" ) );
ZeroMemory( &m_ptOrigin, sizeof( POINT ) );
}
//-----------------------------------------------------------------------------
// Name: ~DIDCfgView()
// Desc: destructor
//-----------------------------------------------------------------------------
DIDCfgView::~DIDCfgView()
{
CleanUp();
if( m_hFont )
{
// free the font
DeleteObject( m_hFont );
m_hFont = NULL;
}
}
//-----------------------------------------------------------------------------
// Name: Init()
// Desc: initializes the DIDCfgView object with a DirectInputDevice8
// reference. upon successful completion of this functions, image
// and callout data for the device should be successfully retrieved,
// loaded, and processed, ready to be used.( ultimately, after optionally
// setting the action format, callout state, performing hit tests, etc -
// the image can be drawn by calling RenderView(). ) this Init()
// must be called successfully before anything else can be used.
//-----------------------------------------------------------------------------
HRESULT DIDCfgView::Init( LPDIRECTINPUTDEVICE8 lpDidev )
{
HRESULT hr;
// always start clean
CleanUp();
// sanity check
if( NULL == lpDidev )
{
return DIERR_INVALIDPARAM;
}
// allocate objects
hr = InitAlloc();
if( FAILED( hr ) )
{
CleanUp();
return hr;
}
// retrieve the image info from DirectInput
hr = InitImageInfoRetrieve( lpDidev );
if( FAILED( hr ) )
{
// no device image on system, let's build our own
hr = InitCustomViews( lpDidev );
if( FAILED( hr ) )
{
CleanUp();
return hr;
}
// keep a reference for custom views, since we might
// need the device to reconstruct collapsed views
m_lpDIDevice = lpDidev;
m_lpDIDevice->AddRef();
}
else
{
// process the image info from DirectInput
hr = InitImageInfoProcess();
if( FAILED( hr ) )
{
CleanUp();
return hr;
}
}
m_bIsInit = TRUE;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: CleanUp()
// Desc: resets the cfgview object, freeing memory and other resources
// this method is idempotent.
//-----------------------------------------------------------------------------
VOID DIDCfgView::CleanUp()
{
m_bIsInit = FALSE;
m_nView = -1;
m_bCanBeCollapsed = FALSE;
m_bIsCollapsed = FALSE;
if( m_lpDidImgHeader )
{
// free array
SAFE_DELETE_ARRAY( m_lpDidImgHeader->lprgImageInfoArray );
// free the imginfoheader
delete m_lpDidImgHeader;
m_lpDidImgHeader = NULL;
}
// free the view manager
SAFE_DELETE( m_lpViewManager );
// free callout manager
SAFE_DELETE( m_lpCalloutManager );
// free the custom view info
SAFE_DELETE( m_lpCustomViewInfo );
// release the DirectInputDevice
SAFE_RELEASE( m_lpDIDevice );
if( m_lpDiaf )
{
// free the DIACTION array
SAFE_DELETE_ARRAY( m_lpDiaf->rgoAction );
// free the DIACTIONFORMAT
delete m_lpDiaf;
m_lpDiaf = NULL;
}
}
//-----------------------------------------------------------------------------
// Name: SetActionFormat()
// Desc: sets the action format mapping for this cfgview object. the action
// format should be relevant to the same DirectInputDevice that was
// used to initialize this object. this information will be used when
// the configuration view is rendered.
//-----------------------------------------------------------------------------
HRESULT DIDCfgView::SetActionFormat( LPDIACTIONFORMAT lpDiaf )
{
UINT i;
// make sure this object has been properly initialized
if( FALSE == m_bIsInit )
return DIERR_NOTINITIALIZED;
// clear any actions currently mapped
m_lpCalloutManager->ClearAllActionMaps();
// no DIACTIONFORMAT passed in, error
if( NULL == lpDiaf )
return DIERR_INVALIDPARAM;
// set each action mapping
for( i = 0; i < lpDiaf->dwNumActions; i++ )
{
m_lpCalloutManager->SetActionMap( &( lpDiaf->rgoAction[i] ),
lpDiaf->rgoAction[i].dwObjID );
}
// if we build custom views
if( m_lpCustomViewInfo )
{
// determine if views can be compacted
m_bCanBeCollapsed = m_lpCalloutManager->CalcCanBeCollapsed();
// keep copy of the action map
if( m_bCanBeCollapsed )
if( FALSE == CopyActionMap( lpDiaf ) )
return DIERR_OUTOFMEMORY;
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: RebuildViews()
// Desc: collapses or exands the views
//-----------------------------------------------------------------------------
HRESULT DIDCfgView::RebuildViews( BOOL bCompact )
{
UINT i;
INT iNumViews;
// make sure this has been properly initialized
if( FALSE == m_bIsInit )
return DIERR_NOTINITIALIZED;
if( NULL == m_lpDiaf )
return DIERR_NOTINITIALIZED;
if( FALSE == m_bCanBeCollapsed )
return DIERR_INVALIDPARAM;
// build the custom views, expand or compact
InitCustomViews( m_lpDIDevice, bCompact );
// set the action map
for( i = 0; i < m_lpDiaf->dwNumActions; i++ )
{
m_lpCalloutManager->SetActionMap( &( m_lpDiaf->rgoAction[i] ),
m_lpDiaf->rgoAction[i].dwObjID );
}
// get the new number of views;
iNumViews = m_lpViewManager->GetNumViews();
// bound the current view id
if( iNumViews == 0 )
m_nView = DIDCV_INVALID_ID;
if( m_nView >= iNumViews )
m_nView = iNumViews - 1;
// keep track of whether the views are compact or not
m_bIsCollapsed = bCompact;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: SetCalloutState()
// Desc: sets the state for a given callout. the flags are:
//
// DIDCV_DRAWCALLOUT - draws the callout
// DIDCV_DRAWOVERLAY - draws the overlay
// DIDCV_DRAWHIGHLIGHT - draws highlight
// DIDCV_DRAWEMPTYCALLOUT - draws the callout even if an action mapping
// is not present
// DIDCV_DRAWFULLNAME - draws the full name of action, if the
// callout clips part of the string
//
// the dwFlags argument should be a bitwise AND of none, any, or all of
// the values.
//-----------------------------------------------------------------------------
HRESULT DIDCfgView::SetCalloutState( DWORD dwFlags, DWORD dwObjID )
{
DidcvCalloutState calloutState;
BOOL bResult;
// make sure this object has been properly initialized
if( FALSE == m_bIsInit )
return DIERR_NOTINITIALIZED;
// set the state structure to match the dword
calloutState.SetFlag( dwFlags );
// set the state for the object id( if exist )
bResult = m_lpCalloutManager->SetCalloutState( &calloutState, dwObjID );
// could be an invalid object id
if( FALSE == bResult )
return DIERR_INVALIDPARAM;
return DI_OK;
}
//-----------------------------------------------------------------------------
// Name: SetAllCalloutState()
// Desc: sets the state for all callouts. see SetCalloutState for flag value
//-----------------------------------------------------------------------------
HRESULT DIDCfgView::SetAllCalloutState( DWORD dwFlags )
{
DidcvCalloutState calloutState;
BOOL bResult;
// make sure this object has been properly initialized
if( FALSE == m_bIsInit )
return DIERR_NOTINITIALIZED;
// set the state structure to match the dword
calloutState.SetFlag( dwFlags );
// set the state for the object id( if exist )
bResult = m_lpCalloutManager->SetAllCalloutState( &calloutState );
// could be an invalid object id
if( FALSE == bResult )
return DIERR_INVALIDPARAM;
return DI_OK;
}
//-----------------------------------------------------------------------------
// Name: GetCalloutState()
// Desc: returns the state for a given callout. see SetCalloutState comments
// for explanation of the flags values
//-----------------------------------------------------------------------------
HRESULT DIDCfgView::GetCalloutState( LPDWORD lpdwFlags, DWORD dwObjID )
{
DidcvCalloutState calloutState;
BOOL bResult;
// make sure this object has been properly initialized
if( FALSE == m_bIsInit )
return DIERR_NOTINITIALIZED;
// sanity check
if( NULL == lpdwFlags )
return DIERR_INVALIDPARAM;
// retrieve callout state from the callout manager
bResult = m_lpCalloutManager->GetCalloutState( &calloutState, dwObjID );
// did not find state info
if( FALSE == bResult )
return DIERR_INVALIDPARAM;
// construct flag from the state
*lpdwFlags = calloutState.MakeFlag();
return DI_OK;
}
//-----------------------------------------------------------------------------
// Name: GetObjectIDByLocation()
// Desc: for a given point in image coordinate, returns a callout with which
// the point intersects. if not found, the functions return success,
// and the return argument will be set to NULL.
//-----------------------------------------------------------------------------
HRESULT DIDCfgView::GetObjectIDByLocation( LPDWORD lpdwObjID, LPPOINT pPt )
{
POINT ptTransform;
// make sure this object has been properly initialized
if( FALSE == m_bIsInit )
return DIERR_NOTINITIALIZED;
// sanity check
if( NULL == lpdwObjID )
return DIERR_INVALIDPARAM;
// transform by new origin
ptTransform.x = pPt->x - m_ptOrigin.x;
ptTransform.y = pPt->y - m_ptOrigin.y;
// pass pt into the callout manager with the current view for hit test
*lpdwObjID = m_lpCalloutManager->GetObjectIDByLocation( &ptTransform, m_nView );
return DI_OK;
}
//-----------------------------------------------------------------------------
// Name: SetCurrentView()
// Desc: set the current view for the DIDCfgView object. all further
// operations will be done in the context of this new view.
//-----------------------------------------------------------------------------
HRESULT DIDCfgView::SetCurrentView( INT nView )
{
// make sure this object has been properly initialized
if( FALSE == m_bIsInit )
return DIERR_NOTINITIALIZED;
// sanity check
if( nView < 0 || nView >=( INT ) m_lpViewManager->GetNumViews() )
return DIERR_INVALIDPARAM;
// set the view
m_nView = nView;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -