// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved #include "Private.h" #include "resource.h" #include "BaseWindow.h" #include "define.h" #include "SampleIMEBaseStructure.h" namespace Global { HINSTANCE dllInstanceHandle; LONG dllRefCount = -1; CRITICAL_SECTION CS; HFONT defaultlFontHandle; // Global font object we use everywhere //--------------------------------------------------------------------- // SampleIME CLSID //--------------------------------------------------------------------- // {D2291A80-84D8-4641-9AB2-BDD1472C846B} extern const CLSID SampleIMECLSID = { 0xd2291a80, 0x84d8, 0x4641, { 0x9a, 0xb2, 0xbd, 0xd1, 0x47, 0x2c, 0x84, 0x6b } }; //--------------------------------------------------------------------- // Profile GUID //--------------------------------------------------------------------- // {83955C0E-2C09-47a5-BCF3-F2B98E11EE8B} extern const GUID SampleIMEGuidProfile = { 0x83955c0e, 0x2c09, 0x47a5, { 0xbc, 0xf3, 0xf2, 0xb9, 0x8e, 0x11, 0xee, 0x8b } }; //--------------------------------------------------------------------- // PreserveKey GUID //--------------------------------------------------------------------- // {4B62B54B-F828-43B5-9095-A96DF9CBDF38} extern const GUID SampleIMEGuidImeModePreserveKey = { 0x4b62b54b, 0xf828, 0x43b5, { 0x90, 0x95, 0xa9, 0x6d, 0xf9, 0xcb, 0xdf, 0x38 } }; // {5A08D6C4-4563-4E46-8DDB-65E75C4E73A3} extern const GUID SampleIMEGuidDoubleSingleBytePreserveKey = { 0x5a08d6c4, 0x4563, 0x4e46, { 0x8d, 0xdb, 0x65, 0xe7, 0x5c, 0x4e, 0x73, 0xa3 } }; // {175F062E-B961-4AED-A3DF-59F78A02862D} extern const GUID SampleIMEGuidPunctuationPreserveKey = { 0x175f062e, 0xb961, 0x4aed, { 0xa3, 0xdf, 0x59, 0xf7, 0x8a, 0x2, 0x86, 0x2d } }; //--------------------------------------------------------------------- // Compartments //--------------------------------------------------------------------- // {101011C5-CF72-4F0C-A515-153019593F10} extern const GUID SampleIMEGuidCompartmentDoubleSingleByte = { 0x101011c5, 0xcf72, 0x4f0c, { 0xa5, 0x15, 0x15, 0x30, 0x19, 0x59, 0x3f, 0x10 } }; // {DD321BCC-A7F8-4561-9B61-9B3508C9BA97} extern const GUID SampleIMEGuidCompartmentPunctuation = { 0xdd321bcc, 0xa7f8, 0x4561, { 0x9b, 0x61, 0x9b, 0x35, 0x8, 0xc9, 0xba, 0x97 } }; //--------------------------------------------------------------------- // LanguageBars //--------------------------------------------------------------------- // {89BE500C-9462-4070-9DB0-B467BB051327} extern const GUID SampleIMEGuidLangBarIMEMode = { 0x89be500c, 0x9462, 0x4070, { 0x9d, 0xb0, 0xb4, 0x67, 0xbb, 0x5, 0x13, 0x27 } }; // {6A11D9DE-46DB-455B-A257-2EB615746BF4} extern const GUID SampleIMEGuidLangBarDoubleSingleByte = { 0x6a11d9de, 0x46db, 0x455b, { 0xa2, 0x57, 0x2e, 0xb6, 0x15, 0x74, 0x6b, 0xf4 } }; // {F29C731A-A51E-49FB-8A3C-EE51752912E2} extern const GUID SampleIMEGuidLangBarPunctuation = { 0xf29c731a, 0xa51e, 0x49fb, { 0x8a, 0x3c, 0xee, 0x51, 0x75, 0x29, 0x12, 0xe2 } }; // {4C802E2C-8140-4436-A5E5-F7C544EBC9CD} extern const GUID SampleIMEGuidDisplayAttributeInput = { 0x4c802e2c, 0x8140, 0x4436, { 0xa5, 0xe5, 0xf7, 0xc5, 0x44, 0xeb, 0xc9, 0xcd } }; // {9A1CC683-F2A7-4701-9C6E-2DA69A5CD474} extern const GUID SampleIMEGuidDisplayAttributeConverted = { 0x9a1cc683, 0xf2a7, 0x4701, { 0x9c, 0x6e, 0x2d, 0xa6, 0x9a, 0x5c, 0xd4, 0x74 } }; //--------------------------------------------------------------------- // UI element //--------------------------------------------------------------------- // {84B0749F-8DE7-4732-907A-3BCB150A01A8} extern const GUID SampleIMEGuidCandUIElement = { 0x84b0749f, 0x8de7, 0x4732, { 0x90, 0x7a, 0x3b, 0xcb, 0x15, 0xa, 0x1, 0xa8 } }; //--------------------------------------------------------------------- // Unicode byte order mark //--------------------------------------------------------------------- extern const WCHAR UnicodeByteOrderMark = 0xFEFF; //--------------------------------------------------------------------- // dictionary table delimiter //--------------------------------------------------------------------- extern const WCHAR KeywordDelimiter = L'='; extern const WCHAR StringDelimiter = L'\"'; //--------------------------------------------------------------------- // defined item in setting file table [PreservedKey] section //--------------------------------------------------------------------- extern const WCHAR ImeModeDescription[] = L"Chinese/English input (Shift)"; extern const int ImeModeOnIcoIndex = IME_MODE_ON_ICON_INDEX; extern const int ImeModeOffIcoIndex = IME_MODE_OFF_ICON_INDEX; extern const WCHAR DoubleSingleByteDescription[] = L"Double/Single byte (Shift+Space)"; extern const int DoubleSingleByteOnIcoIndex = IME_DOUBLE_ON_INDEX; extern const int DoubleSingleByteOffIcoIndex = IME_DOUBLE_OFF_INDEX; extern const WCHAR PunctuationDescription[] = L"Chinese/English punctuation (Ctrl+.)"; extern const int PunctuationOnIcoIndex = IME_PUNCTUATION_ON_INDEX; extern const int PunctuationOffIcoIndex = IME_PUNCTUATION_OFF_INDEX; //--------------------------------------------------------------------- // defined item in setting file table [LanguageBar] section //--------------------------------------------------------------------- extern const WCHAR LangbarImeModeDescription[] = L"Conversion mode"; extern const WCHAR LangbarDoubleSingleByteDescription[] = L"Character width"; extern const WCHAR LangbarPunctuationDescription[] = L"Punctuation"; //--------------------------------------------------------------------- // windows class / titile / atom //--------------------------------------------------------------------- extern const WCHAR CandidateClassName[] = L"SampleIME.CandidateWindow"; ATOM AtomCandidateWindow; extern const WCHAR ShadowClassName[] = L"SampleIME.ShadowWindow"; ATOM AtomShadowWindow; extern const WCHAR ScrollBarClassName[] = L"SampleIME.ScrollBarWindow"; ATOM AtomScrollBarWindow; BOOL RegisterWindowClass() { if (!CBaseWindow::_InitWindowClass(CandidateClassName, &AtomCandidateWindow)) { return FALSE; } if (!CBaseWindow::_InitWindowClass(ShadowClassName, &AtomShadowWindow)) { return FALSE; } if (!CBaseWindow::_InitWindowClass(ScrollBarClassName, &AtomScrollBarWindow)) { return FALSE; } return TRUE; } //--------------------------------------------------------------------- // defined full width characters for Double/Single byte conversion //--------------------------------------------------------------------- extern const WCHAR FullWidthCharTable[] = { // ! " # $ % & ' ( ) * + , - . / 0x3000, 0xFF01, 0xFF02, 0xFF03, 0xFF04, 0xFF05, 0xFF06, 0xFF07, 0xFF08, 0xFF09, 0xFF0A, 0xFF0B, 0xFF0C, 0xFF0D, 0xFF0E, 0xFF0F, // 0 1 2 3 4 5 6 7 8 9 : ; < = > ? 0xFF10, 0xFF11, 0xFF12, 0xFF13, 0xFF14, 0xFF15, 0xFF16, 0xFF17, 0xFF18, 0xFF19, 0xFF1A, 0xFF1B, 0xFF1C, 0xFF1D, 0xFF1E, 0xFF1F, // @ A B C D E F G H I J K L M N 0 0xFF20, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, // P Q R S T U V W X Y Z [ \ ] ^ _ 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0xFF3B, 0xFF3C, 0xFF3D, 0xFF3E, 0xFF3F, // ' a b c d e f g h i j k l m n o 0xFF40, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, // p q r s t u v w x y z { | } ~ 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0xFF5B, 0xFF5C, 0xFF5D, 0xFF5E }; //--------------------------------------------------------------------- // defined punctuation characters //--------------------------------------------------------------------- extern const struct _PUNCTUATION PunctuationTable[14] = { {L'!', 0xFF01}, {L'$', 0xFFE5}, {L'&', 0x2014}, {L'(', 0xFF08}, {L')', 0xFF09}, {L',', 0xFF0C}, {L'.', 0x3002}, {L':', 0xFF1A}, {L';', 0xFF1B}, {L'?', 0xFF1F}, {L'@', 0x00B7}, {L'\\', 0x3001}, {L'^', 0x2026}, {L'_', 0x2014} }; //+--------------------------------------------------------------------------- // // CheckModifiers // //---------------------------------------------------------------------------- #define TF_MOD_ALLALT (TF_MOD_RALT | TF_MOD_LALT | TF_MOD_ALT) #define TF_MOD_ALLCONTROL (TF_MOD_RCONTROL | TF_MOD_LCONTROL | TF_MOD_CONTROL) #define TF_MOD_ALLSHIFT (TF_MOD_RSHIFT | TF_MOD_LSHIFT | TF_MOD_SHIFT) #define TF_MOD_RLALT (TF_MOD_RALT | TF_MOD_LALT) #define TF_MOD_RLCONTROL (TF_MOD_RCONTROL | TF_MOD_LCONTROL) #define TF_MOD_RLSHIFT (TF_MOD_RSHIFT | TF_MOD_LSHIFT) #define CheckMod(m0, m1, mod) \ if (m1 & TF_MOD_ ## mod ##) \ { \ if (!(m0 & TF_MOD_ ## mod ##)) \ { \ return FALSE; \ } \ } \ else \ { \ if ((m1 ^ m0) & TF_MOD_RL ## mod ##) \ { \ return FALSE; \ } \ } \ BOOL CheckModifiers(UINT modCurrent, UINT mod) { mod &= ~TF_MOD_ON_KEYUP; if (mod & TF_MOD_IGNORE_ALL_MODIFIER) { return TRUE; } if (modCurrent == mod) { return TRUE; } if (modCurrent && !mod) { return FALSE; } CheckMod(modCurrent, mod, ALT); CheckMod(modCurrent, mod, SHIFT); CheckMod(modCurrent, mod, CONTROL); return TRUE; } //+--------------------------------------------------------------------------- // // UpdateModifiers // // wParam - virtual-key code // lParam - [0-15] Repeat count // [16-23] Scan code // [24] Extended key // [25-28] Reserved // [29] Context code // [30] Previous key state // [31] Transition state //---------------------------------------------------------------------------- USHORT ModifiersValue = 0; BOOL IsShiftKeyDownOnly = FALSE; BOOL IsControlKeyDownOnly = FALSE; BOOL IsAltKeyDownOnly = FALSE; BOOL UpdateModifiers(WPARAM wParam, LPARAM lParam) { // high-order bit : key down // low-order bit : toggled SHORT sksMenu = GetKeyState(VK_MENU); SHORT sksCtrl = GetKeyState(VK_CONTROL); SHORT sksShft = GetKeyState(VK_SHIFT); switch (wParam & 0xff) { case VK_MENU: // is VK_MENU down? if (sksMenu & 0x8000) { // is extended key? if (lParam & 0x01000000) { ModifiersValue |= (TF_MOD_RALT | TF_MOD_ALT); } else { ModifiersValue |= (TF_MOD_LALT | TF_MOD_ALT); } // is previous key state up? if (!(lParam & 0x40000000)) { // is VK_CONTROL and VK_SHIFT up? if (!(sksCtrl & 0x8000) && !(sksShft & 0x8000)) { IsAltKeyDownOnly = TRUE; } else { IsShiftKeyDownOnly = FALSE; IsControlKeyDownOnly = FALSE; IsAltKeyDownOnly = FALSE; } } } break; case VK_CONTROL: // is VK_CONTROL down? if (sksCtrl & 0x8000) { // is extended key? if (lParam & 0x01000000) { ModifiersValue |= (TF_MOD_RCONTROL | TF_MOD_CONTROL); } else { ModifiersValue |= (TF_MOD_LCONTROL | TF_MOD_CONTROL); } // is previous key state up? if (!(lParam & 0x40000000)) { // is VK_SHIFT and VK_MENU up? if (!(sksShft & 0x8000) && !(sksMenu & 0x8000)) { IsControlKeyDownOnly = TRUE; } else { IsShiftKeyDownOnly = FALSE; IsControlKeyDownOnly = FALSE; IsAltKeyDownOnly = FALSE; } } } break; case VK_SHIFT: // is VK_SHIFT down? if (sksShft & 0x8000) { // is scan code 0x36(right shift)? if (((lParam >> 16) & 0x00ff) == 0x36) { ModifiersValue |= (TF_MOD_RSHIFT | TF_MOD_SHIFT); } else { ModifiersValue |= (TF_MOD_LSHIFT | TF_MOD_SHIFT); } // is previous key state up? if (!(lParam & 0x40000000)) { // is VK_MENU and VK_CONTROL up? if (!(sksMenu & 0x8000) && !(sksCtrl & 0x8000)) { IsShiftKeyDownOnly = TRUE; } else { IsShiftKeyDownOnly = FALSE; IsControlKeyDownOnly = FALSE; IsAltKeyDownOnly = FALSE; } } } break; default: IsShiftKeyDownOnly = FALSE; IsControlKeyDownOnly = FALSE; IsAltKeyDownOnly = FALSE; break; } if (!(sksMenu & 0x8000)) { ModifiersValue &= ~TF_MOD_ALLALT; } if (!(sksCtrl & 0x8000)) { ModifiersValue &= ~TF_MOD_ALLCONTROL; } if (!(sksShft & 0x8000)) { ModifiersValue &= ~TF_MOD_ALLSHIFT; } return TRUE; } //--------------------------------------------------------------------- // override CompareElements //--------------------------------------------------------------------- BOOL CompareElements(LCID locale, const CStringRange* pElement1, const CStringRange* pElement2) { return (CStringRange::Compare(locale, (CStringRange*)pElement1, (CStringRange*)pElement2) == CSTR_EQUAL) ? TRUE : FALSE; } }