https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c6ceae3440679c664b093…
commit c6ceae3440679c664b0936fbb81a20f1c15fbc7c
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Sat Feb 10 13:04:37 2024 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Sat Feb 10 13:04:37 2024 +0900
[MSUTB] Add CTipbarWnd Part 3 (#6467)
Supporting Language Bar...
JIRA issue: CORE-19363
- Add implementation to
CTipbarWnd class.
- Add delay link to imm32.dll.
---
dll/win32/msutb/CMakeLists.txt | 2 +-
dll/win32/msutb/msutb.cpp | 371 +++++++++++++++++++++++++++++++++++++----
dll/win32/msutb/precomp.h | 1 +
3 files changed, 344 insertions(+), 30 deletions(-)
diff --git a/dll/win32/msutb/CMakeLists.txt b/dll/win32/msutb/CMakeLists.txt
index b425c8d0328..ee8204be2ff 100644
--- a/dll/win32/msutb/CMakeLists.txt
+++ b/dll/win32/msutb/CMakeLists.txt
@@ -15,5 +15,5 @@ set_module_type(msutb win32dll)
add_dependencies(msutb msctf psdk)
target_link_libraries(msutb wine uuid atl_classes)
add_importlibs(msutb user32 gdi32 advapi32 msvcrt kernel32 ntdll)
-add_delay_importlibs(msutb uxtheme comctl32 msctf ole32 oleacc oleaut32 shell32)
+add_delay_importlibs(msutb uxtheme imm32 comctl32 msctf ole32 oleacc oleaut32 shell32)
add_cd_file(TARGET msutb DESTINATION reactos/system32 FOR all)
diff --git a/dll/win32/msutb/msutb.cpp b/dll/win32/msutb/msutb.cpp
index cfdfb54d8a7..f1c350035a3 100644
--- a/dll/win32/msutb/msutb.cpp
+++ b/dll/win32/msutb/msutb.cpp
@@ -364,6 +364,24 @@ BOOL IsTransparecyAvailable(void)
return FALSE;
}
+static INT CALLBACK
+FindEAEnumFontProc(ENUMLOGFONT *pLF, NEWTEXTMETRIC *pTM, INT nFontType, LPARAM lParam)
+{
+ if ((nFontType != TRUETYPE_FONTTYPE) || (pLF->elfLogFont.lfFaceName[0] !=
'@'))
+ return TRUE;
+ *(BOOL*)lParam = TRUE;
+ return FALSE;
+}
+
+BOOL CheckEAFonts(void)
+{
+ BOOL bHasVertical = FALSE;
+ HDC hDC = ::GetDC(NULL);
+ ::EnumFonts(hDC, NULL, (FONTENUMPROC)FindEAEnumFontProc, (LPARAM)&bHasVertical);
+ ::ReleaseDC(NULL, hDC);
+ return bHasVertical;
+}
+
BOOL InitFromReg(void)
{
DWORD dwValue;
@@ -680,6 +698,7 @@ protected:
CicArray<CTipbarAccItem*> m_AccItems;
LONG m_cSelection;
friend class CUTBMenuWnd;
+ friend class CTipbarWnd;
public:
CTipbarAccessible(CTipbarAccItem *pItem);
@@ -968,6 +987,7 @@ class CTipbarGripper : public CUIFGripper
protected:
CTipbarWnd *m_pTipbarWnd;
BOOL m_bInDebugMenu;
+ friend class CTipbarWnd;
public:
CTipbarGripper(CTipbarWnd *pTipbarWnd, LPCRECT prc, DWORD style);
@@ -1187,7 +1207,8 @@ class CTipbarWnd
, public CTipbarAccItem
, public CUIFWindow
{
- DWORD m_dwUnknown19[2];
+ CTipbarCoInitialize m_coInit;
+ DWORD m_dwSinkCookie;
CModalMenu *m_pModalMenu;
CTipbarThread *m_pThread;
CicArray<GUID*> m_TipbarGUIDArray;
@@ -1239,6 +1260,11 @@ public:
return static_cast<CUIFWindow*>(this);
}
+ CTipbarAccItem *GetAccItem()
+ {
+ return static_cast<CTipbarAccItem*>(this);
+ }
+
void Init(BOOL bFlag, CDeskBand *pDeskBand);
void InitHighContrast();
void InitMetrics();
@@ -1286,7 +1312,7 @@ public:
void MyClientToScreen(LPPOINT lpPoint, LPRECT prc);
void SavePosition();
void SetAlpha(BYTE bAlpha, BOOL bFlag);
- BOOL SetLangBand(BOOL bFlag1, BOOL bFlag2);
+ BOOL SetLangBand(BOOL bDeskBand, BOOL bFlag2);
void SetMoveRect(INT X, INT Y, INT nWidth, INT nHeight);
void SetShowText(BOOL bShow);
void SetShowTrayIcon(BOOL bShow);
@@ -3627,8 +3653,6 @@ STDMETHODIMP_(BOOL) CTipbarGripper::OnSetCursor(UINT uMsg, LONG x,
LONG y)
CTipbarWnd::CTipbarWnd(DWORD style)
: CUIFWindow(g_hInst, style)
{
- m_dwUnknown19[0] = 0;
-
m_dwUnknown23_1[4] = 0;
m_dwUnknown23_1[5] = 0;
m_dwUnknown23_1[6] = 0;
@@ -3813,9 +3837,11 @@ void CTipbarWnd::MoveToStub(BOOL bFlag)
{
}
-/// @unimplemented
void CTipbarWnd::RestoreFromStub()
{
+ m_dwTipbarWndFlags &= 0x3F;
+ KillTimer(1);
+ KillTimer(2);
}
/// @unimplemented
@@ -3824,16 +3850,38 @@ INT CTipbarWnd::GetCtrlButtonWidth()
return 0;
}
-/// @unimplemented
INT CTipbarWnd::GetGripperWidth()
{
- return 0;
+ if (m_dwTipbarWndFlags & 2)
+ return 0;
+
+ if (!m_pTipbarGripper || FAILED(m_pTipbarGripper->EnsureThemeData(m_hWnd)))
+ return 5;
+
+ INT width = -1;
+ SIZE partSize;
+ HDC hDC = ::GetDC(m_hWnd);
+ if (SUCCEEDED(m_pTipbarGripper->GetThemePartSize(hDC, 1, 0, TS_TRUE,
&partSize)))
+ {
+ INT cx = partSize.cx;
+ if (m_dwTipbarWndFlags & 4)
+ cx = partSize.cy;
+ width = cx + 4;
+ }
+ ::ReleaseDC(m_hWnd, hDC);
+
+ return ((width < 0) ? 5 : width);
}
-/// @unimplemented
INT CTipbarWnd::GetTipbarHeight()
{
- return 0;
+ SIZE size = { 0, 0 };
+ if (m_pWndFrame)
+ m_pWndFrame->GetFrameSize(&size);
+ INT cy = m_Margins.cyBottomHeight + m_Margins.cyTopHeight + 2;
+ if (cy < 6)
+ cy = 6;
+ return m_cySmallIcon + cy + (2 * size.cy);
}
/// @unimplemented
@@ -3853,19 +3901,93 @@ void CTipbarWnd::LocateCtrlButtons()
{
}
-/// @unimplemented
void CTipbarWnd::AdjustPosOnDisplayChange()
{
+ RECT rcWorkArea;
+ RECT rc = { m_nLeft, m_nTop, m_nLeft + m_nWidth, m_nTop + m_nHeight };
+ if (!GetWorkArea(&rc, &rcWorkArea))
+ return;
+
+ INT x = m_nLeft, y = m_nTop;
+ if (m_dwTipbarWndFlags & 0x200000)
+ x = rcWorkArea.left;
+ if (m_dwTipbarWndFlags & 0x40000)
+ y = rcWorkArea.top;
+ if (m_dwTipbarWndFlags & 0x100000)
+ x = rcWorkArea.right - m_nWidth;
+ if (m_dwTipbarWndFlags & 0x80000)
+ y = rcWorkArea.bottom - m_nHeight;
+ if (x != m_nLeft || y != m_nTop)
+ Move(x, y, m_nWidth, m_nHeight);
}
-/// @unimplemented
void CTipbarWnd::SetVertical(BOOL bVertical)
{
+ if (bVertical)
+ m_dwTipbarWndFlags |= 0x4;
+ else
+ m_dwTipbarWndFlags &= ~0x4;
+
+ if (m_pTipbarGripper)
+ {
+ DWORD style = m_pTipbarGripper->m_style;
+ if (bVertical)
+ style |= 0x1;
+ else
+ style &= 0x1;
+ m_pTipbarGripper->SetStyle(style);
+ }
+
+ if (g_fTaskbarTheme)
+ SetActiveTheme(L"TASKBAR", !!(m_dwTipbarWndFlags & 0x4), 1);
+
+ if (!(m_dwTipbarWndFlags & 2))
+ {
+ if (m_dwTipbarWndFlags & 4)
+ {
+ Move(m_nLeft, m_nTop, GetTipbarHeight(), 0);
+ }
+ else
+ {
+ Move(m_nLeft, m_nTop, 0, GetTipbarHeight());
+ }
+ }
+
+ if (m_hWnd)
+ {
+ KillTimer(7);
+ SetTimer(7, g_uTimerElapseSYSCOLORCHANGED);
+ }
}
-/// @unimplemented
void CTipbarWnd::UpdatePosFlags()
{
+ if (m_dwTipbarWndFlags & 0x2)
+ return;
+
+ RECT rc = { m_nLeft, m_nTop, m_nLeft + m_nWidth, m_nTop + m_nHeight }, rcWorkArea;
+ if (!GetWorkArea(&rc, &rcWorkArea))
+ return;
+
+ if (m_nLeft > rcWorkArea.left + 2)
+ m_dwTipbarWndFlags &= ~0x200000;
+ else
+ m_dwTipbarWndFlags |= 0x200000;
+
+ if ( m_nTop> rcWorkArea.top + 2 )
+ m_dwTipbarWndFlags &= ~0x40000;
+ else
+ m_dwTipbarWndFlags |= 0x40000;
+
+ if (m_nLeft + m_nWidth < rcWorkArea.right - 2)
+ m_dwTipbarWndFlags &= ~0x100000;
+ else
+ m_dwTipbarWndFlags |= 0x100000;
+
+ if (m_nTop + m_nHeight < rcWorkArea.bottom - 2)
+ m_dwTipbarWndFlags &= ~0x80000;
+ else
+ m_dwTipbarWndFlags |= 0x80000;
}
/// @unimplemented
@@ -3873,10 +3995,9 @@ void CTipbarWnd::CancelMenu()
{
}
-/// @unimplemented
BOOL CTipbarWnd::CheckExcludeCaptionButtonMode(LPRECT prc1, LPCRECT prc2)
{
- return FALSE;
+ return (prc1->top < prc2->top + 5) && (prc2->right <=
prc1->right + (5 * m_ButtonWidth));
}
/// @unimplemented
@@ -3884,10 +4005,35 @@ void CTipbarWnd::ClearLBItemList()
{
}
-/// @unimplemented
HFONT CTipbarWnd::CreateVerticalFont()
{
- return NULL;
+ if (!m_hWnd)
+ return NULL;
+
+ CUIFTheme theme;
+ theme.m_iPartId = 1;
+ theme.m_iStateId = 0;
+ theme.m_pszClassList = L"TOOLBAR";
+
+ LOGFONTW lf;
+ if (FAILED(theme.InternalOpenThemeData(m_hWnd)) ||
+ FAILED(::GetThemeFont(theme.m_hTheme, NULL, theme.m_iPartId, 0, 210, &lf)))
+ {
+ ::GetObject(::GetStockObject(DEFAULT_GUI_FONT), sizeof(lf), &lf);
+ }
+
+ lf.lfEscapement = lf.lfOrientation = 2700;
+ lf.lfOutPrecision = OUT_TT_ONLY_PRECIS;
+
+ if (CheckEAFonts())
+ {
+ WCHAR szText[LF_FACESIZE];
+ szText[0] = L'@';
+ StringCchCopyW(&szText[1], _countof(szText) - 1, lf.lfFaceName);
+ StringCchCopyW(lf.lfFaceName, _countof(lf.lfFaceName), szText);
+ }
+
+ return ::CreateFontIndirectW(&lf);
}
void CTipbarWnd::UpdateVerticalFont()
@@ -3991,15 +4137,85 @@ void CTipbarWnd::SetAlpha(BYTE bAlpha, BOOL bFlag)
{
}
-/// @unimplemented
-BOOL CTipbarWnd::SetLangBand(BOOL bFlag1, BOOL bFlag2)
+BOOL CTipbarWnd::SetLangBand(BOOL bDeskBand, BOOL bFlag2)
{
- return FALSE;
+ if (bDeskBand == !!(m_dwShowType & TF_SFT_DESKBAND))
+ return TRUE;
+
+ BOOL ret = TRUE;
+ HWND hwndTray = m_ShellWndThread.GetWndTray();
+ if (bFlag2 && hwndTray)
+ {
+ DWORD_PTR dwResult;
+ HWND hImeWnd = ::ImmGetDefaultIMEWnd(hwndTray);
+ if (hImeWnd)
+ ::SendMessageTimeout(hImeWnd, WM_IME_SYSTEM, 0x24 - bDeskBand,
(LPARAM)hwndTray,
+ (SMTO_BLOCK | SMTO_ABORTIFHUNG), 5000, &dwResult);
+ else
+ ::SendMessageTimeout(hwndTray, 0x505, 0, bDeskBand,
+ (SMTO_BLOCK | SMTO_ABORTIFHUNG), 5000, &dwResult);
+ }
+ else
+ {
+ ret = FALSE;
+ }
+
+ if (!(m_dwTipbarWndFlags & 2))
+ {
+ if (bDeskBand)
+ {
+ KillTimer(7);
+ SetTimer(7, g_uTimerElapseSYSCOLORCHANGED);
+ }
+ }
+
+ return ret;
}
-/// @unimplemented
void CTipbarWnd::SetMoveRect(INT X, INT Y, INT nWidth, INT nHeight)
{
+ if (m_dwTipbarWndFlags & 0x2)
+ {
+ m_nWidth = nWidth;
+ m_nHeight = nHeight;
+ return;
+ }
+
+ ++m_bInCallOn;
+
+ m_dwTipbarWndFlags |= 0x400;
+
+ m_X = X;
+ m_Y = Y;
+ m_CX = nWidth;
+ m_CY = nHeight;
+
+ RECT rc;
+ SIZE size = { 0, 0 };
+ if (m_pWndFrame)
+ {
+ ::SetRect(&rc, 0, 0, nWidth - m_cxDlgFrameX2, nHeight - m_cyDlgFrameX2);
+ m_pWndFrame->SetRect(&rc);
+ m_pWndFrame->GetFrameSize(&size);
+ }
+
+ if (m_pTipbarGripper)
+ {
+ if (m_dwTipbarWndFlags & 4)
+ {
+ INT GripperWidth = GetGripperWidth();
+ ::SetRect(&rc, size.cx, size.cy, nWidth - m_cxDlgFrameX2 - size.cx,
size.cy + GripperWidth);
+ }
+ else
+ {
+ INT GripperWidth = GetGripperWidth();
+ INT y1 = nHeight - m_cyDlgFrameX2 - size.cy;
+ ::SetRect(&rc, size.cx, size.cy, size.cx + GripperWidth, y1);
+ }
+ m_pTipbarGripper->SetRect(&rc);
+ }
+
+ --m_bInCallOn;
}
/// @unimplemented
@@ -4209,10 +4425,54 @@ STDMETHODIMP CTipbarWnd::OnThreadItemChange(DWORD dwThreadId)
return E_NOTIMPL;
}
-/// @unimplemented
STDMETHODIMP CTipbarWnd::OnModalInput(DWORD dwThreadId, UINT uMsg, WPARAM wParam, LPARAM
lParam)
{
- return E_NOTIMPL;
+ switch (uMsg)
+ {
+ case WM_NCLBUTTONDOWN:
+ case WM_NCRBUTTONDOWN:
+ case WM_NCMBUTTONDOWN:
+ case WM_LBUTTONUP:
+ case WM_RBUTTONUP:
+ case WM_MBUTTONUP:
+ break;
+
+ case WM_NCLBUTTONUP:
+ case WM_NCRBUTTONUP:
+ case WM_NCMBUTTONUP:
+ if (m_pThread)
+ {
+ CUTBMenuWnd *pMenuUI = m_pModalMenu->m_pMenuUI;
+ if (pMenuUI)
+ {
+ HWND hWnd = *pMenuUI;
+ if (hWnd)
+ {
+ POINT pt = { (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam) };
+ ::ScreenToClient(hWnd, &pt);
+ uMsg += WM_LBUTTONUP - WM_NCLBUTTONUP;
+ ::PostMessage(m_hWnd, uMsg, wParam, MAKELPARAM(pt.x, pt.y));
+ }
+ }
+ }
+ break;
+
+ default:
+ {
+ if (uMsg == WM_KEYDOWN || uMsg == WM_KEYUP)
+ {
+ if (m_pThread)
+ m_pModalMenu->PostKey(uMsg == WM_KEYUP, wParam, lParam);
+ }
+ else
+ {
+ CancelMenu();
+ }
+ break;
+ }
+ }
+
+ return 0;
}
/// @unimplemented
@@ -4236,7 +4496,7 @@ STDMETHODIMP CTipbarWnd::OnLangBarUpdate(TfLBIClick click, BOOL
bFlag)
STDMETHODIMP_(BSTR) CTipbarWnd::GetAccName()
{
WCHAR szText[256];
- ::LoadStringW(g_hInst, IDS_LANGUAGEBAR, szText, _countof(szText));
+ ::LoadStringW(g_hInst, IDS_LANGUAGEBAR, szText, _countof(szText));
return ::SysAllocString(szText);
}
@@ -4272,9 +4532,25 @@ STDMETHODIMP_(void) CTipbarWnd::OnCreate(HWND hWnd)
{
}
-/// @unimplemented
STDMETHODIMP_(void) CTipbarWnd::OnDestroy(HWND hWnd)
{
+ CancelMenu();
+
+ if (m_pTipbarAccessible)
+ m_pTipbarAccessible->NotifyWinEvent(EVENT_OBJECT_DESTROY, GetAccItem());
+
+ OnTerminateToolbar();
+ if (m_pTipbarAccessible)
+ {
+ m_pTipbarAccessible->ClearAccItems();
+ m_pTipbarAccessible->Release();
+ m_pTipbarAccessible = NULL;
+ }
+
+ m_coInit.CoUninit();
+
+ if (m_pLangBarMgr)
+ m_pLangBarMgr->UnAdviseEventSink(m_dwSinkCookie);
}
/// @unimplemented
@@ -4288,9 +4564,13 @@ STDMETHODIMP_(void) CTipbarWnd::OnSysColorChange()
SetTimer(7, g_uTimerElapseSYSCOLORCHANGED);
}
-/// @unimplemented
void CTipbarWnd::OnTerminateToolbar()
{
+ m_dwTipbarWndFlags |= 0x10000;
+ DestroyOverScreenSizeBalloon();
+ TerminateAllThreads(TRUE);
+ if (!(m_dwTipbarWndFlags & 0x2))
+ SavePosition();
}
STDMETHODIMP_(void) CTipbarWnd::OnEndSession(HWND hWnd, WPARAM wParam, LPARAM lParam)
@@ -4349,11 +4629,22 @@ CTipbarWnd::OnWindowPosChanging(HWND hWnd, UINT uMsg, WPARAM
wParam, LPARAM lPar
return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
}
-/// @unimplemented
STDMETHODIMP_(LRESULT)
CTipbarWnd::OnShowWindow(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
- return 0;
+ if (m_pTipbarAccessible)
+ {
+ if (wParam) // Show?
+ {
+ m_pTipbarAccessible->NotifyWinEvent(EVENT_OBJECT_SHOW, GetAccItem());
+ m_pTipbarAccessible->NotifyWinEvent(EVENT_OBJECT_FOCUS, GetAccItem());
+ }
+ else
+ {
+ m_pTipbarAccessible->NotifyWinEvent(EVENT_OBJECT_HIDE, GetAccItem());
+ }
+ }
+ return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
}
STDMETHODIMP_(LRESULT)
@@ -4378,11 +4669,33 @@ CTipbarWnd::OnDisplayChange(HWND hWnd, UINT uMsg, WPARAM wParam,
LPARAM lParam)
return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
}
-/// @unimplemented
STDMETHODIMP_(HRESULT)
CTipbarWnd::OnGetObject(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
- return E_NOTIMPL;
+ if (lParam != -4)
+ return S_OK;
+ if (!m_pTipbarAccessible)
+ return E_OUTOFMEMORY;
+
+ if (m_pTipbarAccessible->m_bInitialized)
+ return m_pTipbarAccessible->CreateRefToAccObj(wParam);
+
+ HRESULT hr = S_OK;
+ if (SUCCEEDED(m_coInit.EnsureCoInit()))
+ {
+ hr = m_pTipbarAccessible->Initialize();
+ if (FAILED(hr))
+ {
+ m_pTipbarAccessible->Release();
+ m_pTipbarAccessible = NULL;
+ return hr;
+ }
+
+ m_pTipbarAccessible->NotifyWinEvent(EVENT_OBJECT_CREATE, GetAccItem());
+ return m_pTipbarAccessible->CreateRefToAccObj(wParam);
+ }
+
+ return hr;
}
STDMETHODIMP_(BOOL) CTipbarWnd::OnEraseBkGnd(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
lParam)
diff --git a/dll/win32/msutb/precomp.h b/dll/win32/msutb/precomp.h
index 05b2a826e27..08b64cdd9fb 100644
--- a/dll/win32/msutb/precomp.h
+++ b/dll/win32/msutb/precomp.h
@@ -17,6 +17,7 @@
#include <oleacc.h>
#include <imm.h>
#include <ddk/immdev.h>
+#include <undocuser.h>
#include <cguid.h>
#include <msctf.h>
#include <ctffunc.h>