1*3a700b0aSSteve Yin /************************************************************** 2*3a700b0aSSteve Yin * 3*3a700b0aSSteve Yin * Licensed to the Apache Software Foundation (ASF) under one 4*3a700b0aSSteve Yin * or more contributor license agreements. See the NOTICE file 5*3a700b0aSSteve Yin * distributed with this work for additional information 6*3a700b0aSSteve Yin * regarding copyright ownership. The ASF licenses this file 7*3a700b0aSSteve Yin * to you under the Apache License, Version 2.0 (the 8*3a700b0aSSteve Yin * "License"); you may not use this file except in compliance 9*3a700b0aSSteve Yin * with the License. You may obtain a copy of the License at 10*3a700b0aSSteve Yin * 11*3a700b0aSSteve Yin * http://www.apache.org/licenses/LICENSE-2.0 12*3a700b0aSSteve Yin * 13*3a700b0aSSteve Yin * Unless required by applicable law or agreed to in writing, 14*3a700b0aSSteve Yin * software distributed under the License is distributed on an 15*3a700b0aSSteve Yin * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*3a700b0aSSteve Yin * KIND, either express or implied. See the License for the 17*3a700b0aSSteve Yin * specific language governing permissions and limitations 18*3a700b0aSSteve Yin * under the License. 19*3a700b0aSSteve Yin * 20*3a700b0aSSteve Yin *************************************************************/ 215fdc4257SSteve Yin 225fdc4257SSteve Yin ////////////////////////////////////////////////////////////////////// 235fdc4257SSteve Yin // AccActionBase.cpp: implementation of the CAccActionBase class. 245fdc4257SSteve Yin ////////////////////////////////////////////////////////////////////// 255fdc4257SSteve Yin #include "stdafx.h" 265fdc4257SSteve Yin 275fdc4257SSteve Yin #include "AccActionBase.h" 285fdc4257SSteve Yin #include <com/sun/star/accessibility/XAccessible.hpp> 295fdc4257SSteve Yin #include <com/sun/star/accessibility/AccessibleStateType.hpp> 305fdc4257SSteve Yin #include <com/sun/star/accessibility/AccessibleRole.hpp> 315fdc4257SSteve Yin #include <com/sun/star/accessibility/XAccessibleContext.hpp> 325fdc4257SSteve Yin 335fdc4257SSteve Yin #include "AccessibleKeyStroke.h" 345fdc4257SSteve Yin 355fdc4257SSteve Yin #ifndef __ACCCOMMON_H_ 365fdc4257SSteve Yin #include "acccommon.h" 375fdc4257SSteve Yin #endif 385fdc4257SSteve Yin 395fdc4257SSteve Yin using namespace com::sun::star::accessibility::AccessibleRole; 405fdc4257SSteve Yin using namespace com::sun::star::accessibility; 415fdc4257SSteve Yin using namespace com::sun::star::uno; 425fdc4257SSteve Yin using namespace com::sun::star::awt; 435fdc4257SSteve Yin 445fdc4257SSteve Yin ////////////////////////////////////////////////////////////////////// 455fdc4257SSteve Yin // Construction/Destruction 465fdc4257SSteve Yin ////////////////////////////////////////////////////////////////////// 475fdc4257SSteve Yin 485fdc4257SSteve Yin CAccActionBase::CAccActionBase() 495fdc4257SSteve Yin {} 505fdc4257SSteve Yin 515fdc4257SSteve Yin CAccActionBase::~CAccActionBase() 525fdc4257SSteve Yin {} 535fdc4257SSteve Yin 545fdc4257SSteve Yin /** 555fdc4257SSteve Yin * Helper function used for getting default action by UNO role. 565fdc4257SSteve Yin * 575fdc4257SSteve Yin * @param pRContext UNO context interface pointer. 585fdc4257SSteve Yin * @param pRet the corresponding string to be returned. 595fdc4257SSteve Yin */ 605fdc4257SSteve Yin void GetDfActionByUNORole(XAccessibleContext* pRContext, BSTR* pRet) 615fdc4257SSteve Yin { 625fdc4257SSteve Yin // #CHECK# 635fdc4257SSteve Yin if(pRContext == NULL || pRet == NULL) 645fdc4257SSteve Yin { 655fdc4257SSteve Yin return; 665fdc4257SSteve Yin } 675fdc4257SSteve Yin 685fdc4257SSteve Yin long Role = pRContext->getAccessibleRole(); 695fdc4257SSteve Yin 705fdc4257SSteve Yin switch(Role) 715fdc4257SSteve Yin { 725fdc4257SSteve Yin case PUSH_BUTTON: 735fdc4257SSteve Yin *pRet = ::SysAllocString(PRESS); 745fdc4257SSteve Yin break; 755fdc4257SSteve Yin case RADIO_BUTTON: 765fdc4257SSteve Yin case MENU_ITEM: 775fdc4257SSteve Yin case LIST_ITEM: 785fdc4257SSteve Yin *pRet = ::SysAllocString(SELECT); 795fdc4257SSteve Yin break; 805fdc4257SSteve Yin case CHECK_BOX: 815fdc4257SSteve Yin { 825fdc4257SSteve Yin Reference< XAccessibleStateSet > pRState = pRContext->getAccessibleStateSet(); 835fdc4257SSteve Yin if( !pRState.is() ) 845fdc4257SSteve Yin { 855fdc4257SSteve Yin return; 865fdc4257SSteve Yin } 875fdc4257SSteve Yin 885fdc4257SSteve Yin Sequence<short> pStates = pRState->getStates(); 895fdc4257SSteve Yin int count = pStates.getLength(); 905fdc4257SSteve Yin *pRet = ::SysAllocString(CHECK); 915fdc4257SSteve Yin for( int iIndex = 0;iIndex < count;iIndex++ ) 925fdc4257SSteve Yin { 935fdc4257SSteve Yin if( pStates[iIndex] == AccessibleStateType::CHECKED ) 945fdc4257SSteve Yin { 955fdc4257SSteve Yin SAFE_SYSFREESTRING(*pRet); 965fdc4257SSteve Yin *pRet = ::SysAllocString(UNCHECK); 975fdc4257SSteve Yin break; 985fdc4257SSteve Yin } 995fdc4257SSteve Yin } 1005fdc4257SSteve Yin break; 1015fdc4257SSteve Yin } 1025fdc4257SSteve Yin } 1035fdc4257SSteve Yin } 1045fdc4257SSteve Yin 1055fdc4257SSteve Yin /** 1065fdc4257SSteve Yin * Returns the number of action. 1075fdc4257SSteve Yin * 1085fdc4257SSteve Yin * @param nActions the number of action. 1095fdc4257SSteve Yin */ 1105fdc4257SSteve Yin STDMETHODIMP CAccActionBase::nActions(/*[out,retval]*/long* nActions) 1115fdc4257SSteve Yin { 1125fdc4257SSteve Yin 1135fdc4257SSteve Yin CHECK_ENABLE_INF 1145fdc4257SSteve Yin 1155fdc4257SSteve Yin ENTER_PROTECTED_BLOCK 1165fdc4257SSteve Yin 1175fdc4257SSteve Yin // #CHECK# 1185fdc4257SSteve Yin if( pRXAct.is() && nActions != NULL ) 1195fdc4257SSteve Yin { 1205fdc4257SSteve Yin *nActions = GetXInterface()->getAccessibleActionCount(); 1215fdc4257SSteve Yin return S_OK; 1225fdc4257SSteve Yin } 1235fdc4257SSteve Yin *nActions = 0; 1245fdc4257SSteve Yin 1255fdc4257SSteve Yin return S_OK; 1265fdc4257SSteve Yin 1275fdc4257SSteve Yin LEAVE_PROTECTED_BLOCK 1285fdc4257SSteve Yin } 1295fdc4257SSteve Yin 1305fdc4257SSteve Yin /** 1315fdc4257SSteve Yin * Performs specified action on the object. 1325fdc4257SSteve Yin * 1335fdc4257SSteve Yin * @param actionIndex the index of action. 1345fdc4257SSteve Yin */ 1355fdc4257SSteve Yin STDMETHODIMP CAccActionBase::doAction(/* [in] */ long actionIndex) 1365fdc4257SSteve Yin { 1375fdc4257SSteve Yin 1385fdc4257SSteve Yin CHECK_ENABLE_INF 1395fdc4257SSteve Yin 1405fdc4257SSteve Yin ENTER_PROTECTED_BLOCK 1415fdc4257SSteve Yin 1425fdc4257SSteve Yin if( pRXAct.is() ) 1435fdc4257SSteve Yin { 1445fdc4257SSteve Yin return GetXInterface()->doAccessibleAction( actionIndex )?S_OK:E_FAIL; 1455fdc4257SSteve Yin } 1465fdc4257SSteve Yin return E_FAIL; 1475fdc4257SSteve Yin 1485fdc4257SSteve Yin LEAVE_PROTECTED_BLOCK 1495fdc4257SSteve Yin } 1505fdc4257SSteve Yin 1515fdc4257SSteve Yin /** 1525fdc4257SSteve Yin * Gets description of specified action. 1535fdc4257SSteve Yin * 1545fdc4257SSteve Yin * @param actionIndex the index of action. 1555fdc4257SSteve Yin * @param description the description string of the specified action. 1565fdc4257SSteve Yin */ 1575fdc4257SSteve Yin STDMETHODIMP CAccActionBase::get_description(long actionIndex,BSTR __RPC_FAR *description) 1585fdc4257SSteve Yin { 1595fdc4257SSteve Yin 1605fdc4257SSteve Yin CHECK_ENABLE_INF 1615fdc4257SSteve Yin 1625fdc4257SSteve Yin ENTER_PROTECTED_BLOCK 1635fdc4257SSteve Yin 1645fdc4257SSteve Yin // #CHECK# 1655fdc4257SSteve Yin if(description == NULL) 1665fdc4257SSteve Yin return E_INVALIDARG; 1675fdc4257SSteve Yin 1685fdc4257SSteve Yin // #CHECK XInterface# 1695fdc4257SSteve Yin if(!pRXAct.is()) 1705fdc4257SSteve Yin return E_FAIL; 1715fdc4257SSteve Yin 1725fdc4257SSteve Yin ::rtl::OUString ouStr = GetXInterface()->getAccessibleActionDescription(actionIndex); 1735fdc4257SSteve Yin // #CHECK# 1745fdc4257SSteve Yin 1755fdc4257SSteve Yin SAFE_SYSFREESTRING(*description); 1765fdc4257SSteve Yin *description = SysAllocString((OLECHAR*)ouStr.getStr()); 1775fdc4257SSteve Yin 1785fdc4257SSteve Yin return S_OK; 1795fdc4257SSteve Yin 1805fdc4257SSteve Yin LEAVE_PROTECTED_BLOCK 1815fdc4257SSteve Yin } 1825fdc4257SSteve Yin 1835fdc4257SSteve Yin STDMETHODIMP CAccActionBase::get_name( long, BSTR __RPC_FAR *) 1845fdc4257SSteve Yin { 1855fdc4257SSteve Yin return E_NOTIMPL; 1865fdc4257SSteve Yin } 1875fdc4257SSteve Yin 1885fdc4257SSteve Yin STDMETHODIMP CAccActionBase::get_localizedName( long, BSTR __RPC_FAR *) 1895fdc4257SSteve Yin { 1905fdc4257SSteve Yin return E_NOTIMPL; 1915fdc4257SSteve Yin } 1925fdc4257SSteve Yin 1935fdc4257SSteve Yin /** 1945fdc4257SSteve Yin * Returns key binding object (if any) associated with specified action 1955fdc4257SSteve Yin * key binding is string. 1965fdc4257SSteve Yin * e.g. "alt+d" (like IAccessible::get_accKeyboardShortcut). 1975fdc4257SSteve Yin * 1985fdc4257SSteve Yin * @param actionIndex the index of action. 1995fdc4257SSteve Yin * @param nMaxBinding the max number of key binding. 2005fdc4257SSteve Yin * @param keyBinding the key binding array. 2015fdc4257SSteve Yin * @param nBinding the actual number of key binding returned. 2025fdc4257SSteve Yin */ 2035fdc4257SSteve Yin STDMETHODIMP CAccActionBase::get_keyBinding( 2045fdc4257SSteve Yin /* [in] */ long actionIndex, 2055fdc4257SSteve Yin /* [in] */ long, 2065fdc4257SSteve Yin /* [length_is][length_is][size_is][size_is][out] */ BSTR __RPC_FAR *__RPC_FAR *keyBinding, 2075fdc4257SSteve Yin /* [retval][out] */ long __RPC_FAR *nBinding) 2085fdc4257SSteve Yin { 2095fdc4257SSteve Yin 2105fdc4257SSteve Yin CHECK_ENABLE_INF 2115fdc4257SSteve Yin 2125fdc4257SSteve Yin ENTER_PROTECTED_BLOCK 2135fdc4257SSteve Yin 2145fdc4257SSteve Yin if( !keyBinding || !nBinding) 2155fdc4257SSteve Yin return E_INVALIDARG; 2165fdc4257SSteve Yin 2175fdc4257SSteve Yin if( !pRXAct.is() ) 2185fdc4257SSteve Yin return E_FAIL; 2195fdc4257SSteve Yin 2205fdc4257SSteve Yin Reference< XAccessibleKeyBinding > binding = GetXInterface()->getAccessibleActionKeyBinding(actionIndex); 2215fdc4257SSteve Yin if( !binding.is() ) 2225fdc4257SSteve Yin return E_FAIL; 2235fdc4257SSteve Yin 2245fdc4257SSteve Yin long nCount = (binding.get())->getAccessibleKeyBindingCount(); 2255fdc4257SSteve Yin 2265fdc4257SSteve Yin OLECHAR wString[64]; 2275fdc4257SSteve Yin 2285fdc4257SSteve Yin *keyBinding = (BSTR*)::CoTaskMemAlloc(nCount*sizeof(BSTR)); 2295fdc4257SSteve Yin 2305fdc4257SSteve Yin // #CHECK Memory Allocation# 2315fdc4257SSteve Yin if(*keyBinding == NULL) 2325fdc4257SSteve Yin return E_FAIL; 2335fdc4257SSteve Yin 2345fdc4257SSteve Yin for( int index = 0;index < nCount;index++ ) 2355fdc4257SSteve Yin { 2365fdc4257SSteve Yin memset(wString,0,sizeof(wString)); 2375fdc4257SSteve Yin GetkeyBindingStrByXkeyBinding( (binding.get())->getAccessibleKeyBinding(index), wString ); 2385fdc4257SSteve Yin 2395fdc4257SSteve Yin (*keyBinding)[index] = SysAllocString(wString); 2405fdc4257SSteve Yin } 2415fdc4257SSteve Yin 2425fdc4257SSteve Yin *nBinding = nCount; 2435fdc4257SSteve Yin return S_OK; 2445fdc4257SSteve Yin 2455fdc4257SSteve Yin LEAVE_PROTECTED_BLOCK 2465fdc4257SSteve Yin } 2475fdc4257SSteve Yin 2485fdc4257SSteve Yin /** 2495fdc4257SSteve Yin * Overide of IUNOXWrapper. 2505fdc4257SSteve Yin * 2515fdc4257SSteve Yin * @param pXInterface the pointer of UNO interface. 2525fdc4257SSteve Yin */ 2535fdc4257SSteve Yin STDMETHODIMP CAccActionBase::put_XInterface(long pXInterface) 2545fdc4257SSteve Yin { 2555fdc4257SSteve Yin 2565fdc4257SSteve Yin 2575fdc4257SSteve Yin ENTER_PROTECTED_BLOCK 2585fdc4257SSteve Yin 2595fdc4257SSteve Yin CUNOXWrapper::put_XInterface(pXInterface); 2605fdc4257SSteve Yin 2615fdc4257SSteve Yin //special query. 2625fdc4257SSteve Yin if(pUNOInterface == NULL) 2635fdc4257SSteve Yin return E_FAIL; 2645fdc4257SSteve Yin Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext(); 2655fdc4257SSteve Yin if( !pRContext.is() ) 2665fdc4257SSteve Yin return E_FAIL; 2675fdc4257SSteve Yin 2685fdc4257SSteve Yin Reference<XAccessibleAction> pRXI(pRContext,UNO_QUERY); 2695fdc4257SSteve Yin if( !pRXI.is() ) 2705fdc4257SSteve Yin pRXAct = NULL; 2715fdc4257SSteve Yin else 2725fdc4257SSteve Yin pRXAct = pRXI.get(); 2735fdc4257SSteve Yin return S_OK; 2745fdc4257SSteve Yin 2755fdc4257SSteve Yin LEAVE_PROTECTED_BLOCK 2765fdc4257SSteve Yin } 2775fdc4257SSteve Yin 2785fdc4257SSteve Yin /** 2795fdc4257SSteve Yin * Helper function used for converting keybinding to string. 2805fdc4257SSteve Yin * 2815fdc4257SSteve Yin * @param keySet the key stroke sequence. 2825fdc4257SSteve Yin * @param pString the output keybinding string. 2835fdc4257SSteve Yin */ 2845fdc4257SSteve Yin void CAccActionBase::GetkeyBindingStrByXkeyBinding( const Sequence< KeyStroke > &keySet, OLECHAR* pString ) 2855fdc4257SSteve Yin { 2865fdc4257SSteve Yin // #CHECK# 2875fdc4257SSteve Yin if(pString == NULL) 2885fdc4257SSteve Yin return; 2895fdc4257SSteve Yin 2905fdc4257SSteve Yin for( int iIndex = 0;iIndex < keySet.getLength();iIndex++ ) 2915fdc4257SSteve Yin { 2925fdc4257SSteve Yin KeyStroke stroke = keySet[iIndex]; 2935fdc4257SSteve Yin OLECHAR wString[64] = {NULL}; 2945fdc4257SSteve Yin if(iIndex>0) 2955fdc4257SSteve Yin wcscat( wString, OLESTR(" ") ); 2965fdc4257SSteve Yin if((stroke.Modifiers & MODIFIER_SHIFT) == MODIFIER_SHIFT) 2975fdc4257SSteve Yin wcscat( wString, OLESTR("Shift+") ); 2985fdc4257SSteve Yin if((stroke.Modifiers & MODIFIER_CTRL) == MODIFIER_CTRL) 2995fdc4257SSteve Yin wcscat( wString, OLESTR("Ctrl+") ); 3005fdc4257SSteve Yin if((stroke.Modifiers & MODIFIER_ALT) == MODIFIER_ALT) 3015fdc4257SSteve Yin wcscat( wString, OLESTR("Alt+") ); 3025fdc4257SSteve Yin if(stroke.KeyCode) 3035fdc4257SSteve Yin { 3045fdc4257SSteve Yin OLECHAR* pChar = getOLECHARFromKeyCode(stroke.KeyCode); 3055fdc4257SSteve Yin if(pChar != NULL) 3065fdc4257SSteve Yin wcscat( wString, pChar ); 3075fdc4257SSteve Yin else if (stroke.KeyCode <= 255) 3085fdc4257SSteve Yin { 3095fdc4257SSteve Yin OLECHAR pChar[4] = {NULL}; 3105fdc4257SSteve Yin swprintf( pChar, L"%c", stroke.KeyCode); 3115fdc4257SSteve Yin wcscat( wString, pChar); 3125fdc4257SSteve Yin } 3135fdc4257SSteve Yin else 3145fdc4257SSteve Yin { 3155fdc4257SSteve Yin OLECHAR pChar[4] = {NULL}; 3165fdc4257SSteve Yin swprintf( pChar, L"%d", stroke.KeyCode); 3175fdc4257SSteve Yin wcscat( wString, pChar); 3185fdc4257SSteve Yin } 3195fdc4257SSteve Yin } 3205fdc4257SSteve Yin 3215fdc4257SSteve Yin wcscat( pString, wString); 3225fdc4257SSteve Yin } 3235fdc4257SSteve Yin } 3245fdc4257SSteve Yin 3255fdc4257SSteve Yin /** 3265fdc4257SSteve Yin * Helper function used for converting key code to ole string. 3275fdc4257SSteve Yin * 3285fdc4257SSteve Yin * @param key the key code. 3295fdc4257SSteve Yin */ 3305fdc4257SSteve Yin OLECHAR* CAccActionBase::getOLECHARFromKeyCode(long key) 3315fdc4257SSteve Yin { 3325fdc4257SSteve Yin static struct keyMap 3335fdc4257SSteve Yin { 3345fdc4257SSteve Yin int keyCode; 3355fdc4257SSteve Yin OLECHAR* key; 3365fdc4257SSteve Yin } 3375fdc4257SSteve Yin map[] = 3385fdc4257SSteve Yin { 3395fdc4257SSteve Yin {MODIFIER_SHIFT, L"SHIFT" }, 3405fdc4257SSteve Yin {MODIFIER_CTRL, L"CTRL" }, 3415fdc4257SSteve Yin {MODIFIER_ALT, L"ALT" }, 3425fdc4257SSteve Yin CODEENTRY(NUM0),CODEENTRY(NUM1),CODEENTRY(NUM2),CODEENTRY(NUM3),CODEENTRY(NUM4),CODEENTRY(NUM5), 3435fdc4257SSteve Yin CODEENTRY(NUM6),CODEENTRY(NUM7),CODEENTRY(NUM8),CODEENTRY(NUM9), 3445fdc4257SSteve Yin CODEENTRY(A),CODEENTRY(B),CODEENTRY(C),CODEENTRY(D),CODEENTRY(E),CODEENTRY(F), 3455fdc4257SSteve Yin CODEENTRY(G),CODEENTRY(H),CODEENTRY(I),CODEENTRY(J),CODEENTRY(K),CODEENTRY(L), 3465fdc4257SSteve Yin CODEENTRY(M),CODEENTRY(N),CODEENTRY(O),CODEENTRY(P),CODEENTRY(Q),CODEENTRY(R), 3475fdc4257SSteve Yin CODEENTRY(S),CODEENTRY(T),CODEENTRY(U),CODEENTRY(V),CODEENTRY(W),CODEENTRY(X), 3485fdc4257SSteve Yin CODEENTRY(Y),CODEENTRY(Z), 3495fdc4257SSteve Yin CODEENTRY(F1),CODEENTRY(F2),CODEENTRY(F3),CODEENTRY(F4),CODEENTRY(F5),CODEENTRY(F6), 3505fdc4257SSteve Yin CODEENTRY(F7),CODEENTRY(F8),CODEENTRY(F9),CODEENTRY(F10),CODEENTRY(F11),CODEENTRY(F12), 3515fdc4257SSteve Yin CODEENTRY(F13),CODEENTRY(F14),CODEENTRY(F15),CODEENTRY(F16),CODEENTRY(F17),CODEENTRY(F18), 3525fdc4257SSteve Yin CODEENTRY(F19),CODEENTRY(F20),CODEENTRY(F21),CODEENTRY(F22),CODEENTRY(F23),CODEENTRY(F24), 3535fdc4257SSteve Yin CODEENTRY(F25),CODEENTRY(F26), 3545fdc4257SSteve Yin 3555fdc4257SSteve Yin { KEYCODE_DOWN, L"DOWN" }, 3565fdc4257SSteve Yin { KEYCODE_UP, L"UP" }, 3575fdc4257SSteve Yin { KEYCODE_LEFT, L"LEFT" }, 3585fdc4257SSteve Yin { KEYCODE_RIGHT, L"RIGHT" }, 3595fdc4257SSteve Yin { KEYCODE_HOME, L"HOME" }, 3605fdc4257SSteve Yin { KEYCODE_END, L"END" }, 3615fdc4257SSteve Yin { KEYCODE_PAGEUP, L"PAGEUP" }, 3625fdc4257SSteve Yin { KEYCODE_PAGEDOWN, L"PAGEDOWN" }, 3635fdc4257SSteve Yin { KEYCODE_RETURN, L"RETURN" }, 3645fdc4257SSteve Yin { KEYCODE_ESCAPE, L"ESCAPE" }, 3655fdc4257SSteve Yin { KEYCODE_TAB, L"TAB" }, 3665fdc4257SSteve Yin { KEYCODE_BACKSPACE, L"BACKSPACE" }, 3675fdc4257SSteve Yin { KEYCODE_SPACE, L"SPACE" }, 3685fdc4257SSteve Yin { KEYCODE_INSERT, L"INSERT" }, 3695fdc4257SSteve Yin { KEYCODE_DELETE, L"DELETE" }, 3705fdc4257SSteve Yin { KEYCODE_ADD, L"ADD" }, 3715fdc4257SSteve Yin { KEYCODE_SUBTRACT, L"SUBTRACT" }, 3725fdc4257SSteve Yin { KEYCODE_MULTIPLY, L"MULTIPLY" }, 3735fdc4257SSteve Yin { KEYCODE_DIVIDE, L"DIVIDE" }, 3745fdc4257SSteve Yin { KEYCODE_POINT, L"POINT" }, 3755fdc4257SSteve Yin { KEYCODE_COMMA, L"COMMA" }, 3765fdc4257SSteve Yin { KEYCODE_LESS, L"LESS" }, 3775fdc4257SSteve Yin { KEYCODE_GREATER, L"GREATER" }, 3785fdc4257SSteve Yin { KEYCODE_EQUAL, L"EQUAL" }, 3795fdc4257SSteve Yin { KEYCODE_OPEN, L"OPEN" }, 3805fdc4257SSteve Yin { KEYCODE_CUT, L"CUT" }, 3815fdc4257SSteve Yin { KEYCODE_COPY, L"COPY" }, 3825fdc4257SSteve Yin { KEYCODE_PASTE, L"PASTE" }, 3835fdc4257SSteve Yin { KEYCODE_UNDO, L"UNDO" }, 3845fdc4257SSteve Yin { KEYCODE_REPEAT, L"REPEAT" }, 3855fdc4257SSteve Yin { KEYCODE_FIND, L"FIND" }, 3865fdc4257SSteve Yin { KEYCODE_PROPERTIES, L"PROPERTIES" }, 3875fdc4257SSteve Yin { KEYCODE_FRONT, L"FRONT" }, 3885fdc4257SSteve Yin { KEYCODE_CONTEXTMENU, L"CONTEXTMENU" }, 3895fdc4257SSteve Yin { KEYCODE_HELP, L"HELP" }, 3905fdc4257SSteve Yin }; 3915fdc4257SSteve Yin static long nCount = countof(map); 3925fdc4257SSteve Yin 3935fdc4257SSteve Yin long min = 0; 3945fdc4257SSteve Yin long max = nCount-1; 3955fdc4257SSteve Yin long mid = nCount/2; 3965fdc4257SSteve Yin while(min<max) 3975fdc4257SSteve Yin { 3985fdc4257SSteve Yin if(key<map[mid].keyCode) 3995fdc4257SSteve Yin max = mid-1; 4005fdc4257SSteve Yin else if(key>map[mid].keyCode) 4015fdc4257SSteve Yin min = mid+1; 4025fdc4257SSteve Yin else 4035fdc4257SSteve Yin break; 4045fdc4257SSteve Yin mid = (min+max)/2; 4055fdc4257SSteve Yin } 4065fdc4257SSteve Yin 4075fdc4257SSteve Yin if(key == map[mid].keyCode) 4085fdc4257SSteve Yin { 4095fdc4257SSteve Yin return map[mid].key; 4105fdc4257SSteve Yin } 4115fdc4257SSteve Yin else 4125fdc4257SSteve Yin { 4135fdc4257SSteve Yin return NULL; 4145fdc4257SSteve Yin } 4155fdc4257SSteve Yin } 4165fdc4257SSteve Yin 417