Professional UI Solutions
Site Map   /  Register
 
 

Forum

Please Log In to post a new message or reply to an existing one. If you are not registered, please register.

NOTE: Some forums may be read-only if you are not currently subscribed to our technical support services.

Forums » Prof-UIS Tech Support » CExtTabWnd navigation Collapse All
Subject Author Date
Chris Anderson Jul 25, 2007 - 10:49 PM

Is it possible to use keyboard shortcuts to navigate the individual tab items (pages) of the CExtTabWnd control?

Chris Anderson Jul 30, 2007 - 9:25 PM

if you have a shortcut like this, La&yout, for one of the tab pages then on pressing Alt+y it doesnt invoke that page. If however you rename it as
La&Yout then it works and selects the appropriate page.

Technical Support Jul 31, 2007 - 8:57 AM

Thank you for reporting this issue. To fix it, please update the following method’s source code:

INT CExtTabWnd::ItemFindByAccessChar(
      __EXT_MFC_SAFE_TCHAR chrAccess,
      INT nStartIdx, // = -1
      BOOL bRestartAt0 // = TRUE
      ) const
{
      ASSERT_VALID( this );
      if( chrAccess == _T(’0’) )
            return -1;
TCHAR szChar[2] = { chrAccess, _T(’\0’) };
      ::CharUpper( szChar );
int cAccelSearch = szChar[0];
      if( cAccelSearch == _T(’\0’) )
            return -1;
LONG nCount = ItemGetCount();
LONG nIdx = ( nStartIdx >= 0L ) ? ( nStartIdx + 1L ) : 0L;
      if( nIdx >= nCount && bRestartAt0 )
            nIdx = 0L;
      for( ; nIdx < nCount; nIdx++ )
      {
            const TAB_ITEM_INFO * pTII = ItemGet( nIdx );
            ASSERT_VALID( pTII );
            if( ! pTII->VisibleGet() )
                  continue;
            if( ! pTII->EnabledGet() )
                  continue;
            CExtSafeString str = pTII->TextGet();
            if( str.IsEmpty() )
                  continue;
            INT nPos = str.Find( _T("&") );
            if(         nPos < 0
                  ||    nPos == (str.GetLength() - 1)
                  )
                  continue;
            ++ nPos;
            TCHAR szAccel[2] = { str.GetAt( nPos ), _T(’\0’) };
            ::CharUpper( szAccel );
            if( szAccel[0] == _T(’\0’) )
                  return -1;
            if( cAccelSearch == szAccel[0] )
            {
                  if( nStartIdx != nIdx )
                        return nIdx;
            }
      } // for( nIdx = nStartIdx; nIdx < nCount; nIdx++ )
      if( nStartIdx == 0 )
            return -1;
      for( nIdx = 0; nIdx<nStartIdx; nIdx++ )
      {
            const TAB_ITEM_INFO * pTII = ItemGet( nIdx );
            ASSERT_VALID( pTII );
            if( ! pTII->VisibleGet() )
                  continue;
            if( ! pTII->EnabledGet() )
                  continue;
            CExtSafeString str = pTII->TextGet();
            if( str.IsEmpty() )
                  continue;
            INT nPos = str.Find( _T("&") );
            if(         nPos < 0
                  ||    nPos == (str.GetLength() - 1)
                  )
                  continue;
            ++ nPos;
            TCHAR szAccel[2] = { str.GetAt( nPos ), _T(’\0’) };
            ::CharUpper( szAccel );
            if( szAccel[0] == _T(’\0’) )
                  return -1;
            if( cAccelSearch == szAccel[0] )
            {
                  if( nStartIdx != nIdx )
                        return nIdx;
            }
      } // for( nIdx = 0; nIdx<nStartIdx; nIdx++ )
      return -1;
}

Chris Anderson Jul 29, 2007 - 11:40 PM

This works fine except for the fact that there is bug in CExtTabWnd::ItemFindByAccessChar which doesnt handle lower case keyboard shortcuts correctly.

Technical Support Jul 30, 2007 - 4:27 AM

The code snippet in our previous message is exactly the same as in the tab page container control. Please provide us with more details about what is working incorrectly with lower case keyboard shortcuts? Which language is used in tab items? Which language is selected when the problem occurs?

Chris Anderson Jul 26, 2007 - 10:36 PM

ok I see that you mention the ItemFindByAccessChar method but how do I use it with the CExtTabWnd control?

Chris Anderson Jul 26, 2007 - 10:29 PM

My question was for navigating the pages of the CExtTabWnd control not the CExtTabPageContainerWnd which has this feature. How do I implement the same for CExtTabWnd.

Technical Support Jul 27, 2007 - 11:01 AM

You should pre-translate keyboard messages in your main frame or dialog window using the following code:

      if(         WM_KEYFIRST <= pMsg->message
            &&    pMsg->message <= WM_KEYLAST
            &&    ( ! CExtPopupMenuWnd::IsKeyPressed( VK_SHIFT ) )
            &&    ( ! CExtPopupMenuWnd::IsKeyPressed( VK_CONTROL ) )
            &&    CExtPopupMenuWnd::IsKeyPressed( VK_MENU )
            )
      {
            CExtTabWnd * pWndTabs = . . .;
            if( pWndTabs->GetSafeHwnd() != NULL )
            {
                  UINT nChar = UINT( pMsg->wParam );
                  ASSERT_VALID( pWndTabs );
                  BYTE lpKeyState[256];
                  ::GetKeyboardState( lpKeyState );
                  UINT wScanCode = ::MapVirtualKey( nChar, 0 );
                  HKL hKeyboardLayout =
                        ::GetKeyboardLayout(
                              ( ::AfxGetThread() ) -> m_nThreadID
                              );
#if (defined _UNICODE)
                  TCHAR szChar[2] = { _T(’\0’), _T(’\0’) };
                  ::ToUnicodeEx(
                        nChar,
                        wScanCode,
                        lpKeyState,
                        szChar, 1,
                        1,
                        hKeyboardLayout
                        );
                  WORD nMapped = WORD( szChar[0] );
#else
                  WORD nMapped = 0;
                  ::ToAsciiEx(
                        nChar,
                        wScanCode,
                        lpKeyState,
                        &nMapped,
                        1,
                        hKeyboardLayout
                        );
#endif
                  LONG nPrevIdx = pWndTabs->SelectionGet();
                  LONG nNextIdx =
                        pWndTabs->ItemFindByAccessChar(
                              (TCHAR)nMapped,
                              nPrevIdx
                              );
                  if( nNextIdx >= 0 && nNextIdx != nPrevIdx )
                  {
                        pWndTabs->SelectionSet( nNextIdx, true, true );
                        return TRUE;
                  } // if( nNextIdx >= 0 && nNextIdx != nPrevIdx )
            } // if( pWndTabs->GetSafeHwnd() != NULL )
      } // if( WM_KEYFIRST <= pMsg->message ...


Technical Support Jul 26, 2007 - 5:43 AM

This feature is available starting from v.2.70. The CExtTabPageContainer::m_bAllowAccelBasedPageSelection allows you to select tabs in tabbed page containers by using keyboard shortcuts. There is also a CExtTabWnd::ItemFindByAccessChar() method, which allows you to get the item by a shortcut character.