https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5e4fe2cf4036499038ebd…
commit 5e4fe2cf4036499038ebdb0f33bbf64536545323
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Wed Jan 31 16:52:02 2024 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Wed Jan 31 16:52:02 2024 +0900
[MSCTF][MSUTB][SDK] Add CTrayIconWnd and CMainIconItem (#6424)
Supporting Language Bar...
JIRA issue: CORE-19363
- Add CTrayIconWnd, CMainIconItem,
and CButtonIconItem classes.
- Modify msctf.spec for TF_GetLangIcon
function.
- Add main icon IDI_MAINICON
("res/earth.ico").
---
dll/win32/msctf/msctf.spec | 2 +-
dll/win32/msutb/lang/en-US.rc | 2 +
dll/win32/msutb/msutb.cpp | 459 ++++++++++++++++++++++++++++++++++--
dll/win32/msutb/msutb.rc | 2 +
dll/win32/msutb/precomp.h | 1 +
dll/win32/msutb/res/earth.ico | Bin 0 -> 22382 bytes
dll/win32/msutb/resource.h | 4 +
sdk/include/psdk/msctf.idl | 1 +
sdk/include/reactos/cicero/cicutb.h | 4 +
9 files changed, 455 insertions(+), 20 deletions(-)
diff --git a/dll/win32/msctf/msctf.spec b/dll/win32/msctf/msctf.spec
index 569f8701e8b..52288129e1c 100644
--- a/dll/win32/msctf/msctf.spec
+++ b/dll/win32/msctf/msctf.spec
@@ -18,7 +18,7 @@
@ stdcall -stub TF_DllDetachInOther()
@ stdcall -stub TF_GetGlobalCompartment(ptr)
@ stub TF_GetInputScope
-@ stub TF_GetLangIcon
+@ stdcall -stub TF_GetLangIcon(long ptr long)
@ stub TF_GetMlngHKL
@ stub TF_GetMlngIconIndex
@ stub TF_GetThreadFlags
diff --git a/dll/win32/msutb/lang/en-US.rc b/dll/win32/msutb/lang/en-US.rc
index 98a9ea10f96..3c3a7a579dd 100644
--- a/dll/win32/msutb/lang/en-US.rc
+++ b/dll/win32/msutb/lang/en-US.rc
@@ -16,6 +16,8 @@ BEGIN
IDS_IGNORE "&Ignore"
IDS_YES "&Yes"
IDS_NO "&No"
+
+ IDS_RESTORELANGBAR "Restore Language Bar"
IDS_MENUWND "Menu Window"
IDS_LEFTCLICK "Left Click"
END
diff --git a/dll/win32/msutb/msutb.cpp b/dll/win32/msutb/msutb.cpp
index 9a4a96e8553..26816ecb962 100644
--- a/dll/win32/msutb/msutb.cpp
+++ b/dll/win32/msutb/msutb.cpp
@@ -16,6 +16,10 @@ DWORD g_dwOSInfo = 0;
CRITICAL_SECTION g_cs;
LONG g_DllRefCount = 0;
+UINT g_uTimerElapseDOACCDEFAULTACTION = 200;
+
+#define TIMER_ID_DOACCDEFAULTACTION 11
+
EXTERN_C void __cxa_pure_virtual(void)
{
ERR("__cxa_pure_virtual\n");
@@ -34,6 +38,12 @@ CMsUtbModule gModule;
class CCicLibMenuItem;
class CTipbarAccItem;
class CUTBMenuItem;
+class CMainIconItem;
+class CTrayIconItem;
+class CTipbarWnd;
+class CButtonIconItem;
+
+CTipbarWnd *g_pTipbarWnd = NULL;
HRESULT GetGlobalCompartment(REFGUID rguid, ITfCompartment **ppComp)
{
@@ -98,9 +108,8 @@ void DoCloseLangbar(void)
if (pLangBarMgr)
{
- hr = pLangBarMgr->ShowFloating(8);
+ hr = pLangBarMgr->ShowFloating(TF_SFT_HIDDEN);
pLangBarMgr->Release();
- pLangBarMgr = NULL;
}
if (SUCCEEDED(hr))
@@ -453,9 +462,50 @@ public:
class CTrayIconWnd
{
+protected:
+ DWORD m_dwUnknown20;
+ BOOL m_bBusy;
+ UINT m_uCallbackMessage;
+ UINT m_uMsg;
+ HWND m_hWnd;
+ DWORD m_dwUnknown21[2];
+ HWND m_hTrayWnd;
+ HWND m_hNotifyWnd;
+ DWORD m_dwTrayWndThreadId;
+ DWORD m_dwUnknown22;
+ HWND m_hwndProgman;
+ DWORD m_dwProgmanThreadId;
+ CMainIconItem *m_pMainIconItem;
+ CicArray<CButtonIconItem*> m_Items;
+ UINT m_uCallbackMsg;
+ UINT m_uNotifyIconID;
+
+ static BOOL CALLBACK EnumChildWndProc(HWND hWnd, LPARAM lParam);
+ static LRESULT CALLBACK _WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
lParam);
+
public:
- //FIXME
- HWND GetNotifyWnd() { return NULL; };
+ CTrayIconWnd();
+ ~CTrayIconWnd();
+
+ BOOL RegisterClass();
+ HWND CreateWnd();
+ void DestroyWnd();
+
+ BOOL SetMainIcon(HKL hKL);
+ BOOL SetIcon(REFGUID rguid, DWORD dwUnknown24, HICON hIcon, LPCWSTR psz);
+
+ void RemoveAllIcon(DWORD dwFlags);
+ void RemoveUnusedIcons(int unknown);
+
+ CButtonIconItem *FindIconItem(REFGUID rguid);
+ BOOL FindTrayEtc();
+ HWND GetNotifyWnd();
+ BOOL OnIconMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+ static CTrayIconWnd *GetThis(HWND hWnd);
+ static void SetThis(HWND hWnd, LPCREATESTRUCT pCS);
+
+ void CallOnDelayMsg();
};
/***********************************************************************/
@@ -469,20 +519,50 @@ protected:
DWORD m_dwIconAddOrModify;
BOOL m_bIconAdded;
CTrayIconWnd *m_pTrayIconWnd;
- DWORD m_dw;
+ DWORD m_dwUnknown25;
GUID m_guid;
RECT m_rcMenu;
POINT m_ptCursor;
+ friend class CTrayIconWnd;
+public:
CTrayIconItem(CTrayIconWnd *pTrayIconWnd);
+ virtual ~CTrayIconItem() { }
BOOL _Init(HWND hWnd, UINT uCallbackMessage, UINT uNotifyIconID, const GUID&
rguid);
BOOL UpdateMenuRectPoint();
BOOL RemoveIcon();
- STDMETHOD_(BOOL, SetIcon)(HICON hIcon, LPCTSTR pszTip);
- STDMETHOD_(LRESULT, OnMsg)(WPARAM wParam, LPARAM lParam) { return 0; };
- STDMETHOD_(LRESULT, OnDelayMsg)(LPARAM lParam) { return 0; };
+ STDMETHOD_(BOOL, SetIcon)(HICON hIcon, LPCWSTR pszTip);
+ STDMETHOD_(BOOL, OnMsg)(WPARAM wParam, LPARAM lParam) { return FALSE; };
+ STDMETHOD_(BOOL, OnDelayMsg)(UINT uMsg) { return 0; };
+};
+
+/***********************************************************************/
+
+class CButtonIconItem : public CTrayIconItem
+{
+protected:
+ DWORD m_dwUnknown24;
+ HKL m_hKL;
+ friend class CTrayIconWnd;
+
+public:
+ CButtonIconItem(CTrayIconWnd *pWnd, DWORD dwUnknown24);
+
+ STDMETHOD_(BOOL, OnMsg)(WPARAM wParam, LPARAM lParam) override;
+ STDMETHOD_(BOOL, OnDelayMsg)(UINT uMsg) override;
+};
+
+/***********************************************************************/
+
+class CMainIconItem : public CButtonIconItem
+{
+public:
+ CMainIconItem(CTrayIconWnd *pWnd);
+
+ BOOL Init(HWND hWnd);
+ STDMETHOD_(BOOL, OnDelayMsg)(UINT uMsg) override;
};
/***********************************************************************
@@ -780,7 +860,7 @@ STDMETHODIMP CCicLibMenu::AddMenuItem(
pSubMenu->AddRef();
}
- *m_MenuItems.Append(1) = pMenuItem;
+ m_MenuItems.Add(pMenuItem);
return S_OK;
}
@@ -1429,8 +1509,8 @@ BOOL CUTBMenuWnd::StartDoAccDefaultActionTimer(CUTBMenuItem
*pTarget)
if (::IsWindow(m_hWnd))
{
- ::KillTimer(m_hWnd, 11);
- ::SetTimer(m_hWnd, 11, 200, NULL);
+ ::KillTimer(m_hWnd, TIMER_ID_DOACCDEFAULTACTION);
+ ::SetTimer(m_hWnd, TIMER_ID_DOACCDEFAULTACTION, g_uTimerElapseDOACCDEFAULTACTION,
NULL);
}
return TRUE;
@@ -1525,9 +1605,9 @@ CUTBMenuWnd::OnShowWindow(HWND hWnd, UINT uMsg, WPARAM wParam,
LPARAM lParam)
STDMETHODIMP_(void) CUTBMenuWnd::OnTimer(WPARAM wParam)
{
- if (wParam == 11)
+ if (wParam == TIMER_ID_DOACCDEFAULTACTION)
{
- ::KillTimer(m_hWnd, 11);
+ ::KillTimer(m_hWnd, TIMER_ID_DOACCDEFAULTACTION);
if (m_pAccessible && m_nMenuWndID)
{
m_pAccessible->DoDefaultActionReal(m_nMenuWndID);
@@ -1633,10 +1713,10 @@ BOOL CTrayIconItem::RemoveIcon()
{
if (m_dwIconAddOrModify == NIM_MODIFY)
{
- NOTIFYICONDATA NotifyIcon = { sizeof(NotifyIcon), m_hWnd, m_uNotifyIconID };
+ NOTIFYICONDATAW NotifyIcon = { sizeof(NotifyIcon), m_hWnd, m_uNotifyIconID };
NotifyIcon.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
NotifyIcon.uCallbackMessage = m_uCallbackMessage;
- ::Shell_NotifyIcon(NIM_DELETE, &NotifyIcon);
+ ::Shell_NotifyIconW(NIM_DELETE, &NotifyIcon);
}
m_dwIconAddOrModify = NIM_ADD;
@@ -1644,22 +1724,22 @@ BOOL CTrayIconItem::RemoveIcon()
return TRUE;
}
-BOOL CTrayIconItem::SetIcon(HICON hIcon, LPCTSTR pszTip)
+BOOL CTrayIconItem::SetIcon(HICON hIcon, LPCWSTR pszTip)
{
if (!hIcon)
return FALSE;
- NOTIFYICONDATA NotifyIcon = { sizeof(NotifyIcon), m_hWnd, m_uNotifyIconID };
+ NOTIFYICONDATAW NotifyIcon = { sizeof(NotifyIcon), m_hWnd, m_uNotifyIconID };
NotifyIcon.uFlags = NIF_ICON | NIF_MESSAGE;
NotifyIcon.uCallbackMessage = m_uCallbackMessage;
NotifyIcon.hIcon = hIcon;
if (pszTip)
{
NotifyIcon.uFlags |= NIF_TIP;
- StringCchCopy(NotifyIcon.szTip, _countof(NotifyIcon.szTip), pszTip);
+ StringCchCopyW(NotifyIcon.szTip, _countof(NotifyIcon.szTip), pszTip);
}
- ::Shell_NotifyIcon(m_dwIconAddOrModify, &NotifyIcon);
+ ::Shell_NotifyIconW(m_dwIconAddOrModify, &NotifyIcon);
m_dwIconAddOrModify = NIM_MODIFY;
m_bIconAdded = NIM_MODIFY;
@@ -1676,6 +1756,347 @@ BOOL CTrayIconItem::UpdateMenuRectPoint()
return TRUE;
}
+/***********************************************************************
+ * CButtonIconItem
+ */
+
+CButtonIconItem::CButtonIconItem(CTrayIconWnd *pWnd, DWORD dwUnknown24)
+ : CTrayIconItem(pWnd)
+{
+ m_dwUnknown24 = dwUnknown24;
+}
+
+/// @unimplemented
+STDMETHODIMP_(BOOL) CButtonIconItem::OnMsg(WPARAM wParam, LPARAM lParam)
+{
+ switch (lParam)
+ {
+ case WM_LBUTTONDOWN:
+ case WM_RBUTTONDOWN:
+ case WM_LBUTTONDBLCLK:
+ case WM_RBUTTONDBLCLK:
+ break;
+ default:
+ return TRUE;
+ }
+
+ //FIXME
+ return TRUE;
+}
+
+/// @unimplemented
+STDMETHODIMP_(BOOL) CButtonIconItem::OnDelayMsg(UINT uMsg)
+{
+ //FIXME
+ return FALSE;
+}
+
+/***********************************************************************
+ * CMainIconItem
+ */
+
+CMainIconItem::CMainIconItem(CTrayIconWnd *pWnd)
+ : CButtonIconItem(pWnd, 1)
+{
+}
+
+BOOL CMainIconItem::Init(HWND hWnd)
+{
+ return CTrayIconItem::_Init(hWnd, WM_USER, 0, GUID_LBI_TRAYMAIN);
+}
+
+/// @unimplemented
+STDMETHODIMP_(BOOL) CMainIconItem::OnDelayMsg(UINT uMsg)
+{
+ if (!CButtonIconItem::OnDelayMsg(uMsg))
+ return 0;
+
+ if (uMsg == WM_LBUTTONDBLCLK)
+ {
+ //FIXME
+ //if (g_pTipbarWnd->m_dwUnknown20)
+ // g_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_SHOWNORMAL);
+ }
+ else if (uMsg == WM_LBUTTONDOWN || uMsg == WM_RBUTTONDOWN)
+ {
+ //FIXME
+ //g_pTipbarWnd->ShowContextMenu(m_ptCursor, &m_rcClient, uMsg ==
WM_RBUTTONDOWN);
+ }
+ return TRUE;
+}
+
+/***********************************************************************
+ * CTrayIconWnd
+ */
+
+CTrayIconWnd::CTrayIconWnd()
+{
+ m_uCallbackMsg = WM_USER + 0x1000;
+ m_uNotifyIconID = 0x1000;
+}
+
+CTrayIconWnd::~CTrayIconWnd()
+{
+ for (size_t iItem = 0; iItem < m_Items.size(); ++iItem)
+ {
+ auto& pItem = m_Items[iItem];
+ if (pItem)
+ {
+ delete pItem;
+ pItem = NULL;
+ }
+ }
+}
+
+void CTrayIconWnd::CallOnDelayMsg()
+{
+ for (size_t iItem = 0; iItem < m_Items.size(); ++iItem)
+ {
+ auto pItem = m_Items[iItem];
+ if (pItem && m_uCallbackMessage == pItem->m_uCallbackMessage)
+ {
+ pItem->OnDelayMsg(m_uMsg);
+ break;
+ }
+ }
+}
+
+HWND CTrayIconWnd::CreateWnd()
+{
+ m_hWnd = ::CreateWindowEx(0, TEXT("CTrayIconWndClass"), NULL, WS_DISABLED,
+ 0, 0, 0, 0, NULL, NULL, g_hInst, this);
+ FindTrayEtc();
+
+ m_pMainIconItem = new(cicNoThrow) CMainIconItem(this);
+ if (m_pMainIconItem)
+ {
+ m_pMainIconItem->Init(m_hWnd);
+ m_Items.Add(m_pMainIconItem);
+ }
+
+ return m_hWnd;
+}
+
+void CTrayIconWnd::DestroyWnd()
+{
+ ::DestroyWindow(m_hWnd);
+ m_hWnd = NULL;
+}
+
+BOOL CALLBACK CTrayIconWnd::EnumChildWndProc(HWND hWnd, LPARAM lParam)
+{
+ CTrayIconWnd *pWnd = (CTrayIconWnd *)lParam;
+
+ TCHAR ClassName[60];
+ ::GetClassName(hWnd, ClassName, _countof(ClassName));
+ if (lstrcmp(ClassName, TEXT("TrayNotifyWnd")) != 0)
+ return TRUE;
+
+ pWnd->m_hNotifyWnd = hWnd;
+ return FALSE;
+}
+
+CButtonIconItem *CTrayIconWnd::FindIconItem(REFGUID rguid)
+{
+ for (size_t iItem = 0; iItem < m_Items.size(); ++iItem)
+ {
+ auto pItem = m_Items[iItem];
+ if (IsEqualGUID(rguid, pItem->m_guid))
+ return pItem;
+ }
+ return NULL;
+}
+
+BOOL CTrayIconWnd::FindTrayEtc()
+{
+ m_hTrayWnd = ::FindWindow(TEXT("Shell_TrayWnd"), NULL);
+ if (!m_hTrayWnd)
+ return FALSE;
+
+ ::EnumChildWindows(m_hTrayWnd, EnumChildWndProc, (LPARAM)this);
+ if (!m_hNotifyWnd)
+ return FALSE;
+ m_dwTrayWndThreadId = ::GetWindowThreadProcessId(m_hTrayWnd, NULL);
+ m_hwndProgman = FindWindow(TEXT("Progman"), NULL);
+ m_dwProgmanThreadId = ::GetWindowThreadProcessId(m_hwndProgman, NULL);
+ return TRUE;
+}
+
+HWND CTrayIconWnd::GetNotifyWnd()
+{
+ if (!::IsWindow(m_hNotifyWnd))
+ FindTrayEtc();
+ return m_hNotifyWnd;
+}
+
+/// @unimplemented
+BOOL CTrayIconWnd::OnIconMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ //FIXME
+ //if (g_pTipbarWnd)
+ // g_pTipbarWnd->AttachFocusThread();
+
+ for (size_t iItem = 0; iItem < m_Items.size(); ++iItem)
+ {
+ auto pItem = m_Items[iItem];
+ if (pItem)
+ {
+ if (uMsg == pItem->m_uCallbackMessage)
+ {
+ pItem->OnMsg(wParam, lParam);
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+BOOL CTrayIconWnd::RegisterClass()
+{
+ WNDCLASSEX wc = { sizeof(wc) };
+ wc.style = CS_HREDRAW | CS_VREDRAW;
+ wc.hInstance = g_hInst;
+ wc.hCursor = ::LoadCursor(NULL, (LPCTSTR)IDC_ARROW);
+ wc.lpfnWndProc = CTrayIconWnd::_WndProc;
+ wc.lpszClassName = TEXT("CTrayIconWndClass");
+ ::RegisterClassEx(&wc);
+ return TRUE;
+}
+
+void CTrayIconWnd::RemoveAllIcon(DWORD dwFlags)
+{
+ for (size_t iItem = 0; iItem < m_Items.size(); ++iItem)
+ {
+ auto pItem = m_Items[iItem];
+ if (dwFlags & 0x1)
+ {
+ if (IsEqualGUID(pItem->m_guid, GUID_LBI_INATITEM) ||
+ IsEqualGUID(pItem->m_guid, GUID_LBI_CTRL))
+ {
+ continue;
+ }
+ }
+
+ if (dwFlags & 0x2)
+ {
+ if (IsEqualGUID(pItem->m_guid, GUID_TFCAT_TIP_KEYBOARD))
+ continue;
+ }
+
+ if (pItem->m_uNotifyIconID < 0x1000)
+ continue;
+
+ pItem->RemoveIcon();
+ }
+}
+
+/// @unimplemented
+void CTrayIconWnd::RemoveUnusedIcons(int unknown)
+{
+ //FIXME
+}
+
+BOOL CTrayIconWnd::SetIcon(REFGUID rguid, DWORD dwUnknown24, HICON hIcon, LPCWSTR psz)
+{
+ CButtonIconItem *pItem = FindIconItem(rguid);
+ if (!pItem)
+ {
+ if (!hIcon)
+ return FALSE;
+ pItem = new(cicNoThrow) CButtonIconItem(this, dwUnknown24);
+ if (!pItem)
+ return FALSE;
+
+ pItem->_Init(m_hWnd, m_uCallbackMsg, m_uNotifyIconID, rguid);
+ m_uCallbackMsg += 2;
+ ++m_uNotifyIconID;
+ m_Items.Add(pItem);
+ }
+
+ if (!hIcon)
+ return pItem->RemoveIcon();
+
+ return pItem->SetIcon(hIcon, psz);
+}
+
+BOOL CTrayIconWnd::SetMainIcon(HKL hKL)
+{
+ if (!hKL)
+ {
+ m_pMainIconItem->RemoveIcon();
+ m_pMainIconItem->m_hKL = NULL;
+ return TRUE;
+ }
+
+ if (hKL != m_pMainIconItem->m_hKL)
+ {
+ WCHAR szText[64];
+ HICON hIcon = TF_GetLangIcon(LOWORD(hKL), szText, _countof(szText));
+ if (hIcon)
+ {
+ m_pMainIconItem->SetIcon(hIcon, szText);
+ ::DestroyIcon(hIcon);
+ }
+ else
+ {
+ ::LoadStringW(g_hInst, IDS_RESTORELANGBAR, szText, _countof(szText));
+ hIcon = ::LoadIconW(g_hInst, MAKEINTRESOURCEW(IDI_MAINICON));
+ m_pMainIconItem->SetIcon(hIcon, szText);
+ }
+
+ m_pMainIconItem->m_hKL = hKL;
+ }
+
+ return TRUE;
+}
+
+CTrayIconWnd *CTrayIconWnd::GetThis(HWND hWnd)
+{
+ return (CTrayIconWnd *)::GetWindowLongPtr(hWnd, GWL_USERDATA);
+}
+
+void CTrayIconWnd::SetThis(HWND hWnd, LPCREATESTRUCT pCS)
+{
+ if (pCS)
+ ::SetWindowLongPtr(hWnd, GWL_USERDATA, (LONG_PTR)pCS->lpCreateParams);
+ else
+ ::SetWindowLongPtr(hWnd, GWL_USERDATA, 0);
+}
+
+LRESULT CALLBACK
+CTrayIconWnd::_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ CTrayIconWnd *pThis;
+ switch (uMsg)
+ {
+ case WM_CREATE:
+ CTrayIconWnd::SetThis(hWnd, (LPCREATESTRUCT)lParam);
+ break;
+ case WM_DESTROY:
+ ::SetWindowLongPtr(hWnd, GWL_USERDATA, 0);
+ break;
+ case WM_TIMER:
+ if (wParam == 100)
+ {
+ ::KillTimer(hWnd, 100);
+ pThis = CTrayIconWnd::GetThis(hWnd);
+ if (pThis)
+ pThis->CallOnDelayMsg();
+ }
+ break;
+ default:
+ {
+ if (uMsg < WM_USER)
+ return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
+ pThis = CTrayIconWnd::GetThis(hWnd);
+ if (pThis && pThis->OnIconMessage(uMsg, wParam, lParam))
+ break;
+ return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
+ }
+ }
+ return 0;
+}
+
/***********************************************************************
* GetLibTls (MSUTB.@)
*
diff --git a/dll/win32/msutb/msutb.rc b/dll/win32/msutb/msutb.rc
index 21964d264da..82ae823ce07 100644
--- a/dll/win32/msutb/msutb.rc
+++ b/dll/win32/msutb/msutb.rc
@@ -20,6 +20,8 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
#include <reactos/manifest_hosted.rc>
+IDI_MAINICON ICON "res/earth.ico"
+
/* UTF-8 */
#pragma code_page(65001)
diff --git a/dll/win32/msutb/precomp.h b/dll/win32/msutb/precomp.h
index d198ded03f1..05b2a826e27 100644
--- a/dll/win32/msutb/precomp.h
+++ b/dll/win32/msutb/precomp.h
@@ -20,6 +20,7 @@
#include <cguid.h>
#include <msctf.h>
#include <ctffunc.h>
+#include <ctfutb.h>
#include <shlwapi.h>
#include <atlbase.h>
#include <atlcom.h>
diff --git a/dll/win32/msutb/res/earth.ico b/dll/win32/msutb/res/earth.ico
new file mode 100644
index 00000000000..7d47171f990
Binary files /dev/null and b/dll/win32/msutb/res/earth.ico differ
diff --git a/dll/win32/msutb/resource.h b/dll/win32/msutb/resource.h
index 6808bd02597..c3abc6b696c 100644
--- a/dll/win32/msutb/resource.h
+++ b/dll/win32/msutb/resource.h
@@ -7,6 +7,10 @@
#define IDS_IGNORE 104
#define IDS_YES 105
#define IDS_NO 106
+
+#define IDI_MAINICON 100
+
+#define IDS_RESTORELANGBAR 308
#define IDS_MENUWND 322
#define IDS_LEFTCLICK 323
diff --git a/sdk/include/psdk/msctf.idl b/sdk/include/psdk/msctf.idl
index 60219b328e0..c9cc9908474 100644
--- a/sdk/include/psdk/msctf.idl
+++ b/sdk/include/psdk/msctf.idl
@@ -43,6 +43,7 @@ cpp_quote("EXTERN_C HRESULT WINAPI
TF_InvalidAssemblyListCacheIfExist(VOID);")
cpp_quote("EXTERN_C HRESULT WINAPI TF_DllDetachInOther(VOID);")
cpp_quote("EXTERN_C HRESULT WINAPI TF_CreateCategoryMgr(ITfCategoryMgr
**ppcat);")
cpp_quote("EXTERN_C HRESULT WINAPI
TF_CreateDisplayAttributeMgr(ITfDisplayAttributeMgr **ppdam);")
+cpp_quote("EXTERN_C HICON WINAPI TF_GetLangIcon(LANGID LangID, LPWSTR pszText, INT
cchText);")
cpp_quote("EXTERN_C const GUID GUID_PROP_TEXTOWNER;")
cpp_quote("EXTERN_C const GUID GUID_PROP_ATTRIBUTE;")
diff --git a/sdk/include/reactos/cicero/cicutb.h b/sdk/include/reactos/cicero/cicutb.h
index 9c0ff831530..916b0c4befb 100644
--- a/sdk/include/reactos/cicero/cicutb.h
+++ b/sdk/include/reactos/cicero/cicutb.h
@@ -8,6 +8,10 @@
#pragma once
DEFINE_GUID(GUID_COMPARTMENT_SPEECH_OPENCLOSE, 0x544D6A63, 0xE2E8, 0x4752, 0xBB, 0xD1,
0x00, 0x09, 0x60, 0xBC, 0xA0, 0x83);
+DEFINE_GUID(GUID_LBI_TRAYMAIN, 0xE0B724E9, 0x6F76, 0x45F7, 0xB4, 0xC1,
0xB1, 0xC0, 0xFA, 0xBC, 0xE2, 0x3E);
+DEFINE_GUID(GUID_LBI_INATITEM, 0xCDBC683A, 0x55CE, 0x4717, 0xBA, 0xC0,
0x50, 0xBF, 0x44, 0xA3, 0x27, 0x0C);
+DEFINE_GUID(GUID_LBI_CTRL, 0x58C99D96, 0x2F9B, 0x42CE, 0x91, 0xBE,
0x37, 0xEF, 0x18, 0x60, 0xF8, 0x82);
+DEFINE_GUID(GUID_TFCAT_TIP_KEYBOARD, 0x34745C63, 0xB2F0, 0x4784, 0x8B, 0x67,
0x5E, 0x12, 0xC8, 0x70, 0x1A, 0x31);
EXTERN_C LPVOID WINAPI GetLibTls(VOID);
EXTERN_C BOOL WINAPI GetPopupTipbar(HWND hWnd, BOOL fWinLogon);