Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

667 lines
18 KiB

//
// utb.cpp
//
#include "private.h"
#include "tim.h"
#include "utb.h"
#include "ithdmshl.h"
#include "shlapip.h"
#include "cregkey.h"
#include "assembly.h"
#include "mui.h"
#include "timlist.h"
#include "compart.h"
#include "tlapi.h"
HWND g_hwndTray = NULL;
HWND g_hwndNotify = NULL;
HWND g_hwndSysTabControlInTray = NULL;
DWORD g_dwThreadIdTray = NULL;
DBG_ID_INSTANCE(CLangBarMgr);
//////////////////////////////////////////////////////////////////////////////
//
// misc func
//
//////////////////////////////////////////////////////////////////////////////
ALLOWSETFOREGROUNDWINDOW EnsureAllowSetForeground()
{
static ALLOWSETFOREGROUNDWINDOW g_fnAllowSetForeground = NULL;
if (!g_fnAllowSetForeground)
{
HINSTANCE hUser32 = GetSystemModuleHandle("USER32");
if (hUser32)
g_fnAllowSetForeground = (ALLOWSETFOREGROUNDWINDOW)GetProcAddress(hUser32, "AllowSetForegroundWindow");
}
return g_fnAllowSetForeground;
}
REGISTERSYSTEMTHREAD EnsureRegSys()
{
static REGISTERSYSTEMTHREAD g_fnRegSys = NULL;
if (!g_fnRegSys)
{
HINSTANCE hUser32 = GetSystemModuleHandle("USER32");
if (hUser32)
g_fnRegSys = (REGISTERSYSTEMTHREAD)GetProcAddress(hUser32, "RegisterSystemThread");
}
return g_fnRegSys;
}
//---------------------------------------------------------------------------
//
// BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam)
//
// Look at the class names using GetClassName to see if you can find the
// Tray notification Window.
//
//---------------------------------------------------------------------------
static const TCHAR c_szNotifyWindow[] = TEXT("TrayNotifyWnd");
static const TCHAR c_szSysTabControl32[] = TEXT("SysTabControl32");
BOOL CALLBACK EnumChildWndProc(HWND hwnd, LPARAM lParam)
{
char szString[50];
if (!GetClassName(hwnd, (LPSTR) szString, sizeof(szString)))
return FALSE;
if (!lstrcmp(szString, c_szNotifyWindow))
{
g_hwndNotify = hwnd;
}
else if (!lstrcmp(szString, c_szSysTabControl32))
{
g_hwndSysTabControlInTray = hwnd;
return FALSE;
}
return TRUE;
}
BOOL FindTrayEtc()
{
if (g_hwndTray)
return TRUE;
g_hwndTray = FindWindow(TEXT(WNDCLASS_TRAYNOTIFY), NULL);
if (!g_hwndTray)
{
return FALSE;
}
EnumChildWindows(g_hwndTray, (WNDENUMPROC)EnumChildWndProc, (LPARAM)0);
if (!g_hwndNotify)
{
return FALSE;
}
g_dwThreadIdTray = GetWindowThreadProcessId(g_hwndTray, NULL);
return TRUE;
}
BOOL IsNotifyTrayWnd(HWND hWnd)
{
FindTrayEtc();
HWND hwndParent = hWnd;
while (hwndParent)
{
if (hwndParent == g_hwndNotify)
return TRUE;
if (hwndParent == g_hwndSysTabControlInTray)
return TRUE;
hwndParent = GetParent(hwndParent);
}
return FALSE;
}
//+---------------------------------------------------------------------------
//
// LangbarClosed
//
//----------------------------------------------------------------------------
void LangBarClosed()
{
SYSTHREAD *psfn;
CThreadInputMgr *ptim;
if (!(psfn = GetSYSTHREAD()))
return;
ptim = CThreadInputMgr::_GetThisFromSYSTHREAD(psfn);
if (!ptim)
return;
MySetCompartmentDWORD(g_gaSystem,
ptim,
GUID_COMPARTMENT_HANDWRITING_OPENCLOSE,
0);
MySetCompartmentDWORD(g_gaSystem,
ptim,
GUID_COMPARTMENT_KEYBOARD_OPENCLOSE,
0);
MySetCompartmentDWORD(g_gaSystem,
ptim->GetGlobalComp(),
GUID_COMPARTMENT_SPEECH_OPENCLOSE,
0);
}
//////////////////////////////////////////////////////////////////////////////
//
// CLangBarMgr
//
//////////////////////////////////////////////////////////////////////////////
//+---------------------------------------------------------------------------
//
// ctor
//
//----------------------------------------------------------------------------
CLangBarMgr::CLangBarMgr()
{
Dbg_MemSetThisNameID(TEXT("CLangBarMgr"));
}
//+---------------------------------------------------------------------------
//
// dtor
//
//----------------------------------------------------------------------------
CLangBarMgr::~CLangBarMgr()
{
}
//+---------------------------------------------------------------------------
//
// GetThreadMarshallInterface
//
//----------------------------------------------------------------------------
STDAPI CLangBarMgr::GetThreadMarshalInterface(DWORD dwThreadId, DWORD dwType, REFIID riid, IUnknown **ppunk)
{
return ::GetThreadMarshalInterface(dwThreadId, dwType, riid, ppunk);
}
//+---------------------------------------------------------------------------
//
// GetThreadLangBarItemMgr
//
//----------------------------------------------------------------------------
STDAPI CLangBarMgr::GetThreadLangBarItemMgr(DWORD dwThreadId, ITfLangBarItemMgr **pplbi, DWORD *pdwThreadId)
{
return ::GetThreadUIManager(dwThreadId, pplbi, pdwThreadId);
}
//+---------------------------------------------------------------------------
//
// GetInputProcessotProdiles
//
//----------------------------------------------------------------------------
STDAPI CLangBarMgr::GetInputProcessorProfiles(DWORD dwThreadId, ITfInputProcessorProfiles **ppaip, DWORD *pdwThreadId)
{
return ::GetInputProcessorProfiles(dwThreadId, ppaip, pdwThreadId);
}
//+---------------------------------------------------------------------------
//
// AadviseEventSink
//
//----------------------------------------------------------------------------
STDAPI CLangBarMgr::AdviseEventSink(ITfLangBarEventSink *pSink, HWND hwnd, DWORD dwFlags, DWORD *pdwCookie)
{
HRESULT hr;
if (!pSink)
return E_INVALIDARG;
hr = RegisterLangBarNotifySink(pSink, hwnd, dwFlags, pdwCookie);
if (SUCCEEDED(hr))
{
OnForegroundChanged(NULL);
DWORD dwActiveThreadId = GetSharedMemory()->dwFocusThread;
if (dwActiveThreadId)
{
PostThreadMessage(dwActiveThreadId,
g_msgPrivate,
TFPRIV_REGISTEREDNEWLANGBAR,
0);
}
}
return hr;
}
//+---------------------------------------------------------------------------
//
// UnadviseEventSink
//
//----------------------------------------------------------------------------
STDAPI CLangBarMgr::UnadviseEventSink(DWORD dwCookie)
{
return UnregisterLangBarNotifySink(dwCookie);
}
//+---------------------------------------------------------------------------
//
// RestoreLastFocus
//
//----------------------------------------------------------------------------
STDAPI CLangBarMgr::RestoreLastFocus(DWORD *pdwThreadId, BOOL fPrev)
{
DWORD dwThreadTarget;
HWND hwndTarget;
BOOL bRet = FALSE;
SYSTHREAD *psfn;
TL_THREADINFO *ptiTarget = NULL;
FindTrayEtc();
if (pdwThreadId)
*pdwThreadId = 0;
if ((fPrev && GetSharedMemory()->hwndForegroundPrev && (g_dwThreadIdTray == GetSharedMemory()->dwFocusThread)) || !GetSharedMemory()->hwndForeground)
{
dwThreadTarget = GetSharedMemory()->dwFocusThreadPrev;
hwndTarget = GetSharedMemory()->hwndForegroundPrev;
}
else
{
dwThreadTarget = GetSharedMemory()->dwFocusThread;
hwndTarget = GetSharedMemory()->hwndForeground;
}
//
// call RegisterSystemThread() is one bad way to allow SetForeground()
// under Win98.
//
if (IsOn98())
{
REGISTERSYSTEMTHREAD fnRegSys = EnsureRegSys();
if (fnRegSys)
fnRegSys(0, 0);
}
#if 0
else if (IsOnNT5())
{
ALLOWSETFOREGROUNDWINDOW fnAllowSetForeground = EnsureAllowSetForeground();
if (fnAllowSetForeground)
bRet = fnAllowSetForeground(ASFW_ANY);
#ifdef DEBUG
if (!bRet)
{
TraceMsg(TF_GENERAL, "AllowForegroundWindow failed thread - %x hwnd - %x", dwThreadTarget, hwndTarget);
}
#endif
}
#endif
//
// RestoreLastFocus() is called in the notify message of TrayIcon.
// sending message to tray icon area thread causes dead lock on Win9x.
//
ptiTarget = g_timlist.IsThreadId(dwThreadTarget);
psfn = GetSYSTHREAD();
if (ptiTarget &&
psfn &&
(ptiTarget->dwMarshalWaitingThread != psfn->dwThreadId))
{
TL_THREADINFO *ptiCur = NULL;
if (psfn->pti && (psfn->pti->dwThreadId == psfn->dwThreadId))
ptiCur = psfn->pti;
if (ptiCur)
ptiCur->dwFlags |= TLF_INSFW;
bRet = SetForegroundWindow(hwndTarget);
if (ptiCur)
ptiCur->dwFlags &= ~TLF_INSFW;
}
#ifdef DEBUG
if (!bRet)
{
TraceMsg(TF_GENERAL, "SetForegroundWindow failed thread - %x hwnd - %x", dwThreadTarget, hwndTarget);
}
#endif
if (bRet && pdwThreadId)
*pdwThreadId = dwThreadTarget;
// Issue:
// we want to restore the focus, too. But we need to go to the target
// thread to call SetFocus()....
// SetFocus(g_hwndFocus);
return bRet ? S_OK : S_FALSE;
}
//+---------------------------------------------------------------------------
//
// SetModalInput
//
//----------------------------------------------------------------------------
STDAPI CLangBarMgr::SetModalInput(ITfLangBarEventSink *pSink, DWORD dwThreadId, DWORD dwFlags)
{
SetModalLBarSink(dwThreadId, pSink ? TRUE : NULL, dwFlags);
return S_OK;
}
//+---------------------------------------------------------------------------
//
// ShowFloating
//
//----------------------------------------------------------------------------
#define REG_TF_SFT_SHOWNORMAL (DWORD)0
#define REG_TF_SFT_DOCK (DWORD)1
#define REG_TF_SFT_MINIMIZED (DWORD)2
#define REG_TF_SFT_HIDDEN (DWORD)3
#define REG_TF_SFT_DESKBAND (DWORD)4
#define TF_SFT_BITS_SHOWSTATUS (TF_SFT_SHOWNORMAL | TF_SFT_DOCK | TF_SFT_MINIMIZED | TF_SFT_HIDDEN | TF_SFT_DESKBAND)
#define TF_SFT_BITS_TRANSPARENCY (TF_SFT_NOTRANSPARENCY | TF_SFT_LOWTRANSPARENCY | TF_SFT_HIGHTRANSPARENCY)
#define TF_SFT_BITS_LABELS (TF_SFT_LABELS | TF_SFT_NOLABELS)
#define TF_SFT_BITS_EXTRAICONSONMINIMIZED (TF_SFT_EXTRAICONSONMINIMIZED | TF_SFT_NOEXTRAICONSONMINIMIZED)
STDAPI CLangBarMgr::ShowFloating(DWORD dwFlags)
{
//
// check params
//
if (!CheckFloatingBits(dwFlags))
return E_INVALIDARG;
return s_ShowFloating(dwFlags);
}
__inline BOOL IsNotPowerOf2(DWORD dw)
{
return (dw & (dw - 1));
}
BOOL CLangBarMgr::CheckFloatingBits(DWORD dwBits)
{
//
// we allow only one bit in each group.
// if there are two or more bits are set there, return FALSE.
//
if (IsNotPowerOf2(dwBits & TF_SFT_BITS_SHOWSTATUS))
return FALSE;
if (IsNotPowerOf2(dwBits & TF_SFT_BITS_TRANSPARENCY))
return FALSE;
if (IsNotPowerOf2(dwBits & TF_SFT_BITS_LABELS))
return FALSE;
if (IsNotPowerOf2(dwBits & TF_SFT_BITS_EXTRAICONSONMINIMIZED))
return FALSE;
return TRUE;
}
HRESULT CLangBarMgr::s_ShowFloating(DWORD dwFlags)
{
DWORD dwStatus;
CMyRegKey key;
//
// keep tracking the prev show floating sttaus.
//
if (SUCCEEDED(s_GetShowFloatingStatus(&dwStatus)))
GetSharedMemory()->dwPrevShowFloatingStatus = dwStatus;
if (key.Create(HKEY_CURRENT_USER, c_szLangBarKey) != S_OK)
return E_FAIL;
if (dwFlags & TF_SFT_SHOWNORMAL)
{
key.SetValue(REG_TF_SFT_SHOWNORMAL, c_szShowStatus);
}
else if (dwFlags & TF_SFT_DOCK)
{
key.SetValue(REG_TF_SFT_DOCK, c_szShowStatus);
}
else if (dwFlags & TF_SFT_MINIMIZED)
{
key.SetValue(REG_TF_SFT_MINIMIZED, c_szShowStatus);
}
else if (dwFlags & TF_SFT_HIDDEN)
{
key.SetValue(REG_TF_SFT_HIDDEN, c_szShowStatus);
}
else if (dwFlags & TF_SFT_DESKBAND)
{
key.SetValue(REG_TF_SFT_DESKBAND, c_szShowStatus);
}
if (dwFlags & TF_SFT_NOTRANSPARENCY)
{
key.SetValue((DWORD)255, c_szTransparency);
}
else if (dwFlags & TF_SFT_LOWTRANSPARENCY)
{
key.SetValue((DWORD)128, c_szTransparency);
}
else if (dwFlags & TF_SFT_HIGHTRANSPARENCY)
{
key.SetValue((DWORD)64, c_szTransparency);
}
if (dwFlags & TF_SFT_LABELS)
{
key.SetValue((DWORD)1, c_szLabel);
}
else if (dwFlags & TF_SFT_NOLABELS)
{
key.SetValue((DWORD)0, c_szLabel);
}
if (dwFlags & TF_SFT_EXTRAICONSONMINIMIZED)
{
key.SetValue((DWORD)1, c_szExtraIconsOnMinimized);
}
else if (dwFlags & TF_SFT_NOEXTRAICONSONMINIMIZED)
{
key.SetValue((DWORD)0, c_szExtraIconsOnMinimized);
}
if (SUCCEEDED(s_GetShowFloatingStatus(&dwStatus)))
MakeSetFocusNotify(g_msgShowFloating, 0, (LPARAM)dwStatus);
if (dwStatus & TF_SFT_HIDDEN)
PostTimListMessage(TLF_TIMACTIVE, 0, g_msgPrivate, TFPRIV_LANGBARCLOSED, 0);
return S_OK;
}
//+---------------------------------------------------------------------------
//
// GetShowFloatingStatus
//
//----------------------------------------------------------------------------
STDAPI CLangBarMgr::GetShowFloatingStatus(DWORD *pdwFlags)
{
if (!pdwFlags)
return E_INVALIDARG;
return s_GetShowFloatingStatus(pdwFlags);
}
//+---------------------------------------------------------------------------
//
// GetPrevShowFloatingStatus
//
//----------------------------------------------------------------------------
STDAPI CLangBarMgr::GetPrevShowFloatingStatus(DWORD *pdwFlags)
{
if (!pdwFlags)
return E_INVALIDARG;
DWORD dwFlags;
if (!GetSharedMemory()->dwPrevShowFloatingStatus)
{
s_GetShowFloatingStatus(&dwFlags);
GetSharedMemory()->dwPrevShowFloatingStatus = dwFlags;
}
*pdwFlags = GetSharedMemory()->dwPrevShowFloatingStatus;
return S_OK;
}
HRESULT CLangBarMgr::s_GetShowFloatingStatus(DWORD *pdwFlags)
{
CMyRegKey key;
DWORD dwFlags = 0;
if (!pdwFlags)
return E_INVALIDARG;
if (key.Open(HKEY_CURRENT_USER, c_szLangBarKey, KEY_READ) != S_OK)
{
// return default.
if (IsFELangId(GetPlatformResourceLangID()))
*pdwFlags = (TF_SFT_SHOWNORMAL |
TF_SFT_NOTRANSPARENCY |
TF_SFT_NOLABELS |
TF_SFT_EXTRAICONSONMINIMIZED);
else
{
if (IsOnNT51())
{
*pdwFlags = (TF_SFT_DESKBAND |
TF_SFT_NOTRANSPARENCY |
TF_SFT_LABELS |
TF_SFT_NOEXTRAICONSONMINIMIZED);
}
else
{
*pdwFlags = (TF_SFT_SHOWNORMAL |
TF_SFT_NOTRANSPARENCY |
TF_SFT_LABELS |
TF_SFT_NOEXTRAICONSONMINIMIZED);
}
}
return S_OK;
}
DWORD dw;
dw = 0;
if (key.QueryValue(dw, c_szShowStatus) == S_OK)
{
switch (dw)
{
case REG_TF_SFT_SHOWNORMAL: dwFlags |= TF_SFT_SHOWNORMAL; break;
case REG_TF_SFT_DOCK: dwFlags |= TF_SFT_DOCK; break;
case REG_TF_SFT_MINIMIZED:
//
// BugBug#452872 - Only take care of GetShowFloating case,
// since SetShowFloating require the regression testing.
// This is simple fix to support the upgrade Window XP from the
// minimized language UI status platform.
//
dwFlags |= IsOnNT51() ? TF_SFT_DESKBAND : TF_SFT_MINIMIZED;
break;
case REG_TF_SFT_HIDDEN: dwFlags |= TF_SFT_HIDDEN; break;
case REG_TF_SFT_DESKBAND: dwFlags |= TF_SFT_DESKBAND; break;
default: dwFlags |= TF_SFT_SHOWNORMAL; break;
}
}
else
{
if (IsOnNT51() && !IsFELangId(GetPlatformResourceLangID()))
{
dwFlags |= TF_SFT_DESKBAND;
}
else
{
dwFlags |= TF_SFT_SHOWNORMAL;
}
}
dw = 0;
if (key.QueryValue(dw, c_szTransparency) == S_OK)
{
switch (dw)
{
case 255: dwFlags |= TF_SFT_NOTRANSPARENCY; break;
case 128: dwFlags |= TF_SFT_LOWTRANSPARENCY; break;
case 64: dwFlags |= TF_SFT_HIGHTRANSPARENCY; break;
default: dwFlags |= TF_SFT_NOTRANSPARENCY; break;
}
}
else
{
dwFlags |= TF_SFT_NOTRANSPARENCY;
}
dw = 0;
if (key.QueryValue(dw, c_szLabel) == S_OK)
{
switch (dw)
{
case 1: dwFlags |= TF_SFT_LABELS; break;
default: dwFlags |= TF_SFT_NOLABELS; break;
}
}
else
{
if (IsFELangId(GetPlatformResourceLangID()))
dwFlags |= TF_SFT_NOLABELS;
else
dwFlags |= TF_SFT_LABELS;
}
dw = 0;
if (key.QueryValue(dw, c_szExtraIconsOnMinimized) == S_OK)
{
switch (dw)
{
case 1: dwFlags |= TF_SFT_EXTRAICONSONMINIMIZED; break;
default: dwFlags |= TF_SFT_NOEXTRAICONSONMINIMIZED; break;
}
}
else
{
if (IsFELangId(GetPlatformResourceLangID()))
dwFlags |= TF_SFT_EXTRAICONSONMINIMIZED;
else
dwFlags |= TF_SFT_NOEXTRAICONSONMINIMIZED;
}
*pdwFlags = dwFlags;
return S_OK;
}