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