Send a suggestion!

We're building a brand new version of the site, and we'd love to hear your ideas

Members

Technology Zones

IBM Learning Center

Articles

Hosted By

MaximumASP

Info

Rated
Read 31,302 times

Contents

Related Categories

Direct Input 8 - Set up the Timer Message Map and Methods

davepamn

Set up the Timer Message Map and Methods

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;
}

NishiSoft provides Part I of the Information Technology Project collaboration. Sign up and list your IT project tasks, assign task too friends, and get percent complete task. Part will include a work order system with NishiSoft acting as the middle man between software task order, verification of requirements meet and services delivered, and generation of the voucher for payment between parties.

Comments