📄 didcfgview.cpp
字号:
// 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 + -