2025-11-28 00:35:46 +09:00

460 lines
14 KiB
C++

// 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;
}
}