From e25d7d724deec7f54691b7715ffd487b8635eb4f Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Sun, 10 Mar 2024 11:35:05 +0900 Subject: [PATCH] [MSCTF][SDK] Implement multi-language handling (#6587) Implementing the back-end of the Language bar... JIRA issue: CORE-19361 - Add mlng.cpp and mlng.h. - Modify msctf.spec. - Implement MLNGINFO structure and CStaticIconList class. - Implement TF_InitMlngInfo, TF_MlngInfoCount, TF_InatExtractIcon, TF_GetMlngIconIndex, and TF_GetMlngHKL functions. --- dll/win32/msctf/CMakeLists.txt | 3 +- dll/win32/msctf/mlng.cpp | 604 +++++++++++++++++++++++++++++++++ dll/win32/msctf/mlng.h | 59 ++++ dll/win32/msctf/msctf.c | 2 + dll/win32/msctf/msctf.spec | 8 +- dll/win32/msctf/utils.cpp | 6 + sdk/include/psdk/msctf.idl | 4 +- 7 files changed, 679 insertions(+), 7 deletions(-) create mode 100644 dll/win32/msctf/mlng.cpp create mode 100644 dll/win32/msctf/mlng.h diff --git a/dll/win32/msctf/CMakeLists.txt b/dll/win32/msctf/CMakeLists.txt index a167162dc58..b269a96fb9b 100644 --- a/dll/win32/msctf/CMakeLists.txt +++ b/dll/win32/msctf/CMakeLists.txt @@ -21,6 +21,7 @@ list(APPEND SOURCE ${CMAKE_CURRENT_BINARY_DIR}/msctf_stubs.c) list(APPEND PCH_SKIP_SOURCE + mlng.cpp utils.cpp) add_library(msctf MODULE @@ -32,6 +33,6 @@ add_library(msctf MODULE set_module_type(msctf win32dll UNICODE) target_link_libraries(msctf uuid wine cicero) add_importlibs(msctf user32 advapi32 advapi32_vista msvcrt kernel32 ntdll) -add_delay_importlibs(msctf ole32 oleaut32) +add_delay_importlibs(msctf shell32 ole32 oleaut32 imm32 gdi32) add_pch(msctf precomp.h SOURCE) add_cd_file(TARGET msctf DESTINATION reactos/system32 FOR all) diff --git a/dll/win32/msctf/mlng.cpp b/dll/win32/msctf/mlng.cpp new file mode 100644 index 00000000000..64f0827c474 --- /dev/null +++ b/dll/win32/msctf/mlng.cpp @@ -0,0 +1,604 @@ +/* + * PROJECT: ReactOS msctf.dll + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Multi-language handling of Cicero + * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ + */ + +#define WIN32_NO_STATUS + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "mlng.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msctf); + +extern CRITICAL_SECTION g_cs; + +CicArray *g_pMlngInfo = NULL; +INT CStaticIconList::s_cx = 0; +INT CStaticIconList::s_cy = 0; +CStaticIconList g_IconList; + +/*********************************************************************** + * The helper funtions + */ + +/// @unimplemented +static VOID +GetLocaleInfoString(_In_ HKL hKL, _Out_ LPWSTR pszDesc, _In_ UINT cchDesc) +{ + if (!::GetLocaleInfoW(LOWORD(hKL), LOCALE_SLANGUAGE, pszDesc, cchDesc)) + *pszDesc = UNICODE_NULL; +#if 0 + if (HIWORD(hKL) != LOWORD(hKL)) + GetKbdLayoutName(hKL, pszDesc, cchDesc); +#endif +} + +/// @unimplemented +HKL GetHKLSubstitute(_In_ HKL hKL) +{ + return hKL; +} + +/// @implemented +static VOID +GetHKLDesctription( + _In_ HKL hKL, + _Out_ LPWSTR pszDesc, + _In_ UINT cchDesc, + _Out_ LPWSTR pszImeFileName, + _In_ UINT cchImeFileName) +{ + pszDesc[0] = pszImeFileName[0] = UNICODE_NULL; + + if (!IS_IME_HKL(hKL)) + { + GetLocaleInfoString(hKL, pszDesc, cchDesc); + return; + } + + hKL = GetHKLSubstitute(hKL); + + WCHAR szSubKey[MAX_PATH]; + StringCchPrintfW(szSubKey, _countof(szSubKey), + L"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\%08lX", + HandleToUlong(hKL)); + + HKEY hKey; + LSTATUS error = ::RegOpenKeyExW(HKEY_LOCAL_MACHINE, szSubKey, 0, KEY_READ, &hKey); + if (error == ERROR_SUCCESS) + { + DWORD cbDesc = cchDesc * sizeof(WCHAR); + error = ::RegQueryValueExW(hKey, L"Layout Display Name", NULL, NULL, + (LPBYTE)pszDesc, &cbDesc); + pszDesc[cbDesc / sizeof(WCHAR) - 1] = UNICODE_NULL; // Avoid buffer overrun + ::RegCloseKey(hKey); + } + + if (pszDesc[0] == UNICODE_NULL && !::ImmGetDescriptionW(hKL, pszDesc, cchDesc)) + { + *pszDesc = UNICODE_NULL; + GetLocaleInfoString(hKL, pszDesc, cchDesc); + } + else if (!::ImmGetIMEFileNameW(hKL, pszImeFileName, cchImeFileName)) + { + *pszImeFileName = UNICODE_NULL; + } +} + +/// @implemented +HICON GetIconFromFile(_In_ INT cx, _In_ INT cy, _In_ LPCWSTR pszFileName, _In_ INT iIcon) +{ + HICON hIcon; + + if (cx <= GetSystemMetrics(SM_CXSMICON)) + ::ExtractIconExW(pszFileName, iIcon, NULL, &hIcon, 1); + else + ::ExtractIconExW(pszFileName, iIcon, &hIcon, NULL, 1); + + return hIcon; +} + +/// @implemented +static BOOL EnsureIconImageList(VOID) +{ + if (!CStaticIconList::s_cx) + g_IconList.Init(::GetSystemMetrics(SM_CYSMICON), ::GetSystemMetrics(SM_CXSMICON)); + + return TRUE; +} + +/// @implemented +static INT GetPhysicalFontHeight(LOGFONTW *plf) +{ + HDC hDC = ::GetDC(NULL); + HFONT hFont = ::CreateFontIndirectW(plf); + HGDIOBJ hFontOld = ::SelectObject(hDC, hFont); + TEXTMETRICW tm; + ::GetTextMetricsW(hDC, &tm); + INT ret = tm.tmExternalLeading + tm.tmHeight; + ::SelectObject(hDC, hFontOld); + ::DeleteObject(hFont); + ::ReleaseDC(NULL, hDC); + return ret; +} + +/*********************************************************************** + * Inat helper functions + */ + +/// @implemented +INT InatAddIcon(_In_ HICON hIcon) +{ + if (!EnsureIconImageList()) + return -1; + return g_IconList.AddIcon(hIcon); +} + +/// @implemented +HICON +InatCreateIconBySize( + _In_ LANGID LangID, + _In_ INT nWidth, + _In_ INT nHeight, + _In_ const LOGFONTW *plf) +{ + WCHAR szText[64]; + BOOL ret = ::GetLocaleInfoW(LangID, LOCALE_NOUSEROVERRIDE | LOCALE_SABBREVLANGNAME, + szText, _countof(szText)); + if (!ret) + szText[0] = szText[1] = L'?'; + + szText[2] = UNICODE_NULL; + CharUpperW(szText); + + HFONT hFont = ::CreateFontIndirectW(plf); + if (!hFont) + return NULL; + + HDC hDC = ::GetDC(NULL); + HDC hMemDC = ::CreateCompatibleDC(hDC); + HBITMAP hbmColor = ::CreateCompatibleBitmap(hDC, nWidth, nHeight); + HBITMAP hbmMask = ::CreateBitmap(nWidth, nHeight, 1, 1, NULL); + ::ReleaseDC(NULL, hDC); + + HICON hIcon = NULL; + HGDIOBJ hbmOld = ::SelectObject(hMemDC, hbmColor); + HGDIOBJ hFontOld = ::SelectObject(hMemDC, hFont); + if (hMemDC && hbmColor && hbmMask) + { + ::SetBkColor(hMemDC, ::GetSysColor(COLOR_HIGHLIGHT)); + ::SetTextColor(hMemDC, ::GetSysColor(COLOR_HIGHLIGHTTEXT)); + + RECT rc = { 0, 0, nWidth, nHeight }; + ::ExtTextOutW(hMemDC, 0, 0, ETO_OPAQUE, &rc, L"", 0, NULL); + + ::DrawTextW(hMemDC, szText, 2, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER); + ::SelectObject(hMemDC, hbmMask); + + ::PatBlt(hMemDC, 0, 0, nWidth, nHeight, BLACKNESS); + + ICONINFO IconInfo = { TRUE, 0, 0, hbmMask, hbmColor }; + hIcon = ::CreateIconIndirect(&IconInfo); + } + ::SelectObject(hMemDC, hFontOld); + ::SelectObject(hMemDC, hbmOld); + + ::DeleteObject(hbmMask); + ::DeleteObject(hbmColor); + ::DeleteDC(hMemDC); + ::DeleteObject(hFont); + return hIcon; +} + +/// @implemented +HICON InatCreateIcon(_In_ LANGID LangID) +{ + INT cxSmIcon = ::GetSystemMetrics(SM_CXSMICON), cySmIcon = ::GetSystemMetrics(SM_CYSMICON); + + LOGFONTW lf; + if (!SystemParametersInfoW(SPI_GETICONTITLELOGFONT, sizeof(LOGFONTW), &lf, 0)) + return NULL; + + if (cySmIcon < GetPhysicalFontHeight(&lf)) + { + lf.lfWidth = 0; + lf.lfHeight = - (7 * cySmIcon) / 10; + } + + return InatCreateIconBySize(LangID, cxSmIcon, cySmIcon, &lf); +} + +/// @implemented +BOOL InatGetIconSize(_Out_ INT *pcx, _Out_ INT *pcy) +{ + g_IconList.GetIconSize(pcx, pcy); + return TRUE; +} + +/// @implemented +INT InatGetImageCount(VOID) +{ + return g_IconList.GetImageCount(); +} + +/// @implemented +VOID InatRemoveAll(VOID) +{ + if (CStaticIconList::s_cx) + g_IconList.RemoveAll(FALSE); +} + +/// @implemented +VOID UninitINAT(VOID) +{ + g_IconList.RemoveAll(TRUE); + + if (g_pMlngInfo) + { + delete g_pMlngInfo; + g_pMlngInfo = NULL; + } +} + +/*********************************************************************** + * MLNGINFO + */ + +/// @implemented +void MLNGINFO::InitDesc() +{ + if (m_bInitDesc) + return; + + WCHAR szDesc[MAX_PATH], szFileName[MAX_PATH]; + GetHKLDesctription(m_hKL, szDesc, (UINT)_countof(szDesc), + szFileName, (UINT)_countof(szFileName)); + SetDesc(szDesc); + m_bInitDesc = TRUE; + + ::EnterCriticalSection(&g_cs); + + for (size_t iKL = 0; iKL < g_pMlngInfo->size(); ++iKL) + { + auto& info = (*g_pMlngInfo)[iKL]; + if (info.m_hKL == m_hKL) + { + info.m_bInitDesc = TRUE; + break; + } + } + + ::LeaveCriticalSection(&g_cs); +} + +/// @implemented +void MLNGINFO::InitIcon() +{ + if (m_bInitIcon) + return; + + WCHAR szDesc[MAX_PATH], szFileName[MAX_PATH]; + GetHKLDesctription(m_hKL, szDesc, _countof(szDesc), szFileName, _countof(szFileName)); + SetDesc(szDesc); + m_bInitDesc = TRUE; + + INT cxIcon, cyIcon; + InatGetIconSize(&cxIcon, &cyIcon); + if (szFileName[0]) + { + HICON hIcon = GetIconFromFile(cxIcon, cyIcon, szFileName, 0); + if (!hIcon) + hIcon = InatCreateIcon(LOWORD(m_hKL)); + if (hIcon) + { + m_iIconIndex = InatAddIcon(hIcon); + ::DestroyIcon(hIcon); + } + } + + ::EnterCriticalSection(&g_cs); + + for (size_t iItem = 0; iItem < g_pMlngInfo->size(); ++iItem) + { + auto& item = (*g_pMlngInfo)[iItem]; + if (item.m_hKL == m_hKL) + { + item.m_bInitDesc = TRUE; + item.m_bInitIcon = TRUE; + item.m_iIconIndex = m_iIconIndex; + item.SetDesc(szDesc); + break; + } + } + + ::LeaveCriticalSection(&g_cs); +} + +/// @implemented +LPCWSTR MLNGINFO::GetDesc() +{ + if (!m_bInitDesc) + InitDesc(); + return m_szDesc; +} + +/// @implemented +void MLNGINFO::SetDesc(LPCWSTR pszDesc) +{ + StringCchCopyW(m_szDesc, _countof(m_szDesc), pszDesc); +} + +/// @implemented +INT MLNGINFO::GetIconIndex() +{ + if (!m_bInitIcon) + InitIcon(); + + return m_iIconIndex; +} + +/*********************************************************************** + * CStaticIconList + */ + +/// @implemented +void CStaticIconList::Init(INT cxIcon, INT cyIcon) +{ + ::EnterCriticalSection(&g_cs); + s_cx = cxIcon; + s_cy = cyIcon; + ::LeaveCriticalSection(&g_cs); +} + +/// @implemented +INT CStaticIconList::AddIcon(HICON hIcon) +{ + ::EnterCriticalSection(&g_cs); + + INT iItem = -1; + HICON hCopyIcon = ::CopyIcon(hIcon); + if (hCopyIcon) + { + if (g_IconList.Add(hIcon)) + iItem = INT(g_IconList.size() - 1); + } + + ::LeaveCriticalSection(&g_cs); + return iItem; +} + +/// @implemented +HICON CStaticIconList::ExtractIcon(INT iIcon) +{ + HICON hCopyIcon = NULL; + ::EnterCriticalSection(&g_cs); + if (iIcon <= (INT)g_IconList.size()) + hCopyIcon = ::CopyIcon(g_IconList[iIcon]); + ::LeaveCriticalSection(&g_cs); + return hCopyIcon; +} + +/// @implemented +void CStaticIconList::GetIconSize(INT *pcx, INT *pcy) +{ + ::EnterCriticalSection(&g_cs); + *pcx = s_cx; + *pcy = s_cy; + ::LeaveCriticalSection(&g_cs); +} + +/// @implemented +INT CStaticIconList::GetImageCount() +{ + ::EnterCriticalSection(&g_cs); + INT cItems = (INT)g_IconList.size(); + ::LeaveCriticalSection(&g_cs); + return cItems; +} + +/// @implemented +void CStaticIconList::RemoveAll(BOOL bNoLock) +{ + if (!bNoLock) + ::EnterCriticalSection(&g_cs); + + for (size_t iItem = 0; iItem < g_IconList.size(); ++iItem) + { + ::DestroyIcon(g_IconList[iItem]); + } + + clear(); + + if (!bNoLock) + ::LeaveCriticalSection(&g_cs); +} + +/// @implemented +static BOOL CheckMlngInfo(VOID) +{ + if (!g_pMlngInfo) + return TRUE; // Needs creation + + INT cKLs = ::GetKeyboardLayoutList(0, NULL); + if (cKLs != TF_MlngInfoCount()) + return TRUE; // Needs refresh + + if (!cKLs) + return FALSE; + + HKL *phKLs = (HKL*)cicMemAlloc(cKLs * sizeof(HKL)); + if (!phKLs) + return FALSE; + + ::GetKeyboardLayoutList(cKLs, phKLs); + + BOOL ret = FALSE; + for (INT iKL = 0; iKL < cKLs; ++iKL) + { + if ((*g_pMlngInfo)[iKL].m_hKL != phKLs[iKL]) + { + ret = TRUE; // Needs refresh + break; + } + } + + cicMemFree(phKLs); + return ret; +} + +/// @implemented +static VOID DestroyMlngInfo(VOID) +{ + if (!g_pMlngInfo) + return; + + delete g_pMlngInfo; + g_pMlngInfo = NULL; +} + +/// @implemented +static VOID CreateMlngInfo(VOID) +{ + if (!g_pMlngInfo) + { + g_pMlngInfo = new(cicNoThrow) CicArray(); + if (!g_pMlngInfo) + return; + } + + if (!EnsureIconImageList()) + return; + + INT cKLs = ::GetKeyboardLayoutList(0, NULL); + HKL *phKLs = (HKL*)cicMemAllocClear(cKLs * sizeof(HKL)); + if (!phKLs) + return; + + ::GetKeyboardLayoutList(cKLs, phKLs); + + for (INT iKL = 0; iKL < cKLs; ++iKL) + { + MLNGINFO& info = (*g_pMlngInfo)[iKL]; + info.m_hKL = phKLs[iKL]; + info.m_bInitDesc = FALSE; + info.m_bInitIcon = FALSE; + } + + cicMemFree(phKLs); +} + +/*********************************************************************** + * TF_InitMlngInfo (MSCTF.@) + * + * @implemented + */ +EXTERN_C VOID WINAPI TF_InitMlngInfo(VOID) +{ + TRACE("()\n"); + + ::EnterCriticalSection(&g_cs); + + if (CheckMlngInfo()) + { + DestroyMlngInfo(); + CreateMlngInfo(); + } + + ::LeaveCriticalSection(&g_cs); +} + +/*********************************************************************** + * TF_MlngInfoCount (MSCTF.@) + * + * @implemented + */ +EXTERN_C INT WINAPI TF_MlngInfoCount(VOID) +{ + TRACE("()\n"); + + if (!g_pMlngInfo) + return 0; + + return (INT)g_pMlngInfo->size(); +} + +/*********************************************************************** + * TF_InatExtractIcon (MSCTF.@) + * + * @implemented + */ +EXTERN_C HICON WINAPI TF_InatExtractIcon(_In_ INT iKL) +{ + TRACE("(%d)\n", iKL); + return g_IconList.ExtractIcon(iKL); +} + +/*********************************************************************** + * TF_GetMlngIconIndex (MSCTF.@) + * + * @implemented + */ +EXTERN_C INT WINAPI TF_GetMlngIconIndex(_In_ INT iKL) +{ + TRACE("(%d)\n", iKL); + + INT iIcon = -1; + + ::EnterCriticalSection(&g_cs); + + if (iKL < (INT)g_pMlngInfo->size()) + iIcon = (*g_pMlngInfo)[iKL].GetIconIndex(); + + ::LeaveCriticalSection(&g_cs); + + return iIcon; +} + +/*********************************************************************** + * TF_GetMlngHKL (MSCTF.@) + * + * @implemented + */ +EXTERN_C BOOL WINAPI +TF_GetMlngHKL( + _In_ INT iKL, + _Out_opt_ HKL *phKL, + _Out_opt_ LPWSTR pszDesc, + _In_ INT cchDesc) +{ + TRACE("(%d, %p, %p, %d)\n", iKL, phKL, pszDesc, cchDesc); + + BOOL ret = FALSE; + + ::EnterCriticalSection(&g_cs); + + if (iKL < (INT)g_pMlngInfo->size()) + { + MLNGINFO& info = (*g_pMlngInfo)[iKL]; + + if (phKL) + *phKL = info.m_hKL; + + if (pszDesc) + StringCchCopyW(pszDesc, cchDesc, info.GetDesc()); + + ret = TRUE; + } + + ::LeaveCriticalSection(&g_cs); + + return ret; +} diff --git a/dll/win32/msctf/mlng.h b/dll/win32/msctf/mlng.h new file mode 100644 index 00000000000..356499b0b71 --- /dev/null +++ b/dll/win32/msctf/mlng.h @@ -0,0 +1,59 @@ +/* + * PROJECT: ReactOS msctf.dll + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Multi-language handling of Cicero + * COPYRIGHT: Copyright 2024 Katayama Hirofumi MZ + */ + +#pragma once + +struct MLNGINFO +{ + HKL m_hKL; + BOOL m_bInitDesc; + BOOL m_bInitIcon; + INT m_iIconIndex; + WCHAR m_szDesc[128]; + + void InitDesc(); + void InitIcon(); + + INT GetIconIndex(); + LPCWSTR GetDesc(); + void SetDesc(LPCWSTR pszDesc); +}; + +class CStaticIconList : public CicArray +{ +public: + static INT s_cx; + static INT s_cy; + + CStaticIconList() { } + + void Init(INT cxIcon, INT cyIcon); + INT AddIcon(HICON hIcon); + HICON ExtractIcon(INT iIcon); + void GetIconSize(INT *pcx, INT *pcy); + INT GetImageCount(); + void RemoveAll(BOOL bNoLock); +}; + +INT InatAddIcon(_In_ HICON hIcon); +HICON InatCreateIcon(_In_ LANGID LangID); + +HICON +InatCreateIconBySize( + _In_ LANGID LangID, + _In_ INT nWidth, + _In_ INT nHeight, + _In_ const LOGFONTW *plf); + +BOOL InatGetIconSize(_Out_ INT *pcx, _Out_ INT *pcy); +INT InatGetImageCount(VOID); +VOID InatRemoveAll(VOID); + +HKL GetHKLSubstitute(_In_ HKL hKL); +HICON GetIconFromFile(_In_ INT cx, _In_ INT cy, _In_ LPCWSTR pszFileName, _In_ INT iIcon); + +VOID UninitINAT(VOID); diff --git a/dll/win32/msctf/msctf.c b/dll/win32/msctf/msctf.c index c6e3a2ca597..a20d0fd55b6 100644 --- a/dll/win32/msctf/msctf.c +++ b/dll/win32/msctf/msctf.c @@ -697,6 +697,7 @@ HRESULT WINAPI TF_CreateLangBarItemMgr(ITfLangBarItemMgr **pplbim) return E_NOTIMPL; } +#ifndef __REACTOS__ /* See mlng.cpp */ /*********************************************************************** * TF_InitMlngInfo (MSCTF.@) */ @@ -705,3 +706,4 @@ HRESULT WINAPI TF_InitMlngInfo(void) FIXME("stub\n"); return S_OK; } +#endif diff --git a/dll/win32/msctf/msctf.spec b/dll/win32/msctf/msctf.spec index a2cb7984b72..6b036567346 100644 --- a/dll/win32/msctf/msctf.spec +++ b/dll/win32/msctf/msctf.spec @@ -19,11 +19,11 @@ @ stdcall -stub TF_GetGlobalCompartment(ptr) @ stub TF_GetInputScope @ stdcall -stub TF_GetLangIcon(long ptr long) -@ stdcall -stub TF_GetMlngHKL(long ptr ptr long) -@ stdcall -stub TF_GetMlngIconIndex(long) +@ stdcall TF_GetMlngHKL(long ptr ptr long) +@ stdcall TF_GetMlngIconIndex(long) @ stdcall -stub TF_GetThreadFlags(long ptr ptr ptr) @ stdcall TF_GetThreadMgr(ptr) -@ stdcall -stub TF_InatExtractIcon(long) +@ stdcall TF_InatExtractIcon(long) @ stdcall TF_InitMlngInfo() @ stdcall -stub TF_InitSystem() @ stdcall -stub TF_UninitSystem() @@ -31,7 +31,7 @@ @ stdcall TF_InvalidAssemblyListCacheIfExist() @ stdcall TF_IsCtfmonRunning() @ stdcall -stub TF_IsInMarshaling(long) -@ stdcall -stub TF_MlngInfoCount() +@ stdcall TF_MlngInfoCount() @ stdcall TF_RunInputCPL() @ stdcall -stub TF_PostAllThreadMsg(long long) @ stdcall TF_RegisterLangBarAddIn(ptr wstr long) diff --git a/dll/win32/msctf/utils.cpp b/dll/win32/msctf/utils.cpp index ec469ceef28..394c21b316e 100644 --- a/dll/win32/msctf/utils.cpp +++ b/dll/win32/msctf/utils.cpp @@ -23,10 +23,13 @@ #include #include +#include #include #include #include +#include "mlng.h" + #include WINE_DEFAULT_DEBUG_CHANNEL(msctf); @@ -617,6 +620,9 @@ VOID ProcessDetach(HINSTANCE hinstDLL) // FIXME: Call me from DllMain TFUninitLib(); //FIXME } + + UninitINAT(); + //FIXME //TF_UninitThreadSystem(); diff --git a/sdk/include/psdk/msctf.idl b/sdk/include/psdk/msctf.idl index 0cd5ac1af9c..787c3d88d1c 100644 --- a/sdk/include/psdk/msctf.idl +++ b/sdk/include/psdk/msctf.idl @@ -62,9 +62,9 @@ cpp_quote("EXTERN_C HRESULT WINAPI TF_DllDetachInOther(VOID);") cpp_quote("EXTERN_C HRESULT WINAPI TF_CreateCategoryMgr(_Out_ ITfCategoryMgr **ppcat);") cpp_quote("EXTERN_C HRESULT WINAPI TF_CreateDisplayAttributeMgr(_Out_ ITfDisplayAttributeMgr **ppdam);") cpp_quote("EXTERN_C HICON WINAPI TF_GetLangIcon(_In_ LANGID LangID, _Out_ LPWSTR pszText, _In_ INT cchText);") -cpp_quote("EXTERN_C HRESULT WINAPI TF_InitMlngInfo(VOID);") +cpp_quote("EXTERN_C VOID WINAPI TF_InitMlngInfo(VOID);") cpp_quote("EXTERN_C INT WINAPI TF_MlngInfoCount(VOID);") -cpp_quote("EXTERN_C BOOL WINAPI TF_GetMlngHKL(_In_ INT iKL, _Out_ HKL *phKL, _Out_ LPWSTR pszText, _In_ INT cchText);") +cpp_quote("EXTERN_C BOOL WINAPI TF_GetMlngHKL(_In_ INT iKL, _Out_opt_ HKL *phKL, _Out_opt_ LPWSTR pszText, _In_ INT cchText);") cpp_quote("EXTERN_C INT WINAPI TF_GetMlngIconIndex(_In_ INT iKL);") cpp_quote("EXTERN_C HICON WINAPI TF_InatExtractIcon(_In_ INT iKL);") cpp_quote("EXTERN_C HRESULT WINAPI TF_RunInputCPL(VOID);")