inline std::wstring wcsnormalize(norm_type norm,wchar_t const *begin,wchar_t const *end) { // We use FoldString, under Vista it actually does normalization; // under XP and below it does something similar, half job, better then nothing unsigned flags = 0; switch(norm) { case norm_nfd: flags = MAP_COMPOSITE; break; case norm_nfc: flags = MAP_PRECOMPOSED; break; case norm_nfkd: flags = MAP_FOLDCZONE; break; case norm_nfkc: flags = MAP_FOLDCZONE | MAP_COMPOSITE; break; default: flags = MAP_PRECOMPOSED; } int len = FoldStringW(flags,begin,end-begin,0,0); if(len == 0) return std::wstring(); std::vector<wchar_t> v(len+1); len = FoldStringW(flags,begin,end-begin,&v.front(),len+1); return std::wstring(&v.front(),len); }
/*********************************************************************** * FoldStringA (KERNEL32.@) */ int WINAPI FoldStringA (DWORD dwMapFlags, LPCSTR lpSrcStr, int cchSrc, LPSTR lpDestStr, int cchDest) { int cchSrcW, ret; WCHAR *pSrcStrW; if (!lpSrcStr || !cchSrc || (cchDest < 0) || ((cchDest > 0) && !lpDestStr)) { SetLastError (ERROR_INVALID_PARAMETER); return 0; } cchSrcW = MultiByteToWideChar (CP_ACP, dwMapFlags & MAP_COMPOSITE ? MB_COMPOSITE : 0, lpSrcStr, cchSrc, NULL, 0); pSrcStrW = HeapAlloc (GetProcessHeap(), 0, cchSrcW * sizeof (WCHAR)); if (!pSrcStrW) { SetLastError (ERROR_NOT_ENOUGH_MEMORY); return 0; } MultiByteToWideChar (CP_ACP, dwMapFlags & MAP_COMPOSITE ? MB_COMPOSITE : 0, lpSrcStr, cchSrc, pSrcStrW, cchSrcW); ret = FoldStringW (dwMapFlags, pSrcStrW, cchSrcW, NULL, 0); if (ret && cchDest) { WCHAR *pDestStrW; pDestStrW = HeapAlloc (GetProcessHeap (), 0, ret * sizeof (WCHAR)); if (!pDestStrW) { SetLastError (ERROR_NOT_ENOUGH_MEMORY); HeapFree (GetProcessHeap (), 0, pSrcStrW); return 0; } ret = FoldStringW (dwMapFlags, pSrcStrW, cchSrcW, pDestStrW, ret); if (ret) { if (!WideCharToMultiByte (CP_ACP, 0, pDestStrW, ret, lpDestStr, cchDest, NULL, NULL)) { ret = 0; SetLastError (ERROR_INSUFFICIENT_BUFFER); } } HeapFree (GetProcessHeap (), 0, pDestStrW); } HeapFree (GetProcessHeap (), 0, pSrcStrW); return ret; }
MyGUI::Char translateWin32Text(MyGUI::KeyCode kc) { static WCHAR deadKey = 0; BYTE keyState[256]; HKL layout = GetKeyboardLayout(0); if ( GetKeyboardState(keyState) == 0 ) return 0; int code = *((int*)&kc); unsigned int vk = MapVirtualKeyEx((UINT)code, 3, layout); if ( vk == 0 ) return 0; WCHAR buff[3] = { 0, 0, 0 }; int ascii = ToUnicodeEx(vk, (UINT)code, keyState, buff, 3, 0, layout); if (ascii == 1 && deadKey != '\0' ) { // A dead key is stored and we have just converted a character key // Combine the two into a single character WCHAR wcBuff[3] = { buff[0], deadKey, '\0' }; WCHAR out[3]; deadKey = '\0'; if (FoldStringW(MAP_PRECOMPOSED, (LPWSTR)wcBuff, 3, (LPWSTR)out, 3)) return out[0]; } else if (ascii == 1) { // We have a single character deadKey = '\0'; return buff[0]; } else if (ascii == 2) { // Convert a non-combining diacritical mark into a combining diacritical mark // Combining versions range from 0x300 to 0x36F; only 5 (for French) have been mapped below // http://www.fileformat.info/info/unicode/block/combining_diacritical_marks/images.htm switch (buff[0]) { case 0x5E: // Circumflex accent: ? deadKey = 0x302; break; case 0x60: // Grave accent: ? deadKey = 0x300; break; case 0xA8: // Diaeresis: ? deadKey = 0x308; break; case 0xB4: // Acute accent: ? deadKey = 0x301; break; case 0xB8: // Cedilla: ? deadKey = 0x327; break; default: deadKey = buff[0]; break; } } return 0; }
LRESULT CALLBACK generic_view_handler( HWND win, UINT msg, WPARAM mp1, LPARAM mp2) { LRESULT ret = 0; Handle self = GetWindowLongPtr( win, GWLP_USERDATA); PWidget v = ( PWidget) self; UINT orgMsg = msg; Event ev; Bool hiStage = false; int i, orgCmd; Bool message_result = true; if ( !self || appDead) return DefWindowProcW( win, msg, mp1, mp2); memset( &ev, 0, sizeof (ev)); ev. gen. source = self; switch ( msg) { case WM_NCACTIVATE: // if activation or deactivation is concerned with declipped window ( e.g.self), // notify its top level frame so that it will have the chance to redraw itself correspondingly if ( is_declipped_child( self) && !Widget_is_child( hwnd_to_view(( HWND) mp2), hwnd_top_level( self))) { Handle x = hwnd_top_level( self); if ( x) SendMessage( DHANDLE( x), WM_NCACTIVATE, mp1, mp2); } break; case WM_MOUSEACTIVATE: // if pointing to non-active frame, but its declipped child is active at the moment, // cancel activation - it could produce unwilling focus changes if ( sys className == WC_FRAME) { Handle x = hwnd_to_view( GetActiveWindow()); if ( is_declipped_child(x) && Widget_is_child( x, self)) return MA_NOACTIVATE; } break; case WM_CLOSE: if ( sys className != WC_FRAME) return 0; break; case WM_COMMAND: if (( HIWORD( mp1) == 0 /* menu source */) && ( mp2 == 0)) { if ( LOWORD( mp1) <= MENU_ID_AUTOSTART) { HWND active = GetFocus(); if ( active != nil) SendMessage( active, LOWORD( mp1), 0, 0); } else if ( sys lastMenu) { PAbstractMenu a = ( PAbstractMenu) sys lastMenu; if ( a-> stage <= csNormal) a-> self-> sub_call_id(( Handle) a, LOWORD( mp1) - MENU_ID_AUTOSTART); } } break; case WM_CONTEXTMENU: { POINT a; a. x = ( short)LOWORD( mp2); a. y = ( short)HIWORD( mp2); ev. cmd = cmPopup; // mouse event ev. gen. B = ( GetKeyState( VK_LBUTTON) < 0) | ( GetKeyState( VK_RBUTTON) < 0); if ( !ev. gen. B && GetSystemMetrics( SM_MOUSEPRESENT)) GetCursorPos(( POINT*) &a); MapWindowPoints( NULL, win, &a, 1); ev. gen. P. x = a. x; ev. gen. P. y = sys lastSize. y - a. y - 1; } break; case WM_ENABLE: ev. cmd = mp1 ? cmEnable : cmDisable; hiStage = true; break; case WM_ERASEBKGND: return 1; case WM_FORCEFOCUS: if ( mp2) ((( PWidget) mp2)-> self)-> set_selected(( Handle) mp2, 1); return 0; case WM_HASMATE: *(( Handle*) mp2) = self; return HASMATE_MAGIC; case WM_IME_CHAR: if ( apc_widget_is_responsive( self)) { ev. cmd = cmKeyDown; ev. key. mod = kmUnicode; ev. key. key = kbNoKey; ev. key. code = mp1; } break; case WM_SYSKEYDOWN: case WM_SYSKEYUP: if ( mp2 & ( 1 << 29)) ev. key. mod = kmAlt; case WM_KEYDOWN: case WM_KEYUP: if ( apc_widget_is_responsive( self)) { BYTE * keyState; Bool up = ( msg == WM_KEYUP) || ( msg == WM_SYSKEYUP); Bool extended = mp2 & ( 1 << 24); UINT scan = ( HIWORD( mp2) & 0xFF) | ( up ? 0x80000000 : 0); int deadPollCount = 0; HKL kl = GetKeyboardLayout(0); // basic assignments ev. cmd = up ? cmKeyUp : cmKeyDown; ev. key. key = ctx_remap_def( mp1, ctx_kb2VK, false, kbNoKey); ev. key. code = mp1; ev. key. repeat = mp2 & 0x000000FF; // VK validations if ( extended) { int ks = ev. key. key; ev. key. key = ctx_remap_def( ks, ctx_kb2VK3, true, ks); if ( ev. key. key != ks) extended = false; // avoid (Ctrl|Alt)R+KeyPad combinations } else if ( mp1 >= VK_NUMPAD0 && mp1 <= VK_DIVIDE) extended = true; // include numpads ev. key. mod = 0 | ( extended ? kmKeyPad : 0) | (( GetKeyState( VK_SHIFT) < 0) ? kmShift : 0) | (( GetKeyState( VK_CONTROL) < 0) ? kmCtrl : 0) | (( GetKeyState( VK_MENU) < 0) ? kmAlt : 0); keyState = guts. keyState; AGAIN: if ( PApplication(application)-> wantUnicodeInput) { WCHAR keys[ 2]; // unicode mapping switch ( ToUnicodeEx( mp1, scan, keyState, keys, 2, 0, kl)) { case 1: // char if ( lastDeadKey ) { WCHAR wcBuffer[3]; WCHAR out[3]; wcBuffer[0] = keys[0]; wcBuffer[1] = lastDeadKey; wcBuffer[2] = '\0'; if ( FoldStringW(MAP_PRECOMPOSED, (LPWSTR) wcBuffer, 3, (LPWSTR) out, 3) ) keys[0] = out[0]; } if ( !deadPollCount && ( GetKeyState( VK_MENU) < 0) && ( GetKeyState( VK_SHIFT) >= 0)) { WCHAR keys2[2]; if (( ToUnicodeEx( mp1, scan, guts. emptyKeyState, keys2, 2, 0, kl) == 1) && ( keys2[0] != keys[0])) { /* example - (AltGr+2) == '@' on danish keyboard. this hack is to tell whether the key without mods will give same character code ... */ ev. key. mod &= ~(kmAlt|kmCtrl|kmShift); } } if (!up) lastDeadKey = 0; break; case 2: { // dead key lastDeadKey = ctx_remap_def( keys[0], ctx_deadkeys, true, keys[0]); keys[ 0] = 0; ev. key. mod |= kmDeadKey; } break; case 0: // virtual key if ( deadPollCount == 0) { /* can't have character code - maybe fish out without mods? */ keyState = guts. emptyKeyState; deadPollCount = 1; goto AGAIN; } else { /* same meaning without mods, no code anyway */ keys[ 0] = 0; } if (!up) lastDeadKey = 0; break; default: ev. key. mod |= kmDeadKey; if (!up) lastDeadKey = 0; } ev. key. code = keys[ 0]; ev. key. mod |= kmUnicode; } else { BYTE keys[ 4]; switch ( ToAsciiEx( mp1, scan, keyState, (LPWORD) keys, 0, kl)) { case 1: // char if ( lastDeadKey ) { BYTE cBuffer[3]; BYTE out[3]; cBuffer[0] = keys[0]; cBuffer[1] = lastDeadKey; cBuffer[2] = '\0'; if ( FoldStringA(MAP_PRECOMPOSED, (LPSTR) cBuffer, 3, (LPSTR) out, 3) ) keys[0] = out[0]; } if ( !deadPollCount && ( GetKeyState( VK_MENU) < 0) && ( GetKeyState( VK_SHIFT) >= 0)) { BYTE keys2[4]; if (( ToAsciiEx( mp1, scan, guts. emptyKeyState, (LPWORD) keys2, 0, kl) == 1) && ( keys2[0] != keys[0])) { /* example - (AltGr+2) == '@' on danish keyboard. this hack is to tell whether the key without mods will give same character code ... */ ev. key. mod &= ~(kmAlt|kmCtrl|kmShift); } } break; case 2: { // dead key lastDeadKey = keys[0]; keys[ 0] = 0; ev. key. mod |= kmDeadKey; } break; case 0: // virtual key if ( deadPollCount == 0) { /* can't have character code - maybe fish out without mods? */ keyState = guts. emptyKeyState; deadPollCount = 1; goto AGAIN; } else { /* same meaning without mods, no code anyway */ keys[ 0] = 0; } if (!up) lastDeadKey = 0; break; default: ev. key. mod |= kmDeadKey; if (!up) lastDeadKey = 0; } ev. key. code = keys[ 0]; } // simulated key codes if ( ev. key. key == kbTab && ( ev. key. mod & kmShift)) ev. key. key = kbBackTab; if ( ev. key. code >= 'A' && ev. key. code <= 'z' && ev. key. mod & kmCtrl) { ev. key. code = toupper(ev. key. code & 0xFF) - '@'; if (!( ev. key. mod & kmShift)) ev. key. code = tolower( ev. key. code); } } break; case WM_INITMENUPOPUP: if ( HIWORD( mp2)) break; // do not use system popup case WM_INITMENU: { PMenuWndData mwd = ( PMenuWndData) hash_fetch( menuMan, &mp1, sizeof( void*)); PMenuItemReg m = nil; sys lastMenu = mwd ? mwd-> menu : nilHandle; if ( mwd && mwd-> menu && ( PAbstractMenu(mwd-> menu)->stage <= csNormal)) { m = ( PMenuItemReg) AbstractMenu_first_that( mwd-> menu, find_oid, INT2PTR(void*,mwd->id), true); hiStage = true; ev. cmd = cmMenu; ev. gen. H = mwd-> menu; ev. gen. i = m ? m-> id : 0; } if (( msg == WM_INITMENUPOPUP) && ( m == nil)) ev. cmd = 0; } break; case WM_KILLFOCUS: if (( HWND) mp1 != win) { ev. cmd = cmReleaseFocus; hiStage = true; apt_assign( aptFocused, 0); DestroyCaret(); } break; case WM_LBUTTONDOWN: ev. pos. button = mbLeft; goto MB_DOWN; case WM_RBUTTONDOWN: ev. pos. button = mbRight; goto MB_DOWN; case WM_MBUTTONDOWN: ev. pos. button = mbMiddle; goto MB_DOWN; case WM_LBUTTONUP: ev. pos. button = mbLeft; goto MB_UP; case WM_RBUTTONUP: ev. pos. button = mbRight; goto MB_UP; case WM_MBUTTONUP: ev. pos. button = mbMiddle; goto MB_UP; case WM_LBUTTONDBLCLK: ev. pos. button = mbLeft; goto MB_DBLCLK; case WM_RBUTTONDBLCLK: ev. pos. button = mbRight; goto MB_DBLCLK; case WM_MBUTTONDBLCLK: ev. pos. button = mbMiddle; goto MB_DBLCLK; case WM_LMOUSECLICK: ev. pos. button = mbLeft; goto MB_CLICK; case WM_RMOUSECLICK: ev. pos. button = mbRight; goto MB_CLICK; case WM_MMOUSECLICK: ev. pos. button = mbMiddle; goto MB_CLICK; case WM_MOUSEWHEEL: { POINT p; p. x = (short)LOWORD( mp2); p. y = (short)HIWORD( mp2); ev. cmd = cmMouseWheel; ev. pos. button = ( short) HIWORD( mp1); MapWindowPoints( nil, win, &p, 1); ev. pos. where. x = p. x; ev. pos. where. y = sys lastSize. y - p. y - 1; } goto MB_MAIN_NOPOS; case WM_MOUSEMOVE: ev. cmd = cmMouseMove; if ( self != lastMouseOver) { Handle old = lastMouseOver; lastMouseOver = self; if ( old && ( PWidget( old)-> stage == csNormal)) SendMessage(( HWND)(( PWidget) old)-> handle, WM_MOUSEEXIT, mp1, mp2); SendMessage( win, WM_MOUSEENTER, mp1, mp2); if ( !guts. mouseTimer) { guts. mouseTimer = 1; if ( !SetTimer( dsys(application)handle, TID_USERMAX, 100, nil)) apiErr; } } goto MB_MAIN; case WM_MOUSEENTER: ev. cmd = cmMouseEnter; goto MB_MAIN; case WM_MOUSEEXIT: ev. cmd = cmMouseLeave; goto MB_MAIN; MB_DOWN: ev. cmd = cmMouseDown; goto MB_MAINACT; MB_UP: ev. cmd = cmMouseUp; goto MB_MAINACT; MB_DBLCLK: ev. pos. dblclk = 1; MB_CLICK: ev. cmd = cmMouseClick; goto MB_MAINACT; MB_MAINACT: if ( !is_apt( aptEnabled) || !apc_widget_is_responsive( self)) { if ( ev. cmd == cmMouseDown || (ev. cmd == cmMouseClick && ev. pos. dblclk)) MessageBeep( MB_OK); return 0; } goto MB_MAIN; MB_MAIN: if ( ev. cmd == cmMouseDown && !is_apt( aptFirstClick)) { Handle x = self; while ( dsys(x) className != WC_FRAME && ( x != application)) x = (( PWidget) x)-> owner; if ( x != application && !local_wnd( GetActiveWindow(), DHANDLE( x))) { ev. cmd = 0; // yes, we abandon mousedown but we should force selection: if ((( PApplication) application)-> hintUnder == self) v-> self-> set_hintVisible( self, 0); if (( v-> options. optSelectable) && ( v-> selectingButtons & ev. pos. button)) apc_widget_set_focused( self); } } ev. pos. where. x = (short)LOWORD( mp2); ev. pos. where. y = sys lastSize. y - (short)HIWORD( mp2) - 1; MB_MAIN_NOPOS: ev. pos. mod = 0 | (( mp1 & MK_CONTROL ) ? kmCtrl : 0) | (( mp1 & MK_SHIFT ) ? kmShift : 0) | (( GetKeyState( VK_MENU) < 0) ? kmAlt : 0) | apc_pointer_get_state(self) ; break; case WM_MENUCHAR: { int key; ev. key. key = ctx_remap_def( mp1, ctx_kb2VK2, false, kbNoKey); ev. key. code = mp1; ev. key. mod |= (( GetKeyState( VK_SHIFT) < 0) ? kmShift : 0) | (( GetKeyState( VK_CONTROL) < 0) ? kmCtrl : 0) | (( GetKeyState( VK_MENU) < 0) ? kmAlt : 0); if (( ev. key. mod & kmCtrl) && ( ev. key. code <= 'z')) ev. key. code += 'A' - 1; key = CAbstractMenu-> translate_key( nilHandle, ev. key. code, ev. key. key, ev. key. mod); if ( v-> self-> process_accel( self, key)) return MAKELONG( 0, MNC_CLOSE); } break; case WM_SYNCMOVE: { Handle parent = v-> self-> get_parent(( Handle) v); if ( parent) { Point pos = var self-> get_origin( self); ev. cmd = cmMove; ev. gen. P = pos; if ( pos. x == var pos. x && pos. y == var pos. y) ev. cmd = 0; } } break; case WM_MOVE: { Handle parent = v-> self-> get_parent(( Handle) v); if ( parent) { Point sz = CWidget(parent)-> get_size( parent); ev. cmd = cmMove; ev. gen . P. x = ( short) LOWORD( mp2); ev. gen . P. y = sz. y - ( short) HIWORD( mp2) - sys yOverride; if ( is_apt( aptTransparent)) InvalidateRect( win, nil, false); } } break; case WM_NCHITTEST: if ( guts. focSysDialog) return HTERROR; // dlg protect code - protecting from user actions if ( !guts. focSysDisabled && ( Application_map_focus( application, self) != self)) return HTERROR; break; case WM_PAINT: ev. cmd = cmPaint; if ( ( sys className == WC_CUSTOM) && ( var stage == csNormal) && ( list_index_of( &guts. transp, self) >= 0) ) return 0; break; case WM_QUERYNEWPALETTE: return palette_change( self); case WM_PALETTECHANGED: if (( HWND) mp1 != win) { Handle mp = hwnd_to_view(( HWND) mp1); if ( mp && ( hwnd_top_level( mp) == hwnd_top_level( self))) return 0; palette_change( self); } break; case WM_POSTAL: ev. cmd = cmPost; ev. gen. H = ( Handle) mp1; ev. gen. p = ( void *) mp2; break; case WM_PRIMA_CREATE: ev. cmd = cmSetup; break; case WM_SETFOCUS: if ( guts. focSysDialog) return 1; // dlg protect code - general case if ( !guts. focSysDisabled && !guts. focSysGranted) { Handle hf = Application_map_focus( application, self); if ( hf != self) { PostMessage( win, WM_FORCEFOCUS, 0, ( LPARAM) hf); return 1; } } if (( HWND) mp1 != win) { ev. cmd = cmReceiveFocus; hiStage = true; apt_assign( aptFocused, 1); cursor_update( self); } break; case WM_SETVISIBLE: if ( list_index_of( &guts. transp, self) < 0) { if ( v-> stage <= csNormal) ev. cmd = mp1 ? cmShow : cmHide; hiStage = true; apt_assign( aptVisible, mp1); } break; case WM_SIZE: ev. cmd = cmSize; ev. gen. R. left = sys lastSize. x; ev. gen. R. bottom = sys lastSize. y; sys lastSize. x = ev. gen. R. right = ev. gen . P. x = ( short) LOWORD( mp2); sys lastSize. y = ev. gen. R. top = ev. gen . P. y = ( short) HIWORD( mp2); if ( ev. gen. R. top != ev. gen. R. bottom) { int delta = ev. gen. R. top - ev. gen. R. bottom; Widget_first_that( self, move_back, &delta); if ( is_apt( aptFocused)) cursor_update(( Handle) self); } if ( sys sizeLockLevel == 0 && var stage <= csNormal) var virtualSize = sys lastSize; break; case WM_TIMER: { int id = mp1 - 1; if ( id >= 0 && id < sys timeDefsCount) ev. gen. H = ( Handle) sys timeDefs[ id]. item; if ( ev. gen. H) { v = ( PWidget)( self = ev. gen. H); ev. cmd = cmTimer; } } break; case WM_WINDOWPOSCHANGING: { LPWINDOWPOS l = ( LPWINDOWPOS) mp2; if ( sys className == WC_CUSTOM) { if (( l-> flags & SWP_NOSIZE) == 0) { ev. cmd = cmCalcBounds; ev. gen. R. right = l-> cx; ev. gen. R. top = l-> cy; } } if (( l-> flags & SWP_NOZORDER) == 0) zorder_sync( self, win, l); } break; case WM_WINDOWPOSCHANGED: { LPWINDOWPOS l = ( LPWINDOWPOS) mp2; if (( l-> flags & SWP_NOZORDER) == 0) PostMessage( win, WM_ZORDERSYNC, 0, 0); if (( l-> flags & SWP_NOSIZE) == 0) { sys yOverride = l-> cy; SendMessage( win, WM_SYNCMOVE, 0, 0); } if ( l-> flags & SWP_HIDEWINDOW) SendMessage( win, WM_SETVISIBLE, 0, 0); if ( l-> flags & SWP_SHOWWINDOW) SendMessage( win, WM_SETVISIBLE, 1, 0); } break; case WM_ZORDERSYNC: ev. cmd = cmZOrderChanged; break; }
/** *@brief キーコード(CEGUI::Key)を文字(CEGUI::utf32)に変換 CEGUI公式サイト(http://cegui.org.uk/wiki/DirectInput_to_CEGUI_utf32)のコードを一部変更(MITライセンス) * @param scanCode キーコード * @return 文字 */ CEGUI::utf32 keycodeToUTF32( unsigned int scanCode) { CEGUI::utf32 utf = 0; #ifdef _WIN32 BYTE keyboardState[256]; unsigned char ucBuffer[3]; static WCHAR deadKey = '\0'; HKL hklKeyboardLayout = GetKeyboardLayout(0); if (GetKeyboardState(keyboardState) == FALSE) return utf; UINT virtualKey = MapVirtualKeyEx(scanCode, 3, hklKeyboardLayout); if (virtualKey == 0) return utf; int ascii = ToAsciiEx(virtualKey, scanCode, keyboardState, (LPWORD) ucBuffer, 0, hklKeyboardLayout); if(deadKey != '\0' && ascii == 1) { WCHAR wcBuffer[3]; WCHAR out[3]; wcBuffer[0] = ucBuffer[0]; wcBuffer[1] = deadKey; wcBuffer[2] = '\0'; if( FoldStringW(MAP_PRECOMPOSED, (LPWSTR) wcBuffer, 3, (LPWSTR) out, 3) ) utf = out[0]; else { DWORD dw = GetLastError(); switch(dw) { case ERROR_INSUFFICIENT_BUFFER: case ERROR_INVALID_FLAGS: case ERROR_INVALID_PARAMETER: break; } } deadKey = '\0'; } else if (ascii == 1) { utf = ucBuffer[0]; deadKey = '\0'; } else { switch(ucBuffer[0]) { case 0x5E: deadKey = 0x302; break; case 0x60: deadKey = 0x300; break; case 0xA8: deadKey = 0x308; break; case 0xB4: deadKey = 0x301; break; case 0xB8: deadKey = 0x327; break; default: deadKey = ucBuffer[0]; } } #else #endif return utf; }
int FS_NormalCase() { int NumErrors = 0; // error count - to be returned int rc; // return code #ifdef PERF DbgBreakPoint(); #endif // // cbDest = 0. // // Variation 1 - cbSrc = -1 rc = FoldStringW( MAP_PRECOMPOSED, FoldSrc1, -1, FoldDest, 0 ); CheckReturnValidW( rc, -1, NULL, FoldSrc1, "cbDest (0) cbSrc (-1)", &NumErrors ); // Variation 2 - cbSrc = value rc = FoldStringW( MAP_PRECOMPOSED, FoldSrc1, WC_STRING_LEN_NULL(FoldSrc1), FoldDest, 0 ); CheckReturnValidW( rc, -1, NULL, FoldSrc1, "cbDest (0) cbSrc (value)", &NumErrors ); // Variation 3 - lpDestStr = NULL rc = FoldStringW( MAP_PRECOMPOSED, FoldSrc1, -1, NULL, 0 ); CheckReturnValidW( rc, -1, NULL, FoldSrc1, "cbDest (0) lpDestStr NULL", &NumErrors ); // // cbSrc. // // Variation 1 - cbSrc = -1 rc = FoldStringW( MAP_PRECOMPOSED, FoldSrc1, -1, FoldDest, BUFSIZE ); CheckReturnValidW( rc, -1, FoldDest, FoldSrc1, "cbSrc (-1)", &NumErrors ); // Variation 2 - cbSrc = value rc = FoldStringW( MAP_PRECOMPOSED, FoldSrc1, WC_STRING_LEN(FoldSrc1), FoldDest, BUFSIZE ); CheckReturnValidW( rc, WC_STRING_LEN(FoldSrc1), FoldDest, FoldSrc1, "cbSrc (value)", &NumErrors ); // Variation 3 - cbSrc = -1, no DestStr rc = FoldStringW( MAP_PRECOMPOSED, FoldSrc1, -1, NULL, 0 ); CheckReturnValidW( rc, -1, NULL, FoldSrc1, "cbSrc (-1), no DestStr", &NumErrors ); // Variation 4 - cbSrc = value, no DestStr rc = FoldStringW( MAP_PRECOMPOSED, FoldSrc1, WC_STRING_LEN(FoldSrc1), NULL, 0 ); CheckReturnValidW( rc, WC_STRING_LEN(FoldSrc1), NULL, FoldSrc1, "cbSrc (value), no DestStr", &NumErrors ); // // MAP_PRECOMPOSED Flag. // // Variation 1 - precomposed rc = FoldStringW( MAP_PRECOMPOSED, FoldSrc2, -1, FoldDest, BUFSIZE ); CheckReturnValidW( rc, -1, FoldDest, FoldSrc2, "precomposed", &NumErrors ); // Variation 2 - precomposed rc = FoldStringW( MAP_PRECOMPOSED, L"\x006e\x0303", -1, FoldDest, BUFSIZE ); CheckReturnValidW( rc, -1, FoldDest, L"\x00f1", "precomposed (n tilde)", &NumErrors ); // Variation 3 - precomposed rc = FoldStringW( MAP_PRECOMPOSED, L"\x006e\x0303", -1, NULL, 0 ); CheckReturnValidW( rc, -1, NULL, L"\x00f1", "precomposed (n tilde), no DestStr", &NumErrors ); // Variation 4 - precomposed rc = FoldStringW( MAP_PRECOMPOSED, L"\x0062\x0303", -1, FoldDest, BUFSIZE ); CheckReturnValidW( rc, -1, FoldDest, L"\x0062\x0303", "precomposed (b tilde)", &NumErrors ); // Variation 5 - precomposed rc = FoldStringW( MAP_PRECOMPOSED, L"\x0062\x0303", -1, NULL, 0 ); CheckReturnValidW( rc, -1, NULL, L"\x0062\x0303", "precomposed (b tilde), no DestStr", &NumErrors ); // // MAP_COMPOSITE Flag. // // Variation 1 - composite rc = FoldStringW( MAP_COMPOSITE, FoldSrc2, -1, FoldDest, BUFSIZE ); CheckReturnValidW( rc, -1, FoldDest, FoldSrc2, "composite", &NumErrors ); // Variation 2 - composite rc = FoldStringW( MAP_COMPOSITE, L"\x00f1", -1, FoldDest, BUFSIZE ); CheckReturnValidW( rc, -1, FoldDest, L"\x006e\x0303", "composite (n tilde)", &NumErrors ); // Variation 3 - composite rc = FoldStringW( MAP_COMPOSITE, L"\x00f1", -1, NULL, 0 ); CheckReturnValidW( rc, -1, NULL, L"\x006e\x0303", "composite (n tilde), no DestStr", &NumErrors ); // Variation 4 - composite rc = FoldStringW( MAP_COMPOSITE, L"\x01c4", -1, FoldDest, BUFSIZE ); CheckReturnValidW( rc, -1, FoldDest, L"\x0044\x017d", "composite (dz hacek)", &NumErrors ); // Variation 5 - composite rc = FoldStringW( MAP_COMPOSITE, L"\x01c4", -1, NULL, 0 ); CheckReturnValidW( rc, -1, NULL, L"\x0044\x017d", "composite (dz hacek), no DestStr", &NumErrors ); // Variation 6 - composite rc = FoldStringW( MAP_COMPOSITE, L"\x0062\x0303", -1, FoldDest, BUFSIZE ); CheckReturnValidW( rc, -1, FoldDest, L"\x0062\x0303", "composite (b tilde)", &NumErrors ); // Variation 7 - composite rc = FoldStringW( MAP_COMPOSITE, L"\x0062\x0303", -1, NULL, 0 ); CheckReturnValidW( rc, -1, NULL, L"\x0062\x0303", "composite (b tilde), no DestStr", &NumErrors ); // // MAP_FOLDCZONE Flag. // // Variation 1 - fold compatibility zone rc = FoldStringW( MAP_FOLDCZONE, FoldSrc2, -1, FoldDest, BUFSIZE ); CheckReturnValidW( rc, -1, FoldDest, FoldSrc2, "fold czone", &NumErrors ); // Variation 2 - fold compatibility zone rc = FoldStringW( MAP_FOLDCZONE, L"\x004a\xff24\xff22", -1, FoldDest, BUFSIZE ); CheckReturnValidW( rc, -1, FoldDest, L"\x004a\x0044\x0042", "fold czone (JDB)", &NumErrors ); // Variation 3 - fold compatibility zone rc = FoldStringW( MAP_FOLDCZONE, L"\x004a\xff24\xff22", -1, NULL, 0 ); CheckReturnValidW( rc, -1, NULL, L"\x004a\x0044\x0042", "fold czone (JDB), no DestStr", &NumErrors ); // // MAP_FOLDDIGITS Flag. // // Variation 1 - fold digits rc = FoldStringW( MAP_FOLDDIGITS, FoldSrc2, -1, FoldDest, BUFSIZE ); CheckReturnValidW( rc, -1, FoldDest, FoldSrc2, "fold digits", &NumErrors ); // Variation 2 - fold digits rc = FoldStringW( MAP_FOLDDIGITS, L"\x00b2\x00b3", -1, FoldDest, BUFSIZE ); CheckReturnValidW( rc, -1, FoldDest, L"\x0032\x0033", "fold digits (23)", &NumErrors ); // Variation 3 - fold digits rc = FoldStringW( MAP_FOLDDIGITS, L"\x00b2\x00b3", -1, NULL, 0 ); CheckReturnValidW( rc, -1, NULL, L"\x0032\x0033", "fold digits (23), no DestStr", &NumErrors ); // // Check precomposed with multiple diacritics. // // Variation 1 - precomp, multi diacritics rc = FoldStringW( MAP_PRECOMPOSED, wcMultiComp, 3, FoldDest, BUFSIZE ); CheckReturnValidW( rc, 2, FoldDest, L"\x00e9\x0300", "precomp, multi diacritics", &NumErrors ); // Variation 2 - precomp, czone rc = FoldStringW( MAP_PRECOMPOSED | MAP_FOLDCZONE, wcCompDigitCZone, -1, FoldDest, BUFSIZE ); CheckReturnValidW( rc, -1, FoldDest, L"\x00e9\x0300\x00b2\x003c", "precomp, czone", &NumErrors ); // Variation 3 - precomp, digits rc = FoldStringW( MAP_PRECOMPOSED | MAP_FOLDDIGITS, wcCompDigitCZone, -1, FoldDest, BUFSIZE ); CheckReturnValidW( rc, -1, FoldDest, L"\x00e9\x0300\x0032\xfe64", "precomp, digits", &NumErrors ); // Variation 4 - precomp, czone, digits rc = FoldStringW( MAP_PRECOMPOSED | MAP_FOLDCZONE | MAP_FOLDDIGITS, wcCompDigitCZone, -1, FoldDest, BUFSIZE ); CheckReturnValidW( rc, -1, FoldDest, L"\x00e9\x0300\x0032\x003c", "precomp, czone, digits", &NumErrors ); // // Check composite. // // Variation 1 - comp, czone rc = FoldStringW( MAP_COMPOSITE | MAP_FOLDCZONE, wcPrecompDigitCZone, -1, FoldDest, BUFSIZE ); CheckReturnValidW( rc, -1, FoldDest, L"\x0065\x0301\x0300\x00b2\x003c", "comp, czone", &NumErrors ); // Variation 2 - comp, digits rc = FoldStringW( MAP_COMPOSITE | MAP_FOLDDIGITS, wcPrecompDigitCZone, -1, FoldDest, BUFSIZE ); CheckReturnValidW( rc, -1, FoldDest, L"\x0065\x0301\x0300\x0032\xfe64", "comp, digits", &NumErrors ); // Variation 3 - comp, czone, digits rc = FoldStringW( MAP_COMPOSITE | MAP_FOLDCZONE | MAP_FOLDDIGITS, wcPrecompDigitCZone, -1, FoldDest, BUFSIZE ); CheckReturnValidW( rc, -1, FoldDest, L"\x0065\x0301\x0300\x0032\x003c", "comp, czone, digits", &NumErrors ); // // Return total number of errors found. // return (NumErrors); }
int FS_BadParamCheck() { int NumErrors = 0; // error count - to be returned int rc; // return code // // Null Pointers. // // Variation 1 - lpSrcStr = NULL rc = FoldStringW( MAP_FOLDDIGITS, NULL, -1, FoldDest, BUFSIZE ); CheckReturnBadParam( rc, 0, ERROR_INVALID_PARAMETER, "lpSrcStr NULL", &NumErrors ); // Variation 2 - lpDestStr = NULL rc = FoldStringW( MAP_FOLDDIGITS, FoldSrc1, -1, NULL, BUFSIZE ); CheckReturnBadParam( rc, 0, ERROR_INVALID_PARAMETER, "lpDestStr NULL", &NumErrors ); // // Bad Counts. // // Variation 1 - cbSrc = 0 rc = FoldStringW( MAP_FOLDDIGITS, FoldSrc1, 0, FoldDest, BUFSIZE ); CheckReturnBadParam( rc, 0, ERROR_INVALID_PARAMETER, "cbSrc = 0", &NumErrors ); // Variation 2 - cbDest < 0 rc = FoldStringW( MAP_FOLDDIGITS, FoldSrc1, -1, FoldDest, -1 ); CheckReturnBadParam( rc, 0, ERROR_INVALID_PARAMETER, "cbDest < 0", &NumErrors ); // // Zero or Invalid Flag Values. // // Variation 1 - dwMapFlags = invalid rc = FoldStringW( FS_INVALID_FLAGS, FoldSrc1, -1, FoldDest, BUFSIZE ); CheckReturnBadParam( rc, 0, ERROR_INVALID_FLAGS, "dwMapFlags invalid", &NumErrors ); // Variation 2 - dwMapFlags = 0 rc = FoldStringW( 0, FoldSrc1, -1, FoldDest, BUFSIZE ); CheckReturnBadParam( rc, 0, ERROR_INVALID_FLAGS, "dwMapFlags zero", &NumErrors ); // Variation 3 - illegal combo comp rc = FoldStringW( MAP_PRECOMPOSED | MAP_COMPOSITE, FoldSrc1, -1, FoldDest, BUFSIZE ); CheckReturnBadParam( rc, 0, ERROR_INVALID_FLAGS, "illegal combo comp", &NumErrors ); // // Same Buffer Check. // // Variation 1 - same buffer FoldDest[0] = 0; rc = FoldStringW( MAP_FOLDDIGITS, FoldDest, -1, FoldDest, BUFSIZE ); CheckReturnBadParam( rc, 0, ERROR_INVALID_PARAMETER, "same buffer", &NumErrors ); // // Return total number of errors found. // return (NumErrors); }