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