S60 3rd Edition
媒體鍵的按鍵事件是無法通過常規手段監測到的,這點和其他按鍵事件不同。媒體鍵,如播放/暫停,停止,音量高/低,前進以及後退等鍵,屬於一些S60第三版手機的新特性,不會產生一般的按鍵事件,以便被程式架構捕捉,如HandleKeyEventL()以及OfferKeyEventL()。
解決方案:
媒體鍵的按鍵事件要通過Remote Control API來處理。
下列程式碼片段示範了如何處理:
CRemConInterfaceSelector</p><p>CRemConCoreApiTarget </p><p>MRemConCoreApiTargetObserver</p><p>Remote Control API requires ReadUserData capability.</p><p>//------------------------------------------------------------------------------</p><p>#include <remconcoreapitargetobserver.h> // link against RemConCoreApi.lib</p><p>#include <remconcoreapitarget.h> // and</p><p>#include <remconinterfaceselector.h> // RemConInterfaceBase.lib</p><p>class CMediaKeysTestUi : public CAknAppUi, public MRemConCoreApiTargetObserver</p><p> {</p><p> ...</p><p> // From MRemConCoreApiTargetObserver</p><p> void MrccatoCommand(TRemConCoreApiOperationId aOperationId, </p><p> TRemConCoreApiButtonAction aButtonAct); </p><p> // following functions from MRemConCoreApiTargetObserver are not needed</p><p> // in this case -> use empty implementations for these: </p><p> // MrccatoPlay</p><p> // MrccatoTuneFunction</p><p> // MrccatoSelectDiskFunction</p><p> // MrccatoSelectAvInputFunction</p><p> // MrccatoSelectAudioInputFunction </p><p>private:</p><p> CRemConInterfaceSelector* iInterfaceSelector;</p><p> CRemConCoreApiTarget* iCoreTarget;</p><p> };</p><p>void CMediaKeysTestUi::ConstructL()</p><p> {</p><p> ...</p><p> iInterfaceSelector = CRemConInterfaceSelector::NewL();</p><p> iCoreTarget = CRemConCoreApiTarget::NewL(*iInterfaceSelector, *this);</p><p> iInterfaceSelector->OpenTargetL();</p><p> }</p><p>// ----------------------------------------------------------------------------</p><p>// MrccatoCommand()</p><p>// Receives events (press/click/release) from the following buttons:</p><p>// 'Play/Pause', 'Volume Up', 'Volume Down', 'Stop', 'Rewind', 'Forward'</p><p>// ----------------------------------------------------------------------------</p><p>void CMediaKeysTestUi::MrccatoCommand(TRemConCoreApiOperationId aOperationId, </p><p> TRemConCoreApiButtonAction aButtonAct)</p><p> {</p><p> TRequestStatus status;</p><p> switch( aOperationId )</p><p> {</p><p> case ERemConCoreApiPausePlayFunction:</p><p> {</p><p> switch (aButtonAct)</p><p> {</p><p> case ERemConCoreApiButtonPress:</p><p> // Play/Pause button pressed</p><p> break;</p><p> case ERemConCoreApiButtonRelease:</p><p> // Play/Pause button released</p><p> break;</p><p> case ERemConCoreApiButtonClick:</p><p> // Play/Pause button clicked</p><p> break;</p><p> default:</p><p> // Play/Pause unknown action</p><p> break;</p><p> } </p><p> //Send the response back to Remcon server </p><p> iCoreTarget->PausePlayFunctionResponse(status, KErrNone);</p><p> User::WaitForRequest(status);</p><p> break;</p><p> } </p><p> case ERemConCoreApiStop:</p><p> {</p><p> switch (aButtonAct)</p><p> {</p><p> // see above (case ERemConCoreApiPausePlayFunction)</p><p> // for possible actions</p><p> }</p><p> iCoreTarget->StopResponse(status, KErrNone);</p><p> User::WaitForRequest(status);</p><p> break; </p><p> } </p><p> case ERemConCoreApiRewind:</p><p> {</p><p> switch (aButtonAct)</p><p> {</p><p> // see above for possible actions</p><p> }</p><p> iCoreTarget->RewindResponse(status, KErrNone);</p><p> User::WaitForRequest(status); </p><p> break;</p><p> } </p><p> case ERemConCoreApiForward:</p><p> {</p><p> switch (aButtonAct)</p><p> {</p><p> // see above for possible actions</p><p> }</p><p> iCoreTarget->ForwardResponse(status, KErrNone);</p><p> User::WaitForRequest(status);</p><p> break; </p><p> } </p><p> case ERemConCoreApiVolumeUp:</p><p> { </p><p> switch (aButtonAct)</p><p> {</p><p> // see above for possible actions</p><p> }</p><p> iCoreTarget->VolumeUpResponse(status, KErrNone);</p><p> User::WaitForRequest(status); </p><p> break;</p><p> } </p><p> case ERemConCoreApiVolumeDown:</p><p> {</p><p> switch (aButtonAct)</p><p> {</p><p> // see above for possible actions</p><p> }</p><p> iCoreTarget->VolumeDownResponse(status, KErrNone);</p><p> User::WaitForRequest(status); </p><p> break;</p><p> } </p><p> case ERemConCoreApiFastForward:</p><p> {</p><p> switch (aButtonAct)</p><p> {</p><p> // see above for possible actions</p><p> }</p><p> iCoreTarget->FastForwardResponse(status, KErrNone);</p><p> User::WaitForRequest(status);</p><p> break; </p><p> } </p><p> case ERemConCoreApiBackward:</p><p> {</p><p> switch (aButtonAct)</p><p> {</p><p> // see above for possible actions</p><p> }</p><p> iCoreTarget->BackwardResponse(status, KErrNone);</p><p> User::WaitForRequest(status);</p><p> break; </p><p> } </p><p> default:</p><p> break;</p><p> }</p><p> }
注意,當按下這些按鍵,媒體鍵無法自動重複這些命令,如果需要重複,那需要自己來完成一個(CPeriodic)時間器。
Huwell:難怪vNes這樣的模擬器無法捕捉到呢,如果能參照這個成功利用媒體鍵,那N95將是多麼好的遊戲機啊,呵呵FROM
NOTE:
if(iInterfaceSelector)
delete iInterfaceSelector;
iInterfaceSelector = NULL;
iCoreTarget = NULL;