Step 1: Create a Message Map for the WM_TIMER event for the CDirectInput1View class
void CDirectInput1View::OnTimer(UINT nIDEvent)
{
/*
The Timer event looks to determine if the user wants to poll
keyboard events in immediate or buffer mode.
*/
UpdateData(TRUE);
BOOL bImmediate = ( m_immediate_control.GetCheck() == BST_CHECKED );
if( bImmediate )
{
if( FAILED( ReadImmediateData( AfxGetMainWnd()->m_hWnd ) ) )
{
KillTimer( 0 );
MessageBox( _T("Error reading input state. ")
_T("The
sample will now exit."),
_T("Keyboard"),
MB_ICONERROR | MB_OK );
EndDialog( m_hWnd, TRUE );
}
}
else
{
if( FAILED( ReadBufferedData( AfxGetMainWnd()->m_hWnd ) ) )
{
KillTimer( 0 );
MessageBox( _T("Error reading input state. ")
_T("The
sample will now exit."),
_T("Keyboard"),
MB_ICONERROR | MB_OK );
EndDialog( m_hWnd, TRUE );
}
}
CFormView::OnTimer(nIDEvent);
}
Step 2: Insert into directInput1View.h
:
HRESULT ReadImmediateData( HWND hDlg );
HRESULT ReadBufferedData( HWND hDlg );
Step 3: Source Code Insert directInput1View.cpp
HRESULT CDirectInput1View::ReadImmediateData( HWND hDlg )
{
HRESULT hr;
TCHAR strNewText[256*5 + 1] = TEXT("");
TCHAR strElement[10];
BYTE diks[256]; // DirectInput keyboard state buffer
int i;
if( NULL == g_pKeyboard )
return S_OK;
// Get the input's device state, and put the state in dims
ZeroMemory( &diks, sizeof(diks) );
hr = g_pKeyboard->GetDeviceState( sizeof(diks), &diks );
if( FAILED(hr) )
{
// DirectInput may be telling us that the input stream
has been
// interrupted. We aren't tracking any state between polls, so
// we don't have any special reset that needs to be done.
// We just re-acquire and try again.
// If input is lost then acquire and keep trying
hr = g_pKeyboard->Acquire();
while( hr == DIERR_INPUTLOST )
hr = g_pKeyboard->Acquire();
// Update the dialog text
if( hr == DIERR_OTHERAPPHASPRIO || hr == DIERR_NOTACQUIRED )
{
m_data="Unacquired";
UpdateData(FALSE);
}
// hr may be DIERR_OTHERAPPHASPRIO or other errors. This
// may occur when the app is minimized or in the process of
// switching, so just try again later
return S_OK;
}
// Make a string of the index values of the keys that are down
for( i = 0; i < 256; i++ )
{
if( diks[i] & 0x80 )
{
wsprintf( strElement, "0x%02x ", i );
strcat( strNewText, strElement );
}
}
// Get the old text in the text box
TCHAR strOldText[128];
UpdateData(TRUE);
strcpy(strOldText,m_data.GetBufferSetLength(m_data.GetLength()));
m_data.ReleaseBuffer();
// If nothing changed then don't repaint - avoid flicker
if( 0 != lstrcmp( strOldText, strNewText ) )
{
m_data=strNewText;
UpdateData(FALSE);
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: ReadBufferedData()
// Desc: Read the input device's state when in buffered mode and display it.
//-----------------------------------------------------------------------------
HRESULT CDirectInput1View::ReadBufferedData( HWND hDlg )
{
TCHAR strNewText[256*5 + 1] = TEXT("");
TCHAR strLetter[10];
DIDEVICEOBJECTDATA didod[ SAMPLE_BUFFER_SIZE ]; // Receives buffered data
DWORD dwElements;
DWORD i;
HRESULT hr;
if( NULL == g_pKeyboard )
return S_OK;
dwElements = SAMPLE_BUFFER_SIZE;
hr = g_pKeyboard->GetDeviceData( sizeof(DIDEVICEOBJECTDATA),
didod, &dwElements, 0 );
if( hr != DI_OK )
{
// We got an error or we got DI_BUFFEROVERFLOW.
//
// Either way, it means that continuous contact with the
// device has been lost, either due to an external
// interruption, or because the buffer overflowed
// and some events were lost.
//
// Consequently, if a button was pressed at the time
// the buffer overflowed or the connection was broken,
// the corresponding "up" message might have been lost.
//
// But since our simple sample doesn't actually have
// any state associated with button up or down events,
// there is no state to reset. (In a real game, ignoring
// the buffer overflow would result in the game thinking
// a key was held down when in fact it isn't; it's just
// that the "up" event got lost because the buffer
// overflowed.)
//
// If we want to be cleverer, we could do a
// GetDeviceState() and compare the current state
// against the state we think the device is in,
// and process all the states that are currently
// different from our private state.
hr = g_pKeyboard->Acquire();
while( hr == DIERR_INPUTLOST )
hr = g_pKeyboard->Acquire();
// Update the dialog text
if( hr == DIERR_OTHERAPPHASPRIO ||
hr == DIERR_NOTACQUIRED )
{
m_data="Unacquired";
UpdateData(FALSE);
}
// hr may be DIERR_OTHERAPPHASPRIO or other errors. This
// may occur when the app is minimized or in the process of
// switching, so just try again later
return S_OK;
}
if( FAILED(hr) )
return hr;
// Study each of the buffer elements and process them.
//
// Since we really don't do anything, our "processing"
// consists merely of squirting the name into our
// local buffer.
for( i = 0; i < dwElements; i++ )
{
// this will display then scan code of the key
// plus a 'D' - meaning the key was pressed
// or a 'U' - meaning the key was released
wsprintf( strLetter, "0x%02x%s ", didod[ i ].dwOfs,
(didod[ i ].dwData & 0x80) ? "D" : "U");
strcat( strNewText, strLetter );
}
// Get the old text in the text box
TCHAR strOldText[128];
UpdateData(TRUE);
strcpy(strOldText,m_data.GetBufferSetLength(m_data.GetLength()));
m_data.ReleaseBuffer();
//strcpy(strOldText,m_data);
// If nothing changed then don't repaint - avoid flicker
if( 0 != lstrcmp( strOldText, strNewText ) )
{
m_data=strNewText;
UpdateData(FALSE);
}
return S_OK;
}
Comments