Reactos
at master 6529 lines 164 kB view raw
1/* 2 * PROJECT: ReactOS msutb.dll 3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) 4 * PURPOSE: Language Bar (Tipbar) 5 * COPYRIGHT: Copyright 2023-2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com> 6 */ 7 8#include "precomp.h" 9 10WINE_DEFAULT_DEBUG_CHANNEL(msutb); 11 12//#define ENABLE_DESKBAND 13 14typedef struct LANGBARITEMSTATE 15{ 16 CLSID m_clsid; 17 DWORD m_dwDemoteLevel; 18 UINT_PTR m_nTimerID; 19 UINT m_uTimeOut; 20 BOOL m_bStartedIntentionally; 21 BOOL m_bDisableDemoting; 22 23 BOOL IsShown() 24 { 25 return m_dwDemoteLevel < 2; 26 } 27} LANGBARITEMSTATE, *PLANGBARITEMSTATE; 28 29HINSTANCE g_hInst = NULL; 30UINT g_wmTaskbarCreated = 0; 31UINT g_uACP = CP_ACP; 32DWORD g_dwOSInfo = 0; 33CRITICAL_SECTION g_cs; 34LONG g_DllRefCount = 0; 35BOOL g_bWinLogon = FALSE; 36BOOL g_fInClosePopupTipbar = FALSE; 37HWND g_hwndParent = NULL; 38CIC_LIBTHREAD g_libTLS = { NULL, NULL }; 39#ifdef ENABLE_DESKBAND 40BOOL g_bEnableDeskBand = TRUE; 41#else 42BOOL g_bEnableDeskBand = FALSE; 43#endif 44 45BOOL g_bShowTipbar = TRUE; 46BOOL g_bShowDebugMenu = FALSE; 47BOOL g_bNewLook = TRUE; 48BOOL g_bIntelliSense = FALSE; 49BOOL g_bShowCloseMenu = FALSE; 50UINT g_uTimeOutNonIntentional = 60 * 1000; 51UINT g_uTimeOutIntentional = 10 * 60 * 1000; 52UINT g_uTimeOutMax = 60 * 60 * 1000; 53BOOL g_bShowMinimizedBalloon = TRUE; 54POINT g_ptTipbar = { -1, -1 }; 55BOOL g_bExcludeCaptionButtons = TRUE; 56BOOL g_bShowShadow = FALSE; 57BOOL g_fTaskbarTheme = TRUE; 58BOOL g_fVertical = FALSE; 59UINT g_uTimerElapseSTUBSTART = 100; 60UINT g_uTimerElapseSTUBEND = 2 * 1000; 61UINT g_uTimerElapseBACKTOALPHA = 3 * 1000; 62UINT g_uTimerElapseONTHREADITEMCHANGE = 200; 63UINT g_uTimerElapseSETWINDOWPOS = 100; 64UINT g_uTimerElapseONUPDATECALLED = 50; 65UINT g_uTimerElapseSYSCOLORCHANGED = 20; 66UINT g_uTimerElapseDISPLAYCHANGE = 20; 67UINT g_uTimerElapseUPDATEUI = 70; 68UINT g_uTimerElapseSHOWWINDOW = 50; 69UINT g_uTimerElapseMOVETOTRAY = 50; 70UINT g_uTimerElapseTRAYWNDONDELAYMSG = 50; 71UINT g_uTimerElapseDOACCDEFAULTACTION = 200; 72UINT g_uTimerElapseENSUREFOCUS = 50; 73BOOL g_bShowDeskBand = FALSE; 74UINT g_uTimerElapseSHOWDESKBAND = 3 * 1000; 75BOOL g_fPolicyDisableCloseButton = FALSE; 76BOOL g_fPolicyEnableLanguagebarInFullscreen = FALSE; 77DWORD g_dwWndStyle = 0; 78DWORD g_dwMenuStyle = 0; 79DWORD g_dwChildWndStyle = 0; 80BOOL g_fRTL = FALSE; 81 82#define TIMER_ID_DOACCDEFAULTACTION 11 83 84class CMsUtbModule : public CComModule 85{ 86}; 87 88CMsUtbModule gModule; 89 90class CCicLibMenuItem; 91class CTipbarAccItem; 92class CUTBMenuItem; 93class CMainIconItem; 94class CTrayIconItem; 95class CTipbarWnd; 96class CButtonIconItem; 97class CTrayIconWnd; 98 99CTipbarWnd *g_pTipbarWnd = NULL; 100CTrayIconWnd *g_pTrayIconWnd = NULL; 101 102CicArray<HKL> *g_prghklSkipRedrawing = NULL; 103 104BOOL IsSkipRedrawHKL(HKL hSkipKL) 105{ 106 if (LOWORD(hSkipKL) == MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT)) 107 return FALSE; // Japanese HKL will be skipped 108 if (!g_prghklSkipRedrawing) 109 return FALSE; 110 111 for (size_t iItem = 0; iItem < g_prghklSkipRedrawing->size(); ++iItem) 112 { 113 if ((*g_prghklSkipRedrawing)[iItem] == hSkipKL) 114 return TRUE; // To be skipped 115 } 116 117 return FALSE; // To be not skipped 118} 119 120BOOL IsBiDiLocalizedSystem(void) 121{ 122 LOCALESIGNATURE Sig; 123 LANGID LangID = ::GetUserDefaultUILanguage(); 124 if (!LangID) 125 return FALSE; 126 127 INT size = sizeof(Sig) / sizeof(WCHAR); 128 if (!::GetLocaleInfoW(LangID, LOCALE_FONTSIGNATURE, (LPWSTR)&Sig, size)) 129 return FALSE; 130 return (Sig.lsUsb[3] & 0x8000000) != 0; 131} 132 133BOOL GetFontSig(HWND hWnd, HKL hKL) 134{ 135 LOCALESIGNATURE Sig; 136 INT size = sizeof(Sig) / sizeof(WCHAR); 137 if (!::GetLocaleInfoW(LOWORD(hKL), LOCALE_FONTSIGNATURE, (LPWSTR)&Sig, size)) 138 return FALSE; 139 140 HDC hDC = ::GetDC(hWnd); 141 DWORD CharSet = ::GetTextCharsetInfo(hDC, NULL, 0); 142 CHARSETINFO CharSetInfo; 143 ::TranslateCharsetInfo((DWORD*)(DWORD_PTR)CharSet, &CharSetInfo, TCI_SRCCHARSET); 144 ::ReleaseDC(hWnd, hDC); 145 146 return !!(CharSetInfo.fs.fsCsb[0] & Sig.lsCsbSupported[0]); 147} 148 149void InitSkipRedrawHKLArray(void) 150{ 151 g_prghklSkipRedrawing = new(cicNoThrow) CicArray<HKL>(); 152 if (!g_prghklSkipRedrawing) 153 return; 154 155 if (g_bEnableDeskBand && (g_dwOSInfo & CIC_OSINFO_XPPLUS)) 156 { 157 // Japanese IME will be skipped 158 g_prghklSkipRedrawing->Add((HKL)UlongToHandle(0xE0010411)); 159 } 160 161 CicRegKey regKey; 162 LSTATUS error = regKey.Open(HKEY_LOCAL_MACHINE, 163 TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\SkipRedrawHKL")); 164 if (error != ERROR_SUCCESS) 165 return; 166 167 TCHAR szValueName[256]; 168 for (DWORD dwIndex = 0; ; ++dwIndex) 169 { 170 error = regKey.EnumValue(dwIndex, szValueName, _countof(szValueName)); 171 if (error != ERROR_SUCCESS) 172 break; 173 174 if (szValueName[0] == TEXT('0') && 175 (szValueName[1] == TEXT('x') || szValueName[1] == TEXT('X'))) 176 { 177 HKL hKL = (HKL)UlongToHandle(_tcstoul(szValueName, NULL, 16)); 178 g_prghklSkipRedrawing->Add(hKL); // This hKL will be skipped 179 } 180 } 181} 182 183void UninitSkipRedrawHKLArray(void) 184{ 185 if (g_prghklSkipRedrawing) 186 { 187 delete g_prghklSkipRedrawing; 188 g_prghklSkipRedrawing = NULL; 189 } 190} 191 192HRESULT GetGlobalCompartment(REFGUID rguid, ITfCompartment **ppComp) 193{ 194 ITfCompartmentMgr *pCompMgr = NULL; 195 HRESULT hr = TF_GetGlobalCompartment(&pCompMgr); 196 if (FAILED(hr)) 197 return hr; 198 199 if (!pCompMgr) 200 return E_FAIL; 201 202 hr = pCompMgr->GetCompartment(rguid, ppComp); 203 pCompMgr->Release(); 204 return hr; 205} 206 207HRESULT GetGlobalCompartmentDWORD(REFGUID rguid, LPDWORD pdwValue) 208{ 209 *pdwValue = 0; 210 ITfCompartment *pComp; 211 HRESULT hr = GetGlobalCompartment(rguid, &pComp); 212 if (SUCCEEDED(hr)) 213 { 214 VARIANT vari; 215 hr = pComp->GetValue(&vari); 216 if (hr == S_OK) 217 *pdwValue = V_I4(&vari); 218 pComp->Release(); 219 } 220 return hr; 221} 222 223HRESULT SetGlobalCompartmentDWORD(REFGUID rguid, DWORD dwValue) 224{ 225 VARIANT vari; 226 ITfCompartment *pComp; 227 HRESULT hr = GetGlobalCompartment(rguid, &pComp); 228 if (SUCCEEDED(hr)) 229 { 230 V_VT(&vari) = VT_I4; 231 V_I4(&vari) = dwValue; 232 hr = pComp->SetValue(0, &vari); 233 pComp->Release(); 234 } 235 return hr; 236} 237 238void TurnOffSpeechIfItsOn(void) 239{ 240 DWORD dwValue = 0; 241 HRESULT hr = GetGlobalCompartmentDWORD(GUID_COMPARTMENT_SPEECH_OPENCLOSE, &dwValue); 242 if (SUCCEEDED(hr) && dwValue) 243 SetGlobalCompartmentDWORD(GUID_COMPARTMENT_SPEECH_OPENCLOSE, 0); 244} 245 246void DoCloseLangbar(void) 247{ 248 ITfLangBarMgr *pLangBarMgr = NULL; 249 HRESULT hr = TF_CreateLangBarMgr(&pLangBarMgr); 250 if (FAILED(hr)) 251 return; 252 253 if (pLangBarMgr) 254 { 255 hr = pLangBarMgr->ShowFloating(TF_SFT_HIDDEN); 256 pLangBarMgr->Release(); 257 } 258 259 if (SUCCEEDED(hr)) 260 TurnOffSpeechIfItsOn(); 261 262 CicRegKey regKey; 263 LSTATUS error = regKey.Open(HKEY_CURRENT_USER, 264 TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Run"), 265 KEY_ALL_ACCESS); 266 if (error == ERROR_SUCCESS) 267 ::RegDeleteValue(regKey, TEXT("ctfmon.exe")); 268} 269 270INT GetIconIndexFromhKL(_In_ HKL hKL) 271{ 272 HKL hGotKL; 273 274 INT iKL, cKLs = TF_MlngInfoCount(); 275 for (iKL = 0; iKL < cKLs; ++iKL) 276 { 277 if (TF_GetMlngHKL(iKL, &hGotKL, NULL, 0) && hKL == hGotKL) 278 return TF_GetMlngIconIndex(iKL); 279 } 280 281 if (!TF_GetMlngHKL(0, &hGotKL, NULL, 0)) 282 return -1; 283 284 return TF_GetMlngIconIndex(0); 285} 286 287BOOL GethKLDesc(_In_ HKL hKL, _Out_ LPWSTR pszDesc, _In_ UINT cchDesc) 288{ 289 HKL hGotKL; 290 291 INT iKL, cKLs = TF_MlngInfoCount(); 292 for (iKL = 0; iKL < cKLs; ++iKL) 293 { 294 if (TF_GetMlngHKL(iKL, &hGotKL, pszDesc, cchDesc) && hKL == hGotKL) 295 return TRUE; 296 } 297 298 return TF_GetMlngHKL(0, &hGotKL, pszDesc, cchDesc); 299} 300 301HRESULT 302LangBarInsertMenu( 303 _In_ ITfMenu *pMenu, 304 _In_ UINT uId, 305 _In_ LPCWSTR pszText, 306 _In_ BOOL bChecked, 307 _Inout_opt_ HICON hIcon) 308{ 309 HBITMAP hbmp = NULL, hbmpMask = NULL; 310 if (hIcon) 311 { 312 HICON hIconNew = (HICON)::CopyImage(hIcon, IMAGE_ICON, 16, 16, LR_COPYFROMRESOURCE); 313 SIZE iconSize = { 16, 16 }; 314 if (!hIconNew) 315 hIconNew = hIcon; 316 if (!cicGetIconBitmaps(hIconNew, &hbmp, &hbmpMask, &iconSize)) 317 return E_FAIL; 318 if (hIconNew) 319 ::DestroyIcon(hIconNew); 320 ::DestroyIcon(hIcon); 321 } 322 323 INT cchText = lstrlenW(pszText); 324 DWORD dwFlags = (bChecked ? TF_LBMENUF_CHECKED : 0); 325 return pMenu->AddMenuItem(uId, dwFlags, hbmp, hbmpMask, pszText, cchText, NULL); 326} 327 328HRESULT LangBarInsertSeparator(_In_ ITfMenu *pMenu) 329{ 330 return pMenu->AddMenuItem(-1, TF_LBMENUF_SEPARATOR, NULL, NULL, NULL, 0, NULL); 331} 332 333// Is it a Far-East language ID? 334BOOL IsFELangId(LANGID LangID) 335{ 336 switch (LangID) 337 { 338 case MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED): // Chinese (Simplified) 339 case MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL): // Chinese (Traditional) 340 case MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT): // Japanese 341 case MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT): // Korean 342 return TRUE; 343 default: 344 return FALSE; 345 } 346} 347 348BOOL CheckCloseMenuAvailable(void) 349{ 350 BOOL ret = FALSE; 351 ITfInputProcessorProfiles *pProfiles = NULL; 352 LANGID *pLangIds = NULL; 353 ULONG iItem, cItems; 354 355 if (g_fPolicyDisableCloseButton) 356 return FALSE; 357 358 if (g_bShowCloseMenu) 359 return TRUE; 360 361 if (SUCCEEDED(TF_CreateInputProcessorProfiles(&pProfiles)) && 362 SUCCEEDED(pProfiles->GetLanguageList(&pLangIds, &cItems))) 363 { 364 for (iItem = 0; iItem < cItems; ++iItem) 365 { 366 if (IsFELangId(pLangIds[iItem])) 367 break; 368 } 369 370 ret = (iItem == cItems); 371 } 372 373 if (pLangIds) 374 CoTaskMemFree(pLangIds); 375 if (pProfiles) 376 pProfiles->Release(); 377 378 return ret; 379} 380 381/// @unimplemented 382BOOL IsTransparecyAvailable(void) 383{ 384 return FALSE; 385} 386 387static INT CALLBACK 388FindEAEnumFontProc(ENUMLOGFONT *pLF, NEWTEXTMETRIC *pTM, INT nFontType, LPARAM lParam) 389{ 390 if ((nFontType != TRUETYPE_FONTTYPE) || (pLF->elfLogFont.lfFaceName[0] != '@')) 391 return TRUE; 392 *(BOOL*)lParam = TRUE; 393 return FALSE; 394} 395 396/// Are there East-Asian vertical fonts? 397BOOL CheckEAFonts(void) 398{ 399 BOOL bHasVertical = FALSE; 400 HDC hDC = ::GetDC(NULL); 401 ::EnumFonts(hDC, NULL, (FONTENUMPROC)FindEAEnumFontProc, (LPARAM)&bHasVertical); 402 ::ReleaseDC(NULL, hDC); 403 return bHasVertical; 404} 405 406BOOL IsDeskBandFromReg() 407{ 408 if (!g_bEnableDeskBand || !(g_dwOSInfo & CIC_OSINFO_XPPLUS)) // Desk band is for XP+ 409 return FALSE; 410 411 CicRegKey regKey; 412 if (regKey.Open(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\"))) 413 { 414 DWORD dwValue = 0; 415 regKey.QueryDword(TEXT("ShowDeskBand"), &dwValue); 416 return !!dwValue; 417 } 418 419 return FALSE; 420} 421 422void SetDeskBandToReg(BOOL bShow) 423{ 424 CicRegKey regKey; 425 if (regKey.Open(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\"), KEY_ALL_ACCESS)) 426 regKey.SetDword(TEXT("ShowDeskBand"), bShow); 427} 428 429BOOL RegisterComCat(REFCLSID rclsid, REFCATID rcatid, BOOL bRegister) 430{ 431 if (FAILED(::CoInitialize(NULL))) 432 return FALSE; 433 434 ICatRegister *pCat; 435 HRESULT hr = ::CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, 436 IID_ICatRegister, (void**)&pCat); 437 if (SUCCEEDED(hr)) 438 { 439 if (bRegister) 440 hr = pCat->RegisterClassImplCategories(rclsid, 1, const_cast<CATID*>(&rcatid)); 441 else 442 hr = pCat->UnRegisterClassImplCategories(rclsid, 1, const_cast<CATID*>(&rcatid)); 443 444 pCat->Release(); 445 } 446 447 ::CoUninitialize(); 448 449 //if (IsIE5()) 450 // ::RegDeleteKey(HKEY_CLASSES_ROOT, TEXT("Component Categories\\{00021492-0000-0000-C000-000000000046}\\Enum")); 451 452 return SUCCEEDED(hr); 453} 454 455BOOL InitFromReg(void) 456{ 457 DWORD dwValue; 458 LSTATUS error; 459 460 CicRegKey regKey1; 461 error = regKey1.Open(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\")); 462 if (error == ERROR_SUCCESS) 463 { 464 error = regKey1.QueryDword(TEXT("ShowTipbar"), &dwValue); 465 if (error == ERROR_SUCCESS) 466 g_bShowTipbar = !!dwValue; 467 } 468 469 CicRegKey regKey2; 470 error = regKey2.Open(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\")); 471 if (error == ERROR_SUCCESS) 472 { 473 error = regKey2.QueryDword(TEXT("ShowDebugMenu"), &dwValue); 474 if (error == ERROR_SUCCESS) 475 g_bShowDebugMenu = !!dwValue; 476 error = regKey2.QueryDword(TEXT("NewLook"), &dwValue); 477 if (error == ERROR_SUCCESS) 478 g_bNewLook = !!dwValue; 479 error = regKey2.QueryDword(TEXT("IntelliSense"), &dwValue); 480 if (error == ERROR_SUCCESS) 481 g_bIntelliSense = !!dwValue; 482 error = regKey2.QueryDword(TEXT("ShowCloseMenu"), &dwValue); 483 if (error == ERROR_SUCCESS) 484 g_bShowCloseMenu = !!dwValue; 485 error = regKey2.QueryDword(TEXT("TimeOutNonIntentional"), &dwValue); 486 if (error == ERROR_SUCCESS) 487 g_uTimeOutNonIntentional = 1000 * dwValue; 488 error = regKey2.QueryDword(TEXT("TimeOutIntentional"), &dwValue); 489 if (error == ERROR_SUCCESS) 490 { 491 g_uTimeOutIntentional = 1000 * dwValue; 492 g_uTimeOutMax = 6000 * dwValue; 493 } 494 error = regKey2.QueryDword(TEXT("ShowMinimizedBalloon"), &dwValue); 495 if (error == ERROR_SUCCESS) 496 g_bShowMinimizedBalloon = !!dwValue; 497 error = regKey2.QueryDword(TEXT("Left"), &dwValue); 498 if (error == ERROR_SUCCESS) 499 g_ptTipbar.x = dwValue; 500 error = regKey2.QueryDword(TEXT("Top"), &dwValue); 501 if (error == ERROR_SUCCESS) 502 g_ptTipbar.y = dwValue; 503 error = regKey2.QueryDword(TEXT("ExcludeCaptionButtons"), &dwValue); 504 if (error == ERROR_SUCCESS) 505 g_bExcludeCaptionButtons = !!dwValue; 506 error = regKey2.QueryDword(TEXT("ShowShadow"), &dwValue); 507 if (error == ERROR_SUCCESS) 508 g_bShowShadow = !!dwValue; 509 error = regKey2.QueryDword(TEXT("TaskbarTheme"), &dwValue); 510 if (error == ERROR_SUCCESS) 511 g_fTaskbarTheme = !!dwValue; 512 error = regKey2.QueryDword(TEXT("Vertical"), &dwValue); 513 if (error == ERROR_SUCCESS) 514 g_fVertical = !!dwValue; 515 error = regKey2.QueryDword(TEXT("TimerElapseSTUBSTART"), &dwValue); 516 if (error == ERROR_SUCCESS) 517 g_uTimerElapseSTUBSTART = dwValue; 518 error = regKey2.QueryDword(TEXT("TimerElapseSTUBEND"), &dwValue); 519 if (error == ERROR_SUCCESS) 520 g_uTimerElapseSTUBEND = dwValue; 521 error = regKey2.QueryDword(TEXT("TimerElapseBACKTOALPHA"), &dwValue); 522 if (error == ERROR_SUCCESS) 523 g_uTimerElapseBACKTOALPHA = dwValue; 524 error = regKey2.QueryDword(TEXT("TimerElapseONTHREADITEMCHANGE"), &dwValue); 525 if (error == ERROR_SUCCESS) 526 g_uTimerElapseONTHREADITEMCHANGE = dwValue; 527 error = regKey2.QueryDword(TEXT("TimerElapseSETWINDOWPOS"), &dwValue); 528 if (error == ERROR_SUCCESS) 529 g_uTimerElapseSETWINDOWPOS = dwValue; 530 error = regKey2.QueryDword(TEXT("TimerElapseONUPDATECALLED"), &dwValue); 531 if (error == ERROR_SUCCESS) 532 g_uTimerElapseONUPDATECALLED = dwValue; 533 error = regKey2.QueryDword(TEXT("TimerElapseSYSCOLORCHANGED"), &dwValue); 534 if (error == ERROR_SUCCESS) 535 g_uTimerElapseSYSCOLORCHANGED = dwValue; 536 error = regKey2.QueryDword(TEXT("TimerElapseDISPLAYCHANGE"), &dwValue); 537 if (error == ERROR_SUCCESS) 538 g_uTimerElapseDISPLAYCHANGE = dwValue; 539 error = regKey2.QueryDword(TEXT("TimerElapseUPDATEUI"), &dwValue); 540 if (error == ERROR_SUCCESS) 541 g_uTimerElapseUPDATEUI = dwValue; 542 error = regKey2.QueryDword(TEXT("TimerElapseSHOWWINDOW"), &dwValue); 543 if (error == ERROR_SUCCESS) 544 g_uTimerElapseSHOWWINDOW = dwValue; 545 error = regKey2.QueryDword(TEXT("TimerElapseMOVETOTRAY"), &dwValue); 546 if (error == ERROR_SUCCESS) 547 g_uTimerElapseMOVETOTRAY = dwValue; 548 error = regKey2.QueryDword(TEXT("TimerElapseTRAYWNDONDELAYMSG"), &dwValue); 549 if (error == ERROR_SUCCESS) 550 g_uTimerElapseTRAYWNDONDELAYMSG = dwValue; 551 error = regKey2.QueryDword(TEXT("TimerElapseDOACCDEFAULTACTION"), &dwValue); 552 if (error == ERROR_SUCCESS) 553 g_uTimerElapseDOACCDEFAULTACTION = dwValue; 554 error = regKey2.QueryDword(TEXT("TimerElapseENSUREFOCUS"), &dwValue); 555 if (error == ERROR_SUCCESS) 556 g_uTimerElapseENSUREFOCUS = dwValue; 557 if (g_bEnableDeskBand && (g_dwOSInfo & CIC_OSINFO_XPPLUS)) 558 { 559 error = regKey2.QueryDword(TEXT("ShowDeskBand"), &dwValue); 560 if (error == ERROR_SUCCESS) 561 g_bShowDeskBand = !!dwValue; 562 error = regKey2.QueryDword(TEXT("TimerElapseSHOWWDESKBAND"), &dwValue); 563 if (error == ERROR_SUCCESS) 564 g_uTimerElapseSHOWDESKBAND = dwValue; 565 } 566 } 567 568 CicRegKey regKey3; 569 error = regKey3.Open(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Policies\\Microsoft\\MSCTF")); 570 if (error == ERROR_SUCCESS) 571 { 572 error = regKey3.QueryDword(TEXT("DisableCloseButton"), &dwValue); 573 if (error == ERROR_SUCCESS) 574 g_fPolicyDisableCloseButton = !!dwValue; 575 } 576 577 CicRegKey regKey4; 578 error = regKey4.Open(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Policies\\Microsoft\\MSCTF")); 579 if (error == ERROR_SUCCESS) 580 { 581 error = regKey4.QueryDword(TEXT("EnableLanguagebarInFullscreen"), &dwValue); 582 if (error == ERROR_SUCCESS) 583 g_fPolicyEnableLanguagebarInFullscreen = !!dwValue; 584 } 585 586 InitSkipRedrawHKLArray(); 587 588 if (g_bNewLook) 589 { 590 g_dwWndStyle = UIF_WINDOW_ENABLETHEMED | UIF_WINDOW_WORKAREA | UIF_WINDOW_TOOLTIP | 591 UIF_WINDOW_TOOLWINDOW | UIF_WINDOW_TOPMOST; 592 if (g_bShowShadow) 593 g_dwWndStyle |= UIF_WINDOW_SHADOW; 594 g_dwMenuStyle = 0x10000000 | UIF_WINDOW_MONITOR | UIF_WINDOW_SHADOW | 595 UIF_WINDOW_TOOLWINDOW | UIF_WINDOW_TOPMOST; 596 } 597 else 598 { 599 g_dwWndStyle = UIF_WINDOW_WORKAREA | UIF_WINDOW_TOOLTIP | UIF_WINDOW_DLGFRAME | 600 UIF_WINDOW_TOPMOST; 601 g_dwMenuStyle = UIF_WINDOW_MONITOR | UIF_WINDOW_DLGFRAME | UIF_WINDOW_TOPMOST; 602 } 603 604 g_dwChildWndStyle = 605 UIF_WINDOW_ENABLETHEMED | UIF_WINDOW_NOMOUSEMSG | UIF_WINDOW_TOOLTIP | UIF_WINDOW_CHILD; 606 607 if (IsBiDiLocalizedSystem()) 608 { 609 g_dwWndStyle |= UIF_WINDOW_LAYOUTRTL; 610 g_dwChildWndStyle |= UIF_WINDOW_LAYOUTRTL; 611 g_dwMenuStyle |= UIF_WINDOW_LAYOUTRTL; 612 g_fRTL = TRUE; 613 } 614 615 return TRUE; 616} 617 618/***********************************************************************/ 619 620struct CShellWndThread 621{ 622 HWND m_hTrayWnd = NULL; 623 HWND m_hProgmanWnd = NULL; 624 625 HWND GetWndTray() 626 { 627 if (!m_hTrayWnd || !::IsWindow(m_hTrayWnd)) 628 m_hTrayWnd = ::FindWindowW(L"Shell_TrayWnd", NULL); 629 return m_hTrayWnd; 630 } 631 632 HWND GetWndProgman() 633 { 634 if (!m_hProgmanWnd || !::IsWindow(m_hProgmanWnd)) 635 m_hProgmanWnd = ::FindWindowW(L"Progman", NULL); 636 return m_hProgmanWnd; 637 } 638 639 void clear() 640 { 641 m_hTrayWnd = m_hProgmanWnd = NULL; 642 } 643}; 644 645/***********************************************************************/ 646 647class CUTBLangBarDlg 648{ 649protected: 650 LPTSTR m_pszDialogName; 651 LONG m_cRefs; 652 653public: 654 CUTBLangBarDlg() { } 655 virtual ~CUTBLangBarDlg() { } 656 657 static CUTBLangBarDlg *GetThis(HWND hDlg); 658 static void SetThis(HWND hDlg, CUTBLangBarDlg *pThis); 659 static DWORD WINAPI s_ThreadProc(LPVOID pParam); 660 static INT_PTR CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); 661 662 BOOL StartThread(); 663 LONG _Release(); 664 665 STDMETHOD_(BOOL, DoModal)(HWND hDlg) = 0; 666 STDMETHOD_(BOOL, OnCommand)(HWND hDlg, WPARAM wParam, LPARAM lParam) = 0; 667 STDMETHOD_(BOOL, IsDlgShown)() = 0; 668 STDMETHOD_(void, SetDlgShown)(BOOL bShown) = 0; 669 STDMETHOD_(BOOL, ThreadProc)(); 670}; 671 672/***********************************************************************/ 673 674class CUTBCloseLangBarDlg : public CUTBLangBarDlg 675{ 676public: 677 CUTBCloseLangBarDlg(); 678 679 static BOOL s_bIsDlgShown; 680 681 STDMETHOD_(BOOL, DoModal)(HWND hDlg) override; 682 STDMETHOD_(BOOL, OnCommand)(HWND hDlg, WPARAM wParam, LPARAM lParam) override; 683 STDMETHOD_(BOOL, IsDlgShown)() override; 684 STDMETHOD_(void, SetDlgShown)(BOOL bShown) override; 685}; 686 687BOOL CUTBCloseLangBarDlg::s_bIsDlgShown = FALSE; 688 689/***********************************************************************/ 690 691class CUTBMinimizeLangBarDlg : public CUTBLangBarDlg 692{ 693public: 694 CUTBMinimizeLangBarDlg(); 695 696 static BOOL s_bIsDlgShown; 697 698 STDMETHOD_(BOOL, DoModal)(HWND hDlg) override; 699 STDMETHOD_(BOOL, OnCommand)(HWND hDlg, WPARAM wParam, LPARAM lParam) override; 700 STDMETHOD_(BOOL, IsDlgShown)() override; 701 STDMETHOD_(void, SetDlgShown)(BOOL bShown) override; 702 STDMETHOD_(BOOL, ThreadProc)() override; 703}; 704 705BOOL CUTBMinimizeLangBarDlg::s_bIsDlgShown = FALSE; 706 707/***********************************************************************/ 708 709class CCicLibMenu : public ITfMenu 710{ 711protected: 712 CicArray<CCicLibMenuItem*> m_MenuItems; 713 LONG m_cRefs; 714 715public: 716 CCicLibMenu(); 717 virtual ~CCicLibMenu(); 718 719 STDMETHOD(QueryInterface)(REFIID riid, LPVOID *ppvObj) override; 720 STDMETHOD_(ULONG, AddRef)() override; 721 STDMETHOD_(ULONG, Release)() override; 722 STDMETHOD(AddMenuItem)( 723 UINT uId, 724 DWORD dwFlags, 725 HBITMAP hbmp, 726 HBITMAP hbmpMask, 727 const WCHAR *pch, 728 ULONG cch, 729 ITfMenu **ppSubMenu) override; 730 STDMETHOD_(CCicLibMenu*, CreateSubMenu)(); 731 STDMETHOD_(CCicLibMenuItem*, CreateMenuItem)(); 732}; 733 734/***********************************************************************/ 735 736class CCicLibMenuItem 737{ 738protected: 739 DWORD m_uId; 740 DWORD m_dwFlags; 741 HBITMAP m_hbmp; 742 HBITMAP m_hbmpMask; 743 BSTR m_bstrText; 744 ITfMenu *m_pMenu; 745 746public: 747 CCicLibMenuItem(); 748 virtual ~CCicLibMenuItem(); 749 750 BOOL Init( 751 UINT uId, 752 DWORD dwFlags, 753 HBITMAP hbmp, 754 HBITMAP hbmpMask, 755 const WCHAR *pch, 756 ULONG cch, 757 ITfMenu *pMenu); 758 HBITMAP CreateBitmap(HANDLE hBitmap); 759}; 760 761/***********************************************************************/ 762 763class CTipbarAccessible : public IAccessible 764{ 765protected: 766 LONG m_cRefs; 767 HWND m_hWnd; 768 IAccessible *m_pStdAccessible; 769 ITypeInfo *m_pTypeInfo; 770 BOOL m_bInitialized; 771 CicArray<CTipbarAccItem*> m_AccItems; 772 LONG m_cSelection; 773 friend class CUTBMenuWnd; 774 friend class CTipbarWnd; 775 776public: 777 CTipbarAccessible(CTipbarAccItem *pItem); 778 virtual ~CTipbarAccessible(); 779 780 HRESULT Initialize(); 781 782 BOOL AddAccItem(CTipbarAccItem *pItem); 783 HRESULT RemoveAccItem(CTipbarAccItem *pItem); 784 void ClearAccItems(); 785 CTipbarAccItem *AccItemFromID(INT iItem); 786 INT GetIDOfItem(CTipbarAccItem *pTarget); 787 788 LONG_PTR CreateRefToAccObj(WPARAM wParam); 789 BOOL DoDefaultActionReal(INT nID); 790 void NotifyWinEvent(DWORD event, CTipbarAccItem *pItem); 791 void SetWindow(HWND hWnd); 792 793 // IUnknown methods 794 STDMETHOD(QueryInterface)(REFIID riid, void **ppvObject); 795 STDMETHOD_(ULONG, AddRef)(); 796 STDMETHOD_(ULONG, Release)(); 797 798 // IDispatch methods 799 STDMETHOD(GetTypeInfoCount)(UINT *pctinfo); 800 STDMETHOD(GetTypeInfo)( 801 UINT iTInfo, 802 LCID lcid, 803 ITypeInfo **ppTInfo); 804 STDMETHOD(GetIDsOfNames)( 805 REFIID riid, 806 LPOLESTR *rgszNames, 807 UINT cNames, 808 LCID lcid, 809 DISPID *rgDispId); 810 STDMETHOD(Invoke)( 811 DISPID dispIdMember, 812 REFIID riid, 813 LCID lcid, 814 WORD wFlags, 815 DISPPARAMS *pDispParams, 816 VARIANT *pVarResult, 817 EXCEPINFO *pExcepInfo, 818 UINT *puArgErr); 819 820 // IAccessible methods 821 STDMETHOD(get_accParent)(IDispatch **ppdispParent); 822 STDMETHOD(get_accChildCount)(LONG *pcountChildren); 823 STDMETHOD(get_accChild)(VARIANT varChildID, IDispatch **ppdispChild); 824 STDMETHOD(get_accName)(VARIANT varID, BSTR *pszName); 825 STDMETHOD(get_accValue)(VARIANT varID, BSTR *pszValue); 826 STDMETHOD(get_accDescription)(VARIANT varID, BSTR *description); 827 STDMETHOD(get_accRole)(VARIANT varID, VARIANT *role); 828 STDMETHOD(get_accState)(VARIANT varID, VARIANT *state); 829 STDMETHOD(get_accHelp)(VARIANT varID, BSTR *help); 830 STDMETHOD(get_accHelpTopic)(BSTR *helpfile, VARIANT varID, LONG *pidTopic); 831 STDMETHOD(get_accKeyboardShortcut)(VARIANT varID, BSTR *shortcut); 832 STDMETHOD(get_accFocus)(VARIANT *pvarID); 833 STDMETHOD(get_accSelection)(VARIANT *pvarID); 834 STDMETHOD(get_accDefaultAction)(VARIANT varID, BSTR *action); 835 STDMETHOD(accSelect)(LONG flagsSelect, VARIANT varID); 836 STDMETHOD(accLocation)( 837 LONG *left, 838 LONG *top, 839 LONG *width, 840 LONG *height, 841 VARIANT varID); 842 STDMETHOD(accNavigate)(LONG dir, VARIANT varStart, VARIANT *pvarEnd); 843 STDMETHOD(accHitTest)(LONG left, LONG top, VARIANT *pvarID); 844 STDMETHOD(accDoDefaultAction)(VARIANT varID); 845 STDMETHOD(put_accName)(VARIANT varID, BSTR name); 846 STDMETHOD(put_accValue)(VARIANT varID, BSTR value); 847}; 848 849/***********************************************************************/ 850 851class CTipbarAccItem 852{ 853public: 854 CTipbarAccItem() { } 855 virtual ~CTipbarAccItem() { } 856 857 STDMETHOD_(BSTR, GetAccName)() 858 { 859 return SysAllocString(L""); 860 } 861 STDMETHOD_(BSTR, GetAccValue)() 862 { 863 return NULL; 864 } 865 STDMETHOD_(INT, GetAccRole)() 866 { 867 return 10; 868 } 869 STDMETHOD_(INT, GetAccState)() 870 { 871 return 256; 872 } 873 STDMETHOD_(void, GetAccLocation)(LPRECT lprc) 874 { 875 *lprc = { 0, 0, 0, 0 }; 876 } 877 STDMETHOD_(BSTR, GetAccDefaultAction)() 878 { 879 return NULL; 880 } 881 STDMETHOD_(BOOL, DoAccDefaultAction)() 882 { 883 return FALSE; 884 } 885 STDMETHOD_(BOOL, DoAccDefaultActionReal)() 886 { 887 return FALSE; 888 } 889}; 890 891/***********************************************************************/ 892 893class CTipbarCoInitialize 894{ 895public: 896 BOOL m_bCoInit; 897 898 CTipbarCoInitialize() : m_bCoInit(FALSE) { } 899 ~CTipbarCoInitialize() { CoUninit(); } 900 901 HRESULT EnsureCoInit() 902 { 903 if (m_bCoInit) 904 return S_OK; 905 HRESULT hr = ::CoInitialize(NULL); 906 if (FAILED(hr)) 907 return hr; 908 m_bCoInit = TRUE; 909 return S_OK; 910 } 911 912 void CoUninit() 913 { 914 if (m_bCoInit) 915 { 916 ::CoUninitialize(); 917 m_bCoInit = FALSE; 918 } 919 } 920}; 921 922/***********************************************************************/ 923 924class CUTBMenuWnd : public CTipbarAccItem, public CUIFMenu 925{ 926protected: 927 CTipbarCoInitialize m_coInit; 928 CTipbarAccessible *m_pAccessible; 929 UINT m_nMenuWndID; 930 friend class CUTBMenuItem; 931 932public: 933 CUTBMenuWnd(HINSTANCE hInst, DWORD style, DWORD dwUnknown14); 934 935 BOOL StartDoAccDefaultActionTimer(CUTBMenuItem *pTarget); 936 937 CTipbarAccItem* GetAccItem() 938 { 939 return static_cast<CTipbarAccItem*>(this); 940 } 941 CUIFMenu* GetMenu() 942 { 943 return static_cast<CUIFMenu*>(this); 944 } 945 946 STDMETHOD_(BSTR, GetAccName)() override; 947 STDMETHOD_(INT, GetAccRole)() override; 948 STDMETHOD_(BOOL, Initialize)() override; 949 STDMETHOD_(void, OnCreate)(HWND hWnd) override; 950 STDMETHOD_(void, OnDestroy)(HWND hWnd) override; 951 STDMETHOD_(HRESULT, OnGetObject)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override; 952 STDMETHOD_(LRESULT, OnShowWindow)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override; 953 STDMETHOD_(void, OnTimer)(WPARAM wParam) override; 954}; 955 956/***********************************************************************/ 957 958class CUTBMenuItem : public CTipbarAccItem, public CUIFMenuItem 959{ 960protected: 961 CUTBMenuWnd *m_pMenuUI; 962 friend class CUTBMenuWnd; 963 964public: 965 CUTBMenuItem(CUTBMenuWnd *pMenuUI); 966 ~CUTBMenuItem() override; 967 968 CUIFMenuItem* GetMenuItem() 969 { 970 return static_cast<CUIFMenuItem*>(this); 971 } 972 973 STDMETHOD_(BOOL, DoAccDefaultAction)() override; 974 STDMETHOD_(BOOL, DoAccDefaultActionReal)() override; 975 STDMETHOD_(BSTR, GetAccDefaultAction)() override; 976 STDMETHOD_(void, GetAccLocation)(LPRECT lprc) override; 977 STDMETHOD_(BSTR, GetAccName)() override; 978 STDMETHOD_(INT, GetAccRole)() override; 979}; 980 981/***********************************************************************/ 982 983class CModalMenu 984{ 985public: 986 DWORD m_dwUnknown26; 987 CUTBMenuWnd *m_pMenuUI; 988 989public: 990 CModalMenu() { } 991 virtual ~CModalMenu() { } 992 993 CUTBMenuItem *InsertItem(CUTBMenuWnd *pMenuUI, INT nCommandId, INT nStringID); 994 void PostKey(BOOL bUp, WPARAM wParam, LPARAM lParam); 995 void CancelMenu(); 996}; 997 998/***********************************************************************/ 999 1000class CTipbarThread; 1001 1002class CUTBContextMenu : public CModalMenu 1003{ 1004public: 1005 CTipbarWnd *m_pTipbarWnd; 1006 CTipbarThread *m_pTipbarThread; 1007 1008public: 1009 CUTBContextMenu(CTipbarWnd *pTipbarWnd); 1010 1011 BOOL Init(); 1012 CUTBMenuWnd *CreateMenuUI(BOOL bFlag); 1013 1014 UINT ShowPopup( 1015 CUIFWindow *pWindow, 1016 POINT pt, 1017 LPCRECT prc, 1018 BOOL bFlag); 1019 1020 BOOL SelectMenuItem(UINT nCommandId); 1021}; 1022 1023/***********************************************************************/ 1024 1025class CUTBLBarMenuItem; 1026 1027class CUTBLBarMenu : public CCicLibMenu 1028{ 1029protected: 1030 CUTBMenuWnd *m_pMenuUI; 1031 HINSTANCE m_hInst; 1032 1033public: 1034 CUTBLBarMenu(HINSTANCE hInst); 1035 ~CUTBLBarMenu() override; 1036 1037 CUTBMenuWnd *CreateMenuUI(); 1038 INT ShowPopup(CUIFWindow *pWindow, POINT pt, LPCRECT prcExclude); 1039 1040 STDMETHOD_(CCicLibMenuItem*, CreateMenuItem)() override; 1041 STDMETHOD_(CCicLibMenu*, CreateSubMenu)() override; 1042}; 1043 1044/***********************************************************************/ 1045 1046class CUTBLBarMenuItem : public CCicLibMenuItem 1047{ 1048public: 1049 CUTBLBarMenu *m_pLBarMenu; 1050 1051public: 1052 CUTBLBarMenuItem() { m_pLBarMenu = NULL; } 1053 BOOL InsertToUI(CUTBMenuWnd *pMenuUI); 1054}; 1055 1056/***********************************************************************/ 1057 1058class CTipbarGripper : public CUIFGripper 1059{ 1060protected: 1061 CTipbarWnd *m_pTipbarWnd; 1062 BOOL m_bInDebugMenu; 1063 friend class CTipbarWnd; 1064 1065public: 1066 CTipbarGripper(CTipbarWnd *pTipbarWnd, LPCRECT prc, DWORD style); 1067 1068 STDMETHOD_(void, OnLButtonUp)(LONG x, LONG y) override; 1069 STDMETHOD_(void, OnRButtonUp)(LONG x, LONG y) override; 1070 STDMETHOD_(BOOL, OnSetCursor)(UINT uMsg, LONG x, LONG y) override; 1071}; 1072 1073/***********************************************************************/ 1074 1075class CLangBarItemList : public CicArray<LANGBARITEMSTATE> 1076{ 1077public: 1078 BOOL IsStartedIntentionally(REFCLSID rclsid); 1079 1080 LANGBARITEMSTATE *AddItem(REFCLSID rclsid); 1081 void Clear(); 1082 BOOL SetDemoteLevel(REFCLSID rclsid, DWORD dwDemoteLevel); 1083 1084 LANGBARITEMSTATE *FindItem(REFCLSID rclsid); 1085 LANGBARITEMSTATE *GetItemStateFromTimerId(UINT_PTR nTimerID); 1086 1087 void Load(); 1088 void SaveItem(CicRegKey *pRegKey, const LANGBARITEMSTATE *pState); 1089 1090 void StartDemotingTimer(REFCLSID rclsid, BOOL bIntentional); 1091 UINT_PTR FindDemotingTimerId(); 1092}; 1093 1094/***********************************************************************/ 1095 1096class CTrayIconWnd 1097{ 1098protected: 1099 DWORD m_dwUnknown20; 1100 BOOL m_bBusy; 1101 UINT m_uCallbackMessage; 1102 UINT m_uMsg; 1103 HWND m_hWnd; 1104 DWORD m_dwUnknown21[2]; 1105 HWND m_hTrayWnd; 1106 HWND m_hNotifyWnd; 1107 DWORD m_dwTrayWndThreadId; 1108 DWORD m_dwUnknown22; 1109 HWND m_hwndProgman; 1110 DWORD m_dwProgmanThreadId; 1111 CMainIconItem *m_pMainIconItem; 1112 CicArray<CButtonIconItem*> m_Items; 1113 UINT m_uCallbackMsg; 1114 UINT m_uNotifyIconID; 1115 friend class CTipbarWnd; 1116 1117 static BOOL CALLBACK EnumChildWndProc(HWND hWnd, LPARAM lParam); 1118 static LRESULT CALLBACK _WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 1119 1120public: 1121 CTrayIconWnd(); 1122 ~CTrayIconWnd(); 1123 1124 static BOOL RegisterClass(); 1125 static CTrayIconWnd *GetThis(HWND hWnd); 1126 static void SetThis(HWND hWnd, LPCREATESTRUCT pCS); 1127 1128 HWND CreateWnd(); 1129 void DestroyWnd(); 1130 1131 BOOL SetMainIcon(HKL hKL); 1132 BOOL SetIcon(REFGUID rguid, DWORD dwUnknown24, HICON hIcon, LPCWSTR psz); 1133 1134 void RemoveAllIcon(DWORD dwFlags); 1135 void RemoveUnusedIcons(int unknown); 1136 1137 CButtonIconItem *FindIconItem(REFGUID rguid); 1138 BOOL FindTrayEtc(); 1139 HWND GetNotifyWnd(); 1140 BOOL OnIconMessage(UINT uMsg, WPARAM wParam, LPARAM lParam); 1141 1142 void CallOnDelayMsg(); 1143}; 1144 1145/***********************************************************************/ 1146 1147class CTrayIconItem 1148{ 1149protected: 1150 HWND m_hWnd; 1151 UINT m_uCallbackMessage; 1152 UINT m_uNotifyIconID; 1153 DWORD m_dwIconAddOrModify; 1154 BOOL m_bIconAdded; 1155 CTrayIconWnd *m_pTrayIconWnd; 1156 DWORD m_dwUnknown25; 1157 GUID m_guid; 1158 RECT m_rcMenu; 1159 POINT m_ptCursor; 1160 friend class CTrayIconWnd; 1161 1162public: 1163 CTrayIconItem(CTrayIconWnd *pTrayIconWnd); 1164 virtual ~CTrayIconItem() { } 1165 1166 BOOL _Init(HWND hWnd, UINT uCallbackMessage, UINT uNotifyIconID, const GUID& rguid); 1167 BOOL UpdateMenuRectPoint(); 1168 BOOL RemoveIcon(); 1169 1170 STDMETHOD_(BOOL, SetIcon)(HICON hIcon, LPCWSTR pszTip); 1171 STDMETHOD_(BOOL, OnMsg)(WPARAM wParam, LPARAM lParam) { return FALSE; }; 1172 STDMETHOD_(BOOL, OnDelayMsg)(UINT uMsg) { return 0; }; 1173}; 1174 1175/***********************************************************************/ 1176 1177class CButtonIconItem : public CTrayIconItem 1178{ 1179protected: 1180 DWORD m_dwUnknown24; 1181 HKL m_hKL; 1182 friend class CTrayIconWnd; 1183 1184public: 1185 CButtonIconItem(CTrayIconWnd *pWnd, DWORD dwUnknown24); 1186 1187 STDMETHOD_(BOOL, OnMsg)(WPARAM wParam, LPARAM lParam) override; 1188 STDMETHOD_(BOOL, OnDelayMsg)(UINT uMsg) override; 1189}; 1190 1191/***********************************************************************/ 1192 1193class CMainIconItem : public CButtonIconItem 1194{ 1195public: 1196 CMainIconItem(CTrayIconWnd *pWnd); 1197 1198 BOOL Init(HWND hWnd); 1199 STDMETHOD_(BOOL, OnDelayMsg)(UINT uMsg) override; 1200}; 1201 1202/***********************************************************************/ 1203 1204class CLBarItemBase 1205{ 1206protected: 1207 DWORD m_dwItemStatus; 1208 TF_LANGBARITEMINFO m_NewUIInfo; 1209 WCHAR m_szToolTipText[256]; 1210 LONG m_cRefs; 1211 ITfLangBarItemSink *m_pLangBarItemSink; 1212 1213public: 1214 CLBarItemBase(); 1215 virtual ~CLBarItemBase(); 1216 1217 HRESULT ShowInternal(BOOL bShow, BOOL bUpdate); 1218 1219 void InitNuiInfo( 1220 REFIID clsidService, 1221 REFGUID guidItem, 1222 DWORD dwStyle, 1223 DWORD ulSort, 1224 LPCWSTR Source); 1225 1226 HRESULT GetInfo(TF_LANGBARITEMINFO *pInfo); 1227 HRESULT GetStatus(DWORD *pdwStatus); 1228 HRESULT Show(BOOL fShow); 1229 HRESULT GetTooltipString(BSTR *pbstrToolTip); 1230 1231 HRESULT AdviseSink(REFIID riid, IUnknown *punk, DWORD *pdwCookie); 1232 HRESULT UnadviseSink(DWORD dwCookie); 1233}; 1234 1235/***********************************************************************/ 1236 1237class CLBarItemButtonBase 1238 : public CLBarItemBase 1239 , public ITfLangBarItem 1240 , public ITfLangBarItemButton 1241 , public ITfSource 1242{ 1243public: 1244 HICON m_hIcon; 1245 1246public: 1247 CLBarItemButtonBase() { m_hIcon = NULL; } 1248 ~CLBarItemButtonBase() override; 1249 1250 // IUnknown methods 1251 STDMETHOD(QueryInterface)(REFIID riid, void **ppvObject) override; 1252 STDMETHOD_(ULONG, AddRef)() override; 1253 STDMETHOD_(ULONG, Release)() override; 1254 1255 // ITfLangBarItem methods 1256 STDMETHOD(GetInfo)(TF_LANGBARITEMINFO *pInfo) override; 1257 STDMETHOD(GetStatus)(DWORD *pdwStatus) override; 1258 STDMETHOD(Show)(BOOL fShow) override; 1259 STDMETHOD(GetTooltipString)(BSTR *pbstrToolTip) override; 1260 1261 // ITfLangBarItemButton methods 1262 STDMETHOD(OnClick)(TfLBIClick click, POINT pt, LPCRECT prc) override; 1263 STDMETHOD(InitMenu)(ITfMenu *pMenu) override; 1264 STDMETHOD(OnMenuSelect)(UINT wID) override; 1265 STDMETHOD(GetIcon)(HICON *phIcon) override; 1266 STDMETHOD(GetText)(BSTR *pbstr) override; 1267 1268 // ITfSource methods 1269 STDMETHOD(AdviseSink)(REFIID riid, IUnknown *punk, DWORD *pdwCookie) override; 1270 STDMETHOD(UnadviseSink)(DWORD dwCookie) override; 1271}; 1272 1273/***********************************************************************/ 1274 1275/// Language Bar international item 1276class CLBarInatItem : public CLBarItemButtonBase 1277{ 1278protected: 1279 HKL m_hKL; 1280 DWORD m_dwThreadId; 1281 1282public: 1283 CLBarInatItem(DWORD dwThreadId); 1284 1285 STDMETHOD(InitMenu)(ITfMenu *pMenu) override; 1286 STDMETHOD(OnMenuSelect)(INT nCommandId); 1287 STDMETHOD(GetIcon)(HICON *phIcon) override; 1288 STDMETHOD(GetText)(BSTR *pbstr) override; 1289}; 1290 1291/***********************************************************************/ 1292 1293class CTipbarItem; 1294class CTipbarBalloonItem; 1295 1296class CTipbarThread 1297{ 1298protected: 1299 CTipbarWnd *m_pTipbarWnd; 1300 ITfLangBarItemMgr *m_pLangBarItemMgr; 1301 CicArray<CTipbarItem*> m_UIObjects; 1302 CicArray<CUIFObject*> m_Separators; 1303 DWORD m_dwUnknown32; 1304 DWORD m_dwThreadId; 1305 DWORD m_dwFlags1; 1306 DWORD m_dwFlags2; 1307 INT m_cxGrip; 1308 INT m_cyGrip; 1309 DWORD m_dwFlags3; 1310 DWORD m_dwUnknown34; 1311 LONG m_cRefs; 1312 friend class CTipbarWnd; 1313 friend class CTipbarItem; 1314 1315public: 1316 CTipbarThread(CTipbarWnd *pTipbarWnd); 1317 virtual ~CTipbarThread(); 1318 1319 HRESULT Init(DWORD dwThreadId); 1320 1321 HRESULT InitItemList(); 1322 HRESULT _UninitItemList(BOOL bUnAdvise); 1323 1324 DWORD IsDirtyItem(); 1325 BOOL IsFocusThread(); 1326 BOOL IsVertical(); 1327 1328 void AddAllSeparators(); 1329 void RemoveAllSeparators(); 1330 1331 void AddUIObjs(); 1332 void RemoveUIObjs(); 1333 1334 CTipbarItem *GetItem(REFCLSID rclsid); 1335 void GetTextSize(BSTR bstr, LPSIZE pSize); 1336 void LocateItems(); 1337 void MyMoveWnd(LONG xDelta, LONG yDelta); 1338 1339 HRESULT _UnadviseItemsSink(); 1340 LONG _AddRef() { return ++m_cRefs; } 1341 LONG _Release(); 1342 1343 /// @unimplemented 1344 BOOL SetFocus(CTipbarBalloonItem *pTarget) 1345 { 1346 return FALSE; 1347 } 1348 1349 /// @unimplemented 1350 HRESULT CallOnUpdateHandler() 1351 { 1352 return E_NOTIMPL; 1353 } 1354 1355 //FIXME 1356}; 1357 1358/***********************************************************************/ 1359 1360class CTipbarItem : public CTipbarAccItem 1361{ 1362protected: 1363 DWORD m_dwCookie; 1364 TF_LANGBARITEMINFO m_ItemInfo; 1365 DWORD m_dwUnknown16; 1366 DWORD m_dwUnknown17; 1367 CTipbarThread *m_pTipbarThread; 1368 ITfLangBarItem *m_pLangBarItem; 1369 DWORD m_dwUnknown18[2]; 1370 DWORD m_dwItemFlags; 1371 DWORD m_dwDirty; 1372 DWORD m_dwUnknown19[4]; 1373 friend class CTipbarThread; 1374 friend class CTipbarWnd; 1375 1376public: 1377 CTipbarItem( 1378 CTipbarThread *pThread, 1379 ITfLangBarItem *pLangBarItem, 1380 TF_LANGBARITEMINFO *pItemInfo, 1381 DWORD dwUnknown16); 1382 ~CTipbarItem() override; 1383 1384 void _AddedToUI(); 1385 void _RemovedToUI(); 1386 void AddRemoveMeToUI(BOOL bFlag); 1387 1388 BOOL IsConnected(); 1389 void ClearConnections(); 1390 1391 void StartDemotingTimer(BOOL bStarted); 1392 1393 void MyClientToScreen(LPPOINT ppt, LPRECT prc); 1394 void MyClientToScreen(LPRECT prc) { return MyClientToScreen(NULL, prc); } 1395 1396 STDMETHOD_(BSTR, GetAccName)() override; 1397 STDMETHOD_(void, GetAccLocation)(LPRECT prc) override; 1398 STDMETHOD_(BOOL, DoAccDefaultAction)() override; 1399 STDMETHOD(OnUnknown40)() { return S_OK; } 1400 STDMETHOD(OnUnknown41)() { return S_OK; } 1401 STDMETHOD(OnUnknown42)() { return S_OK; } 1402 STDMETHOD(OnUnknown43)() { return S_OK; } 1403 STDMETHOD(OnUpdate)(DWORD dwDirty); 1404 STDMETHOD(OnUnknown44)() { return S_OK; } 1405 STDMETHOD_(void, OnUnknown45)(DWORD dwDirty, DWORD dwStatus) { } 1406 STDMETHOD_(void, OnUpdateHandler)(ULONG, ULONG); 1407 STDMETHOD(OnUnknown46)(CUIFWindow *pWindow) { return S_OK; } 1408 STDMETHOD(OnUnknown47)(CUIFWindow *pWindow) { return S_OK; } 1409 STDMETHOD(OnUnknown48)() { return S_OK; } 1410 STDMETHOD(OnUnknown49)() { return S_OK; } 1411 STDMETHOD(OnUnknown50)() { return S_OK; } 1412 STDMETHOD(OnUnknown51)() { return S_OK; } 1413 STDMETHOD(OnUnknown52)() { return S_OK; } 1414 STDMETHOD(OnUnknown53)(BSTR bstr) { return S_OK; } 1415 STDMETHOD_(LPCWSTR, OnUnknown55)() { return NULL; } 1416 STDMETHOD(OnUnknown56)() { return S_OK; } 1417 STDMETHOD_(LPCWSTR, GetToolTip)(); 1418 STDMETHOD(OnUnknown57)(LPRECT prc) { return S_OK; } 1419 STDMETHOD(OnUnknown58)() { return S_OK; } 1420 STDMETHOD_(void, OnUnknown59)() { } 1421 STDMETHOD_(void, OnUnknown60)() { } 1422 STDMETHOD_(void, OnUnknown61)(HWND) { } 1423 STDMETHOD_(void, OnUnknown62)(HWND) { } 1424 STDMETHOD(OnUnknown63)() { return S_OK; } 1425}; 1426 1427/***********************************************************************/ 1428 1429class CTipbarCtrlButtonHolder; 1430class CDeskBand; 1431 1432// Flags for m_dwTipbarWndFlags 1433enum 1434{ 1435 TIPBAR_ATTACHED = 0x1, 1436 TIPBAR_CHILD = 0x2, 1437 TIPBAR_VERTICAL = 0x4, 1438 TIPBAR_HIGHCONTRAST = 0x10, 1439 TIPBAR_TRAYICON = 0x20, 1440 TIPBAR_UPDATING = 0x400, 1441 TIPBAR_ENSURING = 0x2000, 1442 TIPBAR_NODESKBAND = 0x4000, 1443 TIPBAR_TOOLBARENDED = 0x10000, 1444 TIPBAR_TOPFIT = 0x40000, 1445 TIPBAR_BOTTOMFIT = 0x80000, 1446 TIPBAR_RIGHTFIT = 0x100000, 1447 TIPBAR_LEFTFIT = 0x200000, 1448}; 1449 1450class CTipbarWnd 1451 : public ITfLangBarEventSink 1452 , public ITfLangBarEventSink_P 1453 , public CTipbarAccItem 1454 , public CUIFWindow 1455{ 1456 CTipbarCoInitialize m_coInit; 1457 DWORD m_dwSinkCookie; 1458 CModalMenu *m_pModalMenu; 1459 CTipbarThread *m_pThread; 1460 CLangBarItemList m_LangBarItemList; 1461 DWORD m_dwUnknown20; 1462 CUIFWndFrame *m_pWndFrame; 1463 CTipbarGripper *m_pTipbarGripper; 1464 CTipbarThread *m_pFocusThread; 1465 CicArray<CTipbarThread*> m_Threads; 1466 CicArray<CTipbarThread*> m_ThreadCreatingList; 1467 DWORD m_dwAlphaValue; 1468 DWORD m_dwTipbarWndFlags; 1469 LONG m_ButtonWidth; 1470 DWORD m_dwShowType; 1471 DWORD m_dwUnknown21; 1472 INT m_cxSmallIcon; 1473 INT m_cySmallIcon; 1474 INT m_cxDlgFrameX2; 1475 INT m_cyDlgFrameX2; 1476 HFONT m_hMarlettFont; 1477 HFONT m_hTextFont; 1478 ITfLangBarMgr_P *m_pLangBarMgr; 1479 DWORD m_dwUnknown23; 1480 CTipbarCtrlButtonHolder *m_pTipbarCtrlButtonHolder; 1481 DWORD m_dwUnknown23_1[8]; 1482 CUIFWindow *m_pBalloon; 1483 DWORD m_dwChangingThreadId; 1484 LONG m_bInCallOn; 1485 LONG m_X; 1486 LONG m_Y; 1487 LONG m_CX; 1488 LONG m_CY; 1489 CTipbarAccessible *m_pTipbarAccessible; 1490 INT m_nID; 1491 MARGINS m_Margins; 1492 DWORD m_dwUnknown23_5[4]; 1493 CTipbarThread *m_pUnknownThread; 1494 CDeskBand *m_pDeskBand; 1495 CShellWndThread m_ShellWndThread; 1496 LONG m_cRefs; 1497 friend class CUTBContextMenu; 1498 friend class CTipbarGripper; 1499 friend class CTipbarThread; 1500 friend class CTipbarItem; 1501 friend class CLBarInatItem; 1502 friend class CMainIconItem; 1503 friend VOID WINAPI ClosePopupTipbar(VOID); 1504 friend BOOL GetTipbarInternal(HWND hWnd, DWORD dwFlags, CDeskBand *pDeskBand); 1505 friend LONG MyWaitForInputIdle(DWORD dwThreadId, DWORD dwMilliseconds); 1506 1507public: 1508 CTipbarWnd(DWORD style); 1509 ~CTipbarWnd() override; 1510 1511 CUIFWindow *GetWindow() 1512 { 1513 return static_cast<CUIFWindow*>(this); 1514 } 1515 1516 CTipbarAccItem *GetAccItem() 1517 { 1518 return static_cast<CTipbarAccItem*>(this); 1519 } 1520 1521 void Init(BOOL bChild, CDeskBand *pDeskBand); 1522 void InitHighContrast(); 1523 void InitMetrics(); 1524 void InitThemeMargins(); 1525 void UnInit(); 1526 1527 BOOL IsFullScreenWindow(HWND hWnd); 1528 BOOL IsHKLToSkipRedrawOnNoItem(); 1529 BOOL IsInItemChangeOrDirty(CTipbarThread *pTarget); 1530 1531 void AddThreadToThreadCreatingList(CTipbarThread *pThread); 1532 void RemoveThredFromThreadCreatingList(CTipbarThread *pTarget); 1533 1534 void MoveToStub(BOOL bFlag); 1535 void RestoreFromStub(); 1536 1537 INT GetCtrlButtonWidth(); 1538 INT GetGripperWidth(); 1539 INT GetTipbarHeight(); 1540 BOOL AutoAdjustDeskBandSize(); 1541 INT AdjustDeskBandSize(BOOL bFlag); 1542 void LocateCtrlButtons(); 1543 void AdjustPosOnDisplayChange(); 1544 void SetVertical(BOOL bVertical); 1545 void UpdatePosFlags(); 1546 1547 void CancelMenu(); 1548 BOOL CheckExcludeCaptionButtonMode(LPRECT prc1, LPCRECT prc2); 1549 void ClearLBItemList(); 1550 1551 HFONT CreateVerticalFont(); 1552 void UpdateVerticalFont(); 1553 1554 void ShowOverScreenSizeBalloon(); 1555 void DestroyOverScreenSizeBalloon(); 1556 void DestroyWnd(); 1557 1558 HKL GetFocusKeyboardLayout(); 1559 void KillOnTheadItemChangeTimer(); 1560 1561 UINT_PTR SetTimer(UINT_PTR nIDEvent, UINT uElapse); 1562 BOOL KillTimer(UINT_PTR uIDEvent); 1563 1564 void MoveToTray(); 1565 void MyClientToScreen(LPPOINT lpPoint, LPRECT prc); 1566 void SavePosition(); 1567 void SetAlpha(BYTE bAlpha, BOOL bFlag); 1568 BOOL SetLangBand(BOOL bDeskBand, BOOL bFlag2); 1569 void SetMoveRect(INT X, INT Y, INT nWidth, INT nHeight); 1570 void SetShowText(BOOL bShow); 1571 void SetShowTrayIcon(BOOL bShow); 1572 1573 void ShowContextMenu(POINT pt, LPCRECT prc, BOOL bFlag); 1574 void StartBackToAlphaTimer(); 1575 BOOL StartDoAccDefaultActionTimer(CTipbarItem *pTarget); 1576 1577 void StartModalInput(ITfLangBarEventSink *pSink, DWORD dwThreadId); 1578 void StopModalInput(DWORD dwThreadId); 1579 1580 CTipbarThread *_CreateThread(DWORD dwThreadId); 1581 CTipbarThread *_FindThread(DWORD dwThreadId); 1582 void EnsureFocusThread(); 1583 HRESULT SetFocusThread(CTipbarThread *pFocusThread); 1584 HRESULT AttachFocusThread(); 1585 void RestoreLastFocus(DWORD *pdwThreadId, BOOL fPrev); 1586 void CleanUpThreadPointer(CTipbarThread *pThread, BOOL bRemove); 1587 void TerminateAllThreads(BOOL bFlag); 1588 void OnTerminateToolbar(); 1589 HRESULT OnThreadTerminateInternal(DWORD dwThreadId); 1590 1591 /// @unimplemented 1592 HRESULT OnThreadItemChangeInternal(DWORD dwThreadId) 1593 { 1594 return E_NOTIMPL; 1595 } 1596 1597 // IUnknown methods 1598 STDMETHOD(QueryInterface)(REFIID riid, void **ppvObj); 1599 STDMETHOD_(ULONG, AddRef)(); 1600 STDMETHOD_(ULONG, Release)(); 1601 1602 // ITfLangBarEventSink methods 1603 STDMETHOD(OnSetFocus)(DWORD dwThreadId) override; 1604 STDMETHOD(OnThreadTerminate)(DWORD dwThreadId) override; 1605 STDMETHOD(OnThreadItemChange)(DWORD dwThreadId) override; 1606 STDMETHOD(OnModalInput)(DWORD dwThreadId, UINT uMsg, WPARAM wParam, LPARAM lParam) override; 1607 STDMETHOD(ShowFloating)(DWORD dwFlags) override; 1608 STDMETHOD(GetItemFloatingRect)(DWORD dwThreadId, REFGUID rguid, RECT *prc) override; 1609 1610 // ITfLangBarEventSink_P methods 1611 STDMETHOD(OnLangBarUpdate)(TfLBIClick click, BOOL bFlag) override; 1612 1613 // CTipbarAccItem methods 1614 STDMETHOD_(BSTR, GetAccName)() override; 1615 STDMETHOD_(void, GetAccLocation)(LPRECT lprc) override; 1616 1617 // CUIFWindow methods 1618 STDMETHOD_(void, PaintObject)(HDC hDC, LPCRECT prc) override; 1619 STDMETHOD_(DWORD, GetWndStyle)() override; 1620 STDMETHOD_(void, Move)(INT x, INT y, INT nWidth, INT nHeight) override; 1621 STDMETHOD_(void, OnMouseOutFromWindow)(LONG x, LONG y) override; 1622 STDMETHOD_(void, OnCreate)(HWND hWnd) override; 1623 STDMETHOD_(void, OnDestroy)(HWND hWnd) override; 1624 STDMETHOD_(void, OnTimer)(WPARAM wParam) override; 1625 STDMETHOD_(void, OnSysColorChange)() override; 1626 STDMETHOD_(void, OnEndSession)(HWND hWnd, WPARAM wParam, LPARAM lParam) override; 1627 STDMETHOD_(void, OnUser)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override; 1628 STDMETHOD_(LRESULT, OnWindowPosChanged)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override; 1629 STDMETHOD_(LRESULT, OnWindowPosChanging)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override; 1630 STDMETHOD_(LRESULT, OnShowWindow)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override; 1631 STDMETHOD_(LRESULT, OnSettingChange)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override; 1632 STDMETHOD_(LRESULT, OnDisplayChange)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override; 1633 STDMETHOD_(HRESULT, OnGetObject)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override; 1634 STDMETHOD_(BOOL, OnEraseBkGnd)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override; 1635 STDMETHOD_(void, OnThemeChanged)(HWND hWnd, WPARAM wParam, LPARAM lParam) override; 1636 STDMETHOD_(void, UpdateUI)(LPCRECT prc) override; 1637 STDMETHOD_(void, HandleMouseMsg)(UINT uMsg, LONG x, LONG y) override; 1638}; 1639 1640/***********************************************************************/ 1641 1642#ifdef ENABLE_DESKBAND 1643class CDeskBand 1644{ 1645public: 1646 // FIXME: Implement this 1647}; 1648#endif 1649 1650/*********************************************************************** 1651 * CUTBLangBarDlg 1652 */ 1653 1654CUTBLangBarDlg *CUTBLangBarDlg::GetThis(HWND hDlg) 1655{ 1656 return (CUTBLangBarDlg*)::GetWindowLongPtr(hDlg, DWLP_USER); 1657} 1658 1659void CUTBLangBarDlg::SetThis(HWND hDlg, CUTBLangBarDlg *pThis) 1660{ 1661 ::SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pThis); 1662} 1663 1664DWORD WINAPI CUTBLangBarDlg::s_ThreadProc(LPVOID pParam) 1665{ 1666 return ((CUTBLangBarDlg *)pParam)->ThreadProc(); 1667} 1668 1669BOOL CUTBLangBarDlg::StartThread() 1670{ 1671 if (IsDlgShown()) 1672 return FALSE; 1673 1674 SetDlgShown(TRUE); 1675 1676 DWORD dwThreadId; 1677 HANDLE hThread = ::CreateThread(NULL, 0, s_ThreadProc, this, 0, &dwThreadId); 1678 if (!hThread) 1679 { 1680 SetDlgShown(FALSE); 1681 return TRUE; 1682 } 1683 1684 ++m_cRefs; 1685 ::CloseHandle(hThread); 1686 return TRUE; 1687} 1688 1689LONG CUTBLangBarDlg::_Release() 1690{ 1691 if (--m_cRefs == 0) 1692 { 1693 delete this; 1694 return 0; 1695 } 1696 return m_cRefs; 1697} 1698 1699STDMETHODIMP_(BOOL) CUTBLangBarDlg::ThreadProc() 1700{ 1701 extern HINSTANCE g_hInst; 1702 ::DialogBoxParam(g_hInst, m_pszDialogName, NULL, DlgProc, (LPARAM)this); 1703 SetDlgShown(FALSE); 1704 _Release(); 1705 return TRUE; 1706} 1707 1708INT_PTR CALLBACK 1709CUTBLangBarDlg::DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 1710{ 1711 if (uMsg == WM_INITDIALOG) 1712 { 1713 SetThis(hDlg, (CUTBLangBarDlg *)lParam); 1714 ::ShowWindow(hDlg, SW_RESTORE); 1715 ::UpdateWindow(hDlg); 1716 return TRUE; 1717 } 1718 1719 if (uMsg == WM_COMMAND) 1720 { 1721 CUTBLangBarDlg *pThis = CUTBLangBarDlg::GetThis(hDlg); 1722 pThis->OnCommand(hDlg, wParam, lParam); 1723 return TRUE; 1724 } 1725 1726 return FALSE; 1727} 1728 1729/*********************************************************************** 1730 * CUTBCloseLangBarDlg 1731 */ 1732 1733CUTBCloseLangBarDlg::CUTBCloseLangBarDlg() 1734{ 1735 m_cRefs = 1; 1736 1737 if (!(g_dwOSInfo & CIC_OSINFO_XPPLUS)) 1738 m_pszDialogName = MAKEINTRESOURCE(IDD_CLOSELANGBARNOBAND); 1739 else 1740 m_pszDialogName = MAKEINTRESOURCE(IDD_CLOSELANGBAR); 1741} 1742 1743STDMETHODIMP_(BOOL) CUTBCloseLangBarDlg::DoModal(HWND hDlg) 1744{ 1745 CicRegKey regKey; 1746 LSTATUS error; 1747 DWORD dwValue = FALSE; 1748 error = regKey.Open(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\")); 1749 if (error == ERROR_SUCCESS) 1750 regKey.QueryDword(TEXT("DontShowCloseLangBarDlg"), &dwValue); 1751 1752 if (dwValue) 1753 return FALSE; 1754 1755 StartThread(); 1756 return TRUE; 1757} 1758 1759STDMETHODIMP_(BOOL) CUTBCloseLangBarDlg::OnCommand(HWND hDlg, WPARAM wParam, LPARAM lParam) 1760{ 1761 switch (LOWORD(wParam)) 1762 { 1763 case IDOK: 1764 DoCloseLangbar(); 1765 if (::IsDlgButtonChecked(hDlg, IDC_CLOSELANGBAR_CHECK)) 1766 { 1767 CicRegKey regKey; 1768 LSTATUS error; 1769 error = regKey.Create(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\")); 1770 if (error == ERROR_SUCCESS) 1771 regKey.SetDword(TEXT("DontShowCloseLangBarDlg"), TRUE); 1772 } 1773 ::EndDialog(hDlg, TRUE); 1774 break; 1775 1776 case IDCANCEL: 1777 ::EndDialog(hDlg, FALSE); 1778 break; 1779 1780 default: 1781 return FALSE; 1782 } 1783 return TRUE; 1784} 1785 1786STDMETHODIMP_(BOOL) CUTBCloseLangBarDlg::IsDlgShown() 1787{ 1788 return s_bIsDlgShown; 1789} 1790 1791STDMETHODIMP_(void) CUTBCloseLangBarDlg::SetDlgShown(BOOL bShown) 1792{ 1793 s_bIsDlgShown = bShown; 1794} 1795 1796/*********************************************************************** 1797 * CUTBMinimizeLangBarDlg 1798 */ 1799 1800CUTBMinimizeLangBarDlg::CUTBMinimizeLangBarDlg() 1801{ 1802 m_cRefs = 1; 1803 if (!(g_dwOSInfo & CIC_OSINFO_XPPLUS)) 1804 m_pszDialogName = MAKEINTRESOURCE(IDD_MINIMIZELANGBARNOBAND); 1805 else 1806 m_pszDialogName = MAKEINTRESOURCE(IDD_MINIMIZELANGBAR); 1807} 1808 1809STDMETHODIMP_(BOOL) CUTBMinimizeLangBarDlg::DoModal(HWND hDlg) 1810{ 1811 CicRegKey regKey; 1812 LSTATUS error; 1813 1814 DWORD dwValue = FALSE; 1815 error = regKey.Open(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\")); 1816 if (error == ERROR_SUCCESS) 1817 regKey.QueryDword(TEXT("DontShowMinimizeLangBarDlg"), &dwValue); 1818 1819 if (dwValue) 1820 return FALSE; 1821 1822 StartThread(); 1823 return TRUE; 1824} 1825 1826STDMETHODIMP_(BOOL) CUTBMinimizeLangBarDlg::OnCommand(HWND hDlg, WPARAM wParam, LPARAM lParam) 1827{ 1828 switch (LOWORD(wParam)) 1829 { 1830 case IDOK: 1831 if (::IsDlgButtonChecked(hDlg, IDC_MINIMIZELANGBAR_CHECK)) 1832 { 1833 LSTATUS error; 1834 CicRegKey regKey; 1835 error = regKey.Create(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\")); 1836 if (error == ERROR_SUCCESS) 1837 regKey.SetDword(TEXT("DontShowMinimizeLangBarDlg"), TRUE); 1838 } 1839 ::EndDialog(hDlg, TRUE); 1840 break; 1841 case IDCANCEL: 1842 ::EndDialog(hDlg, FALSE); 1843 break; 1844 default: 1845 return FALSE; 1846 } 1847 return TRUE; 1848} 1849 1850STDMETHODIMP_(BOOL) CUTBMinimizeLangBarDlg::IsDlgShown() 1851{ 1852 return s_bIsDlgShown; 1853} 1854 1855STDMETHODIMP_(void) CUTBMinimizeLangBarDlg::SetDlgShown(BOOL bShown) 1856{ 1857 s_bIsDlgShown = bShown; 1858} 1859 1860STDMETHODIMP_(BOOL) CUTBMinimizeLangBarDlg::ThreadProc() 1861{ 1862 ::Sleep(700); 1863 return CUTBLangBarDlg::ThreadProc(); 1864} 1865 1866/*********************************************************************** 1867 * CCicLibMenu 1868 */ 1869 1870CCicLibMenu::CCicLibMenu() : m_cRefs(1) 1871{ 1872} 1873 1874CCicLibMenu::~CCicLibMenu() 1875{ 1876 for (size_t iItem = 0; iItem < m_MenuItems.size(); ++iItem) 1877 { 1878 delete m_MenuItems[iItem]; 1879 m_MenuItems[iItem] = NULL; 1880 } 1881} 1882 1883STDMETHODIMP CCicLibMenu::QueryInterface(REFIID riid, LPVOID *ppvObj) 1884{ 1885 static const QITAB c_tab[] = 1886 { 1887 QITABENT(CCicLibMenu, ITfMenu), 1888 { NULL } 1889 }; 1890 return ::QISearch(this, c_tab, riid, ppvObj); 1891} 1892 1893STDMETHODIMP_(ULONG) CCicLibMenu::AddRef() 1894{ 1895 return ++m_cRefs; 1896} 1897 1898STDMETHODIMP_(ULONG) CCicLibMenu::Release() 1899{ 1900 if (--m_cRefs == 0) 1901 { 1902 delete this; 1903 return 0; 1904 } 1905 return m_cRefs; 1906} 1907 1908STDMETHODIMP_(CCicLibMenu*) CCicLibMenu::CreateSubMenu() 1909{ 1910 return new(cicNoThrow) CCicLibMenu(); 1911} 1912 1913STDMETHODIMP_(CCicLibMenuItem*) CCicLibMenu::CreateMenuItem() 1914{ 1915 return new(cicNoThrow) CCicLibMenuItem(); 1916} 1917 1918STDMETHODIMP CCicLibMenu::AddMenuItem( 1919 UINT uId, 1920 DWORD dwFlags, 1921 HBITMAP hbmp, 1922 HBITMAP hbmpMask, 1923 const WCHAR *pch, 1924 ULONG cch, 1925 ITfMenu **ppSubMenu) 1926{ 1927 if (ppSubMenu) 1928 *ppSubMenu = NULL; 1929 1930 CCicLibMenu *pSubMenu = NULL; 1931 if (dwFlags & TF_LBMENUF_SUBMENU) 1932 { 1933 if (!ppSubMenu) 1934 return E_INVALIDARG; 1935 pSubMenu = CreateSubMenu(); 1936 } 1937 1938 CCicLibMenuItem *pMenuItem = CreateMenuItem(); 1939 if (!pMenuItem) 1940 return E_OUTOFMEMORY; 1941 1942 if (!pMenuItem->Init(uId, dwFlags, hbmp, hbmpMask, pch, cch, pSubMenu)) 1943 return E_FAIL; 1944 1945 if (ppSubMenu && pSubMenu) 1946 { 1947 *ppSubMenu = pSubMenu; 1948 pSubMenu->AddRef(); 1949 } 1950 1951 m_MenuItems.Add(pMenuItem); 1952 return S_OK; 1953} 1954 1955/*********************************************************************** 1956 * CCicLibMenuItem 1957 */ 1958 1959CCicLibMenuItem::CCicLibMenuItem() 1960{ 1961 m_uId = 0; 1962 m_dwFlags = 0; 1963 m_hbmp = NULL; 1964 m_hbmpMask = NULL; 1965 m_bstrText = NULL; 1966 m_pMenu = NULL; 1967} 1968 1969CCicLibMenuItem::~CCicLibMenuItem() 1970{ 1971 if (m_pMenu) 1972 { 1973 m_pMenu->Release(); 1974 m_pMenu = NULL; 1975 } 1976 1977 if (m_hbmp) 1978 { 1979 ::DeleteObject(m_hbmp); 1980 m_hbmp = NULL; 1981 } 1982 1983 if (m_hbmpMask) 1984 { 1985 ::DeleteObject(m_hbmpMask); 1986 m_hbmpMask = NULL; 1987 } 1988 1989 ::SysFreeString(m_bstrText); 1990 m_bstrText = NULL; 1991} 1992 1993BOOL CCicLibMenuItem::Init( 1994 UINT uId, 1995 DWORD dwFlags, 1996 HBITMAP hbmp, 1997 HBITMAP hbmpMask, 1998 const WCHAR *pch, 1999 ULONG cch, 2000 ITfMenu *pMenu) 2001{ 2002 m_uId = uId; 2003 m_dwFlags = dwFlags; 2004 m_bstrText = ::SysAllocStringLen(pch, cch); 2005 if (!m_bstrText && cch) 2006 return FALSE; 2007 2008 m_pMenu = pMenu; 2009 m_hbmp = CreateBitmap(hbmp); 2010 m_hbmpMask = CreateBitmap(hbmpMask); 2011 if (hbmp) 2012 ::DeleteObject(hbmp); 2013 if (hbmpMask) 2014 ::DeleteObject(hbmpMask); 2015 2016 return TRUE; 2017} 2018 2019HBITMAP CCicLibMenuItem::CreateBitmap(HANDLE hBitmap) 2020{ 2021 if (!hBitmap) 2022 return NULL; 2023 2024 HDC hDC = ::CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL); 2025 if (!hDC) 2026 return NULL; 2027 2028 HBITMAP hbmMem = NULL; 2029 2030 BITMAP bm; 2031 ::GetObject(hBitmap, sizeof(bm), &bm); 2032 2033 HGDIOBJ hbmOld1 = NULL; 2034 HDC hdcMem1 = ::CreateCompatibleDC(hDC); 2035 if (hdcMem1) 2036 hbmOld1 = ::SelectObject(hdcMem1, hBitmap); 2037 2038 HGDIOBJ hbmOld2 = NULL; 2039 HDC hdcMem2 = ::CreateCompatibleDC(hDC); 2040 if (hdcMem2) 2041 { 2042 hbmMem = ::CreateCompatibleBitmap(hDC, bm.bmWidth, bm.bmHeight); 2043 hbmOld2 = ::SelectObject(hdcMem2, hbmMem); 2044 } 2045 2046 ::BitBlt(hdcMem2, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem1, 0, 0, SRCCOPY); 2047 2048 if (hbmOld1) 2049 ::SelectObject(hdcMem1, hbmOld1); 2050 if (hbmOld2) 2051 ::SelectObject(hdcMem2, hbmOld2); 2052 2053 ::DeleteDC(hDC); 2054 if (hdcMem1) 2055 ::DeleteDC(hdcMem1); 2056 if (hdcMem2) 2057 ::DeleteDC(hdcMem2); 2058 2059 return hbmMem; 2060} 2061 2062/*********************************************************************** 2063 * CTipbarAccessible 2064 */ 2065 2066CTipbarAccessible::CTipbarAccessible(CTipbarAccItem *pItem) 2067{ 2068 m_cRefs = 1; 2069 m_hWnd = NULL; 2070 m_pTypeInfo = NULL; 2071 m_pStdAccessible = NULL; 2072 m_bInitialized = FALSE; 2073 m_cSelection = 1; 2074 m_AccItems.Add(pItem); 2075 ++g_DllRefCount; 2076} 2077 2078CTipbarAccessible::~CTipbarAccessible() 2079{ 2080 m_pTypeInfo = m_pTypeInfo; 2081 if (m_pTypeInfo) 2082 { 2083 m_pTypeInfo->Release(); 2084 m_pTypeInfo = NULL; 2085 } 2086 if (m_pStdAccessible) 2087 { 2088 m_pStdAccessible->Release(); 2089 m_pStdAccessible = NULL; 2090 } 2091 --g_DllRefCount; 2092} 2093 2094HRESULT CTipbarAccessible::Initialize() 2095{ 2096 m_bInitialized = TRUE; 2097 2098 HRESULT hr = ::CreateStdAccessibleObject(m_hWnd, OBJID_CLIENT, IID_IAccessible, 2099 (void **)&m_pStdAccessible); 2100 if (FAILED(hr)) 2101 return hr; 2102 2103 ITypeLib *pTypeLib; 2104 hr = ::LoadRegTypeLib(LIBID_Accessibility, 1, 0, 0, &pTypeLib); 2105 if (FAILED(hr)) 2106 hr = ::LoadTypeLib(L"OLEACC.DLL", &pTypeLib); 2107 2108 if (SUCCEEDED(hr)) 2109 { 2110 hr = pTypeLib->GetTypeInfoOfGuid(IID_IAccessible, &m_pTypeInfo); 2111 pTypeLib->Release(); 2112 } 2113 2114 return hr; 2115} 2116 2117BOOL CTipbarAccessible::AddAccItem(CTipbarAccItem *pItem) 2118{ 2119 return m_AccItems.Add(pItem); 2120} 2121 2122HRESULT CTipbarAccessible::RemoveAccItem(CTipbarAccItem *pItem) 2123{ 2124 for (size_t iItem = 0; iItem < m_AccItems.size(); ++iItem) 2125 { 2126 if (m_AccItems[iItem] == pItem) 2127 { 2128 m_AccItems.Remove(iItem, 1); 2129 break; 2130 } 2131 } 2132 return S_OK; 2133} 2134 2135void CTipbarAccessible::ClearAccItems() 2136{ 2137 m_AccItems.clear(); 2138} 2139 2140CTipbarAccItem *CTipbarAccessible::AccItemFromID(INT iItem) 2141{ 2142 if (iItem < 0 || (INT)m_AccItems.size() <= iItem) 2143 return NULL; 2144 return m_AccItems[iItem]; 2145} 2146 2147INT CTipbarAccessible::GetIDOfItem(CTipbarAccItem *pTarget) 2148{ 2149 for (size_t iItem = 0; iItem < m_AccItems.size(); ++iItem) 2150 { 2151 if (pTarget == m_AccItems[iItem]) 2152 return (INT)iItem; 2153 } 2154 return -1; 2155} 2156 2157LONG_PTR CTipbarAccessible::CreateRefToAccObj(WPARAM wParam) 2158{ 2159 return ::LresultFromObject(IID_IAccessible, wParam, this); 2160} 2161 2162BOOL CTipbarAccessible::DoDefaultActionReal(INT nID) 2163{ 2164 CTipbarAccItem *pItem = AccItemFromID(nID); 2165 if (!pItem) 2166 return FALSE; 2167 return pItem->DoAccDefaultActionReal(); 2168} 2169 2170void CTipbarAccessible::NotifyWinEvent(DWORD event, CTipbarAccItem *pItem) 2171{ 2172 INT nID = GetIDOfItem(pItem); 2173 if (nID < 0) 2174 return; 2175 2176 ::NotifyWinEvent(event, m_hWnd, -4, nID); 2177} 2178 2179void CTipbarAccessible::SetWindow(HWND hWnd) 2180{ 2181 m_hWnd = hWnd; 2182} 2183 2184STDMETHODIMP CTipbarAccessible::QueryInterface( 2185 REFIID riid, 2186 void **ppvObject) 2187{ 2188 static const QITAB c_tab[] = 2189 { 2190 QITABENT(CTipbarAccessible, IDispatch), 2191 QITABENT(CTipbarAccessible, IAccessible), 2192 { NULL } 2193 }; 2194 return ::QISearch(this, c_tab, riid, ppvObject); 2195} 2196 2197STDMETHODIMP_(ULONG) CTipbarAccessible::AddRef() 2198{ 2199 return ::InterlockedIncrement(&m_cRefs); 2200} 2201 2202STDMETHODIMP_(ULONG) CTipbarAccessible::Release() 2203{ 2204 LONG count = ::InterlockedDecrement(&m_cRefs); 2205 if (count == 0) 2206 { 2207 delete this; 2208 return 0; 2209 } 2210 return count; 2211} 2212 2213STDMETHODIMP CTipbarAccessible::GetTypeInfoCount(UINT *pctinfo) 2214{ 2215 if (!pctinfo) 2216 return E_INVALIDARG; 2217 *pctinfo = (m_pTypeInfo == NULL); 2218 return S_OK; 2219} 2220 2221STDMETHODIMP CTipbarAccessible::GetTypeInfo( 2222 UINT iTInfo, 2223 LCID lcid, 2224 ITypeInfo **ppTInfo) 2225{ 2226 if (!ppTInfo) 2227 return E_INVALIDARG; 2228 *ppTInfo = NULL; 2229 if (iTInfo != 0) 2230 return TYPE_E_ELEMENTNOTFOUND; 2231 if (!m_pTypeInfo) 2232 return E_NOTIMPL; 2233 *ppTInfo = m_pTypeInfo; 2234 m_pTypeInfo->AddRef(); 2235 return S_OK; 2236} 2237 2238STDMETHODIMP CTipbarAccessible::GetIDsOfNames( 2239 REFIID riid, 2240 LPOLESTR *rgszNames, 2241 UINT cNames, 2242 LCID lcid, 2243 DISPID *rgDispId) 2244{ 2245 if (!m_pTypeInfo) 2246 return E_NOTIMPL; 2247 return m_pTypeInfo->GetIDsOfNames(rgszNames, cNames, rgDispId); 2248} 2249 2250STDMETHODIMP CTipbarAccessible::Invoke( 2251 DISPID dispIdMember, 2252 REFIID riid, 2253 LCID lcid, 2254 WORD wFlags, 2255 DISPPARAMS *pDispParams, 2256 VARIANT *pVarResult, 2257 EXCEPINFO *pExcepInfo, 2258 UINT *puArgErr) 2259{ 2260 if (!m_pTypeInfo) 2261 return E_NOTIMPL; 2262 return m_pTypeInfo->Invoke(this, 2263 dispIdMember, 2264 wFlags, 2265 pDispParams, 2266 pVarResult, 2267 pExcepInfo, 2268 puArgErr); 2269} 2270 2271STDMETHODIMP CTipbarAccessible::get_accParent(IDispatch **ppdispParent) 2272{ 2273 return m_pStdAccessible->get_accParent(ppdispParent); 2274} 2275 2276STDMETHODIMP CTipbarAccessible::get_accChildCount(LONG *pcountChildren) 2277{ 2278 if (!pcountChildren) 2279 return E_INVALIDARG; 2280 INT cItems = (INT)m_AccItems.size(); 2281 if (!cItems) 2282 return E_FAIL; 2283 *pcountChildren = cItems - 1; 2284 return S_OK; 2285} 2286 2287STDMETHODIMP CTipbarAccessible::get_accChild( 2288 VARIANT varChildID, 2289 IDispatch **ppdispChild) 2290{ 2291 if (!ppdispChild) 2292 return E_INVALIDARG; 2293 *ppdispChild = NULL; 2294 return S_FALSE; 2295} 2296 2297STDMETHODIMP CTipbarAccessible::get_accName( 2298 VARIANT varID, 2299 BSTR *pszName) 2300{ 2301 if (!pszName) 2302 return E_INVALIDARG; 2303 CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID)); 2304 if (!pItem) 2305 return E_INVALIDARG; 2306 *pszName = pItem->GetAccName(); 2307 if (!*pszName) 2308 return DISP_E_MEMBERNOTFOUND; 2309 return S_OK; 2310} 2311 2312STDMETHODIMP CTipbarAccessible::get_accValue( 2313 VARIANT varID, 2314 BSTR *pszValue) 2315{ 2316 if (!pszValue) 2317 return E_INVALIDARG; 2318 CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID)); 2319 if (!pItem) 2320 return E_INVALIDARG; 2321 *pszValue = pItem->GetAccValue(); 2322 if (!*pszValue) 2323 return DISP_E_MEMBERNOTFOUND; 2324 return S_OK; 2325} 2326 2327STDMETHODIMP CTipbarAccessible::get_accDescription( 2328 VARIANT varID, 2329 BSTR *description) 2330{ 2331 if (!description) 2332 return E_INVALIDARG; 2333 return m_pStdAccessible->get_accDescription(varID, description); 2334} 2335 2336STDMETHODIMP CTipbarAccessible::get_accRole( 2337 VARIANT varID, 2338 VARIANT *role) 2339{ 2340 if (!role) 2341 return E_INVALIDARG; 2342 CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID)); 2343 if (!pItem) 2344 return E_INVALIDARG; 2345 V_VT(role) = VT_I4; 2346 V_I4(role) = pItem->GetAccRole(); 2347 return S_OK; 2348} 2349 2350STDMETHODIMP CTipbarAccessible::get_accState( 2351 VARIANT varID, 2352 VARIANT *state) 2353{ 2354 if (!state) 2355 return E_INVALIDARG; 2356 CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID)); 2357 if (!pItem) 2358 return E_INVALIDARG; 2359 V_VT(state) = VT_I4; 2360 V_I4(state) = pItem->GetAccState(); 2361 return S_OK; 2362} 2363 2364STDMETHODIMP CTipbarAccessible::get_accHelp(VARIANT varID, BSTR *help) 2365{ 2366 return DISP_E_MEMBERNOTFOUND; 2367} 2368 2369STDMETHODIMP CTipbarAccessible::get_accHelpTopic( 2370 BSTR *helpfile, 2371 VARIANT varID, 2372 LONG *pidTopic) 2373{ 2374 return DISP_E_MEMBERNOTFOUND; 2375} 2376 2377STDMETHODIMP CTipbarAccessible::get_accKeyboardShortcut(VARIANT varID, BSTR *shortcut) 2378{ 2379 return DISP_E_MEMBERNOTFOUND; 2380} 2381 2382STDMETHODIMP CTipbarAccessible::get_accFocus(VARIANT *pvarID) 2383{ 2384 if (!pvarID) 2385 return E_INVALIDARG; 2386 V_VT(pvarID) = VT_EMPTY; 2387 return S_FALSE; 2388} 2389 2390STDMETHODIMP CTipbarAccessible::get_accSelection(VARIANT *pvarID) 2391{ 2392 if (!pvarID) 2393 return E_INVALIDARG; 2394 2395 V_VT(pvarID) = VT_EMPTY; 2396 2397 INT cItems = (INT)m_AccItems.size(); 2398 if (cItems < m_cSelection) 2399 return S_FALSE; 2400 2401 if (cItems > m_cSelection) 2402 { 2403 V_VT(pvarID) = VT_I4; 2404 V_I4(pvarID) = m_cSelection; 2405 } 2406 2407 return S_OK; 2408} 2409 2410STDMETHODIMP CTipbarAccessible::get_accDefaultAction( 2411 VARIANT varID, 2412 BSTR *action) 2413{ 2414 if (!action) 2415 return E_INVALIDARG; 2416 *action = NULL; 2417 2418 if (V_VT(&varID) != VT_I4) 2419 return E_INVALIDARG; 2420 2421 CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID)); 2422 if (!pItem) 2423 return DISP_E_MEMBERNOTFOUND; 2424 *action = pItem->GetAccDefaultAction(); 2425 if (!*action) 2426 return S_FALSE; 2427 return S_OK; 2428} 2429 2430STDMETHODIMP CTipbarAccessible::accSelect( 2431 LONG flagsSelect, 2432 VARIANT varID) 2433{ 2434 if ((flagsSelect & SELFLAG_ADDSELECTION) && (flagsSelect & SELFLAG_REMOVESELECTION)) 2435 return E_INVALIDARG; 2436 if (flagsSelect & (SELFLAG_TAKEFOCUS | SELFLAG_ADDSELECTION | SELFLAG_EXTENDSELECTION)) 2437 return S_FALSE; 2438 if (flagsSelect & SELFLAG_REMOVESELECTION) 2439 return S_OK; 2440 if (V_VT(&varID) != VT_I4) 2441 return E_INVALIDARG; 2442 if (flagsSelect & SELFLAG_TAKESELECTION) 2443 { 2444 m_cSelection = V_I4(&varID); 2445 return S_OK; 2446 } 2447 return S_FALSE; 2448} 2449 2450STDMETHODIMP CTipbarAccessible::accLocation( 2451 LONG *left, 2452 LONG *top, 2453 LONG *width, 2454 LONG *height, 2455 VARIANT varID) 2456{ 2457 if (!left || !top || !width || !height) 2458 return E_INVALIDARG; 2459 2460 if (!V_I4(&varID)) 2461 return m_pStdAccessible->accLocation(left, top, width, height, varID); 2462 2463 RECT rc; 2464 CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID)); 2465 pItem->GetAccLocation(&rc); 2466 2467 *left = rc.left; 2468 *top = rc.top; 2469 *width = rc.right - rc.left; 2470 *height = rc.bottom - rc.top; 2471 return S_OK; 2472} 2473 2474STDMETHODIMP CTipbarAccessible::accNavigate( 2475 LONG dir, 2476 VARIANT varStart, 2477 VARIANT *pvarEnd) 2478{ 2479 if (m_AccItems.size() <= 1) 2480 { 2481 V_VT(pvarEnd) = VT_EMPTY; 2482 return S_OK; 2483 } 2484 2485 switch (dir) 2486 { 2487 case NAVDIR_UP: 2488 case NAVDIR_LEFT: 2489 case NAVDIR_PREVIOUS: 2490 V_VT(pvarEnd) = VT_I4; 2491 V_I4(pvarEnd) = V_I4(&varStart) - 1; 2492 if (V_I4(&varStart) - 1 <= 0) 2493 V_I4(pvarEnd) = (INT)(m_AccItems.size() - 1); 2494 return S_OK; 2495 2496 case NAVDIR_DOWN: 2497 case NAVDIR_RIGHT: 2498 case NAVDIR_NEXT: 2499 V_VT(pvarEnd) = VT_I4; 2500 V_I4(pvarEnd) = V_I4(&varStart) + 1; 2501 if ((INT)m_AccItems.size() <= V_I4(&varStart) + 1) 2502 V_I4(pvarEnd) = 1; 2503 return S_OK; 2504 2505 case NAVDIR_FIRSTCHILD: 2506 V_VT(pvarEnd) = VT_I4; 2507 V_I4(pvarEnd) = 1; 2508 return S_OK; 2509 2510 case NAVDIR_LASTCHILD: 2511 V_VT(pvarEnd) = VT_I4; 2512 V_I4(pvarEnd) = (INT)(m_AccItems.size() - 1); 2513 return S_OK; 2514 2515 default: 2516 break; 2517 } 2518 2519 V_VT(pvarEnd) = VT_EMPTY; 2520 return S_OK; 2521} 2522 2523STDMETHODIMP CTipbarAccessible::accHitTest(LONG left, LONG top, VARIANT *pvarID) 2524{ 2525 if (!pvarID) 2526 return E_INVALIDARG; 2527 POINT Point = { left, top }; 2528 RECT Rect; 2529 ::ScreenToClient(m_hWnd, &Point); 2530 ::GetClientRect(m_hWnd, &Rect); 2531 2532 if (!::PtInRect(&Rect, Point)) 2533 { 2534 V_VT(pvarID) = VT_EMPTY; 2535 return S_OK; 2536 } 2537 2538 V_VT(pvarID) = VT_I4; 2539 V_I4(pvarID) = 0; 2540 2541 for (size_t iItem = 1; iItem < m_AccItems.size(); ++iItem) 2542 { 2543 CTipbarAccItem *pItem = m_AccItems[iItem]; 2544 if (pItem) 2545 { 2546 pItem->GetAccLocation(&Rect); 2547 if (::PtInRect(&Rect, Point)) 2548 { 2549 V_I4(pvarID) = iItem; 2550 break; 2551 } 2552 } 2553 } 2554 2555 return S_OK; 2556} 2557 2558STDMETHODIMP CTipbarAccessible::accDoDefaultAction(VARIANT varID) 2559{ 2560 if (V_VT(&varID) != VT_I4) 2561 return E_INVALIDARG; 2562 CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID)); 2563 if (!pItem) 2564 return DISP_E_MEMBERNOTFOUND; 2565 return (pItem->DoAccDefaultAction() ? S_OK : S_FALSE); 2566} 2567 2568STDMETHODIMP CTipbarAccessible::put_accName(VARIANT varID, BSTR name) 2569{ 2570 return S_FALSE; 2571} 2572 2573STDMETHODIMP CTipbarAccessible::put_accValue(VARIANT varID, BSTR value) 2574{ 2575 return S_FALSE; 2576} 2577 2578/*********************************************************************** 2579 * CUTBMenuWnd 2580 */ 2581 2582CUTBMenuWnd::CUTBMenuWnd(HINSTANCE hInst, DWORD style, DWORD dwUnknown14) 2583 : CUIFMenu(hInst, style, dwUnknown14) 2584{ 2585} 2586 2587BOOL CUTBMenuWnd::StartDoAccDefaultActionTimer(CUTBMenuItem *pTarget) 2588{ 2589 if (!m_pAccessible) 2590 return FALSE; 2591 2592 m_nMenuWndID = m_pAccessible->GetIDOfItem(pTarget); 2593 if (!m_nMenuWndID || m_nMenuWndID == (UINT)-1) 2594 return FALSE; 2595 2596 if (::IsWindow(m_hWnd)) 2597 { 2598 ::KillTimer(m_hWnd, TIMER_ID_DOACCDEFAULTACTION); 2599 ::SetTimer(m_hWnd, TIMER_ID_DOACCDEFAULTACTION, g_uTimerElapseDOACCDEFAULTACTION, NULL); 2600 } 2601 2602 return TRUE; 2603} 2604 2605STDMETHODIMP_(BSTR) CUTBMenuWnd::GetAccName() 2606{ 2607 WCHAR szText[64]; 2608 LoadStringW(g_hInst, IDS_MENUWND, szText, _countof(szText)); 2609 return ::SysAllocString(szText); 2610} 2611 2612STDMETHODIMP_(INT) CUTBMenuWnd::GetAccRole() 2613{ 2614 return 9; 2615} 2616 2617STDMETHODIMP_(BOOL) CUTBMenuWnd::Initialize() 2618{ 2619 CTipbarAccessible *pAccessible = new(cicNoThrow) CTipbarAccessible(GetAccItem()); 2620 if (pAccessible) 2621 m_pAccessible = pAccessible; 2622 2623 return CUIFObject::Initialize(); 2624} 2625 2626STDMETHODIMP_(void) CUTBMenuWnd::OnCreate(HWND hWnd) 2627{ 2628 if (m_pAccessible) 2629 m_pAccessible->SetWindow(hWnd); 2630} 2631 2632STDMETHODIMP_(void) CUTBMenuWnd::OnDestroy(HWND hWnd) 2633{ 2634 if (m_pAccessible) 2635 { 2636 m_pAccessible->NotifyWinEvent(EVENT_OBJECT_DESTROY, GetAccItem()); 2637 m_pAccessible->ClearAccItems(); 2638 m_pAccessible->Release(); 2639 m_pAccessible = NULL; 2640 } 2641 m_coInit.CoUninit(); 2642} 2643 2644STDMETHODIMP_(HRESULT) 2645CUTBMenuWnd::OnGetObject(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 2646{ 2647 if (lParam != -4) 2648 return S_OK; 2649 2650 if (!m_pAccessible) 2651 return E_OUTOFMEMORY; 2652 2653 if (m_pAccessible->m_bInitialized) 2654 return m_pAccessible->CreateRefToAccObj(wParam); 2655 2656 if (SUCCEEDED(m_coInit.EnsureCoInit())) 2657 { 2658 HRESULT hr = m_pAccessible->Initialize(); 2659 if (FAILED(hr)) 2660 { 2661 m_pAccessible->Release(); 2662 m_pAccessible = NULL; 2663 return hr; 2664 } 2665 2666 m_pAccessible->NotifyWinEvent(EVENT_OBJECT_CREATE, GetAccItem()); 2667 return m_pAccessible->CreateRefToAccObj(wParam); 2668 } 2669 2670 return S_OK; 2671} 2672 2673STDMETHODIMP_(LRESULT) 2674CUTBMenuWnd::OnShowWindow(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 2675{ 2676 if (m_pAccessible) 2677 { 2678 if (wParam) 2679 { 2680 m_pAccessible->NotifyWinEvent(EVENT_OBJECT_SHOW, GetAccItem()); 2681 m_pAccessible->NotifyWinEvent(EVENT_OBJECT_FOCUS, GetAccItem()); 2682 } 2683 else 2684 { 2685 m_pAccessible->NotifyWinEvent(EVENT_OBJECT_HIDE, GetAccItem()); 2686 } 2687 } 2688 2689 return ::DefWindowProc(hWnd, uMsg, wParam, lParam); 2690} 2691 2692STDMETHODIMP_(void) CUTBMenuWnd::OnTimer(WPARAM wParam) 2693{ 2694 if (wParam == TIMER_ID_DOACCDEFAULTACTION) 2695 { 2696 ::KillTimer(m_hWnd, TIMER_ID_DOACCDEFAULTACTION); 2697 if (m_pAccessible && m_nMenuWndID) 2698 { 2699 m_pAccessible->DoDefaultActionReal(m_nMenuWndID); 2700 m_nMenuWndID = 0; 2701 } 2702 } 2703} 2704 2705/*********************************************************************** 2706 * CUTBMenuItem 2707 */ 2708 2709CUTBMenuItem::CUTBMenuItem(CUTBMenuWnd *pMenuUI) 2710 : CUIFMenuItem(pMenuUI ? pMenuUI->GetMenu() : NULL) 2711{ 2712 m_pMenuUI = pMenuUI; 2713} 2714 2715CUTBMenuItem::~CUTBMenuItem() 2716{ 2717 if (m_hbmColor) 2718 { 2719 ::DeleteObject(m_hbmColor); 2720 m_hbmColor = NULL; 2721 } 2722 if (m_hbmMask) 2723 { 2724 ::DeleteObject(m_hbmMask); 2725 m_hbmMask = NULL; 2726 } 2727} 2728 2729STDMETHODIMP_(BOOL) CUTBMenuItem::DoAccDefaultAction() 2730{ 2731 if (!m_pMenuUI) 2732 return FALSE; 2733 2734 m_pMenuUI->StartDoAccDefaultActionTimer(this); 2735 return TRUE; 2736} 2737 2738STDMETHODIMP_(BOOL) CUTBMenuItem::DoAccDefaultActionReal() 2739{ 2740 if (!m_pSubMenu) 2741 OnLButtonUp(0, 0); 2742 else 2743 ShowSubPopup(); 2744 return TRUE; 2745} 2746 2747STDMETHODIMP_(BSTR) CUTBMenuItem::GetAccDefaultAction() 2748{ 2749 WCHAR szText[64]; 2750 ::LoadStringW(g_hInst, IDS_LEFTCLICK, szText, _countof(szText)); 2751 return ::SysAllocString(szText); 2752} 2753 2754STDMETHODIMP_(void) CUTBMenuItem::GetAccLocation(LPRECT lprc) 2755{ 2756 GetRect(lprc); 2757 ::ClientToScreen(m_pMenuUI->m_hWnd, (LPPOINT)lprc); 2758 ::ClientToScreen(m_pMenuUI->m_hWnd, (LPPOINT)&lprc->right); 2759} 2760 2761STDMETHODIMP_(BSTR) CUTBMenuItem::GetAccName() 2762{ 2763 return ::SysAllocString(m_pszMenuItemLeft); 2764} 2765 2766/// @unimplemented 2767STDMETHODIMP_(INT) CUTBMenuItem::GetAccRole() 2768{ 2769 if (FALSE) //FIXME 2770 return 21; 2771 return 12; 2772} 2773 2774/*********************************************************************** 2775 * CModalMenu 2776 */ 2777 2778CUTBMenuItem * 2779CModalMenu::InsertItem(CUTBMenuWnd *pMenuUI, INT nCommandId, INT nStringID) 2780{ 2781 CUTBMenuItem *pMenuItem = new(cicNoThrow) CUTBMenuItem(pMenuUI); 2782 if (!pMenuItem) 2783 return NULL; 2784 2785 WCHAR szText[256]; 2786 ::LoadStringW(g_hInst, nStringID, szText, _countof(szText)); 2787 2788 if (pMenuItem->Initialize() && 2789 pMenuItem->Init(nCommandId, szText) && 2790 pMenuUI->InsertItem(pMenuItem)) 2791 { 2792 return pMenuItem; 2793 } 2794 2795 delete pMenuItem; 2796 return NULL; 2797} 2798 2799void CModalMenu::PostKey(BOOL bUp, WPARAM wParam, LPARAM lParam) 2800{ 2801 m_pMenuUI->PostKey(bUp, wParam, lParam); 2802} 2803 2804void CModalMenu::CancelMenu() 2805{ 2806 if (m_pMenuUI) 2807 m_pMenuUI->CancelMenu(); 2808} 2809 2810/*********************************************************************** 2811 * CUTBContextMenu 2812 */ 2813 2814CUTBContextMenu::CUTBContextMenu(CTipbarWnd *pTipbarWnd) 2815{ 2816 m_pTipbarWnd = pTipbarWnd; 2817} 2818 2819/// @implemented 2820BOOL CUTBContextMenu::Init() 2821{ 2822 m_pTipbarThread = m_pTipbarWnd->m_pFocusThread; 2823 return !!m_pTipbarThread; 2824} 2825 2826/// @unimplemented 2827CUTBMenuWnd *CUTBContextMenu::CreateMenuUI(BOOL bFlag) 2828{ 2829 DWORD dwStatus = 0; 2830 2831 if (FAILED(m_pTipbarWnd->m_pLangBarMgr->GetShowFloatingStatus(&dwStatus))) 2832 return NULL; 2833 2834 CUTBMenuWnd *pMenuUI = new (cicNoThrow) CUTBMenuWnd(g_hInst, g_dwMenuStyle, 0); 2835 if (!pMenuUI) 2836 return NULL; 2837 2838 pMenuUI->Initialize(); 2839 2840 if (dwStatus & (TF_SFT_DESKBAND | TF_SFT_MINIMIZED)) 2841 { 2842 CUTBMenuItem *pRestoreLangBar = InsertItem(pMenuUI, ID_RESTORELANGBAR, IDS_RESTORELANGBAR2); 2843 if (pRestoreLangBar && !m_pTipbarWnd->m_dwUnknown20) 2844 pRestoreLangBar->Gray(TRUE); 2845 } 2846 else 2847 { 2848 InsertItem(pMenuUI, ID_DESKBAND, IDS_MINIMIZE); 2849 2850 if (bFlag) 2851 { 2852 if (IsTransparecyAvailable()) 2853 { 2854 if (dwStatus & TF_LBI_BALLOON) 2855 { 2856 InsertItem(pMenuUI, ID_TRANS, IDS_TRANSPARENCY); 2857 } 2858 else 2859 { 2860 CUTBMenuItem *pTransparency = InsertItem(pMenuUI, ID_NOTRANS, IDS_TRANSPARENCY); 2861 if (pTransparency) 2862 pTransparency->Check(TRUE); 2863 } 2864 } 2865 2866 if (!(dwStatus & TF_SFT_LABELS)) 2867 { 2868 InsertItem(pMenuUI, ID_LABELS, IDS_TEXTLABELS); 2869 } 2870 else 2871 { 2872 CUTBMenuItem *pTextLabels = InsertItem(pMenuUI, ID_NOLABELS, IDS_TEXTLABELS); 2873 if (pTextLabels) 2874 pTextLabels->Check(TRUE); 2875 } 2876 2877 CUTBMenuItem *pVertical = InsertItem(pMenuUI, ID_VERTICAL, IDS_VERTICAL); 2878 if (pVertical) 2879 pVertical->Check(!!(m_pTipbarWnd->m_dwTipbarWndFlags & TIPBAR_VERTICAL)); 2880 } 2881 } 2882 2883 if (bFlag) 2884 { 2885 CUTBMenuItem *pExtraIcons = NULL; 2886 2887 if (dwStatus & TF_SFT_EXTRAICONSONMINIMIZED) 2888 { 2889 pExtraIcons = InsertItem(pMenuUI, ID_NOEXTRAICONS, IDS_EXTRAICONS); 2890 if (pExtraIcons) 2891 pExtraIcons->Check(TRUE); 2892 } 2893 else 2894 { 2895 pExtraIcons = CModalMenu::InsertItem(pMenuUI, ID_EXTRAICONS, IDS_EXTRAICONS); 2896 } 2897 2898 if (pExtraIcons) 2899 { 2900 if (::GetKeyboardLayoutList(0, NULL) == 1) 2901 { 2902 pExtraIcons->Check(TRUE); 2903 pExtraIcons->Gray(TRUE); 2904 } 2905 else 2906 { 2907 pExtraIcons->Gray(FALSE); 2908 } 2909 } 2910 2911 if (dwStatus & TF_SFT_DESKBAND) 2912 InsertItem(pMenuUI, ID_ADJUSTDESKBAND, IDS_ADJUSTLANGBAND); 2913 2914 InsertItem(pMenuUI, ID_SETTINGS, IDS_SETTINGS); 2915 2916 if (CheckCloseMenuAvailable()) 2917 InsertItem(pMenuUI, ID_CLOSELANGBAR, IDS_CLOSELANGBAR); 2918 } 2919 2920 return pMenuUI; 2921} 2922 2923UINT 2924CUTBContextMenu::ShowPopup( 2925 CUIFWindow *pWindow, 2926 POINT pt, 2927 LPCRECT prc, 2928 BOOL bFlag) 2929{ 2930 if (g_bWinLogon) 2931 return 0; 2932 2933 if (m_pMenuUI) 2934 return -1; 2935 2936 m_pMenuUI = CreateMenuUI(bFlag); 2937 if (!m_pMenuUI) 2938 return 0; 2939 2940 UINT nCommandId = m_pMenuUI->ShowModalPopup(pWindow, prc, TRUE); 2941 2942 if (m_pMenuUI) 2943 { 2944 delete m_pMenuUI; 2945 m_pMenuUI = NULL; 2946 } 2947 2948 return nCommandId; 2949} 2950 2951/// @unimplemented 2952BOOL CUTBContextMenu::SelectMenuItem(UINT nCommandId) 2953{ 2954 switch (nCommandId) 2955 { 2956 case ID_TRANS: 2957 m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_LOWTRANSPARENCY); 2958 break; 2959 2960 case ID_NOTRANS: 2961 m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_NOTRANSPARENCY); 2962 break; 2963 2964 case ID_LABELS: 2965 m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_LABELS); 2966 break; 2967 2968 case ID_NOLABELS: 2969 m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_NOLABELS); 2970 break; 2971 2972 case ID_DESKBAND: 2973 { 2974 if (!g_bEnableDeskBand || !(g_dwOSInfo & CIC_OSINFO_XPPLUS)) 2975 { 2976 m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_MINIMIZED); 2977 } 2978 else 2979 { 2980 DWORD dwStatus; 2981 m_pTipbarWnd->m_pLangBarMgr->GetShowFloatingStatus(&dwStatus); 2982 2983 if (dwStatus & TF_SFT_DESKBAND) 2984 break; 2985 2986 m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_DESKBAND); 2987 } 2988 2989 CUTBMinimizeLangBarDlg *pDialog = new(cicNoThrow) CUTBMinimizeLangBarDlg(); 2990 if (pDialog) 2991 { 2992 pDialog->DoModal(*m_pTipbarWnd->GetWindow()); 2993 pDialog->_Release(); 2994 } 2995 break; 2996 } 2997 2998 case ID_CLOSELANGBAR: 2999 { 3000 CUTBCloseLangBarDlg *pDialog = new(cicNoThrow) CUTBCloseLangBarDlg(); 3001 if (pDialog) 3002 { 3003 BOOL bOK = pDialog->DoModal(*m_pTipbarWnd->GetWindow()); 3004 pDialog->_Release(); 3005 if (!bOK) 3006 DoCloseLangbar(); 3007 } 3008 break; 3009 } 3010 3011 case ID_EXTRAICONS: 3012 m_pTipbarWnd->m_dwTipbarWndFlags &= ~TIPBAR_NODESKBAND; 3013 m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_EXTRAICONSONMINIMIZED); 3014 break; 3015 3016 case ID_NOEXTRAICONS: 3017 m_pTipbarWnd->m_dwTipbarWndFlags &= ~TIPBAR_NODESKBAND; 3018 m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_NOEXTRAICONSONMINIMIZED); 3019 break; 3020 3021 case ID_RESTORELANGBAR: 3022 m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_LBI_ICON); 3023 break; 3024 3025 case ID_VERTICAL: 3026 m_pTipbarWnd->SetVertical(!!(m_pTipbarWnd->m_dwTipbarWndFlags & TIPBAR_VERTICAL)); 3027 break; 3028 3029 case ID_ADJUSTDESKBAND: 3030 m_pTipbarWnd->AdjustDeskBandSize(TRUE); 3031 break; 3032 3033 case ID_SETTINGS: 3034 TF_RunInputCPL(); 3035 break; 3036 3037 default: 3038 break; 3039 } 3040 3041 return TRUE; 3042} 3043 3044/*********************************************************************** 3045 * CTrayIconItem 3046 */ 3047 3048CTrayIconItem::CTrayIconItem(CTrayIconWnd *pTrayIconWnd) 3049{ 3050 m_dwIconAddOrModify = NIM_ADD; 3051 m_pTrayIconWnd = pTrayIconWnd; 3052} 3053 3054BOOL 3055CTrayIconItem::_Init( 3056 HWND hWnd, 3057 UINT uCallbackMessage, 3058 UINT uNotifyIconID, 3059 const GUID& rguid) 3060{ 3061 m_hWnd = hWnd; 3062 m_uCallbackMessage = uCallbackMessage; 3063 m_uNotifyIconID = uNotifyIconID; 3064 m_guid = rguid; 3065 return TRUE; 3066} 3067 3068BOOL CTrayIconItem::RemoveIcon() 3069{ 3070 if (m_dwIconAddOrModify == NIM_MODIFY) 3071 { 3072 NOTIFYICONDATAW NotifyIcon = { sizeof(NotifyIcon), m_hWnd, m_uNotifyIconID }; 3073 NotifyIcon.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; 3074 NotifyIcon.uCallbackMessage = m_uCallbackMessage; 3075 ::Shell_NotifyIconW(NIM_DELETE, &NotifyIcon); 3076 } 3077 3078 m_dwIconAddOrModify = NIM_ADD; 3079 m_bIconAdded = TRUE; 3080 return TRUE; 3081} 3082 3083BOOL CTrayIconItem::SetIcon(HICON hIcon, LPCWSTR pszTip) 3084{ 3085 if (!hIcon) 3086 return FALSE; 3087 3088 NOTIFYICONDATAW NotifyIcon = { sizeof(NotifyIcon), m_hWnd, m_uNotifyIconID }; 3089 NotifyIcon.uFlags = NIF_ICON | NIF_MESSAGE; 3090 NotifyIcon.uCallbackMessage = m_uCallbackMessage; 3091 NotifyIcon.hIcon = hIcon; 3092 if (pszTip) 3093 { 3094 NotifyIcon.uFlags |= NIF_TIP; 3095 StringCchCopyW(NotifyIcon.szTip, _countof(NotifyIcon.szTip), pszTip); 3096 } 3097 3098 ::Shell_NotifyIconW(m_dwIconAddOrModify, &NotifyIcon); 3099 3100 m_dwIconAddOrModify = NIM_MODIFY; 3101 m_bIconAdded = NIM_MODIFY; 3102 return TRUE; 3103} 3104 3105BOOL CTrayIconItem::UpdateMenuRectPoint() 3106{ 3107 HWND hNotifyWnd = m_pTrayIconWnd->GetNotifyWnd(); 3108 ::GetClientRect(hNotifyWnd, &m_rcMenu); 3109 ::ClientToScreen(hNotifyWnd, (LPPOINT)&m_rcMenu); 3110 ::ClientToScreen(hNotifyWnd, (LPPOINT)&m_rcMenu.right); 3111 ::GetCursorPos(&m_ptCursor); 3112 return TRUE; 3113} 3114 3115/*********************************************************************** 3116 * CButtonIconItem 3117 */ 3118 3119CButtonIconItem::CButtonIconItem(CTrayIconWnd *pWnd, DWORD dwUnknown24) 3120 : CTrayIconItem(pWnd) 3121{ 3122 m_dwUnknown24 = dwUnknown24; 3123} 3124 3125/// @unimplemented 3126STDMETHODIMP_(BOOL) CButtonIconItem::OnMsg(WPARAM wParam, LPARAM lParam) 3127{ 3128 switch (lParam) 3129 { 3130 case WM_LBUTTONDOWN: 3131 case WM_RBUTTONDOWN: 3132 case WM_LBUTTONDBLCLK: 3133 case WM_RBUTTONDBLCLK: 3134 break; 3135 default: 3136 return TRUE; 3137 } 3138 3139 //FIXME 3140 return TRUE; 3141} 3142 3143/// @unimplemented 3144STDMETHODIMP_(BOOL) CButtonIconItem::OnDelayMsg(UINT uMsg) 3145{ 3146 //FIXME 3147 return FALSE; 3148} 3149 3150/*********************************************************************** 3151 * CMainIconItem 3152 */ 3153 3154/// @implemented 3155CMainIconItem::CMainIconItem(CTrayIconWnd *pWnd) 3156 : CButtonIconItem(pWnd, 1) 3157{ 3158} 3159 3160/// @implemented 3161BOOL CMainIconItem::Init(HWND hWnd) 3162{ 3163 return CTrayIconItem::_Init(hWnd, WM_USER, 0, GUID_LBI_TRAYMAIN); 3164} 3165 3166/// @implemented 3167STDMETHODIMP_(BOOL) CMainIconItem::OnDelayMsg(UINT uMsg) 3168{ 3169 if (!CButtonIconItem::OnDelayMsg(uMsg)) 3170 return 0; 3171 3172 if (uMsg == WM_LBUTTONDBLCLK) 3173 { 3174 if (g_pTipbarWnd->m_dwUnknown20) 3175 g_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_SHOWNORMAL); 3176 } 3177 else if (uMsg == WM_LBUTTONDOWN || uMsg == WM_RBUTTONDOWN) 3178 { 3179 g_pTipbarWnd->ShowContextMenu(m_ptCursor, &m_rcMenu, uMsg == WM_RBUTTONDOWN); 3180 } 3181 return TRUE; 3182} 3183 3184/*********************************************************************** 3185 * CTrayIconWnd 3186 */ 3187 3188CTrayIconWnd::CTrayIconWnd() 3189{ 3190 m_uCallbackMsg = WM_USER + 0x1000; 3191 m_uNotifyIconID = 0x1000; 3192} 3193 3194CTrayIconWnd::~CTrayIconWnd() 3195{ 3196 for (size_t iItem = 0; iItem < m_Items.size(); ++iItem) 3197 { 3198 auto& pItem = m_Items[iItem]; 3199 if (pItem) 3200 { 3201 delete pItem; 3202 pItem = NULL; 3203 } 3204 } 3205} 3206 3207void CTrayIconWnd::CallOnDelayMsg() 3208{ 3209 for (size_t iItem = 0; iItem < m_Items.size(); ++iItem) 3210 { 3211 auto pItem = m_Items[iItem]; 3212 if (pItem && m_uCallbackMessage == pItem->m_uCallbackMessage) 3213 { 3214 pItem->OnDelayMsg(m_uMsg); 3215 break; 3216 } 3217 } 3218} 3219 3220HWND CTrayIconWnd::CreateWnd() 3221{ 3222 m_hWnd = ::CreateWindowEx(0, TEXT("CTrayIconWndClass"), NULL, WS_DISABLED, 3223 0, 0, 0, 0, NULL, NULL, g_hInst, this); 3224 FindTrayEtc(); 3225 3226 m_pMainIconItem = new(cicNoThrow) CMainIconItem(this); 3227 if (m_pMainIconItem) 3228 { 3229 m_pMainIconItem->Init(m_hWnd); 3230 m_Items.Add(m_pMainIconItem); 3231 } 3232 3233 return m_hWnd; 3234} 3235 3236void CTrayIconWnd::DestroyWnd() 3237{ 3238 ::DestroyWindow(m_hWnd); 3239 m_hWnd = NULL; 3240} 3241 3242BOOL CALLBACK CTrayIconWnd::EnumChildWndProc(HWND hWnd, LPARAM lParam) 3243{ 3244 CTrayIconWnd *pWnd = (CTrayIconWnd *)lParam; 3245 3246 TCHAR ClassName[60]; 3247 ::GetClassName(hWnd, ClassName, _countof(ClassName)); 3248 if (lstrcmp(ClassName, TEXT("TrayNotifyWnd")) != 0) 3249 return TRUE; 3250 3251 pWnd->m_hNotifyWnd = hWnd; 3252 return FALSE; 3253} 3254 3255CButtonIconItem *CTrayIconWnd::FindIconItem(REFGUID rguid) 3256{ 3257 for (size_t iItem = 0; iItem < m_Items.size(); ++iItem) 3258 { 3259 auto pItem = m_Items[iItem]; 3260 if (IsEqualGUID(rguid, pItem->m_guid)) 3261 return pItem; 3262 } 3263 return NULL; 3264} 3265 3266BOOL CTrayIconWnd::FindTrayEtc() 3267{ 3268 m_hTrayWnd = ::FindWindow(TEXT("Shell_TrayWnd"), NULL); 3269 if (!m_hTrayWnd) 3270 return FALSE; 3271 3272 ::EnumChildWindows(m_hTrayWnd, EnumChildWndProc, (LPARAM)this); 3273 if (!m_hNotifyWnd) 3274 return FALSE; 3275 m_dwTrayWndThreadId = ::GetWindowThreadProcessId(m_hTrayWnd, NULL); 3276 m_hwndProgman = FindWindow(TEXT("Progman"), NULL); 3277 m_dwProgmanThreadId = ::GetWindowThreadProcessId(m_hwndProgman, NULL); 3278 return TRUE; 3279} 3280 3281HWND CTrayIconWnd::GetNotifyWnd() 3282{ 3283 if (!::IsWindow(m_hNotifyWnd)) 3284 FindTrayEtc(); 3285 return m_hNotifyWnd; 3286} 3287 3288/// @implemented 3289BOOL CTrayIconWnd::OnIconMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) 3290{ 3291 if (g_pTipbarWnd) 3292 g_pTipbarWnd->AttachFocusThread(); 3293 3294 for (size_t iItem = 0; iItem < m_Items.size(); ++iItem) 3295 { 3296 auto *pItem = m_Items[iItem]; 3297 if (pItem) 3298 { 3299 if (uMsg == pItem->m_uCallbackMessage) 3300 { 3301 pItem->OnMsg(wParam, lParam); 3302 return TRUE; 3303 } 3304 } 3305 } 3306 return FALSE; 3307} 3308 3309BOOL CTrayIconWnd::RegisterClass() 3310{ 3311 WNDCLASSEX wc = { sizeof(wc) }; 3312 wc.style = CS_HREDRAW | CS_VREDRAW; 3313 wc.hInstance = g_hInst; 3314 wc.hCursor = ::LoadCursor(NULL, (LPCTSTR)IDC_ARROW); 3315 wc.lpfnWndProc = CTrayIconWnd::_WndProc; 3316 wc.lpszClassName = TEXT("CTrayIconWndClass"); 3317 ::RegisterClassEx(&wc); 3318 return TRUE; 3319} 3320 3321void CTrayIconWnd::RemoveAllIcon(DWORD dwFlags) 3322{ 3323 for (size_t iItem = 0; iItem < m_Items.size(); ++iItem) 3324 { 3325 auto pItem = m_Items[iItem]; 3326 if (dwFlags & 0x1) 3327 { 3328 if (IsEqualGUID(pItem->m_guid, GUID_LBI_INATITEM) || 3329 IsEqualGUID(pItem->m_guid, GUID_LBI_CTRL)) 3330 { 3331 continue; 3332 } 3333 } 3334 3335 if (dwFlags & 0x2) 3336 { 3337 if (IsEqualGUID(pItem->m_guid, GUID_TFCAT_TIP_KEYBOARD)) 3338 continue; 3339 } 3340 3341 if (pItem->m_uNotifyIconID < 0x1000) 3342 continue; 3343 3344 pItem->RemoveIcon(); 3345 } 3346} 3347 3348/// @unimplemented 3349void CTrayIconWnd::RemoveUnusedIcons(int unknown) 3350{ 3351 //FIXME 3352} 3353 3354BOOL CTrayIconWnd::SetIcon(REFGUID rguid, DWORD dwUnknown24, HICON hIcon, LPCWSTR psz) 3355{ 3356 CButtonIconItem *pItem = FindIconItem(rguid); 3357 if (!pItem) 3358 { 3359 if (!hIcon) 3360 return FALSE; 3361 pItem = new(cicNoThrow) CButtonIconItem(this, dwUnknown24); 3362 if (!pItem) 3363 return FALSE; 3364 3365 pItem->_Init(m_hWnd, m_uCallbackMsg, m_uNotifyIconID, rguid); 3366 m_uCallbackMsg += 2; 3367 ++m_uNotifyIconID; 3368 m_Items.Add(pItem); 3369 } 3370 3371 if (!hIcon) 3372 return pItem->RemoveIcon(); 3373 3374 return pItem->SetIcon(hIcon, psz); 3375} 3376 3377BOOL CTrayIconWnd::SetMainIcon(HKL hKL) 3378{ 3379 if (!hKL) 3380 { 3381 m_pMainIconItem->RemoveIcon(); 3382 m_pMainIconItem->m_hKL = NULL; 3383 return TRUE; 3384 } 3385 3386 if (hKL != m_pMainIconItem->m_hKL) 3387 { 3388 WCHAR szText[64]; 3389 HICON hIcon = TF_GetLangIcon(LOWORD(hKL), szText, _countof(szText)); 3390 if (hIcon) 3391 { 3392 m_pMainIconItem->SetIcon(hIcon, szText); 3393 ::DestroyIcon(hIcon); 3394 } 3395 else 3396 { 3397 ::LoadStringW(g_hInst, IDS_RESTORELANGBAR, szText, _countof(szText)); 3398 hIcon = ::LoadIconW(g_hInst, MAKEINTRESOURCEW(IDI_MAINICON)); 3399 m_pMainIconItem->SetIcon(hIcon, szText); 3400 } 3401 3402 m_pMainIconItem->m_hKL = hKL; 3403 } 3404 3405 return TRUE; 3406} 3407 3408CTrayIconWnd *CTrayIconWnd::GetThis(HWND hWnd) 3409{ 3410 return (CTrayIconWnd *)::GetWindowLongPtr(hWnd, GWL_USERDATA); 3411} 3412 3413void CTrayIconWnd::SetThis(HWND hWnd, LPCREATESTRUCT pCS) 3414{ 3415 if (pCS) 3416 ::SetWindowLongPtr(hWnd, GWL_USERDATA, (LONG_PTR)pCS->lpCreateParams); 3417 else 3418 ::SetWindowLongPtr(hWnd, GWL_USERDATA, 0); 3419} 3420 3421LRESULT CALLBACK 3422CTrayIconWnd::_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 3423{ 3424 CTrayIconWnd *pThis; 3425 switch (uMsg) 3426 { 3427 case WM_CREATE: 3428 CTrayIconWnd::SetThis(hWnd, (LPCREATESTRUCT)lParam); 3429 break; 3430 case WM_DESTROY: 3431 ::SetWindowLongPtr(hWnd, GWL_USERDATA, 0); 3432 break; 3433 case WM_TIMER: 3434 if (wParam == 100) 3435 { 3436 ::KillTimer(hWnd, 100); 3437 pThis = CTrayIconWnd::GetThis(hWnd); 3438 if (pThis) 3439 pThis->CallOnDelayMsg(); 3440 } 3441 break; 3442 default: 3443 { 3444 if (uMsg < WM_USER) 3445 return ::DefWindowProc(hWnd, uMsg, wParam, lParam); 3446 pThis = CTrayIconWnd::GetThis(hWnd); 3447 if (pThis && pThis->OnIconMessage(uMsg, wParam, lParam)) 3448 break; 3449 return ::DefWindowProc(hWnd, uMsg, wParam, lParam); 3450 } 3451 } 3452 return 0; 3453} 3454 3455/*********************************************************************** 3456 * CLBarItemBase 3457 */ 3458 3459CLBarItemBase::CLBarItemBase() 3460{ 3461 m_dwItemStatus = 0; 3462 m_szToolTipText[0] = 0; 3463 m_cRefs = 1; 3464 m_pLangBarItemSink = NULL; 3465} 3466 3467CLBarItemBase::~CLBarItemBase() 3468{ 3469 if (m_pLangBarItemSink) 3470 m_pLangBarItemSink->Release(); 3471} 3472 3473HRESULT 3474CLBarItemBase::AdviseSink( 3475 REFIID riid, 3476 IUnknown *punk, 3477 DWORD *pdwCookie) 3478{ 3479 if (IsEqualIID(riid, IID_ITfLangBarItemSink) || m_pLangBarItemSink) 3480 return TF_E_NOOBJECT; 3481 3482 HRESULT hr = punk->QueryInterface(IID_ITfLangBarItemSink, (void **)&m_pLangBarItemSink); 3483 if (SUCCEEDED(hr)) 3484 *pdwCookie = 0x80000001; 3485 return hr; 3486} 3487 3488HRESULT CLBarItemBase::UnadviseSink(DWORD dwCookie) 3489{ 3490 if (dwCookie != 0x80000001) 3491 return E_FAIL; 3492 3493 if (!m_pLangBarItemSink) 3494 return E_UNEXPECTED; 3495 3496 m_pLangBarItemSink->Release(); 3497 m_pLangBarItemSink = NULL; 3498 return S_OK; 3499} 3500 3501void 3502CLBarItemBase::InitNuiInfo( 3503 REFIID clsidService, 3504 REFGUID guidItem, 3505 DWORD dwStyle, 3506 DWORD ulSort, 3507 LPCWSTR Source) 3508{ 3509 m_NewUIInfo.clsidService = clsidService; 3510 m_NewUIInfo.guidItem = guidItem; 3511 m_NewUIInfo.dwStyle = dwStyle; 3512 m_NewUIInfo.ulSort = ulSort; 3513 StringCchCopyW(m_NewUIInfo.szDescription, _countof(m_NewUIInfo.szDescription), Source); 3514} 3515 3516HRESULT 3517CLBarItemBase::ShowInternal(BOOL bShow, BOOL bUpdate) 3518{ 3519 DWORD dwOldStatus = m_dwItemStatus; 3520 3521 if (bShow) 3522 m_dwItemStatus &= ~TF_LBI_STATUS_HIDDEN; 3523 else 3524 m_dwItemStatus |= TF_LBI_STATUS_HIDDEN; 3525 3526 if (bUpdate && (dwOldStatus != m_dwItemStatus)) 3527 { 3528 if (m_pLangBarItemSink) 3529 m_pLangBarItemSink->OnUpdate(TF_LBI_STATUS); 3530 } 3531 3532 return S_OK; 3533} 3534 3535HRESULT CLBarItemBase::GetInfo(TF_LANGBARITEMINFO *pInfo) 3536{ 3537 CopyMemory(pInfo, &m_NewUIInfo, sizeof(*pInfo)); 3538 return S_OK; 3539} 3540 3541HRESULT CLBarItemBase::GetStatus(DWORD *pdwStatus) 3542{ 3543 *pdwStatus = m_dwItemStatus; 3544 return S_OK; 3545} 3546 3547HRESULT CLBarItemBase::Show(BOOL fShow) 3548{ 3549 return ShowInternal(fShow, TRUE); 3550} 3551 3552HRESULT CLBarItemBase::GetTooltipString(BSTR *pbstrToolTip) 3553{ 3554 if (!pbstrToolTip) 3555 return E_INVALIDARG; 3556 BSTR bstr = ::SysAllocString(m_szToolTipText); 3557 *pbstrToolTip = bstr; 3558 return bstr ? S_OK : E_OUTOFMEMORY; 3559} 3560 3561/*********************************************************************** 3562 * CUTBLBarMenu 3563 */ 3564 3565CUTBLBarMenu::CUTBLBarMenu(HINSTANCE hInst) : CCicLibMenu() 3566{ 3567 m_hInst = hInst; 3568} 3569 3570CUTBLBarMenu::~CUTBLBarMenu() 3571{ 3572} 3573 3574STDMETHODIMP_(CCicLibMenuItem*) CUTBLBarMenu::CreateMenuItem() 3575{ 3576 CUTBLBarMenuItem *pItem = new(cicNoThrow) CUTBLBarMenuItem(); 3577 if (!pItem) 3578 return NULL; 3579 pItem->m_pLBarMenu = this; 3580 return pItem; 3581} 3582 3583CUTBMenuWnd *CUTBLBarMenu::CreateMenuUI() 3584{ 3585 CUTBMenuWnd *pMenuUI = new(cicNoThrow) CUTBMenuWnd(m_hInst, g_dwMenuStyle, 0); 3586 if (!pMenuUI) 3587 return NULL; 3588 3589 pMenuUI->Initialize(); 3590 for (size_t iItem = 0; iItem < m_MenuItems.size(); ++iItem) 3591 { 3592 CUTBLBarMenuItem *pItem = (CUTBLBarMenuItem *)m_MenuItems[iItem]; 3593 pItem->InsertToUI(pMenuUI); 3594 } 3595 3596 return pMenuUI; 3597} 3598 3599STDMETHODIMP_(CCicLibMenu*) CUTBLBarMenu::CreateSubMenu() 3600{ 3601 return new(cicNoThrow) CUTBLBarMenu(m_hInst); 3602} 3603 3604INT CUTBLBarMenu::ShowPopup(CUIFWindow *pWindow, POINT pt, LPCRECT prcExclude) 3605{ 3606 if (m_pMenuUI) 3607 return 0; 3608 3609 m_pMenuUI = CreateMenuUI(); 3610 if (!m_pMenuUI) 3611 return -1; 3612 3613 INT nCommandId = m_pMenuUI->ShowModalPopup(pWindow, prcExclude, TRUE); 3614 3615 if (m_pMenuUI) 3616 { 3617 delete m_pMenuUI; 3618 m_pMenuUI = NULL; 3619 } 3620 3621 return nCommandId; 3622} 3623 3624/*********************************************************************** 3625 * CUTBLBarMenuItem 3626 */ 3627 3628/// @unimplemented 3629BOOL CUTBLBarMenuItem::InsertToUI(CUTBMenuWnd *pMenuUI) 3630{ 3631 if ((m_dwFlags & 4) != 0) 3632 { 3633 pMenuUI->InsertSeparator(); 3634 return TRUE; 3635 } 3636 if (m_dwFlags & 2) 3637 { 3638 //FIXME 3639 } 3640 else 3641 { 3642 //FIXME 3643 } 3644 return FALSE; 3645} 3646 3647/*********************************************************************** 3648 * CLBarItemButtonBase 3649 */ 3650 3651CLBarItemButtonBase::~CLBarItemButtonBase() 3652{ 3653 if (m_hIcon) 3654 { 3655 ::DestroyIcon(m_hIcon); 3656 m_hIcon = NULL; 3657 } 3658} 3659 3660STDMETHODIMP CLBarItemButtonBase::QueryInterface(REFIID riid, void **ppvObject) 3661{ 3662 static const QITAB c_tab[] = 3663 { 3664 QITABENT(CLBarItemButtonBase, ITfLangBarItem), 3665 QITABENT(CLBarItemButtonBase, ITfLangBarItemButton), 3666 QITABENT(CLBarItemButtonBase, ITfSource), 3667 { NULL } 3668 }; 3669 return ::QISearch(this, c_tab, riid, ppvObject); 3670} 3671 3672STDMETHODIMP_(ULONG) CLBarItemButtonBase::AddRef() 3673{ 3674 return ++m_cRefs; 3675} 3676 3677STDMETHODIMP_(ULONG) CLBarItemButtonBase::Release() 3678{ 3679 if (--m_cRefs == 0) 3680 { 3681 delete this; 3682 return 0; 3683 } 3684 return m_cRefs; 3685} 3686 3687/// @unimplemented 3688STDMETHODIMP CLBarItemButtonBase::OnClick(TfLBIClick click, POINT pt, LPCRECT prc) 3689{ 3690 if (click == TF_LBI_CLK_RIGHT) 3691 { 3692 return E_NOTIMPL; //FIXME 3693 } 3694 if (click == TF_LBI_CLK_LEFT) 3695 { 3696 return E_NOTIMPL; //FIXME 3697 } 3698 return E_NOTIMPL; 3699} 3700 3701STDMETHODIMP CLBarItemButtonBase::InitMenu(ITfMenu *pMenu) 3702{ 3703 return E_NOTIMPL; 3704} 3705 3706STDMETHODIMP CLBarItemButtonBase::OnMenuSelect(UINT wID) 3707{ 3708 return E_NOTIMPL; 3709} 3710 3711STDMETHODIMP CLBarItemButtonBase::GetIcon(HICON *phIcon) 3712{ 3713 return E_NOTIMPL; 3714} 3715 3716STDMETHODIMP CLBarItemButtonBase::GetText(BSTR *pbstr) 3717{ 3718 if (!pbstr) 3719 return E_INVALIDARG; 3720 *pbstr = ::SysAllocString(m_NewUIInfo.szDescription); 3721 return (*pbstr ? S_OK : E_OUTOFMEMORY); 3722} 3723 3724STDMETHODIMP CLBarItemButtonBase::GetInfo(TF_LANGBARITEMINFO *pInfo) 3725{ 3726 return CLBarItemBase::GetInfo(pInfo); 3727} 3728 3729STDMETHODIMP CLBarItemButtonBase::GetStatus(DWORD *pdwStatus) 3730{ 3731 return CLBarItemBase::GetStatus(pdwStatus); 3732} 3733 3734STDMETHODIMP CLBarItemButtonBase::Show(BOOL fShow) 3735{ 3736 return CLBarItemBase::Show(fShow); 3737} 3738 3739STDMETHODIMP CLBarItemButtonBase::GetTooltipString(BSTR *pbstrToolTip) 3740{ 3741 return CLBarItemBase::GetTooltipString(pbstrToolTip); 3742} 3743 3744STDMETHODIMP CLBarItemButtonBase::AdviseSink( 3745 REFIID riid, 3746 IUnknown *punk, 3747 DWORD *pdwCookie) 3748{ 3749 return CLBarItemBase::AdviseSink(riid, punk, pdwCookie); 3750} 3751 3752STDMETHODIMP CLBarItemButtonBase::UnadviseSink(DWORD dwCookie) 3753{ 3754 return CLBarItemBase::UnadviseSink(dwCookie); 3755} 3756 3757/*********************************************************************** 3758 * CLBarInatItem 3759 */ 3760 3761CLBarInatItem::CLBarInatItem(DWORD dwThreadId) 3762{ 3763 WCHAR szText[256]; 3764 ::LoadStringW(g_hInst, IDS_LANGUAGE, szText, _countof(szText)); 3765 InitNuiInfo(CLSID_SYSTEMLANGBARITEM, GUID_LBI_INATITEM, 0x20001, 0, szText); 3766 3767 ::LoadStringW(g_hInst, IDS_LANGUAGEBUTTON, szText, _countof(szText)); 3768 StringCchCopyW(m_szToolTipText, _countof(m_szToolTipText), szText); 3769 m_dwThreadId = dwThreadId; 3770 m_hKL = ::GetKeyboardLayout(m_dwThreadId); 3771 3772 TF_InitMlngInfo(); 3773 ShowInternal(TF_MlngInfoCount() > 1, 0); 3774} 3775 3776STDMETHODIMP CLBarInatItem::GetIcon(HICON *phIcon) 3777{ 3778 HICON hIcon = NULL; 3779 INT iIndex = GetIconIndexFromhKL(m_hKL); 3780 if (iIndex != -1) 3781 hIcon = TF_InatExtractIcon(iIndex); 3782 *phIcon = hIcon; 3783 return S_OK; 3784} 3785 3786STDMETHODIMP CLBarInatItem::GetText(BSTR *pbstr) 3787{ 3788 if (!pbstr) 3789 return E_INVALIDARG; 3790 3791 WCHAR szText[256]; 3792 if (!GethKLDesc(m_hKL, szText, _countof(szText))) 3793 return GetText(pbstr); 3794 3795 *pbstr = ::SysAllocString(szText); 3796 return S_OK; 3797} 3798 3799STDMETHODIMP CLBarInatItem::InitMenu(ITfMenu *pMenu) 3800{ 3801 TF_InitMlngInfo(); 3802 3803 INT iKL, cKLs = TF_MlngInfoCount(); 3804 for (iKL = 0; iKL < cKLs; ++iKL) 3805 { 3806 HKL hKL; 3807 WCHAR szDesc[128]; 3808 if (TF_GetMlngHKL(iKL, &hKL, szDesc, _countof(szDesc))) 3809 { 3810 HICON hIcon = NULL; 3811 INT iIndex = GetIconIndexFromhKL(hKL); 3812 if (iIndex != -1) 3813 hIcon = TF_InatExtractIcon(iIndex); 3814 3815 LangBarInsertMenu(pMenu, iKL, szDesc, (hKL == m_hKL), hIcon); 3816 } 3817 } 3818 3819 DWORD dwStatus; 3820 if (g_pTipbarWnd && 3821 g_pTipbarWnd->m_pLangBarMgr && 3822 SUCCEEDED(g_pTipbarWnd->m_pLangBarMgr->GetShowFloatingStatus(&dwStatus)) && 3823 (dwStatus & (TF_SFT_DESKBAND | TF_SFT_MINIMIZED))) 3824 { 3825 LangBarInsertSeparator(pMenu); 3826 3827 WCHAR szText[256]; 3828 ::LoadStringW(g_hInst, IDS_RESTORELANGBAR2, szText, _countof(szText)); 3829 LangBarInsertMenu(pMenu, 2000, szText, FALSE, NULL); 3830 } 3831 3832 return S_OK; 3833} 3834 3835STDMETHODIMP CLBarInatItem::OnMenuSelect(INT nCommandId) 3836{ 3837 HKL hKL; 3838 3839 if (nCommandId == 2000) 3840 { 3841 if (g_pTipbarWnd) 3842 { 3843 ITfLangBarMgr *pLangBarMgr = g_pTipbarWnd->m_pLangBarMgr; 3844 if (pLangBarMgr) 3845 pLangBarMgr->ShowFloating(TF_SFT_SHOWNORMAL); 3846 } 3847 } 3848 else if (TF_GetMlngHKL(nCommandId, &hKL, NULL, 0)) 3849 { 3850 g_pTipbarWnd->RestoreLastFocus(NULL, !!(g_pTipbarWnd->m_dwTipbarWndFlags & TIPBAR_CHILD)); 3851 HWND hwndFore = ::GetForegroundWindow(); 3852 if (m_dwThreadId == ::GetWindowThreadProcessId(hwndFore, NULL)) 3853 { 3854 BOOL FontSig = GetFontSig(hwndFore, hKL); 3855 ::PostMessage(hwndFore, WM_INPUTLANGCHANGEREQUEST, FontSig, (LPARAM)hKL); 3856 } 3857 } 3858 3859 return S_OK; 3860} 3861 3862/*********************************************************************** 3863 * CTipbarGripper 3864 */ 3865 3866CTipbarGripper::CTipbarGripper(CTipbarWnd *pTipbarWnd, LPCRECT prc, DWORD style) 3867 : CUIFGripper((pTipbarWnd ? pTipbarWnd->GetWindow() : NULL), prc, style) 3868{ 3869 m_bInDebugMenu = FALSE; 3870 m_pTipbarWnd = pTipbarWnd; 3871} 3872 3873/// @unimplemented 3874STDMETHODIMP_(void) CTipbarGripper::OnLButtonUp(LONG x, LONG y) 3875{ 3876 m_pTipbarWnd->RestoreFromStub(); 3877 3878 if (g_bEnableDeskBand && (g_dwOSInfo & CIC_OSINFO_XPPLUS)) 3879 { 3880 APPBARDATA AppBar = { sizeof(AppBar) }; 3881 AppBar.hWnd = ::FindWindowW(L"Shell_TrayWnd", NULL); 3882 if (::SHAppBarMessage(ABM_GETTASKBARPOS, &AppBar)) 3883 { 3884 RECT rc = AppBar.rc; 3885 POINT pt; 3886 ::GetCursorPos(&pt); 3887 if (g_pTipbarWnd && ::PtInRect(&rc, pt)) 3888 g_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_DESKBAND | 3889 TF_SFT_EXTRAICONSONMINIMIZED); 3890 } 3891 } 3892 3893 CUIFGripper::OnLButtonUp(x, y); 3894 m_pTipbarWnd->UpdatePosFlags(); 3895} 3896 3897/// @unimplemented 3898STDMETHODIMP_(void) CTipbarGripper::OnRButtonUp(LONG x, LONG y) 3899{ 3900 if (g_bShowDebugMenu) 3901 { 3902 // FIXME: Debugging feature 3903 } 3904} 3905 3906STDMETHODIMP_(BOOL) CTipbarGripper::OnSetCursor(UINT uMsg, LONG x, LONG y) 3907{ 3908 if (m_bInDebugMenu) 3909 return FALSE; 3910 3911 return CUIFGripper::OnSetCursor(uMsg, x, y); 3912} 3913 3914/*********************************************************************** 3915 * CLangBarItemList 3916 */ 3917 3918BOOL CLangBarItemList::IsStartedIntentionally(REFCLSID rclsid) 3919{ 3920 auto *pItem = FindItem(rclsid); 3921 if (!pItem) 3922 return FALSE; 3923 return pItem->m_bStartedIntentionally; 3924} 3925 3926LANGBARITEMSTATE *CLangBarItemList::AddItem(REFCLSID rclsid) 3927{ 3928 auto *pItem = FindItem(rclsid); 3929 if (pItem) 3930 return pItem; 3931 3932 pItem = Append(1); 3933 if (!pItem) 3934 return NULL; 3935 3936 ZeroMemory(pItem, sizeof(*pItem)); 3937 pItem->m_clsid = rclsid; 3938 pItem->m_dwDemoteLevel = 0; 3939 return pItem; 3940} 3941 3942void CLangBarItemList::Clear() 3943{ 3944 clear(); 3945 3946 CicRegKey regKey; 3947 LSTATUS error; 3948 error = regKey.Open(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\CTF\\LangBar", KEY_ALL_ACCESS); 3949 if (error == ERROR_SUCCESS) 3950 regKey.RecurseDeleteKey(L"ItemState"); 3951} 3952 3953BOOL CLangBarItemList::SetDemoteLevel(REFCLSID rclsid, DWORD dwDemoteLevel) 3954{ 3955 auto *pItem = AddItem(rclsid); 3956 if (!pItem) 3957 return TRUE; 3958 3959 pItem->m_dwDemoteLevel = dwDemoteLevel; 3960 if (!pItem->IsShown()) 3961 { 3962 if (pItem->m_nTimerID) 3963 { 3964 if (g_pTipbarWnd) 3965 g_pTipbarWnd->KillTimer(pItem->m_nTimerID); 3966 pItem->m_nTimerID = 0; 3967 pItem->m_uTimeOut = 0; 3968 } 3969 pItem->m_bDisableDemoting = FALSE; 3970 } 3971 3972 SaveItem(0, pItem); 3973 return TRUE; 3974} 3975 3976LANGBARITEMSTATE *CLangBarItemList::FindItem(REFCLSID rclsid) 3977{ 3978 for (size_t iItem = 0; iItem < size(); ++iItem) 3979 { 3980 auto& item = (*this)[iItem]; 3981 if (IsEqualCLSID(item.m_clsid, rclsid)) 3982 return &item; 3983 } 3984 return NULL; 3985} 3986 3987LANGBARITEMSTATE *CLangBarItemList::GetItemStateFromTimerId(UINT_PTR nTimerID) 3988{ 3989 for (size_t iItem = 0; iItem < size(); ++iItem) 3990 { 3991 auto& item = (*this)[iItem]; 3992 if (item.m_nTimerID == nTimerID) 3993 return &item; 3994 } 3995 return NULL; 3996} 3997 3998void CLangBarItemList::Load() 3999{ 4000 CicRegKey regKey; 4001 LSTATUS error; 4002 error = regKey.Open(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\CTF\\LangBar\\ItemState"); 4003 if (error != ERROR_SUCCESS) 4004 return; 4005 4006 WCHAR szKeyName[MAX_PATH]; 4007 for (DWORD dwIndex = 0; ; ++dwIndex) 4008 { 4009 error = ::RegEnumKeyW(regKey, dwIndex, szKeyName, _countof(szKeyName)); 4010 if (error != ERROR_SUCCESS) 4011 break; 4012 4013 CLSID clsid; 4014 if (::CLSIDFromString(szKeyName, &clsid) != S_OK) 4015 continue; 4016 4017 CicRegKey regKey2; 4018 error = regKey2.Open(regKey, szKeyName); 4019 if (error != ERROR_SUCCESS) 4020 continue; 4021 4022 auto *pItem = AddItem(clsid); 4023 if (!pItem) 4024 continue; 4025 4026 DWORD Data = 0; 4027 regKey2.QueryDword(L"DemoteLevel", &Data); 4028 pItem->m_dwDemoteLevel = Data; 4029 regKey2.QueryDword(L"DisableDemoting", &Data); 4030 pItem->m_bDisableDemoting = !!Data; 4031 } 4032} 4033 4034void CLangBarItemList::SaveItem(CicRegKey *pRegKey, const LANGBARITEMSTATE *pState) 4035{ 4036 LSTATUS error; 4037 CicRegKey regKey; 4038 4039 if (!pRegKey) 4040 { 4041 error = regKey.Create(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\CTF\\LangBar\\ItemState"); 4042 if (error != ERROR_SUCCESS) 4043 return; 4044 4045 pRegKey = &regKey; 4046 } 4047 4048 WCHAR szSubKey[MAX_PATH]; 4049 ::StringFromGUID2(pState->m_clsid, szSubKey, _countof(szSubKey)); 4050 4051 if (pState->m_dwDemoteLevel || pState->m_bDisableDemoting) 4052 { 4053 CicRegKey regKey2; 4054 error = regKey2.Create(*pRegKey, szSubKey); 4055 if (error == ERROR_SUCCESS) 4056 { 4057 DWORD dwDemoteLevel = pState->m_dwDemoteLevel; 4058 if (dwDemoteLevel) 4059 regKey2.SetDword(L"DemoteLevel", dwDemoteLevel); 4060 else 4061 regKey2.DeleteValue(L"DemoteLevel"); 4062 4063 regKey2.SetDword(L"DisableDemoting", pState->m_bDisableDemoting); 4064 } 4065 } 4066 else 4067 { 4068 pRegKey->RecurseDeleteKey(szSubKey); 4069 } 4070} 4071 4072void CLangBarItemList::StartDemotingTimer(REFCLSID rclsid, BOOL bIntentional) 4073{ 4074 if (!g_bIntelliSense) 4075 return; 4076 4077 auto *pItem = AddItem(rclsid); 4078 if (!pItem || pItem->m_bDisableDemoting) 4079 return; 4080 4081 if (pItem->m_nTimerID) 4082 { 4083 if (!bIntentional) 4084 return; 4085 4086 if (g_pTipbarWnd) 4087 g_pTipbarWnd->KillTimer(pItem->m_nTimerID); 4088 4089 pItem->m_nTimerID = 0; 4090 } 4091 4092 pItem->m_bStartedIntentionally |= bIntentional; 4093 4094 UINT uTimeOut = (bIntentional ? g_uTimeOutIntentional : g_uTimeOutNonIntentional); 4095 pItem->m_uTimeOut += uTimeOut; 4096 4097 if (pItem->m_uTimeOut < g_uTimeOutMax) 4098 { 4099 UINT_PTR uDemotingTimerId = FindDemotingTimerId(); 4100 pItem->m_nTimerID = uDemotingTimerId; 4101 if (uDemotingTimerId) 4102 { 4103 if (g_pTipbarWnd) 4104 g_pTipbarWnd->SetTimer(uDemotingTimerId, uTimeOut); 4105 } 4106 } 4107 else 4108 { 4109 pItem->m_bDisableDemoting = TRUE; 4110 } 4111} 4112 4113UINT_PTR CLangBarItemList::FindDemotingTimerId() 4114{ 4115 UINT_PTR nTimerID = 10000; 4116 4117 if (empty()) 4118 return nTimerID; 4119 4120 for (;;) 4121 { 4122 size_t iItem = 0; 4123 4124 while ((*this)[iItem].m_nTimerID != nTimerID) 4125 { 4126 ++iItem; 4127 if (iItem >= size()) 4128 return nTimerID; 4129 } 4130 4131 ++nTimerID; 4132 if (nTimerID >= 10050) 4133 return 0; 4134 } 4135} 4136 4137/*********************************************************************** 4138 * CTipbarWnd 4139 */ 4140 4141/// @unimplemented 4142CTipbarWnd::CTipbarWnd(DWORD style) 4143 : CUIFWindow(g_hInst, style) 4144{ 4145 m_dwUnknown23_1[4] = 0; 4146 m_dwUnknown23_1[5] = 0; 4147 m_dwUnknown23_1[6] = 0; 4148 m_dwUnknown23_1[7] = 0; 4149 4150 RECT rc; 4151 cicGetScreenRect(g_ptTipbar, &rc); 4152 4153 //FIXME: Fix g_ptTipbar 4154 4155 Move(g_ptTipbar.x, g_ptTipbar.y, 100, 24); 4156 UpdatePosFlags(); 4157 4158 m_hMarlettFont = ::CreateFontW(8, 8, 0, 0, FW_NORMAL, 0, 0, 0, 4159 SYMBOL_CHARSET, 0, 0, 0, 0, L"Marlett"); 4160 4161 ITfLangBarMgr *pLangBarMgr = NULL; 4162 if (SUCCEEDED(TF_CreateLangBarMgr(&pLangBarMgr)) && pLangBarMgr) 4163 { 4164 pLangBarMgr->QueryInterface(IID_ITfLangBarMgr_P, (void **)&m_pLangBarMgr); 4165 pLangBarMgr->Release(); 4166 } 4167 4168 if (style & UIF_WINDOW_ENABLETHEMED) 4169 { 4170 if (g_fTaskbarTheme) 4171 { 4172 m_iPartId = 1; 4173 m_iStateId = 1; 4174 m_pszClassList = L"TASKBAR"; 4175 } 4176 else 4177 { 4178 m_iPartId = 0; 4179 m_iStateId = 1; 4180 m_pszClassList = L"REBAR"; 4181 } 4182 } 4183 4184 SetVertical(g_fVertical); 4185 4186 m_cRefs = 1; 4187} 4188 4189CTipbarWnd::~CTipbarWnd() 4190{ 4191 UnInit(); 4192 4193 if (m_hMarlettFont) 4194 ::DeleteObject(m_hMarlettFont); 4195 if (m_hTextFont) 4196 ::DeleteObject(m_hTextFont); 4197 4198 TFUninitLib_Thread(&g_libTLS); 4199} 4200 4201/// @unimplemented 4202void CTipbarWnd::Init(BOOL bChild, CDeskBand *pDeskBand) 4203{ 4204 if (bChild) 4205 m_dwTipbarWndFlags |= TIPBAR_CHILD; 4206 else 4207 m_dwTipbarWndFlags &= ~TIPBAR_CHILD; 4208 4209 if (m_dwTipbarWndFlags & TIPBAR_CHILD) 4210 m_dwTipbarWndFlags &= TIPBAR_HIGHCONTRAST; 4211 4212 m_pDeskBand = pDeskBand; 4213 4214 RECT rc = { 0, 0, 0, 0 }; 4215 4216 if (g_bNewLook && !m_pWndFrame && (m_style & 0x20000000)) 4217 { 4218 CUIFWndFrame *pWndFrame = new(cicNoThrow) CUIFWndFrame(GetWindow(), &rc, 0); 4219 if (pWndFrame) 4220 { 4221 pWndFrame->Initialize(); 4222 AddUIObj(m_pWndFrame); 4223 } 4224 } 4225 4226 if (!m_pTipbarGripper && !(m_dwTipbarWndFlags & TIPBAR_CHILD)) 4227 { 4228 m_pTipbarGripper = 4229 new(cicNoThrow) CTipbarGripper(this, &rc, !!(m_dwTipbarWndFlags & TIPBAR_VERTICAL)); 4230 if (m_pTipbarGripper) 4231 { 4232 m_pTipbarGripper->Initialize(); 4233 AddUIObj(m_pTipbarGripper); 4234 } 4235 } 4236 4237 //FIXME: CTipbarCtrlButtonHolder 4238 4239 if (m_dwTipbarWndFlags & TIPBAR_VERTICAL) 4240 { 4241 Move(m_nLeft, m_nTop, GetTipbarHeight(), 0); 4242 } 4243 else 4244 { 4245 Move(m_nLeft, m_nTop, 0, GetTipbarHeight()); 4246 } 4247} 4248 4249void CTipbarWnd::InitHighContrast() 4250{ 4251 m_dwTipbarWndFlags &= ~TIPBAR_HIGHCONTRAST; 4252 4253 HIGHCONTRAST HiCon = { sizeof(HiCon) }; 4254 if (::SystemParametersInfo(SPI_GETHIGHCONTRAST, sizeof(HiCon), &HiCon, 0)) 4255 { 4256 if (HiCon.dwFlags & HCF_HIGHCONTRASTON) 4257 m_dwTipbarWndFlags |= TIPBAR_HIGHCONTRAST; 4258 } 4259} 4260 4261void CTipbarWnd::InitMetrics() 4262{ 4263 m_cxSmallIcon = ::GetSystemMetrics(SM_CXSMICON); 4264 m_cySmallIcon = ::GetSystemMetrics(SM_CYSMICON); 4265 4266 DWORD_PTR style = ::GetWindowLongPtr(m_hWnd, GWL_STYLE); 4267 if (style & WS_DLGFRAME) 4268 { 4269 m_cxDlgFrameX2 = 2 * ::GetSystemMetrics(SM_CXDLGFRAME); 4270 m_cyDlgFrameX2 = 2 * ::GetSystemMetrics(SM_CYDLGFRAME); 4271 } 4272 else if (style & WS_BORDER) 4273 { 4274 m_cxDlgFrameX2 = 2 * ::GetSystemMetrics(SM_CXBORDER); 4275 m_cyDlgFrameX2 = 2 * ::GetSystemMetrics(SM_CYBORDER); 4276 } 4277 else 4278 { 4279 m_cxDlgFrameX2 = m_cyDlgFrameX2 = 0; 4280 } 4281} 4282 4283void CTipbarWnd::InitThemeMargins() 4284{ 4285 ZeroMemory(&m_Margins, sizeof(m_Margins)); 4286 4287 CUIFTheme theme; 4288 m_dwUnknown23_5[0] = 6; 4289 m_dwUnknown23_5[1] = 6; 4290 m_dwUnknown23_5[2] = 0; 4291 m_ButtonWidth = GetSystemMetrics(SM_CXSIZE); 4292 4293 theme.m_iPartId = 1; 4294 theme.m_iStateId = 0; 4295 theme.m_pszClassList = L"TOOLBAR"; 4296 if (SUCCEEDED(theme.InternalOpenThemeData(m_hWnd))) 4297 { 4298 ::GetThemeMargins(theme.m_hTheme, NULL, theme.m_iPartId, 1, 3602, NULL, &m_Margins); 4299 m_dwUnknown23_5[0] = 4; 4300 m_dwUnknown23_5[1] = 2; 4301 m_dwUnknown23_5[2] = 1; 4302 } 4303 theme.CloseThemeData(); 4304 4305 theme.m_iPartId = 18; 4306 theme.m_iStateId = 0; 4307 theme.m_pszClassList = L"WINDOW"; 4308 if (SUCCEEDED(theme.InternalOpenThemeData(m_hWnd))) 4309 { 4310 SIZE partSize; 4311 ::GetThemePartSize(theme.m_hTheme, NULL, theme.m_iPartId, 1, 0, TS_TRUE, &partSize); 4312 INT size = ::GetThemeSysSize(theme.m_hTheme, 31); 4313 m_ButtonWidth = MulDiv(size, partSize.cx, partSize.cy); 4314 } 4315 theme.CloseThemeData(); 4316} 4317 4318void CTipbarWnd::UnInit() 4319{ 4320 SetFocusThread(NULL); 4321 for (size_t iItem = 0; iItem < m_Threads.size(); ++iItem) 4322 { 4323 CTipbarThread* pThread = m_Threads[iItem]; 4324 if (pThread) 4325 { 4326 pThread->_UninitItemList(TRUE); 4327 pThread->m_pTipbarWnd = NULL; 4328 pThread->_Release(); 4329 } 4330 } 4331 m_Threads.clear(); 4332 4333 if (m_pLangBarMgr) 4334 m_pLangBarMgr->UnAdviseEventSink(m_dwSinkCookie); 4335 4336 if (m_pLangBarMgr) 4337 { 4338 m_pLangBarMgr->Release(); 4339 m_pLangBarMgr = NULL; 4340 } 4341} 4342 4343BOOL CTipbarWnd::IsFullScreenWindow(HWND hWnd) 4344{ 4345 if (g_fPolicyEnableLanguagebarInFullscreen) 4346 return FALSE; 4347 4348 DWORD_PTR style = ::GetWindowLongPtr(hWnd, GWL_STYLE); 4349 if (!(style & WS_VISIBLE) || (style & WS_CAPTION)) 4350 return FALSE; 4351 4352 DWORD_PTR exstyle = ::GetWindowLongPtr(hWnd, GWL_EXSTYLE); 4353 if (exstyle & WS_EX_LAYERED) 4354 return FALSE; 4355 4356 if ((exstyle & WS_EX_TOOLWINDOW) && (hWnd == m_ShellWndThread.GetWndProgman())) 4357 return FALSE; 4358 4359 return !!cicIsFullScreenSize(hWnd); 4360} 4361 4362BOOL CTipbarWnd::IsHKLToSkipRedrawOnNoItem() 4363{ 4364 HKL hKL = GetFocusKeyboardLayout(); 4365 return IsSkipRedrawHKL(hKL); 4366} 4367 4368BOOL CTipbarWnd::IsInItemChangeOrDirty(CTipbarThread *pTarget) 4369{ 4370 if (pTarget->m_dwThreadId == m_dwChangingThreadId) 4371 return TRUE; 4372 return pTarget->IsDirtyItem(); 4373} 4374 4375void CTipbarWnd::AddThreadToThreadCreatingList(CTipbarThread *pThread) 4376{ 4377 m_ThreadCreatingList.Add(pThread); 4378} 4379 4380void CTipbarWnd::RemoveThredFromThreadCreatingList(CTipbarThread *pTarget) 4381{ 4382 ssize_t iItem = m_ThreadCreatingList.Find(pTarget); 4383 if (iItem >= 0) 4384 m_ThreadCreatingList.Remove(iItem); 4385} 4386 4387void CTipbarWnd::MoveToStub(BOOL bFlag) 4388{ 4389 m_dwTipbarWndFlags |= 0x40; 4390 4391 RECT rcWorkArea; 4392 ::SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWorkArea, 0); 4393 4394 if (bFlag) 4395 { 4396 m_nLeft = rcWorkArea.right - 38; 4397 m_dwTipbarWndFlags &= ~0x80; 4398 } 4399 else 4400 { 4401 RECT Rect; 4402 ::GetWindowRect(m_hWnd, &Rect); 4403 m_nLeft = rcWorkArea.right + Rect.left - Rect.right; 4404 m_dwTipbarWndFlags |= 0x80; 4405 } 4406 4407 m_nTop = rcWorkArea.bottom - m_cyDlgFrameX2 - GetTipbarHeight(); 4408 4409 if (m_pFocusThread) 4410 m_pFocusThread->MyMoveWnd(0, 0); 4411} 4412 4413void CTipbarWnd::RestoreFromStub() 4414{ 4415 m_dwTipbarWndFlags &= 0x3F; 4416 KillTimer(1); 4417 KillTimer(2); 4418} 4419 4420/// @unimplemented 4421INT CTipbarWnd::GetCtrlButtonWidth() 4422{ 4423 return 0; 4424} 4425 4426INT CTipbarWnd::GetGripperWidth() 4427{ 4428 if (m_dwTipbarWndFlags & 2) 4429 return 0; 4430 4431 if (!m_pTipbarGripper || FAILED(m_pTipbarGripper->EnsureThemeData(m_hWnd))) 4432 return 5; 4433 4434 INT width = -1; 4435 SIZE partSize; 4436 HDC hDC = ::GetDC(m_hWnd); 4437 if (SUCCEEDED(m_pTipbarGripper->GetThemePartSize(hDC, 1, 0, TS_TRUE, &partSize))) 4438 { 4439 INT cx = partSize.cx; 4440 if (m_dwTipbarWndFlags & 4) 4441 cx = partSize.cy; 4442 width = cx + 4; 4443 } 4444 ::ReleaseDC(m_hWnd, hDC); 4445 4446 return ((width < 0) ? 5 : width); 4447} 4448 4449INT CTipbarWnd::GetTipbarHeight() 4450{ 4451 SIZE size = { 0, 0 }; 4452 if (m_pWndFrame) 4453 m_pWndFrame->GetFrameSize(&size); 4454 INT cy = m_Margins.cyBottomHeight + m_Margins.cyTopHeight + 2; 4455 if (cy < 6) 4456 cy = 6; 4457 return m_cySmallIcon + cy + (2 * size.cy); 4458} 4459 4460BOOL CTipbarWnd::AutoAdjustDeskBandSize() 4461{ 4462 if ((m_dwTipbarWndFlags & TIPBAR_NODESKBAND) || 4463 !m_pFocusThread || 4464 (m_pFocusThread->m_dwFlags1 & 0x800)) 4465 { 4466 return FALSE; 4467 } 4468 4469 DWORD dwOldWndFlags = m_dwTipbarWndFlags; 4470 m_dwTipbarWndFlags &= ~0x8000; 4471 4472 if (!AdjustDeskBandSize(!(dwOldWndFlags & 0x8000))) 4473 return FALSE; 4474 4475 m_dwTipbarWndFlags |= TIPBAR_NODESKBAND; 4476 return TRUE; 4477} 4478 4479/// @unimplemented 4480INT CTipbarWnd::AdjustDeskBandSize(BOOL bFlag) 4481{ 4482 return 0; 4483} 4484 4485/// @unimplemented 4486void CTipbarWnd::LocateCtrlButtons() 4487{ 4488} 4489 4490void CTipbarWnd::AdjustPosOnDisplayChange() 4491{ 4492 RECT rcWorkArea; 4493 RECT rc = { m_nLeft, m_nTop, m_nLeft + m_nWidth, m_nTop + m_nHeight }; 4494 if (!GetWorkArea(&rc, &rcWorkArea)) 4495 return; 4496 4497 INT x = m_nLeft, y = m_nTop; 4498 if (m_dwTipbarWndFlags & TIPBAR_LEFTFIT) 4499 x = rcWorkArea.left; 4500 if (m_dwTipbarWndFlags & TIPBAR_TOPFIT) 4501 y = rcWorkArea.top; 4502 if (m_dwTipbarWndFlags & TIPBAR_RIGHTFIT) 4503 x = rcWorkArea.right - m_nWidth; 4504 if (m_dwTipbarWndFlags & TIPBAR_BOTTOMFIT) 4505 y = rcWorkArea.bottom - m_nHeight; 4506 if (x != m_nLeft || y != m_nTop) 4507 Move(x, y, m_nWidth, m_nHeight); 4508} 4509 4510void CTipbarWnd::SetVertical(BOOL bVertical) 4511{ 4512 if (bVertical) 4513 m_dwTipbarWndFlags |= TIPBAR_VERTICAL; 4514 else 4515 m_dwTipbarWndFlags &= ~TIPBAR_VERTICAL; 4516 4517 if (m_pTipbarGripper) 4518 { 4519 DWORD style = m_pTipbarGripper->m_style; 4520 if (bVertical) 4521 style |= 0x1; 4522 else 4523 style &= 0x1; 4524 m_pTipbarGripper->SetStyle(style); 4525 } 4526 4527 if (g_fTaskbarTheme) 4528 SetActiveTheme(L"TASKBAR", !!(m_dwTipbarWndFlags & TIPBAR_VERTICAL), 1); 4529 4530 if (!(m_dwTipbarWndFlags & TIPBAR_CHILD)) 4531 { 4532 if (m_dwTipbarWndFlags & TIPBAR_VERTICAL) 4533 { 4534 Move(m_nLeft, m_nTop, GetTipbarHeight(), 0); 4535 } 4536 else 4537 { 4538 Move(m_nLeft, m_nTop, 0, GetTipbarHeight()); 4539 } 4540 } 4541 4542 if (m_hWnd) 4543 { 4544 KillTimer(7); 4545 SetTimer(7, g_uTimerElapseSYSCOLORCHANGED); 4546 } 4547} 4548 4549void CTipbarWnd::UpdatePosFlags() 4550{ 4551 if (m_dwTipbarWndFlags & TIPBAR_CHILD) 4552 return; 4553 4554 RECT rc = { m_nLeft, m_nTop, m_nLeft + m_nWidth, m_nTop + m_nHeight }, rcWorkArea; 4555 if (!GetWorkArea(&rc, &rcWorkArea)) 4556 return; 4557 4558 if (rcWorkArea.left + 2 < m_nLeft) 4559 m_dwTipbarWndFlags &= ~TIPBAR_LEFTFIT; 4560 else 4561 m_dwTipbarWndFlags |= TIPBAR_LEFTFIT; 4562 4563 if (rcWorkArea.top + 2 < m_nTop) 4564 m_dwTipbarWndFlags &= ~TIPBAR_TOPFIT; 4565 else 4566 m_dwTipbarWndFlags |= TIPBAR_TOPFIT; 4567 4568 if (m_nLeft + m_nWidth < rcWorkArea.right - 2) 4569 m_dwTipbarWndFlags &= ~TIPBAR_RIGHTFIT; 4570 else 4571 m_dwTipbarWndFlags |= TIPBAR_RIGHTFIT; 4572 4573 if (m_nTop + m_nHeight < rcWorkArea.bottom - 2) 4574 m_dwTipbarWndFlags &= ~TIPBAR_BOTTOMFIT; 4575 else 4576 m_dwTipbarWndFlags |= TIPBAR_BOTTOMFIT; 4577} 4578 4579void CTipbarWnd::CancelMenu() 4580{ 4581 if (!m_pThread) 4582 return; 4583 4584 CTipbarWnd *pTipbarWnd = m_pThread->m_pTipbarWnd; 4585 if (pTipbarWnd) 4586 { 4587 if (pTipbarWnd->m_pLangBarMgr) 4588 pTipbarWnd->StartModalInput(NULL, m_pThread->m_dwThreadId); 4589 } 4590 4591 m_pModalMenu->CancelMenu(); 4592 StartBackToAlphaTimer(); 4593} 4594 4595BOOL CTipbarWnd::CheckExcludeCaptionButtonMode(LPRECT prc1, LPCRECT prc2) 4596{ 4597 return (prc1->top < prc2->top + 5) && (prc2->right <= prc1->right + (5 * m_ButtonWidth)); 4598} 4599 4600void CTipbarWnd::ClearLBItemList() 4601{ 4602 m_LangBarItemList.Clear(); 4603 if (m_pFocusThread) 4604 OnThreadItemChange(m_pFocusThread->m_dwThreadId); 4605} 4606 4607HFONT CTipbarWnd::CreateVerticalFont() 4608{ 4609 if (!m_hWnd) 4610 return NULL; 4611 4612 CUIFTheme theme; 4613 theme.m_iPartId = 1; 4614 theme.m_iStateId = 0; 4615 theme.m_pszClassList = L"TOOLBAR"; 4616 4617 LOGFONTW lf; 4618 if (FAILED(theme.InternalOpenThemeData(m_hWnd)) || 4619 FAILED(::GetThemeFont(theme.m_hTheme, NULL, theme.m_iPartId, 0, 210, &lf))) 4620 { 4621 ::GetObject(::GetStockObject(DEFAULT_GUI_FONT), sizeof(lf), &lf); 4622 } 4623 4624 lf.lfEscapement = lf.lfOrientation = 2700; 4625 lf.lfOutPrecision = OUT_TT_ONLY_PRECIS; 4626 4627 if (CheckEAFonts()) 4628 { 4629 WCHAR szText[LF_FACESIZE]; 4630 szText[0] = L'@'; 4631 StringCchCopyW(&szText[1], _countof(szText) - 1, lf.lfFaceName); 4632 StringCchCopyW(lf.lfFaceName, _countof(lf.lfFaceName), szText); 4633 } 4634 4635 return ::CreateFontIndirectW(&lf); 4636} 4637 4638void CTipbarWnd::UpdateVerticalFont() 4639{ 4640 if (m_dwTipbarWndFlags & TIPBAR_VERTICAL) 4641 { 4642 if (m_hTextFont) 4643 { 4644 ::DeleteObject(m_hTextFont); 4645 SetFontToThis(NULL); 4646 m_hTextFont = NULL; 4647 } 4648 m_hTextFont = CreateVerticalFont(); 4649 SetFontToThis(m_hTextFont); 4650 } 4651 else 4652 { 4653 SetFontToThis(NULL); 4654 } 4655} 4656 4657/// @unimplemented 4658void CTipbarWnd::ShowOverScreenSizeBalloon() 4659{ 4660 //FIXME: CTipbarCtrlButtonHolder 4661} 4662 4663void CTipbarWnd::DestroyOverScreenSizeBalloon() 4664{ 4665 if (m_pBalloon) 4666 { 4667 if (::IsWindow(*m_pBalloon)) 4668 ::DestroyWindow(*m_pBalloon); 4669 delete m_pBalloon; 4670 m_pBalloon = NULL; 4671 } 4672} 4673 4674void CTipbarWnd::DestroyWnd() 4675{ 4676 if (::IsWindow(m_hWnd)) 4677 ::DestroyWindow(m_hWnd); 4678} 4679 4680HKL CTipbarWnd::GetFocusKeyboardLayout() 4681{ 4682 DWORD dwThreadId = 0; 4683 if (m_pFocusThread) 4684 dwThreadId = m_pFocusThread->m_dwThreadId; 4685 return ::GetKeyboardLayout(dwThreadId); 4686} 4687 4688void CTipbarWnd::KillOnTheadItemChangeTimer() 4689{ 4690 DWORD dwChangingThreadId = m_dwChangingThreadId; 4691 m_dwChangingThreadId = 0; 4692 KillTimer(4); 4693 4694 if (dwChangingThreadId) 4695 { 4696 CTipbarThread *pThread = _FindThread(dwChangingThreadId); 4697 if (pThread) 4698 pThread->m_dwUnknown34 |= 0x1; 4699 } 4700} 4701 4702UINT_PTR CTipbarWnd::SetTimer(UINT_PTR nIDEvent, UINT uElapse) 4703{ 4704 if (::IsWindow(m_hWnd)) 4705 return ::SetTimer(m_hWnd, nIDEvent, uElapse, NULL); 4706 return 0; 4707} 4708 4709BOOL CTipbarWnd::KillTimer(UINT_PTR uIDEvent) 4710{ 4711 if (::IsWindow(m_hWnd)) 4712 return ::KillTimer(m_hWnd, uIDEvent); 4713 return FALSE; 4714} 4715 4716/// @unimplemented 4717void CTipbarWnd::MoveToTray() 4718{ 4719 if (!g_bEnableDeskBand || !(g_dwOSInfo & CIC_OSINFO_XPPLUS)) 4720 { 4721 //FIXME 4722 } 4723} 4724 4725void CTipbarWnd::MyClientToScreen(LPPOINT lpPoint, LPRECT prc) 4726{ 4727 if (lpPoint) 4728 ::ClientToScreen(m_hWnd, lpPoint); 4729 4730 if (prc) 4731 { 4732 ::ClientToScreen(m_hWnd, (LPPOINT)prc); 4733 ::ClientToScreen(m_hWnd, (LPPOINT)&prc->right); 4734 } 4735} 4736 4737void CTipbarWnd::SavePosition() 4738{ 4739 CicRegKey regKey; 4740 if (regKey.Create(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\"))) 4741 { 4742 POINT pt = { 0, 0 }; 4743 ::ClientToScreen(m_hWnd, &pt); 4744 regKey.SetDword(TEXT("Left"), pt.x); 4745 regKey.SetDword(TEXT("Top"), pt.y); 4746 regKey.SetDword(TEXT("Vertical"), !!(m_dwTipbarWndFlags & TIPBAR_VERTICAL)); 4747 } 4748} 4749 4750/// @unimplemented 4751void CTipbarWnd::SetAlpha(BYTE bAlpha, BOOL bFlag) 4752{ 4753} 4754 4755BOOL CTipbarWnd::SetLangBand(BOOL bDeskBand, BOOL bFlag2) 4756{ 4757 if (bDeskBand == !!(m_dwShowType & TF_SFT_DESKBAND)) 4758 return TRUE; 4759 4760 BOOL ret = TRUE; 4761 HWND hwndTray = m_ShellWndThread.GetWndTray(); 4762 if (bFlag2 && hwndTray) 4763 { 4764 DWORD_PTR dwResult; 4765 HWND hImeWnd = ::ImmGetDefaultIMEWnd(hwndTray); 4766 if (hImeWnd) 4767 ::SendMessageTimeout(hImeWnd, WM_IME_SYSTEM, 0x24 - bDeskBand, (LPARAM)hwndTray, 4768 (SMTO_BLOCK | SMTO_ABORTIFHUNG), 5000, &dwResult); 4769 else 4770 ::SendMessageTimeout(hwndTray, 0x505, 0, bDeskBand, 4771 (SMTO_BLOCK | SMTO_ABORTIFHUNG), 5000, &dwResult); 4772 } 4773 else 4774 { 4775 ret = FALSE; 4776 } 4777 4778 if (!(m_dwTipbarWndFlags & TIPBAR_CHILD) && bDeskBand) 4779 { 4780 KillTimer(7); 4781 SetTimer(7, g_uTimerElapseSYSCOLORCHANGED); 4782 } 4783 4784 return ret; 4785} 4786 4787void CTipbarWnd::SetMoveRect(INT X, INT Y, INT nWidth, INT nHeight) 4788{ 4789 if (m_dwTipbarWndFlags & TIPBAR_CHILD) 4790 { 4791 m_nWidth = nWidth; 4792 m_nHeight = nHeight; 4793 return; 4794 } 4795 4796 ++m_bInCallOn; 4797 4798 m_dwTipbarWndFlags |= TIPBAR_UPDATING; 4799 4800 m_X = X; 4801 m_Y = Y; 4802 m_CX = nWidth; 4803 m_CY = nHeight; 4804 4805 RECT rc; 4806 SIZE size = { 0, 0 }; 4807 if (m_pWndFrame) 4808 { 4809 ::SetRect(&rc, 0, 0, nWidth - m_cxDlgFrameX2, nHeight - m_cyDlgFrameX2); 4810 m_pWndFrame->SetRect(&rc); 4811 m_pWndFrame->GetFrameSize(&size); 4812 } 4813 4814 if (m_pTipbarGripper) 4815 { 4816 if (m_dwTipbarWndFlags & TIPBAR_VERTICAL) 4817 { 4818 INT GripperWidth = GetGripperWidth(); 4819 ::SetRect(&rc, size.cx, size.cy, nWidth - m_cxDlgFrameX2 - size.cx, size.cy + GripperWidth); 4820 } 4821 else 4822 { 4823 INT GripperWidth = GetGripperWidth(); 4824 INT y1 = nHeight - m_cyDlgFrameX2 - size.cy; 4825 ::SetRect(&rc, size.cx, size.cy, size.cx + GripperWidth, y1); 4826 } 4827 m_pTipbarGripper->SetRect(&rc); 4828 } 4829 4830 --m_bInCallOn; 4831} 4832 4833void CTipbarWnd::SetShowText(BOOL bShow) 4834{ 4835 if (bShow) 4836 m_dwTipbarWndFlags |= TIPBAR_HIGHCONTRAST; 4837 else 4838 m_dwTipbarWndFlags &= ~TIPBAR_HIGHCONTRAST; 4839 4840 if (m_pFocusThread) 4841 OnThreadItemChange(m_pFocusThread->m_dwThreadId); 4842 4843 TerminateAllThreads(FALSE); 4844} 4845 4846void CTipbarWnd::SetShowTrayIcon(BOOL bShow) 4847{ 4848 if (m_dwTipbarWndFlags & TIPBAR_TRAYICON) 4849 m_dwTipbarWndFlags &= ~TIPBAR_TRAYICON; 4850 else 4851 m_dwTipbarWndFlags |= TIPBAR_TRAYICON; 4852 4853 if ((m_dwTipbarWndFlags & TIPBAR_TRAYICON) && m_pFocusThread) 4854 { 4855 KillTimer(10); 4856 SetTimer(10, g_uTimerElapseMOVETOTRAY); 4857 } 4858 else if (g_pTrayIconWnd) 4859 { 4860 g_pTrayIconWnd->SetMainIcon(NULL); 4861 g_pTrayIconWnd->RemoveAllIcon(0); 4862 } 4863} 4864 4865void CTipbarWnd::ShowContextMenu(POINT pt, LPCRECT prc, BOOL bFlag) 4866{ 4867 AddRef(); 4868 4869 RECT rc; 4870 if (!prc) 4871 { 4872 rc = { pt.x, pt.y, pt.x, pt.y }; 4873 prc = &rc; 4874 } 4875 4876 if (m_pFocusThread) 4877 { 4878 CUTBContextMenu *pContextMenu = new(cicNoThrow) CUTBContextMenu(this); 4879 if (pContextMenu) 4880 { 4881 if (pContextMenu->Init()) 4882 { 4883 m_pThread = m_pFocusThread; 4884 StartModalInput(this, m_pFocusThread->m_dwThreadId); 4885 4886 m_pModalMenu = pContextMenu; 4887 DWORD dwCommandId = pContextMenu->ShowPopup(GetWindow(), pt, prc, bFlag); 4888 m_pModalMenu = NULL; 4889 4890 if (m_pThread) 4891 StopModalInput(m_pThread->m_dwThreadId); 4892 4893 m_pThread = NULL; 4894 4895 if (dwCommandId != (DWORD)-1) 4896 pContextMenu->SelectMenuItem(dwCommandId); 4897 } 4898 4899 delete pContextMenu; 4900 } 4901 } 4902 4903 Release(); 4904} 4905 4906void CTipbarWnd::StartBackToAlphaTimer() 4907{ 4908 UINT uTime = ::GetDoubleClickTime(); 4909 ::SetTimer(m_hWnd, 3, 3 * uTime, NULL); 4910} 4911 4912BOOL CTipbarWnd::StartDoAccDefaultActionTimer(CTipbarItem *pTarget) 4913{ 4914 if (!m_pTipbarAccessible) 4915 return FALSE; 4916 INT IDOfItem = m_pTipbarAccessible->GetIDOfItem(pTarget); 4917 m_nID = IDOfItem; 4918 if (!IDOfItem || IDOfItem == -1) 4919 return FALSE; 4920 KillTimer(11); 4921 SetTimer(11, g_uTimerElapseDOACCDEFAULTACTION); 4922 return TRUE; 4923} 4924 4925void CTipbarWnd::StartModalInput(ITfLangBarEventSink *pSink, DWORD dwThreadId) 4926{ 4927 if (!m_pLangBarMgr) 4928 return; 4929 4930 m_pLangBarMgr->SetModalInput(pSink, dwThreadId, 0); 4931 if (g_pTrayIconWnd) 4932 m_pLangBarMgr->SetModalInput(pSink, g_pTrayIconWnd->m_dwTrayWndThreadId, 0); 4933 4934 DWORD dwCurThreadId = ::GetCurrentThreadId(); 4935 m_pLangBarMgr->SetModalInput(pSink, dwCurThreadId, 1); 4936} 4937 4938void CTipbarWnd::StopModalInput(DWORD dwThreadId) 4939{ 4940 if (!m_pLangBarMgr) 4941 return; 4942 4943 m_pLangBarMgr->SetModalInput(NULL, dwThreadId, 0); 4944 if (g_pTrayIconWnd) 4945 m_pLangBarMgr->SetModalInput(NULL, g_pTrayIconWnd->m_dwTrayWndThreadId, 0); 4946 4947 DWORD dwCurThreadId = ::GetCurrentThreadId(); 4948 m_pLangBarMgr->SetModalInput(NULL, dwCurThreadId, 0); 4949} 4950 4951LONG MyWaitForInputIdle(DWORD dwThreadId, DWORD dwMilliseconds) 4952{ 4953 if (g_pTipbarWnd && (g_pTipbarWnd->m_dwShowType & TF_SFT_DESKBAND)) 4954 return 0; 4955 4956 if (TF_IsInMarshaling(dwThreadId)) 4957 return STATUS_TIMEOUT; 4958 4959 DWORD dwFlags1 = 0, dwFlags2 = 0; 4960 if (!TF_GetThreadFlags(dwThreadId, &dwFlags1, &dwFlags2, NULL) && dwFlags2) 4961 return -1; 4962 4963 return TF_CheckThreadInputIdle(dwThreadId, dwMilliseconds); 4964} 4965 4966CTipbarThread *CTipbarWnd::_CreateThread(DWORD dwThreadId) 4967{ 4968 CTipbarThread *pTarget = _FindThread(dwThreadId); 4969 if (pTarget) 4970 return pTarget; 4971 4972 MyWaitForInputIdle(dwThreadId, 2000); 4973 4974 pTarget = new(cicNoThrow) CTipbarThread(this); 4975 if (!pTarget) 4976 return NULL; 4977 4978 AddThreadToThreadCreatingList(pTarget); 4979 4980 HRESULT hr = pTarget->Init(dwThreadId); 4981 4982 RemoveThredFromThreadCreatingList(pTarget); 4983 4984 if (SUCCEEDED(hr) && !m_Threads.Add(pTarget)) 4985 { 4986 pTarget->_UninitItemList(TRUE); 4987 pTarget->m_pTipbarWnd = NULL; 4988 pTarget->_Release(); 4989 return NULL; 4990 } 4991 4992 return pTarget; 4993} 4994 4995CTipbarThread *CTipbarWnd::_FindThread(DWORD dwThreadId) 4996{ 4997 if (g_bWinLogon) 4998 return NULL; 4999 5000 CTipbarThread *pTarget = NULL; 5001 for (size_t iItem = 0; iItem < m_Threads.size(); ++iItem) 5002 { 5003 CTipbarThread *pThread = m_Threads[iItem]; 5004 if (pThread && pThread->m_dwThreadId == dwThreadId) 5005 { 5006 pTarget = pThread; 5007 break; 5008 } 5009 } 5010 5011 if (!pTarget) 5012 return NULL; 5013 5014 DWORD dwFlags1, dwFlags2, dwFlags3; 5015 TF_GetThreadFlags(dwThreadId, &dwFlags1, &dwFlags2, &dwFlags3); 5016 5017 if (!dwFlags2 || (dwFlags2 != pTarget->m_dwFlags2) || (dwFlags3 != pTarget->m_dwFlags3)) 5018 { 5019 OnThreadTerminateInternal(dwThreadId); 5020 return NULL; 5021 } 5022 5023 return pTarget; 5024} 5025 5026void CTipbarWnd::EnsureFocusThread() 5027{ 5028 if (m_pFocusThread || (m_dwTipbarWndFlags & (TIPBAR_TOOLBARENDED | TIPBAR_ENSURING))) 5029 return; 5030 5031 m_dwTipbarWndFlags |= TIPBAR_ENSURING; 5032 5033 HWND hwndFore = ::GetForegroundWindow(); 5034 if (!hwndFore) 5035 return; 5036 5037 DWORD dwThreadId = ::GetWindowThreadProcessId(hwndFore, NULL); 5038 if (dwThreadId) 5039 OnSetFocus(dwThreadId); 5040 5041 m_dwTipbarWndFlags &= ~TIPBAR_ENSURING; 5042} 5043 5044HRESULT CTipbarWnd::SetFocusThread(CTipbarThread *pFocusThread) 5045{ 5046 if (pFocusThread == m_pFocusThread) 5047 return S_OK; 5048 5049 DWORD dwThreadId = ::GetCurrentThreadId(); 5050 DestroyOverScreenSizeBalloon(); 5051 5052 if (m_pFocusThread) 5053 { 5054 m_pFocusThread->SetFocus(NULL); 5055 ::AttachThreadInput(dwThreadId, m_pFocusThread->m_dwThreadId, FALSE); 5056 } 5057 5058 m_dwTipbarWndFlags &= ~TIPBAR_ATTACHED; 5059 m_pFocusThread = pFocusThread; 5060 return S_OK; 5061} 5062 5063HRESULT CTipbarWnd::AttachFocusThread() 5064{ 5065 if (m_dwTipbarWndFlags & TIPBAR_ATTACHED) 5066 return S_FALSE; 5067 5068 if (m_pFocusThread) 5069 { 5070 DWORD dwThreadId = ::GetCurrentThreadId(); 5071 ::AttachThreadInput(dwThreadId, m_pFocusThread->m_dwThreadId, TRUE); 5072 m_dwTipbarWndFlags |= TIPBAR_ATTACHED; 5073 } 5074 5075 return S_OK; 5076} 5077 5078void CTipbarWnd::RestoreLastFocus(DWORD *pdwThreadId, BOOL fPrev) 5079{ 5080 if (m_pLangBarMgr) 5081 m_pLangBarMgr->RestoreLastFocus(pdwThreadId, fPrev); 5082} 5083 5084void CTipbarWnd::CleanUpThreadPointer(CTipbarThread *pThread, BOOL bRemove) 5085{ 5086 if (bRemove) 5087 { 5088 ssize_t iItem = m_Threads.Find(pThread); 5089 if (iItem >= 0) 5090 m_Threads.Remove(iItem); 5091 } 5092 5093 if (pThread == m_pFocusThread) 5094 SetFocusThread(NULL); 5095 5096 if (pThread == m_pThread) 5097 m_pThread = NULL; 5098 5099 if (pThread == m_pUnknownThread) 5100 m_pUnknownThread = NULL; 5101} 5102 5103void CTipbarWnd::TerminateAllThreads(BOOL bFlag) 5104{ 5105 const size_t cItems = m_Threads.size(); 5106 5107 DWORD *pdwThreadIds = new(cicNoThrow) DWORD[cItems]; 5108 if (!pdwThreadIds) 5109 return; 5110 5111 for (size_t iItem = 0; iItem < cItems; ++iItem) 5112 { 5113 pdwThreadIds[iItem] = 0; 5114 CTipbarThread* pThread = m_Threads[iItem]; 5115 if (pThread && (bFlag || (pThread != m_pFocusThread))) 5116 { 5117 pdwThreadIds[iItem] = pThread->m_dwThreadId; 5118 } 5119 } 5120 5121 for (size_t iItem = 0; iItem < cItems; ++iItem) 5122 { 5123 if (pdwThreadIds[iItem]) 5124 OnThreadTerminateInternal(pdwThreadIds[iItem]); 5125 } 5126 5127 delete[] pdwThreadIds; 5128} 5129 5130STDMETHODIMP CTipbarWnd::QueryInterface(REFIID riid, void **ppvObj) 5131{ 5132 static const QITAB c_tab[] = 5133 { 5134 QITABENT(CTipbarWnd, ITfLangBarEventSink), 5135 QITABENT(CTipbarWnd, ITfLangBarEventSink_P), 5136 { NULL } 5137 }; 5138 return ::QISearch(this, c_tab, riid, ppvObj); 5139} 5140 5141STDMETHODIMP_(ULONG) CTipbarWnd::AddRef() 5142{ 5143 return ++m_cRefs; 5144} 5145 5146STDMETHODIMP_(ULONG) CTipbarWnd::Release() 5147{ 5148 if (--m_cRefs == 0) 5149 { 5150 delete this; 5151 return 0; 5152 } 5153 return m_cRefs; 5154} 5155 5156/// @unimplemented 5157STDMETHODIMP CTipbarWnd::OnSetFocus(DWORD dwThreadId) 5158{ 5159 return E_NOTIMPL; 5160} 5161 5162STDMETHODIMP CTipbarWnd::OnThreadTerminate(DWORD dwThreadId) 5163{ 5164 HRESULT hr; 5165 ++m_bInCallOn; 5166 AddRef(); 5167 { 5168 hr = OnThreadTerminateInternal(dwThreadId); 5169 if (!m_pFocusThread) 5170 EnsureFocusThread(); 5171 } 5172 --m_bInCallOn; 5173 Release(); 5174 return hr; 5175} 5176 5177HRESULT CTipbarWnd::OnThreadTerminateInternal(DWORD dwThreadId) 5178{ 5179 for (size_t iItem = 0; iItem < m_Threads.size(); ++iItem) 5180 { 5181 CTipbarThread *pThread = m_Threads[iItem]; 5182 if (pThread && pThread->m_dwThreadId == dwThreadId) 5183 { 5184 m_Threads.Remove(iItem); 5185 pThread->RemoveUIObjs(); 5186 CleanUpThreadPointer(pThread, FALSE); 5187 pThread->_UninitItemList(TRUE); 5188 pThread->m_pTipbarWnd = NULL; 5189 pThread->_Release(); 5190 break; 5191 } 5192 } 5193 5194 return S_OK; 5195} 5196 5197STDMETHODIMP CTipbarWnd::OnThreadItemChange(DWORD dwThreadId) 5198{ 5199 if (m_dwTipbarWndFlags & TIPBAR_TOOLBARENDED) 5200 return S_OK; 5201 if (!(m_dwTipbarWndFlags & TIPBAR_CHILD) && (m_dwShowType & TF_SFT_DESKBAND)) 5202 return S_OK; 5203 5204 CTipbarThread *pThread = _FindThread(dwThreadId); 5205 if (pThread) 5206 { 5207 if ((!m_dwUnknown23 || m_dwUnknown23 == dwThreadId) && pThread == m_pFocusThread) 5208 { 5209 KillOnTheadItemChangeTimer(); 5210 m_dwChangingThreadId = dwThreadId; 5211 KillTimer(6); 5212 SetTimer(4, g_uTimerElapseONTHREADITEMCHANGE); 5213 } 5214 else 5215 { 5216 pThread->m_dwUnknown34 |= 0x1; 5217 } 5218 } 5219 else 5220 { 5221 for (size_t iItem = 0; iItem < m_ThreadCreatingList.size(); ++iItem) 5222 { 5223 CTipbarThread *pItem = m_ThreadCreatingList[iItem]; 5224 if (pItem && pItem->m_dwThreadId == dwThreadId) 5225 { 5226 pItem->m_dwUnknown34 |= 0x1; 5227 } 5228 } 5229 } 5230 5231 return S_OK; 5232} 5233 5234STDMETHODIMP CTipbarWnd::OnModalInput(DWORD dwThreadId, UINT uMsg, WPARAM wParam, LPARAM lParam) 5235{ 5236 switch (uMsg) 5237 { 5238 case WM_NCLBUTTONDOWN: 5239 case WM_NCRBUTTONDOWN: 5240 case WM_NCMBUTTONDOWN: 5241 case WM_LBUTTONUP: 5242 case WM_RBUTTONUP: 5243 case WM_MBUTTONUP: 5244 break; 5245 5246 case WM_NCLBUTTONUP: 5247 case WM_NCRBUTTONUP: 5248 case WM_NCMBUTTONUP: 5249 if (m_pThread) 5250 { 5251 CUTBMenuWnd *pMenuUI = m_pModalMenu->m_pMenuUI; 5252 if (pMenuUI) 5253 { 5254 HWND hWnd = *pMenuUI; 5255 if (hWnd) 5256 { 5257 POINT pt = { (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam) }; 5258 ::ScreenToClient(hWnd, &pt); 5259 uMsg += WM_LBUTTONUP - WM_NCLBUTTONUP; 5260 ::PostMessage(m_hWnd, uMsg, wParam, MAKELPARAM(pt.x, pt.y)); 5261 } 5262 } 5263 } 5264 break; 5265 5266 default: 5267 { 5268 if (uMsg == WM_KEYDOWN || uMsg == WM_KEYUP) 5269 { 5270 if (m_pThread) 5271 m_pModalMenu->PostKey(uMsg == WM_KEYUP, wParam, lParam); 5272 } 5273 else 5274 { 5275 CancelMenu(); 5276 } 5277 break; 5278 } 5279 } 5280 5281 return 0; 5282} 5283 5284/// @unimplemented 5285STDMETHODIMP CTipbarWnd::ShowFloating(DWORD dwFlags) 5286{ 5287 return E_NOTIMPL; 5288} 5289 5290STDMETHODIMP CTipbarWnd::GetItemFloatingRect(DWORD dwThreadId, REFGUID rguid, RECT *prc) 5291{ 5292 if (m_dwTipbarWndFlags & TIPBAR_TRAYICON) 5293 return E_UNEXPECTED; 5294 5295 if (!m_pFocusThread || (m_pFocusThread->m_dwThreadId != dwThreadId)) 5296 return E_FAIL; 5297 5298 for (size_t iItem = 0; iItem < m_pFocusThread->m_UIObjects.size(); ++iItem) 5299 { 5300 CTipbarItem* pItem = m_pFocusThread->m_UIObjects[iItem]; 5301 if (pItem) 5302 { 5303 if ((pItem->m_dwItemFlags & 0x8) && IsEqualGUID(pItem->m_ItemInfo.guidItem, rguid)) 5304 { 5305 pItem->OnUnknown57(prc); 5306 return S_OK; 5307 } 5308 } 5309 } 5310 5311 return E_FAIL; 5312} 5313 5314/// @unimplemented 5315STDMETHODIMP CTipbarWnd::OnLangBarUpdate(TfLBIClick click, BOOL bFlag) 5316{ 5317 return E_NOTIMPL; 5318} 5319 5320STDMETHODIMP_(BSTR) CTipbarWnd::GetAccName() 5321{ 5322 WCHAR szText[256]; 5323 ::LoadStringW(g_hInst, IDS_LANGUAGEBAR, szText, _countof(szText)); 5324 return ::SysAllocString(szText); 5325} 5326 5327STDMETHODIMP_(void) CTipbarWnd::GetAccLocation(LPRECT lprc) 5328{ 5329 GetRect(lprc); 5330} 5331 5332STDMETHODIMP_(void) CTipbarWnd::PaintObject(HDC hDC, LPCRECT prc) 5333{ 5334 if (m_dwTipbarWndFlags & TIPBAR_UPDATING) 5335 { 5336 Move(m_X, m_Y, m_CX, m_CY); 5337 m_dwTipbarWndFlags &= ~TIPBAR_UPDATING; 5338 } 5339 5340 if (!m_pFocusThread || !m_pFocusThread->IsDirtyItem()) 5341 { 5342 m_pFocusThread->CallOnUpdateHandler(); 5343 if (g_pTipbarWnd) 5344 CUIFWindow::PaintObject(hDC, prc); 5345 } 5346} 5347 5348STDMETHODIMP_(DWORD) CTipbarWnd::GetWndStyle() 5349{ 5350 return CUIFWindow::GetWndStyle() & ~WS_BORDER; 5351} 5352 5353STDMETHODIMP_(void) CTipbarWnd::Move(INT x, INT y, INT nWidth, INT nHeight) 5354{ 5355 CUIFWindow::Move(x, y, nWidth, nHeight); 5356} 5357 5358STDMETHODIMP_(void) CTipbarWnd::OnMouseOutFromWindow(LONG x, LONG y) 5359{ 5360 StartBackToAlphaTimer(); 5361 if ((m_dwTipbarWndFlags & 0x40) && (m_dwTipbarWndFlags & 0x80)) 5362 SetTimer(2, g_uTimerElapseSTUBEND); 5363} 5364 5365/// @unimplemented 5366STDMETHODIMP_(void) CTipbarWnd::OnCreate(HWND hWnd) 5367{ 5368} 5369 5370STDMETHODIMP_(void) CTipbarWnd::OnDestroy(HWND hWnd) 5371{ 5372 CancelMenu(); 5373 5374 if (m_pTipbarAccessible) 5375 m_pTipbarAccessible->NotifyWinEvent(EVENT_OBJECT_DESTROY, GetAccItem()); 5376 5377 OnTerminateToolbar(); 5378 if (m_pTipbarAccessible) 5379 { 5380 m_pTipbarAccessible->ClearAccItems(); 5381 m_pTipbarAccessible->Release(); 5382 m_pTipbarAccessible = NULL; 5383 } 5384 5385 m_coInit.CoUninit(); 5386 5387 if (m_pLangBarMgr) 5388 m_pLangBarMgr->UnAdviseEventSink(m_dwSinkCookie); 5389} 5390 5391/// @unimplemented 5392STDMETHODIMP_(void) CTipbarWnd::OnTimer(WPARAM wParam) 5393{ 5394 AddRef(); 5395 switch (wParam) 5396 { 5397 case 1: 5398 KillTimer(1); 5399 MoveToStub(FALSE); 5400 break; 5401 case 2: 5402 KillTimer(2); 5403 MoveToStub(TRUE); 5404 break; 5405 case 3: 5406 KillTimer(3); 5407 SetAlpha((BYTE)m_dwAlphaValue, TRUE); 5408 break; 5409 case 4: 5410 { 5411 LONG status = MyWaitForInputIdle(m_dwChangingThreadId, 2000); 5412 if (status) 5413 { 5414 if (status != STATUS_TIMEOUT) 5415 { 5416 KillTimer(4); 5417 m_dwChangingThreadId = 0; 5418 } 5419 } 5420 else if (!m_pThread) 5421 { 5422 KillTimer(4); 5423 DWORD dwOldThreadId = m_dwChangingThreadId; 5424 m_dwChangingThreadId = 0; 5425 OnThreadItemChangeInternal(dwOldThreadId); 5426 } 5427 break; 5428 } 5429 case 5: 5430 KillTimer(5); 5431 ::SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); 5432 break; 5433 case 6: 5434 KillTimer(6); 5435 if (m_pFocusThread) 5436 { 5437 if (m_pFocusThread->m_dwThreadId != m_dwChangingThreadId && 5438 !m_pFocusThread->CallOnUpdateHandler()) 5439 { 5440 if (m_pFocusThread) 5441 OnThreadItemChange(m_pFocusThread->m_dwThreadId); 5442 } 5443 } 5444 break; 5445 case 7: 5446 { 5447 DWORD dwThreadId = 0; 5448 if (KillTimer(7)) 5449 { 5450 if (m_pFocusThread) 5451 dwThreadId = m_pFocusThread->m_dwThreadId; 5452 5453 TerminateAllThreads(TRUE); 5454 UpdateVerticalFont(); 5455 5456 if (dwThreadId) 5457 OnSetFocus(dwThreadId); 5458 5459 InitMetrics(); 5460 // FIXME: CTipbarCtrlButtonHolder 5461 5462 InitHighContrast(); 5463 SetAlpha(0xFF, TRUE); 5464 ::RedrawWindow(m_hWnd, NULL, NULL, (RDW_FRAME | RDW_UPDATENOW | RDW_INVALIDATE)); 5465 } 5466 break; 5467 } 5468 case 8: 5469 KillTimer(8); 5470 UpdateUI(NULL); 5471 break; 5472 case 9: 5473 KillTimer(9); 5474 //FIXME 5475 if (m_pUnknownThread == m_pFocusThread) 5476 Show(!!(m_dwUnknown23_5[3] & 0x80000000)); 5477 m_pUnknownThread = NULL; 5478 if ((m_dwUnknown23_5[3] & 0x2)) 5479 ShowOverScreenSizeBalloon(); 5480 break; 5481 case 10: 5482 KillTimer(10); 5483 MoveToTray(); 5484 break; 5485 case 11: 5486 KillTimer(11); 5487 if (m_pTipbarAccessible) 5488 { 5489 if (m_nID) 5490 { 5491 m_pTipbarAccessible->DoDefaultActionReal(m_nID); 5492 m_nID = 0; 5493 } 5494 } 5495 break; 5496 case 12: 5497 KillTimer(12); 5498 AdjustPosOnDisplayChange(); 5499 break; 5500 case 13: 5501#ifdef ENABLE_DESKBAND 5502 if (!m_pDeskBand || !m_pDeskBand->m_dwUnknown19) 5503 { 5504 KillTimer(13); 5505 if (!m_pFocusThread) 5506 EnsureFocusThread(); 5507 } 5508#endif 5509 break; 5510 case 14: 5511 if (SetLangBand(TRUE, TRUE)) 5512 { 5513 m_dwShowType = TF_SFT_DESKBAND; 5514 KillTimer(14); 5515 } 5516 break; 5517 default: 5518 { 5519 if (10000 <= wParam && wParam < 10050) 5520 { 5521 auto *pItem = m_LangBarItemList.GetItemStateFromTimerId(wParam); 5522 if (pItem) 5523 { 5524 auto& clsid = pItem->m_clsid; 5525 m_LangBarItemList.SetDemoteLevel(pItem->m_clsid, 2); 5526 if (m_pFocusThread) 5527 { 5528 auto *pThreadItem = m_pFocusThread->GetItem(clsid); 5529 if (pThreadItem) 5530 pThreadItem->AddRemoveMeToUI(FALSE); 5531 } 5532 } 5533 } 5534 break; 5535 } 5536 } 5537 5538 Release(); 5539} 5540 5541STDMETHODIMP_(void) CTipbarWnd::OnSysColorChange() 5542{ 5543 KillTimer(7); 5544 SetTimer(7, g_uTimerElapseSYSCOLORCHANGED); 5545} 5546 5547void CTipbarWnd::OnTerminateToolbar() 5548{ 5549 m_dwTipbarWndFlags |= TIPBAR_TOOLBARENDED; 5550 DestroyOverScreenSizeBalloon(); 5551 TerminateAllThreads(TRUE); 5552 if (!(m_dwTipbarWndFlags & TIPBAR_CHILD)) 5553 SavePosition(); 5554} 5555 5556STDMETHODIMP_(void) CTipbarWnd::OnEndSession(HWND hWnd, WPARAM wParam, LPARAM lParam) 5557{ 5558 if (!g_bWinLogon) 5559 OnTerminateToolbar(); 5560 5561 if (wParam) // End session? 5562 { 5563 if (lParam & ENDSESSION_LOGOFF) 5564 { 5565 KillTimer(9); 5566 Show(FALSE); 5567 } 5568 else 5569 { 5570 OnTerminateToolbar(); 5571 5572 AddRef(); 5573 ::DestroyWindow(hWnd); 5574 Release(); 5575 } 5576 } 5577} 5578 5579STDMETHODIMP_(void) CTipbarWnd::OnUser(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 5580{ 5581 if (uMsg == WM_USER + 1) 5582 { 5583 POINT pt = { (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam) }; 5584 ::ClientToScreen(m_hWnd, &pt); 5585 ShowContextMenu(pt, NULL, TRUE); 5586 } 5587 else if (uMsg == g_wmTaskbarCreated) 5588 { 5589 m_ShellWndThread.clear(); 5590 } 5591} 5592 5593STDMETHODIMP_(LRESULT) 5594CTipbarWnd::OnWindowPosChanged(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 5595{ 5596 if (m_pFocusThread) 5597 { 5598 for (size_t iItem = 0; iItem < m_pFocusThread->m_UIObjects.size(); ++iItem) 5599 { 5600 CTipbarItem *pItem = m_pFocusThread->m_UIObjects[iItem]; 5601 if (pItem) 5602 pItem->OnUnknown44(); 5603 } 5604 } 5605 5606 return ::DefWindowProc(hWnd, uMsg, wParam, lParam); 5607} 5608 5609STDMETHODIMP_(LRESULT) 5610CTipbarWnd::OnWindowPosChanging(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 5611{ 5612 LPWINDOWPOS pWP = (LPWINDOWPOS)lParam; 5613 if (!(pWP->flags & SWP_NOZORDER)) 5614 { 5615 if (!m_pThread && (!m_pToolTip || !m_pToolTip->m_bShowToolTip)) 5616 pWP->hwndInsertAfter = NULL; 5617 } 5618 return ::DefWindowProc(hWnd, uMsg, wParam, lParam); 5619} 5620 5621STDMETHODIMP_(LRESULT) 5622CTipbarWnd::OnShowWindow(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 5623{ 5624 if (m_pTipbarAccessible) 5625 { 5626 if (wParam) // Show? 5627 { 5628 m_pTipbarAccessible->NotifyWinEvent(EVENT_OBJECT_SHOW, GetAccItem()); 5629 m_pTipbarAccessible->NotifyWinEvent(EVENT_OBJECT_FOCUS, GetAccItem()); 5630 } 5631 else 5632 { 5633 m_pTipbarAccessible->NotifyWinEvent(EVENT_OBJECT_HIDE, GetAccItem()); 5634 } 5635 } 5636 return ::DefWindowProc(hWnd, uMsg, wParam, lParam); 5637} 5638 5639STDMETHODIMP_(LRESULT) 5640CTipbarWnd::OnSettingChange(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 5641{ 5642 if (!wParam || wParam == SPI_SETNONCLIENTMETRICS || wParam == SPI_SETHIGHCONTRAST) 5643 { 5644 KillTimer(7); 5645 SetTimer(7, g_uTimerElapseSYSCOLORCHANGED); 5646 } 5647 return 0; 5648} 5649 5650STDMETHODIMP_(LRESULT) 5651CTipbarWnd::OnDisplayChange(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 5652{ 5653 if (!(m_dwTipbarWndFlags & TIPBAR_CHILD)) 5654 { 5655 KillTimer(12); 5656 SetTimer(12, g_uTimerElapseDISPLAYCHANGE); 5657 } 5658 return ::DefWindowProc(hWnd, uMsg, wParam, lParam); 5659} 5660 5661STDMETHODIMP_(HRESULT) 5662CTipbarWnd::OnGetObject(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 5663{ 5664 if (lParam != -4) 5665 return S_OK; 5666 if (!m_pTipbarAccessible) 5667 return E_OUTOFMEMORY; 5668 5669 if (m_pTipbarAccessible->m_bInitialized) 5670 return m_pTipbarAccessible->CreateRefToAccObj(wParam); 5671 5672 HRESULT hr = S_OK; 5673 if (SUCCEEDED(m_coInit.EnsureCoInit())) 5674 { 5675 hr = m_pTipbarAccessible->Initialize(); 5676 if (FAILED(hr)) 5677 { 5678 m_pTipbarAccessible->Release(); 5679 m_pTipbarAccessible = NULL; 5680 return hr; 5681 } 5682 5683 m_pTipbarAccessible->NotifyWinEvent(EVENT_OBJECT_CREATE, GetAccItem()); 5684 return m_pTipbarAccessible->CreateRefToAccObj(wParam); 5685 } 5686 5687 return hr; 5688} 5689 5690STDMETHODIMP_(BOOL) CTipbarWnd::OnEraseBkGnd(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 5691{ 5692 return TRUE; 5693} 5694 5695STDMETHODIMP_(void) CTipbarWnd::OnThemeChanged(HWND hWnd, WPARAM wParam, LPARAM lParam) 5696{ 5697 CUIFWindow::OnThemeChanged(hWnd, wParam, lParam); 5698} 5699 5700STDMETHODIMP_(void) CTipbarWnd::UpdateUI(LPCRECT prc) 5701{ 5702 KillTimer(8); 5703 5704 if (m_dwChangingThreadId || m_bInCallOn || (m_pFocusThread && m_pFocusThread->IsDirtyItem())) 5705 { 5706 SetTimer(8, g_uTimerElapseUPDATEUI); 5707 return; 5708 } 5709 5710 if (m_dwTipbarWndFlags & TIPBAR_UPDATING) 5711 { 5712 ++m_bInCallOn; 5713 Move(m_X, m_Y, m_CX, m_CY); 5714 m_dwTipbarWndFlags &= ~TIPBAR_UPDATING; 5715 --m_bInCallOn; 5716 } 5717 5718 CUIFWindow::UpdateUI(NULL); 5719} 5720 5721/// @unimplemented 5722STDMETHODIMP_(void) CTipbarWnd::HandleMouseMsg(UINT uMsg, LONG x, LONG y) 5723{ 5724} 5725 5726/*********************************************************************** 5727 * CTipbarThread 5728 */ 5729 5730CTipbarThread::CTipbarThread(CTipbarWnd *pTipbarWnd) 5731{ 5732 m_pTipbarWnd = pTipbarWnd; 5733 m_dwThreadId = 0; 5734 m_pLangBarItemMgr = NULL; 5735 m_cRefs = 1; 5736} 5737 5738CTipbarThread::~CTipbarThread() 5739{ 5740 if (m_pTipbarWnd) 5741 { 5742 RemoveUIObjs(); 5743 m_pTipbarWnd->CleanUpThreadPointer(this, 1); 5744 } 5745 5746 _UninitItemList(1); 5747 5748 if (m_pLangBarItemMgr) 5749 { 5750 m_pLangBarItemMgr->Release(); 5751 m_pLangBarItemMgr = NULL; 5752 } 5753} 5754 5755HRESULT CTipbarThread::Init(DWORD dwThreadId) 5756{ 5757 m_dwThreadId = dwThreadId; 5758 if (!TF_GetThreadFlags(dwThreadId, &m_dwFlags1, &m_dwFlags2, &m_dwFlags3)) 5759 return E_FAIL; 5760 if (m_dwFlags1 & 0x8) 5761 return S_OK; 5762 return m_pTipbarWnd->m_pLangBarMgr->GetThreadLangBarItemMgr(m_dwThreadId, 5763 &m_pLangBarItemMgr, 5764 &dwThreadId); 5765} 5766 5767/// @unimplemented 5768HRESULT CTipbarThread::InitItemList() 5769{ 5770 return E_NOTIMPL; 5771} 5772 5773HRESULT CTipbarThread::_UninitItemList(BOOL bUnAdvise) 5774{ 5775 for (size_t iItem = 0; iItem < m_UIObjects.size(); ++iItem) 5776 { 5777 CTipbarItem* pItem = m_UIObjects[iItem]; 5778 if (pItem) 5779 pItem->m_dwItemFlags |= 0x10; 5780 } 5781 5782 HRESULT hr = S_OK; 5783 if (bUnAdvise) 5784 { 5785 if (m_dwThreadId == ::GetCurrentThreadId() || !MyWaitForInputIdle(m_dwThreadId, 2000)) 5786 hr = _UnadviseItemsSink(); 5787 } 5788 5789 for (size_t iItem = 0; iItem < m_UIObjects.size(); ++iItem) 5790 { 5791 CTipbarItem* pItem = m_UIObjects[iItem]; 5792 if (pItem) 5793 { 5794 if (m_pTipbarWnd) 5795 pItem->OnUnknown47(m_pTipbarWnd->GetWindow()); 5796 5797 pItem->ClearConnections(); 5798 5799 if (m_pTipbarWnd) 5800 pItem->OnUnknown50(); 5801 else 5802 pItem->OnUnknown51(); 5803 5804 pItem->OnUnknown59(); 5805 pItem->OnUnknown42(); 5806 } 5807 } 5808 5809 m_UIObjects.clear(); 5810 5811 RemoveAllSeparators(); 5812 5813 return hr; 5814} 5815 5816void CTipbarThread::AddAllSeparators() 5817{ 5818 for (size_t iItem = 0; iItem < m_Separators.size(); ++iItem) 5819 { 5820 CUIFObject *pItem = m_Separators[iItem]; 5821 if (pItem) 5822 m_pTipbarWnd->AddUIObj(pItem); 5823 } 5824} 5825 5826void CTipbarThread::RemoveAllSeparators() 5827{ 5828 for (size_t iItem = 0; iItem < m_Separators.size(); ++iItem) 5829 { 5830 CUIFObject *pItem = m_Separators[iItem]; 5831 if (pItem) 5832 { 5833 if (m_pTipbarWnd) 5834 m_pTipbarWnd->RemoveUIObj(pItem); 5835 delete pItem; 5836 } 5837 } 5838 m_Separators.clear(); 5839} 5840 5841void CTipbarThread::AddUIObjs() 5842{ 5843 _AddRef(); 5844 5845 for (size_t iItem = 0; iItem < m_UIObjects.size(); ++iItem) 5846 { 5847 CTipbarItem* pItem = m_UIObjects[iItem]; 5848 if (pItem && (pItem->m_dwItemFlags & 0x8)) 5849 { 5850 pItem->OnUnknown46(m_pTipbarWnd ? m_pTipbarWnd->GetWindow() : NULL); 5851 } 5852 } 5853 5854 AddAllSeparators(); 5855 MyMoveWnd(0, 0); 5856 5857 _Release(); 5858} 5859 5860void CTipbarThread::RemoveUIObjs() 5861{ 5862 for (size_t iItem = 0; iItem < m_UIObjects.size(); ++iItem) 5863 { 5864 CTipbarItem* pItem = m_UIObjects[iItem]; 5865 if (pItem) 5866 { 5867 pItem->OnUnknown47(m_pTipbarWnd ? m_pTipbarWnd->GetWindow() : NULL); 5868 } 5869 } 5870 RemoveAllSeparators(); 5871} 5872 5873CTipbarItem *CTipbarThread::GetItem(REFCLSID rclsid) 5874{ 5875 for (size_t iItem = 0; iItem < m_UIObjects.size(); ++iItem) 5876 { 5877 auto *pItem = m_UIObjects[iItem]; 5878 if (pItem && IsEqualCLSID(pItem->m_ItemInfo.guidItem, rclsid)) 5879 return pItem; 5880 } 5881 return NULL; 5882} 5883 5884void CTipbarThread::GetTextSize(BSTR bstr, LPSIZE pSize) 5885{ 5886 HWND hWnd = *m_pTipbarWnd->GetWindow(); 5887 5888 HGDIOBJ hFontOld = NULL; 5889 5890 HDC hDC = ::GetDC(hWnd); 5891 if (FAILED(m_pTipbarWnd->EnsureThemeData(*m_pTipbarWnd->GetWindow()))) 5892 { 5893 HFONT hFont = m_pTipbarWnd->m_hFont; 5894 if (hFont) 5895 hFontOld = ::SelectObject(hDC, hFont); 5896 INT cch = ::SysStringLen(bstr); 5897 ::GetTextExtentPoint32W(hDC, bstr, cch, pSize); 5898 if (hFontOld) 5899 ::SelectObject(hDC, hFontOld); 5900 } 5901 else 5902 { 5903 CUIFTheme theme; 5904 theme.m_iPartId = 1; 5905 theme.m_iStateId = 0; 5906 theme.m_pszClassList = L"TOOLBAR"; 5907 5908 HFONT hFont = NULL; 5909 5910 if (SUCCEEDED(theme.InternalOpenThemeData(hWnd))) 5911 { 5912 LOGFONTW lf; 5913 if (SUCCEEDED(::GetThemeFont(theme.m_hTheme, NULL, theme.m_iPartId, 0, 210, &lf))) 5914 { 5915 hFont = ::CreateFontIndirectW(&lf); 5916 if (hFont) 5917 hFontOld = ::SelectObject(hDC, hFont); 5918 } 5919 5920 RECT rc; 5921 INT cch = ::SysStringLen(bstr); 5922 ::GetThemeTextExtent(theme.m_hTheme, hDC, theme.m_iPartId, 0, bstr, cch, 0, NULL, &rc); 5923 5924 pSize->cx = rc.right; 5925 pSize->cy = rc.bottom; 5926 } 5927 5928 if (hFontOld) 5929 ::SelectObject(hDC, hFontOld); 5930 if (hFont) 5931 ::DeleteObject(hFont); 5932 } 5933 5934 ::ReleaseDC(hWnd, hDC); 5935} 5936 5937DWORD CTipbarThread::IsDirtyItem() 5938{ 5939 DWORD dwDirty = 0; 5940 for (size_t iItem = 0; iItem < m_UIObjects.size(); ++iItem) 5941 { 5942 CTipbarItem* pItem = m_UIObjects[iItem]; 5943 if (pItem) 5944 dwDirty |= pItem->m_dwDirty; 5945 } 5946 return dwDirty; 5947} 5948 5949BOOL CTipbarThread::IsFocusThread() 5950{ 5951 if (!m_pTipbarWnd) 5952 return FALSE; 5953 return this == m_pTipbarWnd->m_pFocusThread; 5954} 5955 5956BOOL CTipbarThread::IsVertical() 5957{ 5958 if (!m_pTipbarWnd) 5959 return FALSE; 5960 return !!(m_pTipbarWnd->m_dwTipbarWndFlags & TIPBAR_VERTICAL); 5961} 5962 5963/// @unimplemented 5964void CTipbarThread::LocateItems() 5965{ 5966} 5967 5968LONG CTipbarThread::_Release() 5969{ 5970 if (--m_cRefs == 0) 5971 { 5972 delete this; 5973 return 0; 5974 } 5975 return m_cRefs; 5976} 5977 5978HRESULT CTipbarThread::_UnadviseItemsSink() 5979{ 5980 if (!m_pLangBarItemMgr) 5981 return E_FAIL; 5982 5983 DWORD *pdwCoolkies = new(cicNoThrow) DWORD[m_UIObjects.size()]; 5984 if (!pdwCoolkies) 5985 return E_OUTOFMEMORY; 5986 5987 const size_t cItems = m_UIObjects.size(); 5988 for (size_t iItem = 0; iItem < cItems; ++iItem) 5989 { 5990 CTipbarItem* pItem = m_UIObjects[iItem]; 5991 if (pItem) 5992 pdwCoolkies[iItem] = pItem->m_dwCookie; 5993 } 5994 5995 HRESULT hr = m_pLangBarItemMgr->UnadviseItemsSink((LONG)cItems, pdwCoolkies); 5996 5997 delete[] pdwCoolkies; 5998 5999 return hr; 6000} 6001 6002void CTipbarThread::MyMoveWnd(LONG xDelta, LONG yDelta) 6003{ 6004 if (!m_pTipbarWnd || (m_pTipbarWnd->m_pFocusThread != this)) 6005 return; 6006 6007 RECT Rect, rcWorkArea; 6008 m_pTipbarWnd->GetRect(&Rect); 6009 POINT pt = { Rect.left, Rect.top }; 6010 cicGetWorkAreaRect(pt, &rcWorkArea); 6011 6012 ::GetWindowRect(*m_pTipbarWnd->GetWindow(), &Rect); 6013 6014 LONG X0 = Rect.left + xDelta, Y0 = Rect.top + yDelta; 6015 if (m_pTipbarWnd->m_dwTipbarWndFlags & 0x1000) 6016 { 6017 if (m_pTipbarWnd->CheckExcludeCaptionButtonMode(&Rect, &rcWorkArea)) 6018 { 6019 X0 = rcWorkArea.right - (3 * m_pTipbarWnd->m_ButtonWidth + 6020 m_pTipbarWnd->m_cxDlgFrameX2 + m_cxGrip); 6021 Y0 = 0; 6022 } 6023 else 6024 { 6025 m_pTipbarWnd->m_dwTipbarWndFlags &= ~0x1000; 6026 } 6027 } 6028 6029 if (IsVertical()) 6030 { 6031 LONG width = m_pTipbarWnd->m_cxDlgFrameX2 + m_pTipbarWnd->GetTipbarHeight(); 6032 LONG height = m_cyGrip + m_pTipbarWnd->m_cyDlgFrameX2; 6033 m_pTipbarWnd->SetMoveRect(X0, Y0, width, height); 6034 } 6035 else 6036 { 6037 LONG width = m_cxGrip + m_pTipbarWnd->m_cxDlgFrameX2; 6038 LONG height = m_pTipbarWnd->m_cyDlgFrameX2 + m_pTipbarWnd->GetTipbarHeight(); 6039 m_pTipbarWnd->SetMoveRect(X0, Y0, width, height); 6040 } 6041 6042 SIZE frameSize = { 0, 0 }; 6043 if (m_pTipbarWnd->m_pWndFrame) 6044 m_pTipbarWnd->m_pWndFrame->GetFrameSize(&frameSize); 6045 6046 m_pTipbarWnd->LocateCtrlButtons(); 6047 m_pTipbarWnd->AutoAdjustDeskBandSize(); 6048} 6049 6050/*********************************************************************** 6051 * CTipbarItem 6052 */ 6053 6054CTipbarItem::CTipbarItem( 6055 CTipbarThread *pThread, 6056 ITfLangBarItem *pLangBarItem, 6057 TF_LANGBARITEMINFO *pItemInfo, 6058 DWORD dwUnknown16) 6059{ 6060 m_dwUnknown19[1] = 0; 6061 m_dwUnknown19[2] = 0; 6062 m_dwUnknown19[3] = 0; 6063 m_pTipbarThread = pThread; 6064 m_ItemInfo = *pItemInfo; 6065 m_pLangBarItem = pLangBarItem; 6066 m_pLangBarItem->AddRef(); 6067 m_dwItemFlags = 0; 6068 m_dwUnknown16 = dwUnknown16; 6069 m_dwDirty = 0x1001F; 6070} 6071 6072CTipbarItem::~CTipbarItem() 6073{ 6074 if (g_pTipbarWnd) 6075 { 6076 if (g_pTipbarWnd->m_pTipbarAccessible) 6077 g_pTipbarWnd->m_pTipbarAccessible->RemoveAccItem(this); 6078 } 6079 6080 if (m_pLangBarItem) 6081 m_pLangBarItem->Release(); 6082} 6083 6084void CTipbarItem::_AddedToUI() 6085{ 6086 if (!IsConnected()) 6087 return; 6088 6089 OnUnknown41(); 6090 6091 m_dwItemFlags |= 0x2; 6092 6093 DWORD dwStatus; 6094 if (m_dwDirty) 6095 { 6096 if (m_dwDirty & 0x10000) 6097 m_pLangBarItem->GetStatus(&dwStatus); 6098 else 6099 dwStatus = 0; 6100 OnUnknown45(m_dwDirty, dwStatus); 6101 m_dwDirty = 0; 6102 } 6103 6104 if (m_pTipbarThread) 6105 { 6106 CTipbarWnd *pTipbarWnd = m_pTipbarThread->m_pTipbarWnd; 6107 if (pTipbarWnd) 6108 { 6109 CTipbarAccessible *pTipbarAccessible = pTipbarWnd->m_pTipbarAccessible; 6110 if (pTipbarAccessible) 6111 pTipbarAccessible->AddAccItem(this); 6112 } 6113 } 6114 6115 OnUnknown42(); 6116} 6117 6118void CTipbarItem::_RemovedToUI() 6119{ 6120 m_dwItemFlags &= ~0x2; 6121 6122 if (g_pTipbarWnd) 6123 { 6124 CTipbarAccessible *pAccessible = g_pTipbarWnd->m_pTipbarAccessible; 6125 if (pAccessible) 6126 pAccessible->RemoveAccItem(this); 6127 } 6128} 6129 6130void CTipbarItem::AddRemoveMeToUI(BOOL bFlag) 6131{ 6132 if (!IsConnected()) 6133 return; 6134 6135 m_pTipbarThread->LocateItems(); 6136 6137 if (!IsConnected()) 6138 return; 6139 6140 m_pTipbarThread->AddAllSeparators(); 6141 6142 CTipbarWnd *pTipbarWnd = m_pTipbarThread->m_pTipbarWnd; 6143 if (bFlag) 6144 OnUnknown46(pTipbarWnd ? pTipbarWnd->GetWindow() : NULL); 6145 else 6146 OnUnknown47(pTipbarWnd ? pTipbarWnd->GetWindow() : NULL); 6147} 6148 6149BOOL CTipbarItem::IsConnected() 6150{ 6151 return (!(m_dwItemFlags & 0x10) && m_pTipbarThread && m_pTipbarThread->m_pTipbarWnd && 6152 m_pLangBarItem); 6153} 6154 6155void CTipbarItem::ClearConnections() 6156{ 6157 m_pTipbarThread = NULL; 6158 if (m_pLangBarItem) 6159 { 6160 m_pLangBarItem->Release(); 6161 m_pLangBarItem = NULL; 6162 } 6163} 6164 6165/// @unimplemented 6166void CTipbarItem::StartDemotingTimer(BOOL bStarted) 6167{ 6168 if (!g_bIntelliSense) 6169 return; 6170 6171 if (!m_pTipbarThread) 6172 return; 6173 6174 CTipbarWnd *pTipbarWnd = m_pTipbarThread->m_pTipbarWnd; 6175 if (!pTipbarWnd) 6176 return; 6177 6178 //FIXME 6179} 6180 6181STDMETHODIMP_(BOOL) CTipbarItem::DoAccDefaultAction() 6182{ 6183 if (!m_pTipbarThread) 6184 return FALSE; 6185 CTipbarWnd *pTipbarWnd = m_pTipbarThread->m_pTipbarWnd; 6186 if (!pTipbarWnd) 6187 return FALSE; 6188 pTipbarWnd->StartDoAccDefaultActionTimer(this); 6189 return TRUE; 6190} 6191 6192/// @unimplemented 6193STDMETHODIMP_(void) CTipbarItem::OnUpdateHandler(ULONG, ULONG) 6194{ 6195} 6196 6197STDMETHODIMP_(void) CTipbarItem::GetAccLocation(LPRECT prc) 6198{ 6199 OnUnknown57(prc); 6200} 6201 6202STDMETHODIMP_(BSTR) CTipbarItem::GetAccName() 6203{ 6204 return ::SysAllocString(m_ItemInfo.szDescription); 6205} 6206 6207STDMETHODIMP_(LPCWSTR) CTipbarItem::GetToolTip() 6208{ 6209 OnUnknown41(); 6210 6211 if (!(m_dwItemFlags & 0x1)) 6212 { 6213 m_dwItemFlags |= 0x1; 6214 6215 BSTR bstrString; 6216 if (FAILED(m_pLangBarItem->GetTooltipString(&bstrString))) 6217 return NULL; 6218 6219 if (bstrString) 6220 { 6221 OnUnknown53(bstrString); 6222 ::SysFreeString(bstrString); 6223 } 6224 } 6225 6226 LPCWSTR pszToolTip = OnUnknown55(); 6227 6228 OnUnknown42(); 6229 6230 return pszToolTip; 6231} 6232 6233HRESULT CTipbarItem::OnUpdate(DWORD dwDirty) 6234{ 6235 if (!IsConnected()) 6236 return S_OK; 6237 6238 m_dwDirty |= dwDirty; 6239 m_dwItemFlags |= 0x20; 6240 6241 if ((dwDirty & 0x10000) || (m_dwItemFlags & 0x6)) 6242 { 6243 if (m_pTipbarThread) 6244 { 6245 CTipbarWnd *pTipBarWnd = m_pTipbarThread->m_pTipbarWnd; 6246 if (pTipBarWnd && *pTipBarWnd) 6247 { 6248 pTipBarWnd->KillTimer(6); 6249 pTipBarWnd->SetTimer(6, g_uTimerElapseONUPDATECALLED); 6250 } 6251 } 6252 } 6253 6254 return S_OK; 6255} 6256 6257void CTipbarItem::MyClientToScreen(LPPOINT ppt, LPRECT prc) 6258{ 6259 if (!m_pTipbarThread) 6260 return; 6261 if (m_pTipbarThread->m_pTipbarWnd) 6262 m_pTipbarThread->m_pTipbarWnd->MyClientToScreen(ppt, prc); 6263} 6264 6265/*********************************************************************** 6266 * GetTipbarInternal 6267 */ 6268BOOL GetTipbarInternal(HWND hWnd, DWORD dwFlags, CDeskBand *pDeskBand) 6269{ 6270 BOOL bParent = !!(dwFlags & 0x80000000); 6271 g_bWinLogon = !!(dwFlags & 0x1); 6272 6273 InitFromReg(); 6274 6275 if (!g_bShowTipbar) 6276 return FALSE; 6277 6278 if (bParent) 6279 { 6280 g_pTrayIconWnd = new(cicNoThrow) CTrayIconWnd(); 6281 if (!g_pTrayIconWnd) 6282 return FALSE; 6283 g_pTrayIconWnd->CreateWnd(); 6284 } 6285 6286 g_pTipbarWnd = new(cicNoThrow) CTipbarWnd(bParent ? g_dwWndStyle : g_dwChildWndStyle); 6287 if (!g_pTipbarWnd || !g_pTipbarWnd->Initialize()) 6288 return FALSE; 6289 6290 g_pTipbarWnd->Init(!bParent, pDeskBand); 6291 g_pTipbarWnd->CreateWnd(hWnd); 6292 6293 ::SetWindowText(*g_pTipbarWnd, TEXT("TF_FloatingLangBar_WndTitle")); 6294 6295 DWORD dwOldStatus = 0; 6296 if (!bParent) 6297 { 6298 g_pTipbarWnd->m_pLangBarMgr->GetPrevShowFloatingStatus(&dwOldStatus); 6299 g_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_DESKBAND); 6300 } 6301 6302 DWORD dwStatus; 6303 g_pTipbarWnd->m_pLangBarMgr->GetShowFloatingStatus(&dwStatus); 6304 g_pTipbarWnd->ShowFloating(dwStatus); 6305 6306 if (!bParent && (dwOldStatus & TF_SFT_DESKBAND)) 6307 g_pTipbarWnd->m_dwTipbarWndFlags |= TIPBAR_NODESKBAND; 6308 6309 g_hwndParent = hWnd; 6310 return TRUE; 6311} 6312 6313/*********************************************************************** 6314 * GetLibTls (MSUTB.@) 6315 * 6316 * @implemented 6317 */ 6318EXTERN_C PCIC_LIBTHREAD WINAPI 6319GetLibTls(VOID) 6320{ 6321 TRACE("()\n"); 6322 return &g_libTLS; 6323} 6324 6325/*********************************************************************** 6326 * GetPopupTipbar (MSUTB.@) 6327 * 6328 * @implemented 6329 */ 6330EXTERN_C BOOL WINAPI 6331GetPopupTipbar(HWND hWnd, BOOL fWinLogon) 6332{ 6333 TRACE("(%p, %d)\n", hWnd, fWinLogon); 6334 6335 if (!fWinLogon) 6336 TurnOffSpeechIfItsOn(); 6337 6338 return GetTipbarInternal(hWnd, fWinLogon | 0x80000000, NULL); 6339} 6340 6341/*********************************************************************** 6342 * SetRegisterLangBand (MSUTB.@) 6343 * 6344 * @implemented 6345 */ 6346EXTERN_C HRESULT WINAPI 6347SetRegisterLangBand(BOOL bRegister) 6348{ 6349 TRACE("(%d)\n", bRegister); 6350 6351 if (!g_bEnableDeskBand || !(g_dwOSInfo & CIC_OSINFO_XPPLUS)) // Desk band is for XP+ 6352 return E_FAIL; 6353 6354 BOOL bDeskBand = IsDeskBandFromReg(); 6355 if (bDeskBand == bRegister) 6356 return S_OK; 6357 6358 SetDeskBandToReg(bRegister); 6359 6360 if (!RegisterComCat(CLSID_MSUTBDeskBand, CATID_DeskBand, bRegister)) 6361 return TF_E_NOLOCK; 6362 6363 return S_OK; 6364} 6365 6366/*********************************************************************** 6367 * ClosePopupTipbar (MSUTB.@) 6368 * 6369 * @implemented 6370 */ 6371EXTERN_C VOID WINAPI 6372ClosePopupTipbar(VOID) 6373{ 6374 TRACE("()\n"); 6375 6376 if (g_fInClosePopupTipbar) 6377 return; 6378 6379 g_fInClosePopupTipbar = TRUE; 6380 6381 if (g_pTipbarWnd) 6382 { 6383 g_pTipbarWnd->m_pDeskBand = NULL; 6384 g_pTipbarWnd->DestroyWnd(); 6385 g_pTipbarWnd->Release(); 6386 g_pTipbarWnd = NULL; 6387 } 6388 6389 if (g_pTrayIconWnd) 6390 { 6391 g_pTrayIconWnd->DestroyWnd(); 6392 delete g_pTrayIconWnd; 6393 g_pTrayIconWnd = NULL; 6394 } 6395 6396 UninitSkipRedrawHKLArray(); 6397 6398 g_fInClosePopupTipbar = FALSE; 6399} 6400 6401/*********************************************************************** 6402 * DllRegisterServer (MSUTB.@) 6403 * 6404 * @implemented 6405 */ 6406STDAPI DllRegisterServer(VOID) 6407{ 6408 TRACE("()\n"); 6409 return gModule.DllRegisterServer(FALSE); 6410} 6411 6412/*********************************************************************** 6413 * DllUnregisterServer (MSUTB.@) 6414 * 6415 * @implemented 6416 */ 6417STDAPI DllUnregisterServer(VOID) 6418{ 6419 TRACE("()\n"); 6420 return gModule.DllUnregisterServer(FALSE); 6421} 6422 6423/*********************************************************************** 6424 * DllCanUnloadNow (MSUTB.@) 6425 * 6426 * @implemented 6427 */ 6428STDAPI DllCanUnloadNow(VOID) 6429{ 6430 TRACE("()\n"); 6431 return gModule.DllCanUnloadNow() && (g_DllRefCount == 0); 6432} 6433 6434/*********************************************************************** 6435 * DllGetClassObject (MSUTB.@) 6436 * 6437 * @implemented 6438 */ 6439STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) 6440{ 6441 TRACE("()\n"); 6442 return gModule.DllGetClassObject(rclsid, riid, ppv); 6443} 6444 6445/// @implemented 6446HRESULT APIENTRY 6447MsUtbCoCreateInstance( 6448 REFCLSID rclsid, 6449 LPUNKNOWN pUnkOuter, 6450 DWORD dwClsContext, 6451 REFIID iid, 6452 LPVOID *ppv) 6453{ 6454 if (IsEqualCLSID(rclsid, CLSID_TF_CategoryMgr)) 6455 return TF_CreateCategoryMgr((ITfCategoryMgr**)ppv); 6456 if (IsEqualCLSID(rclsid, CLSID_TF_DisplayAttributeMgr)) 6457 return TF_CreateDisplayAttributeMgr((ITfDisplayAttributeMgr **)ppv); 6458 return cicRealCoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, ppv); 6459} 6460 6461BEGIN_OBJECT_MAP(ObjectMap) 6462#ifdef ENABLE_DESKBAND 6463 OBJECT_ENTRY(CLSID_MSUTBDeskBand, CDeskBand) // FIXME: Implement this 6464#endif 6465END_OBJECT_MAP() 6466 6467EXTERN_C VOID TFUninitLib(VOID) 6468{ 6469 // Do nothing 6470} 6471 6472/// @implemented 6473BOOL ProcessAttach(HINSTANCE hinstDLL) 6474{ 6475 ::InitializeCriticalSectionAndSpinCount(&g_cs, 0); 6476 6477 g_hInst = hinstDLL; 6478 6479 cicGetOSInfo(&g_uACP, &g_dwOSInfo); 6480 6481 TFInitLib(MsUtbCoCreateInstance); 6482 cicInitUIFLib(); 6483 6484 CTrayIconWnd::RegisterClass(); 6485 6486 g_wmTaskbarCreated = RegisterWindowMessageW(L"TaskbarCreated"); 6487 6488 gModule.Init(ObjectMap, hinstDLL, NULL); 6489 ::DisableThreadLibraryCalls(hinstDLL); 6490 6491 return TRUE; 6492} 6493 6494/// @implemented 6495VOID ProcessDetach(HINSTANCE hinstDLL) 6496{ 6497 cicDoneUIFLib(); 6498 TFUninitLib(); 6499 ::DeleteCriticalSection(&g_cs); 6500 gModule.Term(); 6501} 6502 6503/// @implemented 6504EXTERN_C BOOL WINAPI 6505DllMain( 6506 _In_ HINSTANCE hinstDLL, 6507 _In_ DWORD dwReason, 6508 _Inout_opt_ LPVOID lpvReserved) 6509{ 6510 switch (dwReason) 6511 { 6512 case DLL_PROCESS_ATTACH: 6513 { 6514 TRACE("(%p, %lu, %p)\n", hinstDLL, dwReason, lpvReserved); 6515 if (!ProcessAttach(hinstDLL)) 6516 { 6517 ProcessDetach(hinstDLL); 6518 return FALSE; 6519 } 6520 break; 6521 } 6522 case DLL_PROCESS_DETACH: 6523 { 6524 ProcessDetach(hinstDLL); 6525 break; 6526 } 6527 } 6528 return TRUE; 6529}