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 HINSTANCE g_hInst = NULL; 13 UINT g_wmTaskbarCreated = 0; 14 UINT g_uACP = CP_ACP; 15 DWORD g_dwOSInfo = 0; 16 CRITICAL_SECTION g_cs; 17 LONG g_DllRefCount = 0; 18 BOOL g_bWinLogon = FALSE; 19 BOOL g_fInClosePopupTipbar = FALSE; 20 HWND g_hwndParent = NULL; 21 22 BOOL g_bShowTipbar = TRUE; 23 BOOL g_bShowDebugMenu = FALSE; 24 BOOL g_bNewLook = TRUE; 25 BOOL g_bIntelliSense = FALSE; 26 BOOL g_bShowCloseMenu = FALSE; 27 UINT g_uTimeOutNonIntentional = 60 * 1000; 28 UINT g_uTimeOutIntentional = 10 * 60 * 1000; 29 UINT g_uTimeOutMax = 60 * 60 * 1000; 30 BOOL g_bShowMinimizedBalloon = TRUE; 31 POINT g_ptTipbar = { -1, -1 }; 32 BOOL g_bExcludeCaptionButtons = TRUE; 33 BOOL g_bShowShadow = FALSE; 34 BOOL g_fTaskbarTheme = TRUE; 35 BOOL g_fVertical = FALSE; 36 UINT g_uTimerElapseSTUBSTART = 100; 37 UINT g_uTimerElapseSTUBEND = 2 * 1000; 38 UINT g_uTimerElapseBACKTOALPHA = 3 * 1000; 39 UINT g_uTimerElapseONTHREADITEMCHANGE = 200; 40 UINT g_uTimerElapseSETWINDOWPOS = 100; 41 UINT g_uTimerElapseONUPDATECALLED = 50; 42 UINT g_uTimerElapseSYSCOLORCHANGED = 20; 43 UINT g_uTimerElapseDISPLAYCHANGE = 20; 44 UINT g_uTimerElapseUPDATEUI = 70; 45 UINT g_uTimerElapseSHOWWINDOW = 50; 46 UINT g_uTimerElapseMOVETOTRAY = 50; 47 UINT g_uTimerElapseTRAYWNDONDELAYMSG = 50; 48 UINT g_uTimerElapseDOACCDEFAULTACTION = 200; 49 UINT g_uTimerElapseENSUREFOCUS = 50; 50 BOOL g_bShowDeskBand = FALSE; 51 UINT g_uTimerElapseSHOWDESKBAND = 3 * 1000; 52 BOOL g_fPolicyDisableCloseButton = FALSE; 53 BOOL g_fPolicyEnableLanguagebarInFullscreen = FALSE; 54 DWORD g_dwWndStyle = 0; 55 DWORD g_dwMenuStyle = 0; 56 DWORD g_dwChildWndStyle = 0; 57 BOOL g_fRTL = FALSE; 58 59 #define TIMER_ID_DOACCDEFAULTACTION 11 60 61 EXTERN_C void __cxa_pure_virtual(void) 62 { 63 ERR("__cxa_pure_virtual\n"); 64 } 65 66 class CMsUtbModule : public CComModule 67 { 68 }; 69 70 BEGIN_OBJECT_MAP(ObjectMap) 71 //OBJECT_ENTRY(CLSID_MSUTBDeskBand, CDeskBand) // FIXME: Implement this 72 END_OBJECT_MAP() 73 74 CMsUtbModule gModule; 75 76 class CCicLibMenuItem; 77 class CTipbarAccItem; 78 class CUTBMenuItem; 79 class CMainIconItem; 80 class CTrayIconItem; 81 class CTipbarWnd; 82 class CButtonIconItem; 83 class CTrayIconWnd; 84 85 CTipbarWnd *g_pTipbarWnd = NULL; 86 CTrayIconWnd *g_pTrayIconWnd = NULL; 87 88 CicArray<HKL> *g_prghklSkipRedrawing = NULL; 89 90 BOOL IsSkipRedrawHKL(HKL hSkipKL) 91 { 92 if (LOWORD(hSkipKL) == MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT)) 93 return FALSE; // Japanese HKL will be skipped 94 if (!g_prghklSkipRedrawing) 95 return FALSE; 96 97 for (size_t iItem = 0; iItem < g_prghklSkipRedrawing->size(); ++iItem) 98 { 99 if ((*g_prghklSkipRedrawing)[iItem] == hSkipKL) 100 return TRUE; // To be skipped 101 } 102 103 return FALSE; // To be not skipped 104 } 105 106 BOOL IsBiDiLocalizedSystem(void) 107 { 108 LOCALESIGNATURE Sig; 109 LANGID LangID = ::GetUserDefaultUILanguage(); 110 if (!LangID) 111 return FALSE; 112 113 INT size = sizeof(Sig) / sizeof(WCHAR); 114 if (!::GetLocaleInfoW(LangID, LOCALE_FONTSIGNATURE, (LPWSTR)&Sig, size)) 115 return FALSE; 116 return (Sig.lsUsb[3] & 0x8000000) != 0; 117 } 118 119 BOOL GetFontSig(HWND hWnd, HKL hKL) 120 { 121 LOCALESIGNATURE Sig; 122 INT size = sizeof(Sig) / sizeof(WCHAR); 123 if (!::GetLocaleInfoW(LOWORD(hKL), LOCALE_FONTSIGNATURE, (LPWSTR)&Sig, size)) 124 return FALSE; 125 126 HDC hDC = ::GetDC(hWnd); 127 DWORD CharSet = ::GetTextCharsetInfo(hDC, NULL, 0); 128 CHARSETINFO CharSetInfo; 129 ::TranslateCharsetInfo((DWORD*)(DWORD_PTR)CharSet, &CharSetInfo, TCI_SRCCHARSET); 130 ::ReleaseDC(hWnd, hDC); 131 132 return !!(CharSetInfo.fs.fsCsb[0] & Sig.lsCsbSupported[0]); 133 } 134 135 void InitSkipRedrawHKLArray(void) 136 { 137 g_prghklSkipRedrawing = new(cicNoThrow) CicArray<HKL>(); 138 if (!g_prghklSkipRedrawing) 139 return; 140 141 g_prghklSkipRedrawing->Add((HKL)UlongToHandle(0xE0010411)); // Japanese IME will be skipped 142 143 CicRegKey regKey; 144 LSTATUS error = regKey.Open(HKEY_LOCAL_MACHINE, 145 TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\SkipRedrawHKL")); 146 if (error != ERROR_SUCCESS) 147 return; 148 149 TCHAR szValueName[256]; 150 for (DWORD dwIndex = 0; ; ++dwIndex) 151 { 152 error = regKey.EnumValue(dwIndex, szValueName, _countof(szValueName)); 153 if (error != ERROR_SUCCESS) 154 break; 155 156 if (szValueName[0] == TEXT('0') && 157 (szValueName[1] == TEXT('x') || szValueName[1] == TEXT('X'))) 158 { 159 HKL hKL = (HKL)UlongToHandle(_tcstoul(szValueName, NULL, 16)); 160 g_prghklSkipRedrawing->Add(hKL); // This hKL will be skipped 161 } 162 } 163 } 164 165 void UninitSkipRedrawHKLArray(void) 166 { 167 if (g_prghklSkipRedrawing) 168 { 169 delete g_prghklSkipRedrawing; 170 g_prghklSkipRedrawing = NULL; 171 } 172 } 173 174 HRESULT GetGlobalCompartment(REFGUID rguid, ITfCompartment **ppComp) 175 { 176 ITfCompartmentMgr *pCompMgr = NULL; 177 HRESULT hr = TF_GetGlobalCompartment(&pCompMgr); 178 if (FAILED(hr)) 179 return hr; 180 181 if (!pCompMgr) 182 return E_FAIL; 183 184 hr = pCompMgr->GetCompartment(rguid, ppComp); 185 pCompMgr->Release(); 186 return hr; 187 } 188 189 HRESULT GetGlobalCompartmentDWORD(REFGUID rguid, LPDWORD pdwValue) 190 { 191 *pdwValue = 0; 192 ITfCompartment *pComp; 193 HRESULT hr = GetGlobalCompartment(rguid, &pComp); 194 if (SUCCEEDED(hr)) 195 { 196 VARIANT vari; 197 hr = pComp->GetValue(&vari); 198 if (hr == S_OK) 199 *pdwValue = V_I4(&vari); 200 pComp->Release(); 201 } 202 return hr; 203 } 204 205 HRESULT SetGlobalCompartmentDWORD(REFGUID rguid, DWORD dwValue) 206 { 207 VARIANT vari; 208 ITfCompartment *pComp; 209 HRESULT hr = GetGlobalCompartment(rguid, &pComp); 210 if (SUCCEEDED(hr)) 211 { 212 V_VT(&vari) = VT_I4; 213 V_I4(&vari) = dwValue; 214 hr = pComp->SetValue(0, &vari); 215 pComp->Release(); 216 } 217 return hr; 218 } 219 220 void TurnOffSpeechIfItsOn(void) 221 { 222 DWORD dwValue = 0; 223 HRESULT hr = GetGlobalCompartmentDWORD(GUID_COMPARTMENT_SPEECH_OPENCLOSE, &dwValue); 224 if (SUCCEEDED(hr) && dwValue) 225 SetGlobalCompartmentDWORD(GUID_COMPARTMENT_SPEECH_OPENCLOSE, 0); 226 } 227 228 void DoCloseLangbar(void) 229 { 230 ITfLangBarMgr *pLangBarMgr = NULL; 231 HRESULT hr = TF_CreateLangBarMgr(&pLangBarMgr); 232 if (FAILED(hr)) 233 return; 234 235 if (pLangBarMgr) 236 { 237 hr = pLangBarMgr->ShowFloating(TF_SFT_HIDDEN); 238 pLangBarMgr->Release(); 239 } 240 241 if (SUCCEEDED(hr)) 242 TurnOffSpeechIfItsOn(); 243 244 CicRegKey regKey; 245 LSTATUS error = regKey.Open(HKEY_CURRENT_USER, 246 TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Run"), 247 KEY_ALL_ACCESS); 248 if (error == ERROR_SUCCESS) 249 ::RegDeleteValue(regKey, TEXT("ctfmon.exe")); 250 } 251 252 INT GetIconIndexFromhKL(_In_ HKL hKL) 253 { 254 HKL hGotKL; 255 256 INT iKL, cKLs = TF_MlngInfoCount(); 257 for (iKL = 0; iKL < cKLs; ++iKL) 258 { 259 if (TF_GetMlngHKL(iKL, &hGotKL, NULL, 0) && hKL == hGotKL) 260 return TF_GetMlngIconIndex(iKL); 261 } 262 263 if (!TF_GetMlngHKL(0, &hGotKL, NULL, 0)) 264 return -1; 265 266 return TF_GetMlngIconIndex(0); 267 } 268 269 BOOL GethKLDesc(_In_ HKL hKL, _Out_ LPWSTR pszDesc, _In_ UINT cchDesc) 270 { 271 HKL hGotKL; 272 273 INT iKL, cKLs = TF_MlngInfoCount(); 274 for (iKL = 0; iKL < cKLs; ++iKL) 275 { 276 if (TF_GetMlngHKL(iKL, &hGotKL, pszDesc, cchDesc) && hKL == hGotKL) 277 return TRUE; 278 } 279 280 return TF_GetMlngHKL(0, &hGotKL, pszDesc, cchDesc); 281 } 282 283 HRESULT 284 LangBarInsertMenu( 285 _In_ ITfMenu *pMenu, 286 _In_ UINT uId, 287 _In_ LPCWSTR pszText, 288 _In_ BOOL bChecked, 289 _Inout_opt_ HICON hIcon) 290 { 291 HBITMAP hbmp = NULL, hbmpMask = NULL; 292 if (hIcon) 293 { 294 HICON hIconNew = (HICON)::CopyImage(hIcon, IMAGE_ICON, 16, 16, LR_COPYFROMRESOURCE); 295 SIZE iconSize = { 16, 16 }; 296 if (!hIconNew) 297 hIconNew = hIcon; 298 if (!cicGetIconBitmaps(hIconNew, &hbmp, &hbmpMask, &iconSize)) 299 return E_FAIL; 300 if (hIconNew) 301 ::DestroyIcon(hIconNew); 302 ::DestroyIcon(hIcon); 303 } 304 305 INT cchText = lstrlenW(pszText); 306 DWORD dwFlags = (bChecked ? TF_LBMENUF_CHECKED : 0); 307 return pMenu->AddMenuItem(uId, dwFlags, hbmp, hbmpMask, pszText, cchText, NULL); 308 } 309 310 HRESULT LangBarInsertSeparator(_In_ ITfMenu *pMenu) 311 { 312 return pMenu->AddMenuItem(-1, TF_LBMENUF_SEPARATOR, NULL, NULL, NULL, 0, NULL); 313 } 314 315 // Is it a Far-East language ID? 316 BOOL IsFELangId(LANGID LangID) 317 { 318 switch (LangID) 319 { 320 case MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED): // Chinese (Simplified) 321 case MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL): // Chinese (Traditional) 322 case MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT): // Japanese 323 case MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT): // Korean 324 return TRUE; 325 default: 326 return FALSE; 327 } 328 } 329 330 BOOL CheckCloseMenuAvailable(void) 331 { 332 BOOL ret = FALSE; 333 ITfInputProcessorProfiles *pProfiles = NULL; 334 LANGID *pLangIds = NULL; 335 ULONG iItem, cItems; 336 337 if (g_fPolicyDisableCloseButton) 338 return FALSE; 339 340 if (g_bShowCloseMenu) 341 return TRUE; 342 343 if (SUCCEEDED(TF_CreateInputProcessorProfiles(&pProfiles)) && 344 SUCCEEDED(pProfiles->GetLanguageList(&pLangIds, &cItems))) 345 { 346 for (iItem = 0; iItem < cItems; ++iItem) 347 { 348 if (IsFELangId(pLangIds[iItem])) 349 break; 350 } 351 352 ret = (iItem == cItems); 353 } 354 355 if (pLangIds) 356 CoTaskMemFree(pLangIds); 357 if (pProfiles) 358 pProfiles->Release(); 359 360 return ret; 361 } 362 363 /// @unimplemented 364 BOOL IsTransparecyAvailable(void) 365 { 366 return FALSE; 367 } 368 369 static INT CALLBACK 370 FindEAEnumFontProc(ENUMLOGFONT *pLF, NEWTEXTMETRIC *pTM, INT nFontType, LPARAM lParam) 371 { 372 if ((nFontType != TRUETYPE_FONTTYPE) || (pLF->elfLogFont.lfFaceName[0] != '@')) 373 return TRUE; 374 *(BOOL*)lParam = TRUE; 375 return FALSE; 376 } 377 378 /// Are there East-Asian vertical fonts? 379 BOOL CheckEAFonts(void) 380 { 381 BOOL bHasVertical = FALSE; 382 HDC hDC = ::GetDC(NULL); 383 ::EnumFonts(hDC, NULL, (FONTENUMPROC)FindEAEnumFontProc, (LPARAM)&bHasVertical); 384 ::ReleaseDC(NULL, hDC); 385 return bHasVertical; 386 } 387 388 BOOL IsDeskBandFromReg() 389 { 390 if (!(g_dwOSInfo & CIC_OSINFO_XPPLUS)) // Desk band is for XP+ 391 return FALSE; 392 393 CicRegKey regKey; 394 if (regKey.Open(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\"))) 395 { 396 DWORD dwValue = 0; 397 regKey.QueryDword(TEXT("ShowDeskBand"), &dwValue); 398 return !!dwValue; 399 } 400 401 return FALSE; 402 } 403 404 void SetDeskBandToReg(BOOL bShow) 405 { 406 CicRegKey regKey; 407 if (regKey.Open(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\"), KEY_ALL_ACCESS)) 408 regKey.SetDword(TEXT("ShowDeskBand"), bShow); 409 } 410 411 BOOL RegisterComCat(REFCLSID rclsid, REFCATID rcatid, BOOL bRegister) 412 { 413 if (FAILED(::CoInitialize(NULL))) 414 return FALSE; 415 416 ICatRegister *pCat; 417 HRESULT hr = ::CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, 418 IID_ICatRegister, (void**)&pCat); 419 if (SUCCEEDED(hr)) 420 { 421 if (bRegister) 422 hr = pCat->RegisterClassImplCategories(rclsid, 1, const_cast<CATID*>(&rcatid)); 423 else 424 hr = pCat->UnRegisterClassImplCategories(rclsid, 1, const_cast<CATID*>(&rcatid)); 425 426 pCat->Release(); 427 } 428 429 ::CoUninitialize(); 430 431 //if (IsIE5()) 432 // ::RegDeleteKey(HKEY_CLASSES_ROOT, TEXT("Component Categories\\{00021492-0000-0000-C000-000000000046}\\Enum")); 433 434 return SUCCEEDED(hr); 435 } 436 437 BOOL InitFromReg(void) 438 { 439 DWORD dwValue; 440 LSTATUS error; 441 442 CicRegKey regKey1; 443 error = regKey1.Open(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\")); 444 if (error == ERROR_SUCCESS) 445 { 446 error = regKey1.QueryDword(TEXT("ShowTipbar"), &dwValue); 447 if (error == ERROR_SUCCESS) 448 g_bShowTipbar = !!dwValue; 449 } 450 451 CicRegKey regKey2; 452 error = regKey2.Open(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\")); 453 if (error == ERROR_SUCCESS) 454 { 455 error = regKey2.QueryDword(TEXT("ShowDebugMenu"), &dwValue); 456 if (error == ERROR_SUCCESS) 457 g_bShowDebugMenu = !!dwValue; 458 error = regKey2.QueryDword(TEXT("NewLook"), &dwValue); 459 if (error == ERROR_SUCCESS) 460 g_bNewLook = !!dwValue; 461 error = regKey2.QueryDword(TEXT("IntelliSense"), &dwValue); 462 if (error == ERROR_SUCCESS) 463 g_bIntelliSense = !!dwValue; 464 error = regKey2.QueryDword(TEXT("ShowCloseMenu"), &dwValue); 465 if (error == ERROR_SUCCESS) 466 g_bShowCloseMenu = !!dwValue; 467 error = regKey2.QueryDword(TEXT("TimeOutNonIntentional"), &dwValue); 468 if (error == ERROR_SUCCESS) 469 g_uTimeOutNonIntentional = 1000 * dwValue; 470 error = regKey2.QueryDword(TEXT("TimeOutIntentional"), &dwValue); 471 if (error == ERROR_SUCCESS) 472 { 473 g_uTimeOutIntentional = 1000 * dwValue; 474 g_uTimeOutMax = 6000 * dwValue; 475 } 476 error = regKey2.QueryDword(TEXT("ShowMinimizedBalloon"), &dwValue); 477 if (error == ERROR_SUCCESS) 478 g_bShowMinimizedBalloon = !!dwValue; 479 error = regKey2.QueryDword(TEXT("Left"), &dwValue); 480 if (error == ERROR_SUCCESS) 481 g_ptTipbar.x = dwValue; 482 error = regKey2.QueryDword(TEXT("Top"), &dwValue); 483 if (error == ERROR_SUCCESS) 484 g_ptTipbar.y = dwValue; 485 error = regKey2.QueryDword(TEXT("ExcludeCaptionButtons"), &dwValue); 486 if (error == ERROR_SUCCESS) 487 g_bExcludeCaptionButtons = !!dwValue; 488 error = regKey2.QueryDword(TEXT("ShowShadow"), &dwValue); 489 if (error == ERROR_SUCCESS) 490 g_bShowShadow = !!dwValue; 491 error = regKey2.QueryDword(TEXT("TaskbarTheme"), &dwValue); 492 if (error == ERROR_SUCCESS) 493 g_fTaskbarTheme = !!dwValue; 494 error = regKey2.QueryDword(TEXT("Vertical"), &dwValue); 495 if (error == ERROR_SUCCESS) 496 g_fVertical = !!dwValue; 497 error = regKey2.QueryDword(TEXT("TimerElapseSTUBSTART"), &dwValue); 498 if (error == ERROR_SUCCESS) 499 g_uTimerElapseSTUBSTART = dwValue; 500 error = regKey2.QueryDword(TEXT("TimerElapseSTUBEND"), &dwValue); 501 if (error == ERROR_SUCCESS) 502 g_uTimerElapseSTUBEND = dwValue; 503 error = regKey2.QueryDword(TEXT("TimerElapseBACKTOALPHA"), &dwValue); 504 if (error == ERROR_SUCCESS) 505 g_uTimerElapseBACKTOALPHA = dwValue; 506 error = regKey2.QueryDword(TEXT("TimerElapseONTHREADITEMCHANGE"), &dwValue); 507 if (error == ERROR_SUCCESS) 508 g_uTimerElapseONTHREADITEMCHANGE = dwValue; 509 error = regKey2.QueryDword(TEXT("TimerElapseSETWINDOWPOS"), &dwValue); 510 if (error == ERROR_SUCCESS) 511 g_uTimerElapseSETWINDOWPOS = dwValue; 512 error = regKey2.QueryDword(TEXT("TimerElapseONUPDATECALLED"), &dwValue); 513 if (error == ERROR_SUCCESS) 514 g_uTimerElapseONUPDATECALLED = dwValue; 515 error = regKey2.QueryDword(TEXT("TimerElapseSYSCOLORCHANGED"), &dwValue); 516 if (error == ERROR_SUCCESS) 517 g_uTimerElapseSYSCOLORCHANGED = dwValue; 518 error = regKey2.QueryDword(TEXT("TimerElapseDISPLAYCHANGE"), &dwValue); 519 if (error == ERROR_SUCCESS) 520 g_uTimerElapseDISPLAYCHANGE = dwValue; 521 error = regKey2.QueryDword(TEXT("TimerElapseUPDATEUI"), &dwValue); 522 if (error == ERROR_SUCCESS) 523 g_uTimerElapseUPDATEUI = dwValue; 524 error = regKey2.QueryDword(TEXT("TimerElapseSHOWWINDOW"), &dwValue); 525 if (error == ERROR_SUCCESS) 526 g_uTimerElapseSHOWWINDOW = dwValue; 527 error = regKey2.QueryDword(TEXT("TimerElapseMOVETOTRAY"), &dwValue); 528 if (error == ERROR_SUCCESS) 529 g_uTimerElapseMOVETOTRAY = dwValue; 530 error = regKey2.QueryDword(TEXT("TimerElapseTRAYWNDONDELAYMSG"), &dwValue); 531 if (error == ERROR_SUCCESS) 532 g_uTimerElapseTRAYWNDONDELAYMSG = dwValue; 533 error = regKey2.QueryDword(TEXT("TimerElapseDOACCDEFAULTACTION"), &dwValue); 534 if (error == ERROR_SUCCESS) 535 g_uTimerElapseDOACCDEFAULTACTION = dwValue; 536 error = regKey2.QueryDword(TEXT("TimerElapseENSUREFOCUS"), &dwValue); 537 if (error == ERROR_SUCCESS) 538 g_uTimerElapseENSUREFOCUS = dwValue; 539 error = regKey2.QueryDword(TEXT("ShowDeskBand"), &dwValue); 540 if (error == ERROR_SUCCESS) 541 g_bShowDeskBand = !!dwValue; 542 error = regKey2.QueryDword(TEXT("TimerElapseSHOWWDESKBAND"), &dwValue); 543 if (error == ERROR_SUCCESS) 544 g_uTimerElapseSHOWDESKBAND = dwValue; 545 } 546 547 CicRegKey regKey3; 548 error = regKey3.Open(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Policies\\Microsoft\\MSCTF")); 549 if (error == ERROR_SUCCESS) 550 { 551 error = regKey3.QueryDword(TEXT("DisableCloseButton"), &dwValue); 552 if (error == ERROR_SUCCESS) 553 g_fPolicyDisableCloseButton = !!dwValue; 554 } 555 556 CicRegKey regKey4; 557 error = regKey4.Open(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Policies\\Microsoft\\MSCTF")); 558 if (error == ERROR_SUCCESS) 559 { 560 error = regKey4.QueryDword(TEXT("EnableLanguagebarInFullscreen"), &dwValue); 561 if (error == ERROR_SUCCESS) 562 g_fPolicyEnableLanguagebarInFullscreen = !!dwValue; 563 } 564 565 InitSkipRedrawHKLArray(); 566 567 if (g_bNewLook) 568 { 569 g_dwWndStyle = UIF_WINDOW_ENABLETHEMED | UIF_WINDOW_WORKAREA | UIF_WINDOW_TOOLTIP | 570 UIF_WINDOW_TOOLWINDOW | UIF_WINDOW_TOPMOST; 571 if (g_bShowShadow) 572 g_dwWndStyle |= UIF_WINDOW_SHADOW; 573 g_dwMenuStyle = 0x10000000 | UIF_WINDOW_MONITOR | UIF_WINDOW_SHADOW | 574 UIF_WINDOW_TOOLWINDOW | UIF_WINDOW_TOPMOST; 575 } 576 else 577 { 578 g_dwWndStyle = UIF_WINDOW_WORKAREA | UIF_WINDOW_TOOLTIP | UIF_WINDOW_DLGFRAME | 579 UIF_WINDOW_TOPMOST; 580 g_dwMenuStyle = UIF_WINDOW_MONITOR | UIF_WINDOW_DLGFRAME | UIF_WINDOW_TOPMOST; 581 } 582 583 g_dwChildWndStyle = 584 UIF_WINDOW_ENABLETHEMED | UIF_WINDOW_NOMOUSEMSG | UIF_WINDOW_TOOLTIP | UIF_WINDOW_CHILD; 585 586 if (IsBiDiLocalizedSystem()) 587 { 588 g_dwWndStyle |= UIF_WINDOW_LAYOUTRTL; 589 g_dwChildWndStyle |= UIF_WINDOW_LAYOUTRTL; 590 g_dwMenuStyle |= UIF_WINDOW_LAYOUTRTL; 591 g_fRTL = TRUE; 592 } 593 594 return TRUE; 595 } 596 597 /***********************************************************************/ 598 599 struct CShellWndThread 600 { 601 HWND m_hTrayWnd = NULL; 602 HWND m_hProgmanWnd = NULL; 603 604 HWND GetWndTray() 605 { 606 if (!m_hTrayWnd || !::IsWindow(m_hTrayWnd)) 607 m_hTrayWnd = ::FindWindowW(L"Shell_TrayWnd", NULL); 608 return m_hTrayWnd; 609 } 610 611 HWND GetWndProgman() 612 { 613 if (!m_hProgmanWnd || !::IsWindow(m_hProgmanWnd)) 614 m_hProgmanWnd = ::FindWindowW(L"Progman", NULL); 615 return m_hProgmanWnd; 616 } 617 618 void clear() 619 { 620 m_hTrayWnd = m_hProgmanWnd = NULL; 621 } 622 }; 623 624 /***********************************************************************/ 625 626 class CUTBLangBarDlg 627 { 628 protected: 629 LPTSTR m_pszDialogName; 630 LONG m_cRefs; 631 632 public: 633 CUTBLangBarDlg() { } 634 virtual ~CUTBLangBarDlg() { } 635 636 static CUTBLangBarDlg *GetThis(HWND hDlg); 637 static void SetThis(HWND hDlg, CUTBLangBarDlg *pThis); 638 static DWORD WINAPI s_ThreadProc(LPVOID pParam); 639 static INT_PTR CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); 640 641 BOOL StartThread(); 642 LONG _Release(); 643 644 STDMETHOD_(BOOL, DoModal)(HWND hDlg) = 0; 645 STDMETHOD_(BOOL, OnCommand)(HWND hDlg, WPARAM wParam, LPARAM lParam) = 0; 646 STDMETHOD_(BOOL, IsDlgShown)() = 0; 647 STDMETHOD_(void, SetDlgShown)(BOOL bShown) = 0; 648 STDMETHOD_(BOOL, ThreadProc)(); 649 }; 650 651 /***********************************************************************/ 652 653 class CUTBCloseLangBarDlg : public CUTBLangBarDlg 654 { 655 public: 656 CUTBCloseLangBarDlg(); 657 658 static BOOL s_bIsDlgShown; 659 660 STDMETHOD_(BOOL, DoModal)(HWND hDlg) override; 661 STDMETHOD_(BOOL, OnCommand)(HWND hDlg, WPARAM wParam, LPARAM lParam) override; 662 STDMETHOD_(BOOL, IsDlgShown)() override; 663 STDMETHOD_(void, SetDlgShown)(BOOL bShown) override; 664 }; 665 666 BOOL CUTBCloseLangBarDlg::s_bIsDlgShown = FALSE; 667 668 /***********************************************************************/ 669 670 class CUTBMinimizeLangBarDlg : public CUTBLangBarDlg 671 { 672 public: 673 CUTBMinimizeLangBarDlg(); 674 675 static BOOL s_bIsDlgShown; 676 677 STDMETHOD_(BOOL, DoModal)(HWND hDlg) override; 678 STDMETHOD_(BOOL, OnCommand)(HWND hDlg, WPARAM wParam, LPARAM lParam) override; 679 STDMETHOD_(BOOL, IsDlgShown)() override; 680 STDMETHOD_(void, SetDlgShown)(BOOL bShown) override; 681 STDMETHOD_(BOOL, ThreadProc)() override; 682 }; 683 684 BOOL CUTBMinimizeLangBarDlg::s_bIsDlgShown = FALSE; 685 686 /***********************************************************************/ 687 688 class CCicLibMenu : public ITfMenu 689 { 690 protected: 691 CicArray<CCicLibMenuItem*> m_MenuItems; 692 LONG m_cRefs; 693 694 public: 695 CCicLibMenu(); 696 virtual ~CCicLibMenu(); 697 698 STDMETHOD(QueryInterface)(REFIID riid, LPVOID *ppvObj) override; 699 STDMETHOD_(ULONG, AddRef)() override; 700 STDMETHOD_(ULONG, Release)() override; 701 STDMETHOD(AddMenuItem)( 702 UINT uId, 703 DWORD dwFlags, 704 HBITMAP hbmp, 705 HBITMAP hbmpMask, 706 const WCHAR *pch, 707 ULONG cch, 708 ITfMenu **ppSubMenu) override; 709 STDMETHOD_(CCicLibMenu*, CreateSubMenu)(); 710 STDMETHOD_(CCicLibMenuItem*, CreateMenuItem)(); 711 }; 712 713 /***********************************************************************/ 714 715 class CCicLibMenuItem 716 { 717 protected: 718 DWORD m_uId; 719 DWORD m_dwFlags; 720 HBITMAP m_hbmp; 721 HBITMAP m_hbmpMask; 722 BSTR m_bstrText; 723 ITfMenu *m_pMenu; 724 725 public: 726 CCicLibMenuItem(); 727 virtual ~CCicLibMenuItem(); 728 729 BOOL Init( 730 UINT uId, 731 DWORD dwFlags, 732 HBITMAP hbmp, 733 HBITMAP hbmpMask, 734 const WCHAR *pch, 735 ULONG cch, 736 ITfMenu *pMenu); 737 HBITMAP CreateBitmap(HANDLE hBitmap); 738 }; 739 740 /***********************************************************************/ 741 742 class CTipbarAccessible : public IAccessible 743 { 744 protected: 745 LONG m_cRefs; 746 HWND m_hWnd; 747 IAccessible *m_pStdAccessible; 748 ITypeInfo *m_pTypeInfo; 749 BOOL m_bInitialized; 750 CicArray<CTipbarAccItem*> m_AccItems; 751 LONG m_cSelection; 752 friend class CUTBMenuWnd; 753 friend class CTipbarWnd; 754 755 public: 756 CTipbarAccessible(CTipbarAccItem *pItem); 757 virtual ~CTipbarAccessible(); 758 759 HRESULT Initialize(); 760 761 BOOL AddAccItem(CTipbarAccItem *pItem); 762 HRESULT RemoveAccItem(CTipbarAccItem *pItem); 763 void ClearAccItems(); 764 CTipbarAccItem *AccItemFromID(INT iItem); 765 INT GetIDOfItem(CTipbarAccItem *pTarget); 766 767 LONG_PTR CreateRefToAccObj(WPARAM wParam); 768 BOOL DoDefaultActionReal(INT nID); 769 void NotifyWinEvent(DWORD event, CTipbarAccItem *pItem); 770 void SetWindow(HWND hWnd); 771 772 // IUnknown methods 773 STDMETHOD(QueryInterface)(REFIID riid, void **ppvObject); 774 STDMETHOD_(ULONG, AddRef)(); 775 STDMETHOD_(ULONG, Release)(); 776 777 // IDispatch methods 778 STDMETHOD(GetTypeInfoCount)(UINT *pctinfo); 779 STDMETHOD(GetTypeInfo)( 780 UINT iTInfo, 781 LCID lcid, 782 ITypeInfo **ppTInfo); 783 STDMETHOD(GetIDsOfNames)( 784 REFIID riid, 785 LPOLESTR *rgszNames, 786 UINT cNames, 787 LCID lcid, 788 DISPID *rgDispId); 789 STDMETHOD(Invoke)( 790 DISPID dispIdMember, 791 REFIID riid, 792 LCID lcid, 793 WORD wFlags, 794 DISPPARAMS *pDispParams, 795 VARIANT *pVarResult, 796 EXCEPINFO *pExcepInfo, 797 UINT *puArgErr); 798 799 // IAccessible methods 800 STDMETHOD(get_accParent)(IDispatch **ppdispParent); 801 STDMETHOD(get_accChildCount)(LONG *pcountChildren); 802 STDMETHOD(get_accChild)(VARIANT varChildID, IDispatch **ppdispChild); 803 STDMETHOD(get_accName)(VARIANT varID, BSTR *pszName); 804 STDMETHOD(get_accValue)(VARIANT varID, BSTR *pszValue); 805 STDMETHOD(get_accDescription)(VARIANT varID, BSTR *description); 806 STDMETHOD(get_accRole)(VARIANT varID, VARIANT *role); 807 STDMETHOD(get_accState)(VARIANT varID, VARIANT *state); 808 STDMETHOD(get_accHelp)(VARIANT varID, BSTR *help); 809 STDMETHOD(get_accHelpTopic)(BSTR *helpfile, VARIANT varID, LONG *pidTopic); 810 STDMETHOD(get_accKeyboardShortcut)(VARIANT varID, BSTR *shortcut); 811 STDMETHOD(get_accFocus)(VARIANT *pvarID); 812 STDMETHOD(get_accSelection)(VARIANT *pvarID); 813 STDMETHOD(get_accDefaultAction)(VARIANT varID, BSTR *action); 814 STDMETHOD(accSelect)(LONG flagsSelect, VARIANT varID); 815 STDMETHOD(accLocation)( 816 LONG *left, 817 LONG *top, 818 LONG *width, 819 LONG *height, 820 VARIANT varID); 821 STDMETHOD(accNavigate)(LONG dir, VARIANT varStart, VARIANT *pvarEnd); 822 STDMETHOD(accHitTest)(LONG left, LONG top, VARIANT *pvarID); 823 STDMETHOD(accDoDefaultAction)(VARIANT varID); 824 STDMETHOD(put_accName)(VARIANT varID, BSTR name); 825 STDMETHOD(put_accValue)(VARIANT varID, BSTR value); 826 }; 827 828 /***********************************************************************/ 829 830 class CTipbarAccItem 831 { 832 public: 833 CTipbarAccItem() { } 834 virtual ~CTipbarAccItem() { } 835 836 STDMETHOD_(BSTR, GetAccName)() 837 { 838 return SysAllocString(L""); 839 } 840 STDMETHOD_(BSTR, GetAccValue)() 841 { 842 return NULL; 843 } 844 STDMETHOD_(INT, GetAccRole)() 845 { 846 return 10; 847 } 848 STDMETHOD_(INT, GetAccState)() 849 { 850 return 256; 851 } 852 STDMETHOD_(void, GetAccLocation)(LPRECT lprc) 853 { 854 *lprc = { 0, 0, 0, 0 }; 855 } 856 STDMETHOD_(BSTR, GetAccDefaultAction)() 857 { 858 return NULL; 859 } 860 STDMETHOD_(BOOL, DoAccDefaultAction)() 861 { 862 return FALSE; 863 } 864 STDMETHOD_(BOOL, DoAccDefaultActionReal)() 865 { 866 return FALSE; 867 } 868 }; 869 870 /***********************************************************************/ 871 872 class CTipbarCoInitialize 873 { 874 public: 875 BOOL m_bCoInit; 876 877 CTipbarCoInitialize() : m_bCoInit(FALSE) { } 878 ~CTipbarCoInitialize() { CoUninit(); } 879 880 HRESULT EnsureCoInit() 881 { 882 if (m_bCoInit) 883 return S_OK; 884 HRESULT hr = ::CoInitialize(NULL); 885 if (FAILED(hr)) 886 return hr; 887 m_bCoInit = TRUE; 888 return S_OK; 889 } 890 891 void CoUninit() 892 { 893 if (m_bCoInit) 894 { 895 ::CoUninitialize(); 896 m_bCoInit = FALSE; 897 } 898 } 899 }; 900 901 /***********************************************************************/ 902 903 class CUTBMenuWnd : public CTipbarAccItem, public CUIFMenu 904 { 905 protected: 906 CTipbarCoInitialize m_coInit; 907 CTipbarAccessible *m_pAccessible; 908 UINT m_nMenuWndID; 909 friend class CUTBMenuItem; 910 911 public: 912 CUTBMenuWnd(HINSTANCE hInst, DWORD style, DWORD dwUnknown14); 913 914 BOOL StartDoAccDefaultActionTimer(CUTBMenuItem *pTarget); 915 916 CTipbarAccItem* GetAccItem() 917 { 918 return static_cast<CTipbarAccItem*>(this); 919 } 920 CUIFMenu* GetMenu() 921 { 922 return static_cast<CUIFMenu*>(this); 923 } 924 925 STDMETHOD_(BSTR, GetAccName)() override; 926 STDMETHOD_(INT, GetAccRole)() override; 927 STDMETHOD_(BOOL, Initialize)() override; 928 STDMETHOD_(void, OnCreate)(HWND hWnd) override; 929 STDMETHOD_(void, OnDestroy)(HWND hWnd) override; 930 STDMETHOD_(HRESULT, OnGetObject)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override; 931 STDMETHOD_(LRESULT, OnShowWindow)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override; 932 STDMETHOD_(void, OnTimer)(WPARAM wParam) override; 933 }; 934 935 /***********************************************************************/ 936 937 class CUTBMenuItem : public CTipbarAccItem, public CUIFMenuItem 938 { 939 protected: 940 CUTBMenuWnd *m_pMenuUI; 941 friend class CUTBMenuWnd; 942 943 public: 944 CUTBMenuItem(CUTBMenuWnd *pMenuUI); 945 ~CUTBMenuItem() override; 946 947 CUIFMenuItem* GetMenuItem() 948 { 949 return static_cast<CUIFMenuItem*>(this); 950 } 951 952 STDMETHOD_(BOOL, DoAccDefaultAction)() override; 953 STDMETHOD_(BOOL, DoAccDefaultActionReal)() override; 954 STDMETHOD_(BSTR, GetAccDefaultAction)() override; 955 STDMETHOD_(void, GetAccLocation)(LPRECT lprc) override; 956 STDMETHOD_(BSTR, GetAccName)() override; 957 STDMETHOD_(INT, GetAccRole)() override; 958 }; 959 960 /***********************************************************************/ 961 962 class CModalMenu 963 { 964 public: 965 DWORD m_dwUnknown26; 966 CUTBMenuWnd *m_pMenuUI; 967 968 public: 969 CModalMenu() { } 970 virtual ~CModalMenu() { } 971 972 CUTBMenuItem *InsertItem(CUTBMenuWnd *pMenuUI, INT nCommandId, INT nStringID); 973 void PostKey(BOOL bUp, WPARAM wParam, LPARAM lParam); 974 void CancelMenu(); 975 }; 976 977 /***********************************************************************/ 978 979 class CTipbarThread; 980 981 class CUTBContextMenu : public CModalMenu 982 { 983 public: 984 CTipbarWnd *m_pTipbarWnd; 985 CTipbarThread *m_pTipbarThread; 986 987 public: 988 CUTBContextMenu(CTipbarWnd *pTipbarWnd); 989 990 BOOL Init(); 991 CUTBMenuWnd *CreateMenuUI(BOOL bFlag); 992 993 UINT ShowPopup( 994 CUIFWindow *pWindow, 995 POINT pt, 996 LPCRECT prc, 997 BOOL bFlag); 998 999 BOOL SelectMenuItem(UINT nCommandId); 1000 }; 1001 1002 /***********************************************************************/ 1003 1004 class CUTBLBarMenuItem; 1005 1006 class CUTBLBarMenu : public CCicLibMenu 1007 { 1008 protected: 1009 CUTBMenuWnd *m_pMenuUI; 1010 HINSTANCE m_hInst; 1011 1012 public: 1013 CUTBLBarMenu(HINSTANCE hInst); 1014 ~CUTBLBarMenu() override; 1015 1016 CUTBMenuWnd *CreateMenuUI(); 1017 INT ShowPopup(CUIFWindow *pWindow, POINT pt, LPCRECT prcExclude); 1018 1019 STDMETHOD_(CCicLibMenuItem*, CreateMenuItem)() override; 1020 STDMETHOD_(CCicLibMenu*, CreateSubMenu)() override; 1021 }; 1022 1023 /***********************************************************************/ 1024 1025 class CUTBLBarMenuItem : public CCicLibMenuItem 1026 { 1027 public: 1028 CUTBLBarMenu *m_pLBarMenu; 1029 1030 public: 1031 CUTBLBarMenuItem() { m_pLBarMenu = NULL; } 1032 BOOL InsertToUI(CUTBMenuWnd *pMenuUI); 1033 }; 1034 1035 /***********************************************************************/ 1036 1037 class CTipbarGripper : public CUIFGripper 1038 { 1039 protected: 1040 CTipbarWnd *m_pTipbarWnd; 1041 BOOL m_bInDebugMenu; 1042 friend class CTipbarWnd; 1043 1044 public: 1045 CTipbarGripper(CTipbarWnd *pTipbarWnd, LPCRECT prc, DWORD style); 1046 1047 STDMETHOD_(void, OnLButtonUp)(LONG x, LONG y) override; 1048 STDMETHOD_(void, OnRButtonUp)(LONG x, LONG y) override; 1049 STDMETHOD_(BOOL, OnSetCursor)(UINT uMsg, LONG x, LONG y) override; 1050 }; 1051 1052 /***********************************************************************/ 1053 1054 class CTrayIconWnd 1055 { 1056 protected: 1057 DWORD m_dwUnknown20; 1058 BOOL m_bBusy; 1059 UINT m_uCallbackMessage; 1060 UINT m_uMsg; 1061 HWND m_hWnd; 1062 DWORD m_dwUnknown21[2]; 1063 HWND m_hTrayWnd; 1064 HWND m_hNotifyWnd; 1065 DWORD m_dwTrayWndThreadId; 1066 DWORD m_dwUnknown22; 1067 HWND m_hwndProgman; 1068 DWORD m_dwProgmanThreadId; 1069 CMainIconItem *m_pMainIconItem; 1070 CicArray<CButtonIconItem*> m_Items; 1071 UINT m_uCallbackMsg; 1072 UINT m_uNotifyIconID; 1073 friend class CTipbarWnd; 1074 1075 static BOOL CALLBACK EnumChildWndProc(HWND hWnd, LPARAM lParam); 1076 static LRESULT CALLBACK _WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 1077 1078 public: 1079 CTrayIconWnd(); 1080 ~CTrayIconWnd(); 1081 1082 static BOOL RegisterClass(); 1083 static CTrayIconWnd *GetThis(HWND hWnd); 1084 static void SetThis(HWND hWnd, LPCREATESTRUCT pCS); 1085 1086 HWND CreateWnd(); 1087 void DestroyWnd(); 1088 1089 BOOL SetMainIcon(HKL hKL); 1090 BOOL SetIcon(REFGUID rguid, DWORD dwUnknown24, HICON hIcon, LPCWSTR psz); 1091 1092 void RemoveAllIcon(DWORD dwFlags); 1093 void RemoveUnusedIcons(int unknown); 1094 1095 CButtonIconItem *FindIconItem(REFGUID rguid); 1096 BOOL FindTrayEtc(); 1097 HWND GetNotifyWnd(); 1098 BOOL OnIconMessage(UINT uMsg, WPARAM wParam, LPARAM lParam); 1099 1100 void CallOnDelayMsg(); 1101 }; 1102 1103 /***********************************************************************/ 1104 1105 class CTrayIconItem 1106 { 1107 protected: 1108 HWND m_hWnd; 1109 UINT m_uCallbackMessage; 1110 UINT m_uNotifyIconID; 1111 DWORD m_dwIconAddOrModify; 1112 BOOL m_bIconAdded; 1113 CTrayIconWnd *m_pTrayIconWnd; 1114 DWORD m_dwUnknown25; 1115 GUID m_guid; 1116 RECT m_rcMenu; 1117 POINT m_ptCursor; 1118 friend class CTrayIconWnd; 1119 1120 public: 1121 CTrayIconItem(CTrayIconWnd *pTrayIconWnd); 1122 virtual ~CTrayIconItem() { } 1123 1124 BOOL _Init(HWND hWnd, UINT uCallbackMessage, UINT uNotifyIconID, const GUID& rguid); 1125 BOOL UpdateMenuRectPoint(); 1126 BOOL RemoveIcon(); 1127 1128 STDMETHOD_(BOOL, SetIcon)(HICON hIcon, LPCWSTR pszTip); 1129 STDMETHOD_(BOOL, OnMsg)(WPARAM wParam, LPARAM lParam) { return FALSE; }; 1130 STDMETHOD_(BOOL, OnDelayMsg)(UINT uMsg) { return 0; }; 1131 }; 1132 1133 /***********************************************************************/ 1134 1135 class CButtonIconItem : public CTrayIconItem 1136 { 1137 protected: 1138 DWORD m_dwUnknown24; 1139 HKL m_hKL; 1140 friend class CTrayIconWnd; 1141 1142 public: 1143 CButtonIconItem(CTrayIconWnd *pWnd, DWORD dwUnknown24); 1144 1145 STDMETHOD_(BOOL, OnMsg)(WPARAM wParam, LPARAM lParam) override; 1146 STDMETHOD_(BOOL, OnDelayMsg)(UINT uMsg) override; 1147 }; 1148 1149 /***********************************************************************/ 1150 1151 class CMainIconItem : public CButtonIconItem 1152 { 1153 public: 1154 CMainIconItem(CTrayIconWnd *pWnd); 1155 1156 BOOL Init(HWND hWnd); 1157 STDMETHOD_(BOOL, OnDelayMsg)(UINT uMsg) override; 1158 }; 1159 1160 /***********************************************************************/ 1161 1162 class CLBarItemBase 1163 { 1164 protected: 1165 DWORD m_dwItemStatus; 1166 TF_LANGBARITEMINFO m_NewUIInfo; 1167 WCHAR m_szToolTipText[256]; 1168 LONG m_cRefs; 1169 ITfLangBarItemSink *m_pLangBarItemSink; 1170 1171 public: 1172 CLBarItemBase(); 1173 virtual ~CLBarItemBase(); 1174 1175 HRESULT ShowInternal(BOOL bShow, BOOL bUpdate); 1176 1177 void InitNuiInfo( 1178 REFIID clsidService, 1179 REFGUID guidItem, 1180 DWORD dwStyle, 1181 DWORD ulSort, 1182 LPCWSTR Source); 1183 1184 HRESULT GetInfo(TF_LANGBARITEMINFO *pInfo); 1185 HRESULT GetStatus(DWORD *pdwStatus); 1186 HRESULT Show(BOOL fShow); 1187 HRESULT GetTooltipString(BSTR *pbstrToolTip); 1188 1189 HRESULT AdviseSink(REFIID riid, IUnknown *punk, DWORD *pdwCookie); 1190 HRESULT UnadviseSink(DWORD dwCookie); 1191 }; 1192 1193 /***********************************************************************/ 1194 1195 class CLBarItemButtonBase 1196 : public CLBarItemBase 1197 , public ITfLangBarItem 1198 , public ITfLangBarItemButton 1199 , public ITfSource 1200 { 1201 public: 1202 HICON m_hIcon; 1203 1204 public: 1205 CLBarItemButtonBase() { m_hIcon = NULL; } 1206 ~CLBarItemButtonBase() override; 1207 1208 // IUnknown methods 1209 STDMETHOD(QueryInterface)(REFIID riid, void **ppvObject) override; 1210 STDMETHOD_(ULONG, AddRef)() override; 1211 STDMETHOD_(ULONG, Release)() override; 1212 1213 // ITfLangBarItem methods 1214 STDMETHOD(GetInfo)(TF_LANGBARITEMINFO *pInfo) override; 1215 STDMETHOD(GetStatus)(DWORD *pdwStatus) override; 1216 STDMETHOD(Show)(BOOL fShow) override; 1217 STDMETHOD(GetTooltipString)(BSTR *pbstrToolTip) override; 1218 1219 // ITfLangBarItemButton methods 1220 STDMETHOD(OnClick)(TfLBIClick click, POINT pt, LPCRECT prc) override; 1221 STDMETHOD(InitMenu)(ITfMenu *pMenu) override; 1222 STDMETHOD(OnMenuSelect)(UINT wID) override; 1223 STDMETHOD(GetIcon)(HICON *phIcon) override; 1224 STDMETHOD(GetText)(BSTR *pbstr) override; 1225 1226 // ITfSource methods 1227 STDMETHOD(AdviseSink)(REFIID riid, IUnknown *punk, DWORD *pdwCookie) override; 1228 STDMETHOD(UnadviseSink)(DWORD dwCookie) override; 1229 }; 1230 1231 /***********************************************************************/ 1232 1233 /// Language Bar international item 1234 class CLBarInatItem : public CLBarItemButtonBase 1235 { 1236 protected: 1237 HKL m_hKL; 1238 DWORD m_dwThreadId; 1239 1240 public: 1241 CLBarInatItem(DWORD dwThreadId); 1242 1243 STDMETHOD(InitMenu)(ITfMenu *pMenu) override; 1244 STDMETHOD(OnMenuSelect)(INT nCommandId); 1245 STDMETHOD(GetIcon)(HICON *phIcon) override; 1246 STDMETHOD(GetText)(BSTR *pbstr) override; 1247 }; 1248 1249 /***********************************************************************/ 1250 1251 class CTipbarItem; 1252 class CTipbarThread; 1253 class CTipbarCtrlButtonHolder; 1254 class CDeskBand; 1255 1256 class CTipbarWnd 1257 : public ITfLangBarEventSink 1258 , public ITfLangBarEventSink_P 1259 , public CTipbarAccItem 1260 , public CUIFWindow 1261 { 1262 CTipbarCoInitialize m_coInit; 1263 DWORD m_dwSinkCookie; 1264 CModalMenu *m_pModalMenu; 1265 CTipbarThread *m_pThread; 1266 CicArray<GUID*> m_TipbarGUIDArray; 1267 DWORD m_dwUnknown20; 1268 CUIFWndFrame *m_pWndFrame; 1269 CTipbarGripper *m_pTipbarGripper; 1270 CTipbarThread *m_pFocusThread; 1271 CicArray<CTipbarThread*> m_Threads; 1272 CicArray<CTipbarThread*> m_ThreadCreatingList; 1273 DWORD m_dwAlphaValue; 1274 DWORD m_dwTipbarWndFlags; 1275 LONG m_ButtonWidth; 1276 DWORD m_dwShowType; 1277 DWORD m_dwUnknown21; 1278 INT m_cxSmallIcon; 1279 INT m_cySmallIcon; 1280 INT m_cxDlgFrameX2; 1281 INT m_cyDlgFrameX2; 1282 HFONT m_hMarlettFont; 1283 HFONT m_hTextFont; 1284 ITfLangBarMgr_P *m_pLangBarMgr; 1285 DWORD m_dwUnknown23; 1286 CTipbarCtrlButtonHolder *m_pTipbarCtrlButtonHolder; 1287 DWORD m_dwUnknown23_1[8]; 1288 CUIFWindow *m_pBalloon; 1289 DWORD m_dwChangingThreadId; 1290 LONG m_bInCallOn; 1291 LONG m_X; 1292 LONG m_Y; 1293 LONG m_CX; 1294 LONG m_CY; 1295 CTipbarAccessible *m_pTipbarAccessible; 1296 INT m_nID; 1297 MARGINS m_Margins; 1298 DWORD m_dwUnknown23_5[4]; 1299 CTipbarThread *m_pUnknownThread; 1300 CDeskBand *m_pDeskBand; 1301 CShellWndThread m_ShellWndThread; 1302 LONG m_cRefs; 1303 friend class CUTBContextMenu; 1304 friend class CTipbarGripper; 1305 friend VOID WINAPI ClosePopupTipbar(VOID); 1306 friend BOOL GetTipbarInternal(HWND hWnd, DWORD dwFlags, CDeskBand *pDeskBand); 1307 1308 public: 1309 CTipbarWnd(DWORD style); 1310 ~CTipbarWnd() override; 1311 1312 CUIFWindow *GetWindow() 1313 { 1314 return static_cast<CUIFWindow*>(this); 1315 } 1316 1317 CTipbarAccItem *GetAccItem() 1318 { 1319 return static_cast<CTipbarAccItem*>(this); 1320 } 1321 1322 void Init(BOOL bChild, CDeskBand *pDeskBand); 1323 void InitHighContrast(); 1324 void InitMetrics(); 1325 void InitThemeMargins(); 1326 void UnInit(); 1327 1328 BOOL IsFullScreenWindow(HWND hWnd); 1329 BOOL IsHKLToSkipRedrawOnNoItem(); 1330 BOOL IsInItemChangeOrDirty(CTipbarThread *pTarget); 1331 1332 void AddThreadToThreadCreatingList(CTipbarThread *pThread); 1333 void RemoveThredFromThreadCreatingList(CTipbarThread *pTarget); 1334 1335 void MoveToStub(BOOL bFlag); 1336 void RestoreFromStub(); 1337 1338 INT GetCtrlButtonWidth(); 1339 INT GetGripperWidth(); 1340 INT GetTipbarHeight(); 1341 BOOL AutoAdjustDeskBandSize(); 1342 INT AdjustDeskBandSize(BOOL bFlag); 1343 void LocateCtrlButtons(); 1344 void AdjustPosOnDisplayChange(); 1345 void SetVertical(BOOL bVertical); 1346 void UpdatePosFlags(); 1347 1348 void CancelMenu(); 1349 BOOL CheckExcludeCaptionButtonMode(LPRECT prc1, LPCRECT prc2); 1350 void ClearLBItemList(); 1351 1352 HFONT CreateVerticalFont(); 1353 void UpdateVerticalFont(); 1354 1355 void ShowOverScreenSizeBalloon(); 1356 void DestroyOverScreenSizeBalloon(); 1357 void DestroyWnd(); 1358 1359 HKL GetFocusKeyboardLayout(); 1360 void KillOnTheadItemChangeTimer(); 1361 1362 UINT_PTR SetTimer(UINT_PTR nIDEvent, UINT uElapse); 1363 BOOL KillTimer(UINT_PTR uIDEvent); 1364 1365 void MoveToTray(); 1366 void MyClientToScreen(LPPOINT lpPoint, LPRECT prc); 1367 void SavePosition(); 1368 void SetAlpha(BYTE bAlpha, BOOL bFlag); 1369 BOOL SetLangBand(BOOL bDeskBand, BOOL bFlag2); 1370 void SetMoveRect(INT X, INT Y, INT nWidth, INT nHeight); 1371 void SetShowText(BOOL bShow); 1372 void SetShowTrayIcon(BOOL bShow); 1373 1374 void ShowContextMenu(POINT pt, LPCRECT prc, BOOL bFlag); 1375 void StartBackToAlphaTimer(); 1376 BOOL StartDoAccDefaultActionTimer(CTipbarItem *pTarget); 1377 1378 void StartModalInput(ITfLangBarEventSink *pSink, DWORD dwThreadId); 1379 void StopModalInput(DWORD dwThreadId); 1380 1381 CTipbarThread *_CreateThread(DWORD dwThreadId); 1382 CTipbarThread *_FindThread(DWORD dwThreadId); 1383 void EnsureFocusThread(); 1384 HRESULT SetFocusThread(CTipbarThread *pFocusThread); 1385 HRESULT AttachFocusThread(); 1386 void RestoreLastFocus(DWORD *pdwThreadId, BOOL fPrev); 1387 void CleanUpThreadPointer(CTipbarThread *pThread, BOOL bRemove); 1388 void TerminateAllThreads(BOOL bFlag); 1389 void OnTerminateToolbar(); 1390 HRESULT OnThreadTerminateInternal(DWORD dwThreadId); 1391 1392 // IUnknown methods 1393 STDMETHOD(QueryInterface)(REFIID riid, void **ppvObj); 1394 STDMETHOD_(ULONG, AddRef)(); 1395 STDMETHOD_(ULONG, Release)(); 1396 1397 // ITfLangBarEventSink methods 1398 STDMETHOD(OnSetFocus)(DWORD dwThreadId) override; 1399 STDMETHOD(OnThreadTerminate)(DWORD dwThreadId) override; 1400 STDMETHOD(OnThreadItemChange)(DWORD dwThreadId) override; 1401 STDMETHOD(OnModalInput)(DWORD dwThreadId, UINT uMsg, WPARAM wParam, LPARAM lParam) override; 1402 STDMETHOD(ShowFloating)(DWORD dwFlags) override; 1403 STDMETHOD(GetItemFloatingRect)(DWORD dwThreadId, REFGUID rguid, RECT *prc) override; 1404 1405 // ITfLangBarEventSink_P methods 1406 STDMETHOD(OnLangBarUpdate)(TfLBIClick click, BOOL bFlag) override; 1407 1408 // CTipbarAccItem methods 1409 STDMETHOD_(BSTR, GetAccName)() override; 1410 STDMETHOD_(void, GetAccLocation)(LPRECT lprc) override; 1411 1412 // CUIFWindow methods 1413 STDMETHOD_(void, PaintObject)(HDC hDC, LPCRECT prc) override; 1414 STDMETHOD_(DWORD, GetWndStyle)() override; 1415 STDMETHOD_(void, Move)(INT x, INT y, INT nWidth, INT nHeight) override; 1416 STDMETHOD_(void, OnMouseOutFromWindow)(LONG x, LONG y) override; 1417 STDMETHOD_(void, OnCreate)(HWND hWnd) override; 1418 STDMETHOD_(void, OnDestroy)(HWND hWnd) override; 1419 STDMETHOD_(void, OnTimer)(WPARAM wParam) override; 1420 STDMETHOD_(void, OnSysColorChange)() override; 1421 STDMETHOD_(void, OnEndSession)(HWND hWnd, WPARAM wParam, LPARAM lParam) override; 1422 STDMETHOD_(void, OnUser)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override; 1423 STDMETHOD_(LRESULT, OnWindowPosChanged)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override; 1424 STDMETHOD_(LRESULT, OnWindowPosChanging)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override; 1425 STDMETHOD_(LRESULT, OnShowWindow)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override; 1426 STDMETHOD_(LRESULT, OnSettingChange)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override; 1427 STDMETHOD_(LRESULT, OnDisplayChange)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override; 1428 STDMETHOD_(HRESULT, OnGetObject)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override; 1429 STDMETHOD_(BOOL, OnEraseBkGnd)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override; 1430 STDMETHOD_(void, OnThemeChanged)(HWND hWnd, WPARAM wParam, LPARAM lParam) override; 1431 STDMETHOD_(void, UpdateUI)(LPCRECT prc) override; 1432 STDMETHOD_(void, HandleMouseMsg)(UINT uMsg, LONG x, LONG y) override; 1433 }; 1434 1435 /*********************************************************************** 1436 * CUTBLangBarDlg 1437 */ 1438 1439 CUTBLangBarDlg *CUTBLangBarDlg::GetThis(HWND hDlg) 1440 { 1441 return (CUTBLangBarDlg*)::GetWindowLongPtr(hDlg, DWLP_USER); 1442 } 1443 1444 void CUTBLangBarDlg::SetThis(HWND hDlg, CUTBLangBarDlg *pThis) 1445 { 1446 ::SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pThis); 1447 } 1448 1449 DWORD WINAPI CUTBLangBarDlg::s_ThreadProc(LPVOID pParam) 1450 { 1451 return ((CUTBLangBarDlg *)pParam)->ThreadProc(); 1452 } 1453 1454 BOOL CUTBLangBarDlg::StartThread() 1455 { 1456 if (IsDlgShown()) 1457 return FALSE; 1458 1459 SetDlgShown(TRUE); 1460 1461 DWORD dwThreadId; 1462 HANDLE hThread = ::CreateThread(NULL, 0, s_ThreadProc, this, 0, &dwThreadId); 1463 if (!hThread) 1464 { 1465 SetDlgShown(FALSE); 1466 return TRUE; 1467 } 1468 1469 ++m_cRefs; 1470 ::CloseHandle(hThread); 1471 return TRUE; 1472 } 1473 1474 LONG CUTBLangBarDlg::_Release() 1475 { 1476 if (--m_cRefs == 0) 1477 { 1478 delete this; 1479 return 0; 1480 } 1481 return m_cRefs; 1482 } 1483 1484 STDMETHODIMP_(BOOL) CUTBLangBarDlg::ThreadProc() 1485 { 1486 extern HINSTANCE g_hInst; 1487 ::DialogBoxParam(g_hInst, m_pszDialogName, NULL, DlgProc, (LPARAM)this); 1488 SetDlgShown(FALSE); 1489 _Release(); 1490 return TRUE; 1491 } 1492 1493 INT_PTR CALLBACK 1494 CUTBLangBarDlg::DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 1495 { 1496 if (uMsg == WM_INITDIALOG) 1497 { 1498 SetThis(hDlg, (CUTBLangBarDlg *)lParam); 1499 ::ShowWindow(hDlg, SW_RESTORE); 1500 ::UpdateWindow(hDlg); 1501 return TRUE; 1502 } 1503 1504 if (uMsg == WM_COMMAND) 1505 { 1506 CUTBLangBarDlg *pThis = CUTBLangBarDlg::GetThis(hDlg); 1507 pThis->OnCommand(hDlg, wParam, lParam); 1508 return TRUE; 1509 } 1510 1511 return FALSE; 1512 } 1513 1514 /*********************************************************************** 1515 * CUTBCloseLangBarDlg 1516 */ 1517 1518 CUTBCloseLangBarDlg::CUTBCloseLangBarDlg() 1519 { 1520 m_cRefs = 1; 1521 m_pszDialogName = MAKEINTRESOURCE(IDD_CLOSELANGBAR); 1522 } 1523 1524 STDMETHODIMP_(BOOL) CUTBCloseLangBarDlg::DoModal(HWND hDlg) 1525 { 1526 CicRegKey regKey; 1527 LSTATUS error; 1528 DWORD dwValue = FALSE; 1529 error = regKey.Open(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\")); 1530 if (error == ERROR_SUCCESS) 1531 regKey.QueryDword(TEXT("DontShowCloseLangBarDlg"), &dwValue); 1532 1533 if (dwValue) 1534 return FALSE; 1535 1536 StartThread(); 1537 return TRUE; 1538 } 1539 1540 STDMETHODIMP_(BOOL) CUTBCloseLangBarDlg::OnCommand(HWND hDlg, WPARAM wParam, LPARAM lParam) 1541 { 1542 switch (LOWORD(wParam)) 1543 { 1544 case IDOK: 1545 DoCloseLangbar(); 1546 if (::IsDlgButtonChecked(hDlg, IDC_CLOSELANGBAR_CHECK)) 1547 { 1548 CicRegKey regKey; 1549 LSTATUS error; 1550 error = regKey.Create(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\")); 1551 if (error == ERROR_SUCCESS) 1552 regKey.SetDword(TEXT("DontShowCloseLangBarDlg"), TRUE); 1553 } 1554 ::EndDialog(hDlg, TRUE); 1555 break; 1556 1557 case IDCANCEL: 1558 ::EndDialog(hDlg, FALSE); 1559 break; 1560 1561 default: 1562 return FALSE; 1563 } 1564 return TRUE; 1565 } 1566 1567 STDMETHODIMP_(BOOL) CUTBCloseLangBarDlg::IsDlgShown() 1568 { 1569 return s_bIsDlgShown; 1570 } 1571 1572 STDMETHODIMP_(void) CUTBCloseLangBarDlg::SetDlgShown(BOOL bShown) 1573 { 1574 s_bIsDlgShown = bShown; 1575 } 1576 1577 /*********************************************************************** 1578 * CUTBMinimizeLangBarDlg 1579 */ 1580 1581 CUTBMinimizeLangBarDlg::CUTBMinimizeLangBarDlg() 1582 { 1583 m_cRefs = 1; 1584 m_pszDialogName = MAKEINTRESOURCE(IDD_MINIMIZELANGBAR); 1585 } 1586 1587 STDMETHODIMP_(BOOL) CUTBMinimizeLangBarDlg::DoModal(HWND hDlg) 1588 { 1589 CicRegKey regKey; 1590 LSTATUS error; 1591 1592 DWORD dwValue = FALSE; 1593 error = regKey.Open(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\")); 1594 if (error == ERROR_SUCCESS) 1595 regKey.QueryDword(TEXT("DontShowMinimizeLangBarDlg"), &dwValue); 1596 1597 if (dwValue) 1598 return FALSE; 1599 1600 StartThread(); 1601 return TRUE; 1602 } 1603 1604 STDMETHODIMP_(BOOL) CUTBMinimizeLangBarDlg::OnCommand(HWND hDlg, WPARAM wParam, LPARAM lParam) 1605 { 1606 switch (LOWORD(wParam)) 1607 { 1608 case IDOK: 1609 if (::IsDlgButtonChecked(hDlg, IDC_MINIMIZELANGBAR_CHECK)) 1610 { 1611 LSTATUS error; 1612 CicRegKey regKey; 1613 error = regKey.Create(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\")); 1614 if (error == ERROR_SUCCESS) 1615 regKey.SetDword(TEXT("DontShowMinimizeLangBarDlg"), TRUE); 1616 } 1617 ::EndDialog(hDlg, TRUE); 1618 break; 1619 case IDCANCEL: 1620 ::EndDialog(hDlg, FALSE); 1621 break; 1622 default: 1623 return FALSE; 1624 } 1625 return TRUE; 1626 } 1627 1628 STDMETHODIMP_(BOOL) CUTBMinimizeLangBarDlg::IsDlgShown() 1629 { 1630 return s_bIsDlgShown; 1631 } 1632 1633 STDMETHODIMP_(void) CUTBMinimizeLangBarDlg::SetDlgShown(BOOL bShown) 1634 { 1635 s_bIsDlgShown = bShown; 1636 } 1637 1638 STDMETHODIMP_(BOOL) CUTBMinimizeLangBarDlg::ThreadProc() 1639 { 1640 ::Sleep(700); 1641 return CUTBLangBarDlg::ThreadProc(); 1642 } 1643 1644 /*********************************************************************** 1645 * CCicLibMenu 1646 */ 1647 1648 CCicLibMenu::CCicLibMenu() : m_cRefs(1) 1649 { 1650 } 1651 1652 CCicLibMenu::~CCicLibMenu() 1653 { 1654 for (size_t iItem = 0; iItem < m_MenuItems.size(); ++iItem) 1655 { 1656 delete m_MenuItems[iItem]; 1657 m_MenuItems[iItem] = NULL; 1658 } 1659 } 1660 1661 STDMETHODIMP CCicLibMenu::QueryInterface(REFIID riid, LPVOID *ppvObj) 1662 { 1663 if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfMenu)) 1664 { 1665 *ppvObj = this; 1666 AddRef(); 1667 return S_OK; 1668 } 1669 return E_NOINTERFACE; 1670 } 1671 1672 STDMETHODIMP_(ULONG) CCicLibMenu::AddRef() 1673 { 1674 return ++m_cRefs; 1675 } 1676 1677 STDMETHODIMP_(ULONG) CCicLibMenu::Release() 1678 { 1679 if (--m_cRefs == 0) 1680 { 1681 delete this; 1682 return 0; 1683 } 1684 return m_cRefs; 1685 } 1686 1687 STDMETHODIMP_(CCicLibMenu*) CCicLibMenu::CreateSubMenu() 1688 { 1689 return new(cicNoThrow) CCicLibMenu(); 1690 } 1691 1692 STDMETHODIMP_(CCicLibMenuItem*) CCicLibMenu::CreateMenuItem() 1693 { 1694 return new(cicNoThrow) CCicLibMenuItem(); 1695 } 1696 1697 STDMETHODIMP CCicLibMenu::AddMenuItem( 1698 UINT uId, 1699 DWORD dwFlags, 1700 HBITMAP hbmp, 1701 HBITMAP hbmpMask, 1702 const WCHAR *pch, 1703 ULONG cch, 1704 ITfMenu **ppSubMenu) 1705 { 1706 if (ppSubMenu) 1707 *ppSubMenu = NULL; 1708 1709 CCicLibMenu *pSubMenu = NULL; 1710 if (dwFlags & TF_LBMENUF_SUBMENU) 1711 { 1712 if (!ppSubMenu) 1713 return E_INVALIDARG; 1714 pSubMenu = CreateSubMenu(); 1715 } 1716 1717 CCicLibMenuItem *pMenuItem = CreateMenuItem(); 1718 if (!pMenuItem) 1719 return E_OUTOFMEMORY; 1720 1721 if (!pMenuItem->Init(uId, dwFlags, hbmp, hbmpMask, pch, cch, pSubMenu)) 1722 return E_FAIL; 1723 1724 if (ppSubMenu && pSubMenu) 1725 { 1726 *ppSubMenu = pSubMenu; 1727 pSubMenu->AddRef(); 1728 } 1729 1730 m_MenuItems.Add(pMenuItem); 1731 return S_OK; 1732 } 1733 1734 /*********************************************************************** 1735 * CCicLibMenuItem 1736 */ 1737 1738 CCicLibMenuItem::CCicLibMenuItem() 1739 { 1740 m_uId = 0; 1741 m_dwFlags = 0; 1742 m_hbmp = NULL; 1743 m_hbmpMask = NULL; 1744 m_bstrText = NULL; 1745 m_pMenu = NULL; 1746 } 1747 1748 CCicLibMenuItem::~CCicLibMenuItem() 1749 { 1750 if (m_pMenu) 1751 { 1752 m_pMenu->Release(); 1753 m_pMenu = NULL; 1754 } 1755 1756 if (m_hbmp) 1757 { 1758 ::DeleteObject(m_hbmp); 1759 m_hbmp = NULL; 1760 } 1761 1762 if (m_hbmpMask) 1763 { 1764 ::DeleteObject(m_hbmpMask); 1765 m_hbmpMask = NULL; 1766 } 1767 1768 ::SysFreeString(m_bstrText); 1769 m_bstrText = NULL; 1770 } 1771 1772 BOOL CCicLibMenuItem::Init( 1773 UINT uId, 1774 DWORD dwFlags, 1775 HBITMAP hbmp, 1776 HBITMAP hbmpMask, 1777 const WCHAR *pch, 1778 ULONG cch, 1779 ITfMenu *pMenu) 1780 { 1781 m_uId = uId; 1782 m_dwFlags = dwFlags; 1783 m_bstrText = ::SysAllocStringLen(pch, cch); 1784 if (!m_bstrText && cch) 1785 return FALSE; 1786 1787 m_pMenu = pMenu; 1788 m_hbmp = CreateBitmap(hbmp); 1789 m_hbmpMask = CreateBitmap(hbmpMask); 1790 if (hbmp) 1791 ::DeleteObject(hbmp); 1792 if (hbmpMask) 1793 ::DeleteObject(hbmpMask); 1794 1795 return TRUE; 1796 } 1797 1798 HBITMAP CCicLibMenuItem::CreateBitmap(HANDLE hBitmap) 1799 { 1800 if (!hBitmap) 1801 return NULL; 1802 1803 HDC hDC = ::CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL); 1804 if (!hDC) 1805 return NULL; 1806 1807 HBITMAP hbmMem = NULL; 1808 1809 BITMAP bm; 1810 ::GetObject(hBitmap, sizeof(bm), &bm); 1811 1812 HGDIOBJ hbmOld1 = NULL; 1813 HDC hdcMem1 = ::CreateCompatibleDC(hDC); 1814 if (hdcMem1) 1815 hbmOld1 = ::SelectObject(hdcMem1, hBitmap); 1816 1817 HGDIOBJ hbmOld2 = NULL; 1818 HDC hdcMem2 = ::CreateCompatibleDC(hDC); 1819 if (hdcMem2) 1820 { 1821 hbmMem = ::CreateCompatibleBitmap(hDC, bm.bmWidth, bm.bmHeight); 1822 hbmOld2 = ::SelectObject(hdcMem2, hbmMem); 1823 } 1824 1825 ::BitBlt(hdcMem2, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem1, 0, 0, SRCCOPY); 1826 1827 if (hbmOld1) 1828 ::SelectObject(hdcMem1, hbmOld1); 1829 if (hbmOld2) 1830 ::SelectObject(hdcMem2, hbmOld2); 1831 1832 ::DeleteDC(hDC); 1833 if (hdcMem1) 1834 ::DeleteDC(hdcMem1); 1835 if (hdcMem2) 1836 ::DeleteDC(hdcMem2); 1837 1838 return hbmMem; 1839 } 1840 1841 /*********************************************************************** 1842 * CTipbarAccessible 1843 */ 1844 1845 CTipbarAccessible::CTipbarAccessible(CTipbarAccItem *pItem) 1846 { 1847 m_cRefs = 1; 1848 m_hWnd = NULL; 1849 m_pTypeInfo = NULL; 1850 m_pStdAccessible = NULL; 1851 m_bInitialized = FALSE; 1852 m_cSelection = 1; 1853 m_AccItems.Add(pItem); 1854 ++g_DllRefCount; 1855 } 1856 1857 CTipbarAccessible::~CTipbarAccessible() 1858 { 1859 m_pTypeInfo = m_pTypeInfo; 1860 if (m_pTypeInfo) 1861 { 1862 m_pTypeInfo->Release(); 1863 m_pTypeInfo = NULL; 1864 } 1865 if (m_pStdAccessible) 1866 { 1867 m_pStdAccessible->Release(); 1868 m_pStdAccessible = NULL; 1869 } 1870 --g_DllRefCount; 1871 } 1872 1873 HRESULT CTipbarAccessible::Initialize() 1874 { 1875 m_bInitialized = TRUE; 1876 1877 HRESULT hr = ::CreateStdAccessibleObject(m_hWnd, OBJID_CLIENT, IID_IAccessible, 1878 (void **)&m_pStdAccessible); 1879 if (FAILED(hr)) 1880 return hr; 1881 1882 ITypeLib *pTypeLib; 1883 hr = ::LoadRegTypeLib(LIBID_Accessibility, 1, 0, 0, &pTypeLib); 1884 if (FAILED(hr)) 1885 hr = ::LoadTypeLib(L"OLEACC.DLL", &pTypeLib); 1886 1887 if (SUCCEEDED(hr)) 1888 { 1889 hr = pTypeLib->GetTypeInfoOfGuid(IID_IAccessible, &m_pTypeInfo); 1890 pTypeLib->Release(); 1891 } 1892 1893 return hr; 1894 } 1895 1896 BOOL CTipbarAccessible::AddAccItem(CTipbarAccItem *pItem) 1897 { 1898 return m_AccItems.Add(pItem); 1899 } 1900 1901 HRESULT CTipbarAccessible::RemoveAccItem(CTipbarAccItem *pItem) 1902 { 1903 for (size_t iItem = 0; iItem < m_AccItems.size(); ++iItem) 1904 { 1905 if (m_AccItems[iItem] == pItem) 1906 { 1907 m_AccItems.Remove(iItem, 1); 1908 break; 1909 } 1910 } 1911 return S_OK; 1912 } 1913 1914 void CTipbarAccessible::ClearAccItems() 1915 { 1916 m_AccItems.clear(); 1917 } 1918 1919 CTipbarAccItem *CTipbarAccessible::AccItemFromID(INT iItem) 1920 { 1921 if (iItem < 0 || (INT)m_AccItems.size() <= iItem) 1922 return NULL; 1923 return m_AccItems[iItem]; 1924 } 1925 1926 INT CTipbarAccessible::GetIDOfItem(CTipbarAccItem *pTarget) 1927 { 1928 for (size_t iItem = 0; iItem < m_AccItems.size(); ++iItem) 1929 { 1930 if (pTarget == m_AccItems[iItem]) 1931 return (INT)iItem; 1932 } 1933 return -1; 1934 } 1935 1936 LONG_PTR CTipbarAccessible::CreateRefToAccObj(WPARAM wParam) 1937 { 1938 return ::LresultFromObject(IID_IAccessible, wParam, this); 1939 } 1940 1941 BOOL CTipbarAccessible::DoDefaultActionReal(INT nID) 1942 { 1943 CTipbarAccItem *pItem = AccItemFromID(nID); 1944 if (!pItem) 1945 return FALSE; 1946 return pItem->DoAccDefaultActionReal(); 1947 } 1948 1949 void CTipbarAccessible::NotifyWinEvent(DWORD event, CTipbarAccItem *pItem) 1950 { 1951 INT nID = GetIDOfItem(pItem); 1952 if (nID < 0) 1953 return; 1954 1955 ::NotifyWinEvent(event, m_hWnd, -4, nID); 1956 } 1957 1958 void CTipbarAccessible::SetWindow(HWND hWnd) 1959 { 1960 m_hWnd = hWnd; 1961 } 1962 1963 STDMETHODIMP CTipbarAccessible::QueryInterface( 1964 REFIID riid, 1965 void **ppvObject) 1966 { 1967 if (IsEqualIID(riid, IID_IUnknown) || 1968 IsEqualIID(riid, IID_IDispatch) || 1969 IsEqualIID(riid, IID_IAccessible)) 1970 { 1971 *ppvObject = this; 1972 AddRef(); 1973 return S_OK; 1974 } 1975 return E_NOINTERFACE; 1976 } 1977 1978 STDMETHODIMP_(ULONG) CTipbarAccessible::AddRef() 1979 { 1980 return ::InterlockedIncrement(&m_cRefs); 1981 } 1982 1983 STDMETHODIMP_(ULONG) CTipbarAccessible::Release() 1984 { 1985 LONG count = ::InterlockedDecrement(&m_cRefs); 1986 if (count == 0) 1987 { 1988 delete this; 1989 return 0; 1990 } 1991 return count; 1992 } 1993 1994 STDMETHODIMP CTipbarAccessible::GetTypeInfoCount(UINT *pctinfo) 1995 { 1996 if (!pctinfo) 1997 return E_INVALIDARG; 1998 *pctinfo = (m_pTypeInfo == NULL); 1999 return S_OK; 2000 } 2001 2002 STDMETHODIMP CTipbarAccessible::GetTypeInfo( 2003 UINT iTInfo, 2004 LCID lcid, 2005 ITypeInfo **ppTInfo) 2006 { 2007 if (!ppTInfo) 2008 return E_INVALIDARG; 2009 *ppTInfo = NULL; 2010 if (iTInfo != 0) 2011 return TYPE_E_ELEMENTNOTFOUND; 2012 if (!m_pTypeInfo) 2013 return E_NOTIMPL; 2014 *ppTInfo = m_pTypeInfo; 2015 m_pTypeInfo->AddRef(); 2016 return S_OK; 2017 } 2018 2019 STDMETHODIMP CTipbarAccessible::GetIDsOfNames( 2020 REFIID riid, 2021 LPOLESTR *rgszNames, 2022 UINT cNames, 2023 LCID lcid, 2024 DISPID *rgDispId) 2025 { 2026 if (!m_pTypeInfo) 2027 return E_NOTIMPL; 2028 return m_pTypeInfo->GetIDsOfNames(rgszNames, cNames, rgDispId); 2029 } 2030 2031 STDMETHODIMP CTipbarAccessible::Invoke( 2032 DISPID dispIdMember, 2033 REFIID riid, 2034 LCID lcid, 2035 WORD wFlags, 2036 DISPPARAMS *pDispParams, 2037 VARIANT *pVarResult, 2038 EXCEPINFO *pExcepInfo, 2039 UINT *puArgErr) 2040 { 2041 if (!m_pTypeInfo) 2042 return E_NOTIMPL; 2043 return m_pTypeInfo->Invoke(this, 2044 dispIdMember, 2045 wFlags, 2046 pDispParams, 2047 pVarResult, 2048 pExcepInfo, 2049 puArgErr); 2050 } 2051 2052 STDMETHODIMP CTipbarAccessible::get_accParent(IDispatch **ppdispParent) 2053 { 2054 return m_pStdAccessible->get_accParent(ppdispParent); 2055 } 2056 2057 STDMETHODIMP CTipbarAccessible::get_accChildCount(LONG *pcountChildren) 2058 { 2059 if (!pcountChildren) 2060 return E_INVALIDARG; 2061 INT cItems = (INT)m_AccItems.size(); 2062 if (!cItems) 2063 return E_FAIL; 2064 *pcountChildren = cItems - 1; 2065 return S_OK; 2066 } 2067 2068 STDMETHODIMP CTipbarAccessible::get_accChild( 2069 VARIANT varChildID, 2070 IDispatch **ppdispChild) 2071 { 2072 if (!ppdispChild) 2073 return E_INVALIDARG; 2074 *ppdispChild = NULL; 2075 return S_FALSE; 2076 } 2077 2078 STDMETHODIMP CTipbarAccessible::get_accName( 2079 VARIANT varID, 2080 BSTR *pszName) 2081 { 2082 if (!pszName) 2083 return E_INVALIDARG; 2084 CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID)); 2085 if (!pItem) 2086 return E_INVALIDARG; 2087 *pszName = pItem->GetAccName(); 2088 if (!*pszName) 2089 return DISP_E_MEMBERNOTFOUND; 2090 return S_OK; 2091 } 2092 2093 STDMETHODIMP CTipbarAccessible::get_accValue( 2094 VARIANT varID, 2095 BSTR *pszValue) 2096 { 2097 if (!pszValue) 2098 return E_INVALIDARG; 2099 CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID)); 2100 if (!pItem) 2101 return E_INVALIDARG; 2102 *pszValue = pItem->GetAccValue(); 2103 if (!*pszValue) 2104 return DISP_E_MEMBERNOTFOUND; 2105 return S_OK; 2106 } 2107 2108 STDMETHODIMP CTipbarAccessible::get_accDescription( 2109 VARIANT varID, 2110 BSTR *description) 2111 { 2112 if (!description) 2113 return E_INVALIDARG; 2114 return m_pStdAccessible->get_accDescription(varID, description); 2115 } 2116 2117 STDMETHODIMP CTipbarAccessible::get_accRole( 2118 VARIANT varID, 2119 VARIANT *role) 2120 { 2121 if (!role) 2122 return E_INVALIDARG; 2123 CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID)); 2124 if (!pItem) 2125 return E_INVALIDARG; 2126 V_VT(role) = VT_I4; 2127 V_I4(role) = pItem->GetAccRole(); 2128 return S_OK; 2129 } 2130 2131 STDMETHODIMP CTipbarAccessible::get_accState( 2132 VARIANT varID, 2133 VARIANT *state) 2134 { 2135 if (!state) 2136 return E_INVALIDARG; 2137 CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID)); 2138 if (!pItem) 2139 return E_INVALIDARG; 2140 V_VT(state) = VT_I4; 2141 V_I4(state) = pItem->GetAccState(); 2142 return S_OK; 2143 } 2144 2145 STDMETHODIMP CTipbarAccessible::get_accHelp(VARIANT varID, BSTR *help) 2146 { 2147 return DISP_E_MEMBERNOTFOUND; 2148 } 2149 2150 STDMETHODIMP CTipbarAccessible::get_accHelpTopic( 2151 BSTR *helpfile, 2152 VARIANT varID, 2153 LONG *pidTopic) 2154 { 2155 return DISP_E_MEMBERNOTFOUND; 2156 } 2157 2158 STDMETHODIMP CTipbarAccessible::get_accKeyboardShortcut(VARIANT varID, BSTR *shortcut) 2159 { 2160 return DISP_E_MEMBERNOTFOUND; 2161 } 2162 2163 STDMETHODIMP CTipbarAccessible::get_accFocus(VARIANT *pvarID) 2164 { 2165 if (!pvarID) 2166 return E_INVALIDARG; 2167 V_VT(pvarID) = VT_EMPTY; 2168 return S_FALSE; 2169 } 2170 2171 STDMETHODIMP CTipbarAccessible::get_accSelection(VARIANT *pvarID) 2172 { 2173 if (!pvarID) 2174 return E_INVALIDARG; 2175 2176 V_VT(pvarID) = VT_EMPTY; 2177 2178 INT cItems = (INT)m_AccItems.size(); 2179 if (cItems < m_cSelection) 2180 return S_FALSE; 2181 2182 if (cItems > m_cSelection) 2183 { 2184 V_VT(pvarID) = VT_I4; 2185 V_I4(pvarID) = m_cSelection; 2186 } 2187 2188 return S_OK; 2189 } 2190 2191 STDMETHODIMP CTipbarAccessible::get_accDefaultAction( 2192 VARIANT varID, 2193 BSTR *action) 2194 { 2195 if (!action) 2196 return E_INVALIDARG; 2197 *action = NULL; 2198 2199 if (V_VT(&varID) != VT_I4) 2200 return E_INVALIDARG; 2201 2202 CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID)); 2203 if (!pItem) 2204 return DISP_E_MEMBERNOTFOUND; 2205 *action = pItem->GetAccDefaultAction(); 2206 if (!*action) 2207 return S_FALSE; 2208 return S_OK; 2209 } 2210 2211 STDMETHODIMP CTipbarAccessible::accSelect( 2212 LONG flagsSelect, 2213 VARIANT varID) 2214 { 2215 if ((flagsSelect & SELFLAG_ADDSELECTION) && (flagsSelect & SELFLAG_REMOVESELECTION)) 2216 return E_INVALIDARG; 2217 if (flagsSelect & (SELFLAG_TAKEFOCUS | SELFLAG_ADDSELECTION | SELFLAG_EXTENDSELECTION)) 2218 return S_FALSE; 2219 if (flagsSelect & SELFLAG_REMOVESELECTION) 2220 return S_OK; 2221 if (V_VT(&varID) != VT_I4) 2222 return E_INVALIDARG; 2223 if (flagsSelect & SELFLAG_TAKESELECTION) 2224 { 2225 m_cSelection = V_I4(&varID); 2226 return S_OK; 2227 } 2228 return S_FALSE; 2229 } 2230 2231 STDMETHODIMP CTipbarAccessible::accLocation( 2232 LONG *left, 2233 LONG *top, 2234 LONG *width, 2235 LONG *height, 2236 VARIANT varID) 2237 { 2238 if (!left || !top || !width || !height) 2239 return E_INVALIDARG; 2240 2241 if (!V_I4(&varID)) 2242 return m_pStdAccessible->accLocation(left, top, width, height, varID); 2243 2244 RECT rc; 2245 CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID)); 2246 pItem->GetAccLocation(&rc); 2247 2248 *left = rc.left; 2249 *top = rc.top; 2250 *width = rc.right - rc.left; 2251 *height = rc.bottom - rc.top; 2252 return S_OK; 2253 } 2254 2255 STDMETHODIMP CTipbarAccessible::accNavigate( 2256 LONG dir, 2257 VARIANT varStart, 2258 VARIANT *pvarEnd) 2259 { 2260 if (m_AccItems.size() <= 1) 2261 { 2262 V_VT(pvarEnd) = VT_EMPTY; 2263 return S_OK; 2264 } 2265 2266 switch (dir) 2267 { 2268 case NAVDIR_UP: 2269 case NAVDIR_LEFT: 2270 case NAVDIR_PREVIOUS: 2271 V_VT(pvarEnd) = VT_I4; 2272 V_I4(pvarEnd) = V_I4(&varStart) - 1; 2273 if (V_I4(&varStart) - 1 <= 0) 2274 V_I4(pvarEnd) = (INT)(m_AccItems.size() - 1); 2275 return S_OK; 2276 2277 case NAVDIR_DOWN: 2278 case NAVDIR_RIGHT: 2279 case NAVDIR_NEXT: 2280 V_VT(pvarEnd) = VT_I4; 2281 V_I4(pvarEnd) = V_I4(&varStart) + 1; 2282 if ((INT)m_AccItems.size() <= V_I4(&varStart) + 1) 2283 V_I4(pvarEnd) = 1; 2284 return S_OK; 2285 2286 case NAVDIR_FIRSTCHILD: 2287 V_VT(pvarEnd) = VT_I4; 2288 V_I4(pvarEnd) = 1; 2289 return S_OK; 2290 2291 case NAVDIR_LASTCHILD: 2292 V_VT(pvarEnd) = VT_I4; 2293 V_I4(pvarEnd) = (INT)(m_AccItems.size() - 1); 2294 return S_OK; 2295 2296 default: 2297 break; 2298 } 2299 2300 V_VT(pvarEnd) = VT_EMPTY; 2301 return S_OK; 2302 } 2303 2304 STDMETHODIMP CTipbarAccessible::accHitTest(LONG left, LONG top, VARIANT *pvarID) 2305 { 2306 if (!pvarID) 2307 return E_INVALIDARG; 2308 POINT Point = { left, top }; 2309 RECT Rect; 2310 ::ScreenToClient(m_hWnd, &Point); 2311 ::GetClientRect(m_hWnd, &Rect); 2312 2313 if (!::PtInRect(&Rect, Point)) 2314 { 2315 V_VT(pvarID) = VT_EMPTY; 2316 return S_OK; 2317 } 2318 2319 V_VT(pvarID) = VT_I4; 2320 V_I4(pvarID) = 0; 2321 2322 for (size_t iItem = 1; iItem < m_AccItems.size(); ++iItem) 2323 { 2324 CTipbarAccItem *pItem = m_AccItems[iItem]; 2325 if (pItem) 2326 { 2327 pItem->GetAccLocation(&Rect); 2328 if (::PtInRect(&Rect, Point)) 2329 { 2330 V_I4(pvarID) = iItem; 2331 break; 2332 } 2333 } 2334 } 2335 2336 return S_OK; 2337 } 2338 2339 STDMETHODIMP CTipbarAccessible::accDoDefaultAction(VARIANT varID) 2340 { 2341 if (V_VT(&varID) != VT_I4) 2342 return E_INVALIDARG; 2343 CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID)); 2344 if (!pItem) 2345 return DISP_E_MEMBERNOTFOUND; 2346 return (pItem->DoAccDefaultAction() ? S_OK : S_FALSE); 2347 } 2348 2349 STDMETHODIMP CTipbarAccessible::put_accName(VARIANT varID, BSTR name) 2350 { 2351 return S_FALSE; 2352 } 2353 2354 STDMETHODIMP CTipbarAccessible::put_accValue(VARIANT varID, BSTR value) 2355 { 2356 return S_FALSE; 2357 } 2358 2359 /*********************************************************************** 2360 * CUTBMenuWnd 2361 */ 2362 2363 CUTBMenuWnd::CUTBMenuWnd(HINSTANCE hInst, DWORD style, DWORD dwUnknown14) 2364 : CUIFMenu(hInst, style, dwUnknown14) 2365 { 2366 } 2367 2368 BOOL CUTBMenuWnd::StartDoAccDefaultActionTimer(CUTBMenuItem *pTarget) 2369 { 2370 if (!m_pAccessible) 2371 return FALSE; 2372 2373 m_nMenuWndID = m_pAccessible->GetIDOfItem(pTarget); 2374 if (!m_nMenuWndID || m_nMenuWndID == (UINT)-1) 2375 return FALSE; 2376 2377 if (::IsWindow(m_hWnd)) 2378 { 2379 ::KillTimer(m_hWnd, TIMER_ID_DOACCDEFAULTACTION); 2380 ::SetTimer(m_hWnd, TIMER_ID_DOACCDEFAULTACTION, g_uTimerElapseDOACCDEFAULTACTION, NULL); 2381 } 2382 2383 return TRUE; 2384 } 2385 2386 STDMETHODIMP_(BSTR) CUTBMenuWnd::GetAccName() 2387 { 2388 WCHAR szText[64]; 2389 LoadStringW(g_hInst, IDS_MENUWND, szText, _countof(szText)); 2390 return ::SysAllocString(szText); 2391 } 2392 2393 STDMETHODIMP_(INT) CUTBMenuWnd::GetAccRole() 2394 { 2395 return 9; 2396 } 2397 2398 STDMETHODIMP_(BOOL) CUTBMenuWnd::Initialize() 2399 { 2400 CTipbarAccessible *pAccessible = new(cicNoThrow) CTipbarAccessible(GetAccItem()); 2401 if (pAccessible) 2402 m_pAccessible = pAccessible; 2403 2404 return CUIFObject::Initialize(); 2405 } 2406 2407 STDMETHODIMP_(void) CUTBMenuWnd::OnCreate(HWND hWnd) 2408 { 2409 if (m_pAccessible) 2410 m_pAccessible->SetWindow(hWnd); 2411 } 2412 2413 STDMETHODIMP_(void) CUTBMenuWnd::OnDestroy(HWND hWnd) 2414 { 2415 if (m_pAccessible) 2416 { 2417 m_pAccessible->NotifyWinEvent(EVENT_OBJECT_DESTROY, GetAccItem()); 2418 m_pAccessible->ClearAccItems(); 2419 m_pAccessible->Release(); 2420 m_pAccessible = NULL; 2421 } 2422 m_coInit.CoUninit(); 2423 } 2424 2425 STDMETHODIMP_(HRESULT) 2426 CUTBMenuWnd::OnGetObject(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 2427 { 2428 if (lParam != -4) 2429 return S_OK; 2430 2431 if (!m_pAccessible) 2432 return E_OUTOFMEMORY; 2433 2434 if (m_pAccessible->m_bInitialized) 2435 return m_pAccessible->CreateRefToAccObj(wParam); 2436 2437 if (SUCCEEDED(m_coInit.EnsureCoInit())) 2438 { 2439 HRESULT hr = m_pAccessible->Initialize(); 2440 if (FAILED(hr)) 2441 { 2442 m_pAccessible->Release(); 2443 m_pAccessible = NULL; 2444 return hr; 2445 } 2446 2447 m_pAccessible->NotifyWinEvent(EVENT_OBJECT_CREATE, GetAccItem()); 2448 return m_pAccessible->CreateRefToAccObj(wParam); 2449 } 2450 2451 return S_OK; 2452 } 2453 2454 STDMETHODIMP_(LRESULT) 2455 CUTBMenuWnd::OnShowWindow(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 2456 { 2457 if (m_pAccessible) 2458 { 2459 if (wParam) 2460 { 2461 m_pAccessible->NotifyWinEvent(EVENT_OBJECT_SHOW, GetAccItem()); 2462 m_pAccessible->NotifyWinEvent(EVENT_OBJECT_FOCUS, GetAccItem()); 2463 } 2464 else 2465 { 2466 m_pAccessible->NotifyWinEvent(EVENT_OBJECT_HIDE, GetAccItem()); 2467 } 2468 } 2469 2470 return ::DefWindowProc(hWnd, uMsg, wParam, lParam); 2471 } 2472 2473 STDMETHODIMP_(void) CUTBMenuWnd::OnTimer(WPARAM wParam) 2474 { 2475 if (wParam == TIMER_ID_DOACCDEFAULTACTION) 2476 { 2477 ::KillTimer(m_hWnd, TIMER_ID_DOACCDEFAULTACTION); 2478 if (m_pAccessible && m_nMenuWndID) 2479 { 2480 m_pAccessible->DoDefaultActionReal(m_nMenuWndID); 2481 m_nMenuWndID = 0; 2482 } 2483 } 2484 } 2485 2486 /*********************************************************************** 2487 * CUTBMenuItem 2488 */ 2489 2490 CUTBMenuItem::CUTBMenuItem(CUTBMenuWnd *pMenuUI) 2491 : CUIFMenuItem(pMenuUI ? pMenuUI->GetMenu() : NULL) 2492 { 2493 m_pMenuUI = pMenuUI; 2494 } 2495 2496 CUTBMenuItem::~CUTBMenuItem() 2497 { 2498 if (m_hbmColor) 2499 { 2500 ::DeleteObject(m_hbmColor); 2501 m_hbmColor = NULL; 2502 } 2503 if (m_hbmMask) 2504 { 2505 ::DeleteObject(m_hbmMask); 2506 m_hbmMask = NULL; 2507 } 2508 } 2509 2510 STDMETHODIMP_(BOOL) CUTBMenuItem::DoAccDefaultAction() 2511 { 2512 if (!m_pMenuUI) 2513 return FALSE; 2514 2515 m_pMenuUI->StartDoAccDefaultActionTimer(this); 2516 return TRUE; 2517 } 2518 2519 STDMETHODIMP_(BOOL) CUTBMenuItem::DoAccDefaultActionReal() 2520 { 2521 if (!m_pSubMenu) 2522 OnLButtonUp(0, 0); 2523 else 2524 ShowSubPopup(); 2525 return TRUE; 2526 } 2527 2528 STDMETHODIMP_(BSTR) CUTBMenuItem::GetAccDefaultAction() 2529 { 2530 WCHAR szText[64]; 2531 ::LoadStringW(g_hInst, IDS_LEFTCLICK, szText, _countof(szText)); 2532 return ::SysAllocString(szText); 2533 } 2534 2535 STDMETHODIMP_(void) CUTBMenuItem::GetAccLocation(LPRECT lprc) 2536 { 2537 GetRect(lprc); 2538 ::ClientToScreen(m_pMenuUI->m_hWnd, (LPPOINT)lprc); 2539 ::ClientToScreen(m_pMenuUI->m_hWnd, (LPPOINT)&lprc->right); 2540 } 2541 2542 STDMETHODIMP_(BSTR) CUTBMenuItem::GetAccName() 2543 { 2544 return ::SysAllocString(m_pszMenuItemLeft); 2545 } 2546 2547 /// @unimplemented 2548 STDMETHODIMP_(INT) CUTBMenuItem::GetAccRole() 2549 { 2550 if (FALSE) //FIXME 2551 return 21; 2552 return 12; 2553 } 2554 2555 /*********************************************************************** 2556 * CModalMenu 2557 */ 2558 2559 CUTBMenuItem * 2560 CModalMenu::InsertItem(CUTBMenuWnd *pMenuUI, INT nCommandId, INT nStringID) 2561 { 2562 CUTBMenuItem *pMenuItem = new(cicNoThrow) CUTBMenuItem(pMenuUI); 2563 if (!pMenuItem) 2564 return NULL; 2565 2566 WCHAR szText[256]; 2567 ::LoadStringW(g_hInst, nStringID, szText, _countof(szText)); 2568 2569 if (pMenuItem->Initialize() && 2570 pMenuItem->Init(nCommandId, szText) && 2571 pMenuUI->InsertItem(pMenuItem)) 2572 { 2573 return pMenuItem; 2574 } 2575 2576 delete pMenuItem; 2577 return NULL; 2578 } 2579 2580 void CModalMenu::PostKey(BOOL bUp, WPARAM wParam, LPARAM lParam) 2581 { 2582 m_pMenuUI->PostKey(bUp, wParam, lParam); 2583 } 2584 2585 void CModalMenu::CancelMenu() 2586 { 2587 if (m_pMenuUI) 2588 m_pMenuUI->CancelMenu(); 2589 } 2590 2591 /*********************************************************************** 2592 * CUTBContextMenu 2593 */ 2594 2595 CUTBContextMenu::CUTBContextMenu(CTipbarWnd *pTipbarWnd) 2596 { 2597 m_pTipbarWnd = pTipbarWnd; 2598 } 2599 2600 /// @unimplemented 2601 BOOL CUTBContextMenu::Init() 2602 { 2603 m_pTipbarThread = m_pTipbarWnd->m_pFocusThread; 2604 return !!m_pTipbarThread; 2605 } 2606 2607 /// @unimplemented 2608 CUTBMenuWnd *CUTBContextMenu::CreateMenuUI(BOOL bFlag) 2609 { 2610 DWORD dwStatus = 0; 2611 2612 if (FAILED(m_pTipbarWnd->m_pLangBarMgr->GetShowFloatingStatus(&dwStatus))) 2613 return NULL; 2614 2615 CUTBMenuWnd *pMenuUI = new (cicNoThrow) CUTBMenuWnd(g_hInst, g_dwMenuStyle, 0); 2616 if (!pMenuUI) 2617 return NULL; 2618 2619 pMenuUI->Initialize(); 2620 2621 if (dwStatus & (TF_SFT_DESKBAND | TF_SFT_MINIMIZED)) 2622 { 2623 CUTBMenuItem *pRestoreLangBar = InsertItem(pMenuUI, ID_RESTORELANGBAR, IDS_RESTORELANGBAR2); 2624 if (pRestoreLangBar && !m_pTipbarWnd->m_dwUnknown20) 2625 pRestoreLangBar->Gray(TRUE); 2626 } 2627 else 2628 { 2629 InsertItem(pMenuUI, ID_DESKBAND, IDS_MINIMIZE); 2630 2631 if (bFlag) 2632 { 2633 if (IsTransparecyAvailable()) 2634 { 2635 if (dwStatus & TF_LBI_BALLOON) 2636 { 2637 InsertItem(pMenuUI, ID_TRANS, IDS_TRANSPARENCY); 2638 } 2639 else 2640 { 2641 CUTBMenuItem *pTransparency = InsertItem(pMenuUI, ID_NOTRANS, IDS_TRANSPARENCY); 2642 if (pTransparency) 2643 pTransparency->Check(TRUE); 2644 } 2645 } 2646 2647 if (!(dwStatus & TF_SFT_LABELS)) 2648 { 2649 InsertItem(pMenuUI, ID_LABELS, IDS_TEXTLABELS); 2650 } 2651 else 2652 { 2653 CUTBMenuItem *pTextLabels = InsertItem(pMenuUI, ID_NOLABELS, IDS_TEXTLABELS); 2654 if (pTextLabels) 2655 pTextLabels->Check(TRUE); 2656 } 2657 2658 CUTBMenuItem *pVertical = InsertItem(pMenuUI, ID_VERTICAL, IDS_VERTICAL); 2659 if (pVertical) 2660 pVertical->Check(!!(m_pTipbarWnd->m_dwTipbarWndFlags & 0x800000)); 2661 } 2662 } 2663 2664 if (bFlag) 2665 { 2666 CUTBMenuItem *pExtraIcons = NULL; 2667 2668 if (dwStatus & TF_SFT_EXTRAICONSONMINIMIZED) 2669 { 2670 pExtraIcons = InsertItem(pMenuUI, ID_NOEXTRAICONS, IDS_EXTRAICONS); 2671 if (pExtraIcons) 2672 pExtraIcons->Check(TRUE); 2673 } 2674 else 2675 { 2676 pExtraIcons = CModalMenu::InsertItem(pMenuUI, ID_EXTRAICONS, IDS_EXTRAICONS); 2677 } 2678 2679 if (pExtraIcons) 2680 { 2681 if (::GetKeyboardLayoutList(0, NULL) == 1) 2682 { 2683 pExtraIcons->Check(TRUE); 2684 pExtraIcons->Gray(TRUE); 2685 } 2686 else 2687 { 2688 pExtraIcons->Gray(FALSE); 2689 } 2690 } 2691 2692 if (dwStatus & TF_SFT_DESKBAND) 2693 InsertItem(pMenuUI, ID_ADJUSTDESKBAND, IDS_ADJUSTLANGBAND); 2694 2695 InsertItem(pMenuUI, ID_SETTINGS, IDS_SETTINGS); 2696 2697 if (CheckCloseMenuAvailable()) 2698 InsertItem(pMenuUI, ID_CLOSELANGBAR, IDS_CLOSELANGBAR); 2699 } 2700 2701 return pMenuUI; 2702 } 2703 2704 UINT 2705 CUTBContextMenu::ShowPopup( 2706 CUIFWindow *pWindow, 2707 POINT pt, 2708 LPCRECT prc, 2709 BOOL bFlag) 2710 { 2711 if (g_bWinLogon) 2712 return 0; 2713 2714 if (m_pMenuUI) 2715 return -1; 2716 2717 m_pMenuUI = CreateMenuUI(bFlag); 2718 if (!m_pMenuUI) 2719 return 0; 2720 2721 UINT nCommandId = m_pMenuUI->ShowModalPopup(pWindow, prc, TRUE); 2722 2723 if (m_pMenuUI) 2724 { 2725 delete m_pMenuUI; 2726 m_pMenuUI = NULL; 2727 } 2728 2729 return nCommandId; 2730 } 2731 2732 /// @unimplemented 2733 BOOL CUTBContextMenu::SelectMenuItem(UINT nCommandId) 2734 { 2735 switch (nCommandId) 2736 { 2737 case ID_TRANS: 2738 m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_LOWTRANSPARENCY); 2739 break; 2740 2741 case ID_NOTRANS: 2742 m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_NOTRANSPARENCY); 2743 break; 2744 2745 case ID_LABELS: 2746 m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_LABELS); 2747 break; 2748 2749 case ID_NOLABELS: 2750 m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_NOLABELS); 2751 break; 2752 2753 case ID_DESKBAND: 2754 { 2755 DWORD dwStatus; 2756 m_pTipbarWnd->m_pLangBarMgr->GetShowFloatingStatus(&dwStatus); 2757 2758 if (dwStatus & TF_SFT_DESKBAND) 2759 break; 2760 2761 m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_DESKBAND); 2762 2763 CUTBMinimizeLangBarDlg *pDialog = new(cicNoThrow) CUTBMinimizeLangBarDlg(); 2764 if (pDialog) 2765 { 2766 pDialog->DoModal(*m_pTipbarWnd->GetWindow()); 2767 pDialog->_Release(); 2768 } 2769 break; 2770 } 2771 2772 case ID_CLOSELANGBAR: 2773 { 2774 CUTBCloseLangBarDlg *pDialog = new(cicNoThrow) CUTBCloseLangBarDlg(); 2775 if (pDialog) 2776 { 2777 BOOL bOK = pDialog->DoModal(*m_pTipbarWnd->GetWindow()); 2778 pDialog->_Release(); 2779 if (!bOK) 2780 DoCloseLangbar(); 2781 } 2782 break; 2783 } 2784 2785 case ID_EXTRAICONS: 2786 m_pTipbarWnd->m_dwTipbarWndFlags &= ~0x4000; 2787 m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_EXTRAICONSONMINIMIZED); 2788 break; 2789 2790 case ID_NOEXTRAICONS: 2791 m_pTipbarWnd->m_dwTipbarWndFlags &= ~0x4000; 2792 m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_NOEXTRAICONSONMINIMIZED); 2793 break; 2794 2795 case ID_RESTORELANGBAR: 2796 m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_LBI_ICON); 2797 break; 2798 2799 case ID_VERTICAL: 2800 m_pTipbarWnd->SetVertical((m_pTipbarWnd->m_dwTipbarWndFlags & 0x4) ? TRUE : FALSE); 2801 break; 2802 2803 case ID_ADJUSTDESKBAND: 2804 m_pTipbarWnd->AdjustDeskBandSize(TRUE); 2805 break; 2806 2807 case ID_SETTINGS: 2808 TF_RunInputCPL(); 2809 break; 2810 2811 default: 2812 break; 2813 } 2814 2815 return TRUE; 2816 } 2817 2818 /*********************************************************************** 2819 * CTrayIconItem 2820 */ 2821 2822 CTrayIconItem::CTrayIconItem(CTrayIconWnd *pTrayIconWnd) 2823 { 2824 m_dwIconAddOrModify = NIM_ADD; 2825 m_pTrayIconWnd = pTrayIconWnd; 2826 } 2827 2828 BOOL 2829 CTrayIconItem::_Init( 2830 HWND hWnd, 2831 UINT uCallbackMessage, 2832 UINT uNotifyIconID, 2833 const GUID& rguid) 2834 { 2835 m_hWnd = hWnd; 2836 m_uCallbackMessage = uCallbackMessage; 2837 m_uNotifyIconID = uNotifyIconID; 2838 m_guid = rguid; 2839 return TRUE; 2840 } 2841 2842 BOOL CTrayIconItem::RemoveIcon() 2843 { 2844 if (m_dwIconAddOrModify == NIM_MODIFY) 2845 { 2846 NOTIFYICONDATAW NotifyIcon = { sizeof(NotifyIcon), m_hWnd, m_uNotifyIconID }; 2847 NotifyIcon.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; 2848 NotifyIcon.uCallbackMessage = m_uCallbackMessage; 2849 ::Shell_NotifyIconW(NIM_DELETE, &NotifyIcon); 2850 } 2851 2852 m_dwIconAddOrModify = NIM_ADD; 2853 m_bIconAdded = TRUE; 2854 return TRUE; 2855 } 2856 2857 BOOL CTrayIconItem::SetIcon(HICON hIcon, LPCWSTR pszTip) 2858 { 2859 if (!hIcon) 2860 return FALSE; 2861 2862 NOTIFYICONDATAW NotifyIcon = { sizeof(NotifyIcon), m_hWnd, m_uNotifyIconID }; 2863 NotifyIcon.uFlags = NIF_ICON | NIF_MESSAGE; 2864 NotifyIcon.uCallbackMessage = m_uCallbackMessage; 2865 NotifyIcon.hIcon = hIcon; 2866 if (pszTip) 2867 { 2868 NotifyIcon.uFlags |= NIF_TIP; 2869 StringCchCopyW(NotifyIcon.szTip, _countof(NotifyIcon.szTip), pszTip); 2870 } 2871 2872 ::Shell_NotifyIconW(m_dwIconAddOrModify, &NotifyIcon); 2873 2874 m_dwIconAddOrModify = NIM_MODIFY; 2875 m_bIconAdded = NIM_MODIFY; 2876 return TRUE; 2877 } 2878 2879 BOOL CTrayIconItem::UpdateMenuRectPoint() 2880 { 2881 HWND hNotifyWnd = m_pTrayIconWnd->GetNotifyWnd(); 2882 ::GetClientRect(hNotifyWnd, &m_rcMenu); 2883 ::ClientToScreen(hNotifyWnd, (LPPOINT)&m_rcMenu); 2884 ::ClientToScreen(hNotifyWnd, (LPPOINT)&m_rcMenu.right); 2885 ::GetCursorPos(&m_ptCursor); 2886 return TRUE; 2887 } 2888 2889 /*********************************************************************** 2890 * CButtonIconItem 2891 */ 2892 2893 CButtonIconItem::CButtonIconItem(CTrayIconWnd *pWnd, DWORD dwUnknown24) 2894 : CTrayIconItem(pWnd) 2895 { 2896 m_dwUnknown24 = dwUnknown24; 2897 } 2898 2899 /// @unimplemented 2900 STDMETHODIMP_(BOOL) CButtonIconItem::OnMsg(WPARAM wParam, LPARAM lParam) 2901 { 2902 switch (lParam) 2903 { 2904 case WM_LBUTTONDOWN: 2905 case WM_RBUTTONDOWN: 2906 case WM_LBUTTONDBLCLK: 2907 case WM_RBUTTONDBLCLK: 2908 break; 2909 default: 2910 return TRUE; 2911 } 2912 2913 //FIXME 2914 return TRUE; 2915 } 2916 2917 /// @unimplemented 2918 STDMETHODIMP_(BOOL) CButtonIconItem::OnDelayMsg(UINT uMsg) 2919 { 2920 //FIXME 2921 return FALSE; 2922 } 2923 2924 /*********************************************************************** 2925 * CMainIconItem 2926 */ 2927 2928 CMainIconItem::CMainIconItem(CTrayIconWnd *pWnd) 2929 : CButtonIconItem(pWnd, 1) 2930 { 2931 } 2932 2933 BOOL CMainIconItem::Init(HWND hWnd) 2934 { 2935 return CTrayIconItem::_Init(hWnd, WM_USER, 0, GUID_LBI_TRAYMAIN); 2936 } 2937 2938 /// @unimplemented 2939 STDMETHODIMP_(BOOL) CMainIconItem::OnDelayMsg(UINT uMsg) 2940 { 2941 if (!CButtonIconItem::OnDelayMsg(uMsg)) 2942 return 0; 2943 2944 if (uMsg == WM_LBUTTONDBLCLK) 2945 { 2946 //FIXME 2947 //if (g_pTipbarWnd->m_dwUnknown20) 2948 // g_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_SHOWNORMAL); 2949 } 2950 else if (uMsg == WM_LBUTTONDOWN || uMsg == WM_RBUTTONDOWN) 2951 { 2952 //FIXME 2953 //g_pTipbarWnd->ShowContextMenu(m_ptCursor, &m_rcClient, uMsg == WM_RBUTTONDOWN); 2954 } 2955 return TRUE; 2956 } 2957 2958 /*********************************************************************** 2959 * CTrayIconWnd 2960 */ 2961 2962 CTrayIconWnd::CTrayIconWnd() 2963 { 2964 m_uCallbackMsg = WM_USER + 0x1000; 2965 m_uNotifyIconID = 0x1000; 2966 } 2967 2968 CTrayIconWnd::~CTrayIconWnd() 2969 { 2970 for (size_t iItem = 0; iItem < m_Items.size(); ++iItem) 2971 { 2972 auto& pItem = m_Items[iItem]; 2973 if (pItem) 2974 { 2975 delete pItem; 2976 pItem = NULL; 2977 } 2978 } 2979 } 2980 2981 void CTrayIconWnd::CallOnDelayMsg() 2982 { 2983 for (size_t iItem = 0; iItem < m_Items.size(); ++iItem) 2984 { 2985 auto pItem = m_Items[iItem]; 2986 if (pItem && m_uCallbackMessage == pItem->m_uCallbackMessage) 2987 { 2988 pItem->OnDelayMsg(m_uMsg); 2989 break; 2990 } 2991 } 2992 } 2993 2994 HWND CTrayIconWnd::CreateWnd() 2995 { 2996 m_hWnd = ::CreateWindowEx(0, TEXT("CTrayIconWndClass"), NULL, WS_DISABLED, 2997 0, 0, 0, 0, NULL, NULL, g_hInst, this); 2998 FindTrayEtc(); 2999 3000 m_pMainIconItem = new(cicNoThrow) CMainIconItem(this); 3001 if (m_pMainIconItem) 3002 { 3003 m_pMainIconItem->Init(m_hWnd); 3004 m_Items.Add(m_pMainIconItem); 3005 } 3006 3007 return m_hWnd; 3008 } 3009 3010 void CTrayIconWnd::DestroyWnd() 3011 { 3012 ::DestroyWindow(m_hWnd); 3013 m_hWnd = NULL; 3014 } 3015 3016 BOOL CALLBACK CTrayIconWnd::EnumChildWndProc(HWND hWnd, LPARAM lParam) 3017 { 3018 CTrayIconWnd *pWnd = (CTrayIconWnd *)lParam; 3019 3020 TCHAR ClassName[60]; 3021 ::GetClassName(hWnd, ClassName, _countof(ClassName)); 3022 if (lstrcmp(ClassName, TEXT("TrayNotifyWnd")) != 0) 3023 return TRUE; 3024 3025 pWnd->m_hNotifyWnd = hWnd; 3026 return FALSE; 3027 } 3028 3029 CButtonIconItem *CTrayIconWnd::FindIconItem(REFGUID rguid) 3030 { 3031 for (size_t iItem = 0; iItem < m_Items.size(); ++iItem) 3032 { 3033 auto pItem = m_Items[iItem]; 3034 if (IsEqualGUID(rguid, pItem->m_guid)) 3035 return pItem; 3036 } 3037 return NULL; 3038 } 3039 3040 BOOL CTrayIconWnd::FindTrayEtc() 3041 { 3042 m_hTrayWnd = ::FindWindow(TEXT("Shell_TrayWnd"), NULL); 3043 if (!m_hTrayWnd) 3044 return FALSE; 3045 3046 ::EnumChildWindows(m_hTrayWnd, EnumChildWndProc, (LPARAM)this); 3047 if (!m_hNotifyWnd) 3048 return FALSE; 3049 m_dwTrayWndThreadId = ::GetWindowThreadProcessId(m_hTrayWnd, NULL); 3050 m_hwndProgman = FindWindow(TEXT("Progman"), NULL); 3051 m_dwProgmanThreadId = ::GetWindowThreadProcessId(m_hwndProgman, NULL); 3052 return TRUE; 3053 } 3054 3055 HWND CTrayIconWnd::GetNotifyWnd() 3056 { 3057 if (!::IsWindow(m_hNotifyWnd)) 3058 FindTrayEtc(); 3059 return m_hNotifyWnd; 3060 } 3061 3062 /// @unimplemented 3063 BOOL CTrayIconWnd::OnIconMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) 3064 { 3065 //FIXME 3066 //if (g_pTipbarWnd) 3067 // g_pTipbarWnd->AttachFocusThread(); 3068 3069 for (size_t iItem = 0; iItem < m_Items.size(); ++iItem) 3070 { 3071 auto pItem = m_Items[iItem]; 3072 if (pItem) 3073 { 3074 if (uMsg == pItem->m_uCallbackMessage) 3075 { 3076 pItem->OnMsg(wParam, lParam); 3077 return TRUE; 3078 } 3079 } 3080 } 3081 return FALSE; 3082 } 3083 3084 BOOL CTrayIconWnd::RegisterClass() 3085 { 3086 WNDCLASSEX wc = { sizeof(wc) }; 3087 wc.style = CS_HREDRAW | CS_VREDRAW; 3088 wc.hInstance = g_hInst; 3089 wc.hCursor = ::LoadCursor(NULL, (LPCTSTR)IDC_ARROW); 3090 wc.lpfnWndProc = CTrayIconWnd::_WndProc; 3091 wc.lpszClassName = TEXT("CTrayIconWndClass"); 3092 ::RegisterClassEx(&wc); 3093 return TRUE; 3094 } 3095 3096 void CTrayIconWnd::RemoveAllIcon(DWORD dwFlags) 3097 { 3098 for (size_t iItem = 0; iItem < m_Items.size(); ++iItem) 3099 { 3100 auto pItem = m_Items[iItem]; 3101 if (dwFlags & 0x1) 3102 { 3103 if (IsEqualGUID(pItem->m_guid, GUID_LBI_INATITEM) || 3104 IsEqualGUID(pItem->m_guid, GUID_LBI_CTRL)) 3105 { 3106 continue; 3107 } 3108 } 3109 3110 if (dwFlags & 0x2) 3111 { 3112 if (IsEqualGUID(pItem->m_guid, GUID_TFCAT_TIP_KEYBOARD)) 3113 continue; 3114 } 3115 3116 if (pItem->m_uNotifyIconID < 0x1000) 3117 continue; 3118 3119 pItem->RemoveIcon(); 3120 } 3121 } 3122 3123 /// @unimplemented 3124 void CTrayIconWnd::RemoveUnusedIcons(int unknown) 3125 { 3126 //FIXME 3127 } 3128 3129 BOOL CTrayIconWnd::SetIcon(REFGUID rguid, DWORD dwUnknown24, HICON hIcon, LPCWSTR psz) 3130 { 3131 CButtonIconItem *pItem = FindIconItem(rguid); 3132 if (!pItem) 3133 { 3134 if (!hIcon) 3135 return FALSE; 3136 pItem = new(cicNoThrow) CButtonIconItem(this, dwUnknown24); 3137 if (!pItem) 3138 return FALSE; 3139 3140 pItem->_Init(m_hWnd, m_uCallbackMsg, m_uNotifyIconID, rguid); 3141 m_uCallbackMsg += 2; 3142 ++m_uNotifyIconID; 3143 m_Items.Add(pItem); 3144 } 3145 3146 if (!hIcon) 3147 return pItem->RemoveIcon(); 3148 3149 return pItem->SetIcon(hIcon, psz); 3150 } 3151 3152 BOOL CTrayIconWnd::SetMainIcon(HKL hKL) 3153 { 3154 if (!hKL) 3155 { 3156 m_pMainIconItem->RemoveIcon(); 3157 m_pMainIconItem->m_hKL = NULL; 3158 return TRUE; 3159 } 3160 3161 if (hKL != m_pMainIconItem->m_hKL) 3162 { 3163 WCHAR szText[64]; 3164 HICON hIcon = TF_GetLangIcon(LOWORD(hKL), szText, _countof(szText)); 3165 if (hIcon) 3166 { 3167 m_pMainIconItem->SetIcon(hIcon, szText); 3168 ::DestroyIcon(hIcon); 3169 } 3170 else 3171 { 3172 ::LoadStringW(g_hInst, IDS_RESTORELANGBAR, szText, _countof(szText)); 3173 hIcon = ::LoadIconW(g_hInst, MAKEINTRESOURCEW(IDI_MAINICON)); 3174 m_pMainIconItem->SetIcon(hIcon, szText); 3175 } 3176 3177 m_pMainIconItem->m_hKL = hKL; 3178 } 3179 3180 return TRUE; 3181 } 3182 3183 CTrayIconWnd *CTrayIconWnd::GetThis(HWND hWnd) 3184 { 3185 return (CTrayIconWnd *)::GetWindowLongPtr(hWnd, GWL_USERDATA); 3186 } 3187 3188 void CTrayIconWnd::SetThis(HWND hWnd, LPCREATESTRUCT pCS) 3189 { 3190 if (pCS) 3191 ::SetWindowLongPtr(hWnd, GWL_USERDATA, (LONG_PTR)pCS->lpCreateParams); 3192 else 3193 ::SetWindowLongPtr(hWnd, GWL_USERDATA, 0); 3194 } 3195 3196 LRESULT CALLBACK 3197 CTrayIconWnd::_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 3198 { 3199 CTrayIconWnd *pThis; 3200 switch (uMsg) 3201 { 3202 case WM_CREATE: 3203 CTrayIconWnd::SetThis(hWnd, (LPCREATESTRUCT)lParam); 3204 break; 3205 case WM_DESTROY: 3206 ::SetWindowLongPtr(hWnd, GWL_USERDATA, 0); 3207 break; 3208 case WM_TIMER: 3209 if (wParam == 100) 3210 { 3211 ::KillTimer(hWnd, 100); 3212 pThis = CTrayIconWnd::GetThis(hWnd); 3213 if (pThis) 3214 pThis->CallOnDelayMsg(); 3215 } 3216 break; 3217 default: 3218 { 3219 if (uMsg < WM_USER) 3220 return ::DefWindowProc(hWnd, uMsg, wParam, lParam); 3221 pThis = CTrayIconWnd::GetThis(hWnd); 3222 if (pThis && pThis->OnIconMessage(uMsg, wParam, lParam)) 3223 break; 3224 return ::DefWindowProc(hWnd, uMsg, wParam, lParam); 3225 } 3226 } 3227 return 0; 3228 } 3229 3230 /*********************************************************************** 3231 * CLBarItemBase 3232 */ 3233 3234 CLBarItemBase::CLBarItemBase() 3235 { 3236 m_dwItemStatus = 0; 3237 m_szToolTipText[0] = 0; 3238 m_cRefs = 1; 3239 m_pLangBarItemSink = NULL; 3240 } 3241 3242 CLBarItemBase::~CLBarItemBase() 3243 { 3244 if (m_pLangBarItemSink) 3245 m_pLangBarItemSink->Release(); 3246 } 3247 3248 HRESULT 3249 CLBarItemBase::AdviseSink( 3250 REFIID riid, 3251 IUnknown *punk, 3252 DWORD *pdwCookie) 3253 { 3254 if (IsEqualIID(riid, IID_ITfLangBarItemSink) || m_pLangBarItemSink) 3255 return TF_E_NOOBJECT; 3256 3257 HRESULT hr = punk->QueryInterface(IID_ITfLangBarItemSink, (void **)&m_pLangBarItemSink); 3258 if (SUCCEEDED(hr)) 3259 *pdwCookie = 0x80000001; 3260 return hr; 3261 } 3262 3263 HRESULT CLBarItemBase::UnadviseSink(DWORD dwCookie) 3264 { 3265 if (dwCookie != 0x80000001) 3266 return E_FAIL; 3267 3268 if (!m_pLangBarItemSink) 3269 return E_UNEXPECTED; 3270 3271 m_pLangBarItemSink->Release(); 3272 m_pLangBarItemSink = NULL; 3273 return S_OK; 3274 } 3275 3276 void 3277 CLBarItemBase::InitNuiInfo( 3278 REFIID clsidService, 3279 REFGUID guidItem, 3280 DWORD dwStyle, 3281 DWORD ulSort, 3282 LPCWSTR Source) 3283 { 3284 m_NewUIInfo.clsidService = clsidService; 3285 m_NewUIInfo.guidItem = guidItem; 3286 m_NewUIInfo.dwStyle = dwStyle; 3287 m_NewUIInfo.ulSort = ulSort; 3288 StringCchCopyW(m_NewUIInfo.szDescription, _countof(m_NewUIInfo.szDescription), Source); 3289 } 3290 3291 HRESULT 3292 CLBarItemBase::ShowInternal(BOOL bShow, BOOL bUpdate) 3293 { 3294 DWORD dwOldStatus = m_dwItemStatus; 3295 3296 if (bShow) 3297 m_dwItemStatus &= ~TF_LBI_STATUS_HIDDEN; 3298 else 3299 m_dwItemStatus |= TF_LBI_STATUS_HIDDEN; 3300 3301 if (bUpdate && (dwOldStatus != m_dwItemStatus)) 3302 { 3303 if (m_pLangBarItemSink) 3304 m_pLangBarItemSink->OnUpdate(TF_LBI_STATUS); 3305 } 3306 3307 return S_OK; 3308 } 3309 3310 HRESULT CLBarItemBase::GetInfo(TF_LANGBARITEMINFO *pInfo) 3311 { 3312 CopyMemory(pInfo, &m_NewUIInfo, sizeof(*pInfo)); 3313 return S_OK; 3314 } 3315 3316 HRESULT CLBarItemBase::GetStatus(DWORD *pdwStatus) 3317 { 3318 *pdwStatus = m_dwItemStatus; 3319 return S_OK; 3320 } 3321 3322 HRESULT CLBarItemBase::Show(BOOL fShow) 3323 { 3324 return ShowInternal(fShow, TRUE); 3325 } 3326 3327 HRESULT CLBarItemBase::GetTooltipString(BSTR *pbstrToolTip) 3328 { 3329 if (!pbstrToolTip) 3330 return E_INVALIDARG; 3331 BSTR bstr = ::SysAllocString(m_szToolTipText); 3332 *pbstrToolTip = bstr; 3333 return bstr ? S_OK : E_OUTOFMEMORY; 3334 } 3335 3336 /*********************************************************************** 3337 * CUTBLBarMenu 3338 */ 3339 3340 CUTBLBarMenu::CUTBLBarMenu(HINSTANCE hInst) : CCicLibMenu() 3341 { 3342 m_hInst = hInst; 3343 } 3344 3345 CUTBLBarMenu::~CUTBLBarMenu() 3346 { 3347 } 3348 3349 STDMETHODIMP_(CCicLibMenuItem*) CUTBLBarMenu::CreateMenuItem() 3350 { 3351 CUTBLBarMenuItem *pItem = new(cicNoThrow) CUTBLBarMenuItem(); 3352 if (!pItem) 3353 return NULL; 3354 pItem->m_pLBarMenu = this; 3355 return pItem; 3356 } 3357 3358 CUTBMenuWnd *CUTBLBarMenu::CreateMenuUI() 3359 { 3360 CUTBMenuWnd *pMenuUI = new(cicNoThrow) CUTBMenuWnd(m_hInst, g_dwMenuStyle, 0); 3361 if (!pMenuUI) 3362 return NULL; 3363 3364 pMenuUI->Initialize(); 3365 for (size_t iItem = 0; iItem < m_MenuItems.size(); ++iItem) 3366 { 3367 CUTBLBarMenuItem *pItem = (CUTBLBarMenuItem *)m_MenuItems[iItem]; 3368 pItem->InsertToUI(pMenuUI); 3369 } 3370 3371 return pMenuUI; 3372 } 3373 3374 STDMETHODIMP_(CCicLibMenu*) CUTBLBarMenu::CreateSubMenu() 3375 { 3376 return new(cicNoThrow) CUTBLBarMenu(m_hInst); 3377 } 3378 3379 INT CUTBLBarMenu::ShowPopup(CUIFWindow *pWindow, POINT pt, LPCRECT prcExclude) 3380 { 3381 if (m_pMenuUI) 3382 return 0; 3383 3384 m_pMenuUI = CreateMenuUI(); 3385 if (!m_pMenuUI) 3386 return -1; 3387 3388 INT nCommandId = m_pMenuUI->ShowModalPopup(pWindow, prcExclude, TRUE); 3389 3390 if (m_pMenuUI) 3391 { 3392 delete m_pMenuUI; 3393 m_pMenuUI = NULL; 3394 } 3395 3396 return nCommandId; 3397 } 3398 3399 /*********************************************************************** 3400 * CUTBLBarMenuItem 3401 */ 3402 3403 /// @unimplemented 3404 BOOL CUTBLBarMenuItem::InsertToUI(CUTBMenuWnd *pMenuUI) 3405 { 3406 if ((m_dwFlags & 4) != 0) 3407 { 3408 pMenuUI->InsertSeparator(); 3409 return TRUE; 3410 } 3411 if (m_dwFlags & 2) 3412 { 3413 //FIXME 3414 } 3415 else 3416 { 3417 //FIXME 3418 } 3419 return FALSE; 3420 } 3421 3422 /*********************************************************************** 3423 * CLBarItemButtonBase 3424 */ 3425 3426 CLBarItemButtonBase::~CLBarItemButtonBase() 3427 { 3428 if (m_hIcon) 3429 { 3430 ::DestroyIcon(m_hIcon); 3431 m_hIcon = NULL; 3432 } 3433 } 3434 3435 STDMETHODIMP CLBarItemButtonBase::QueryInterface(REFIID riid, void **ppvObject) 3436 { 3437 if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfLangBarItem)) 3438 { 3439 *ppvObject = static_cast<ITfLangBarItem*>(this); 3440 AddRef(); 3441 return S_OK; 3442 } 3443 if (IsEqualIID(riid, IID_ITfLangBarItemButton)) 3444 { 3445 *ppvObject = static_cast<ITfLangBarItemButton*>(this); 3446 AddRef(); 3447 return S_OK; 3448 } 3449 if (IsEqualIID(riid, IID_ITfSource)) 3450 { 3451 *ppvObject = static_cast<ITfSource*>(this); 3452 AddRef(); 3453 return S_OK; 3454 } 3455 return E_NOINTERFACE; 3456 } 3457 3458 STDMETHODIMP_(ULONG) CLBarItemButtonBase::AddRef() 3459 { 3460 return ++m_cRefs; 3461 } 3462 3463 STDMETHODIMP_(ULONG) CLBarItemButtonBase::Release() 3464 { 3465 if (--m_cRefs == 0) 3466 { 3467 delete this; 3468 return 0; 3469 } 3470 return m_cRefs; 3471 } 3472 3473 /// @unimplemented 3474 STDMETHODIMP CLBarItemButtonBase::OnClick(TfLBIClick click, POINT pt, LPCRECT prc) 3475 { 3476 if (click == TF_LBI_CLK_RIGHT) 3477 { 3478 return E_NOTIMPL; //FIXME 3479 } 3480 if (click == TF_LBI_CLK_LEFT) 3481 { 3482 return E_NOTIMPL; //FIXME 3483 } 3484 return E_NOTIMPL; 3485 } 3486 3487 STDMETHODIMP CLBarItemButtonBase::InitMenu(ITfMenu *pMenu) 3488 { 3489 return E_NOTIMPL; 3490 } 3491 3492 STDMETHODIMP CLBarItemButtonBase::OnMenuSelect(UINT wID) 3493 { 3494 return E_NOTIMPL; 3495 } 3496 3497 STDMETHODIMP CLBarItemButtonBase::GetIcon(HICON *phIcon) 3498 { 3499 return E_NOTIMPL; 3500 } 3501 3502 STDMETHODIMP CLBarItemButtonBase::GetText(BSTR *pbstr) 3503 { 3504 if (!pbstr) 3505 return E_INVALIDARG; 3506 *pbstr = ::SysAllocString(m_NewUIInfo.szDescription); 3507 return (*pbstr ? S_OK : E_OUTOFMEMORY); 3508 } 3509 3510 STDMETHODIMP CLBarItemButtonBase::GetInfo(TF_LANGBARITEMINFO *pInfo) 3511 { 3512 return CLBarItemBase::GetInfo(pInfo); 3513 } 3514 3515 STDMETHODIMP CLBarItemButtonBase::GetStatus(DWORD *pdwStatus) 3516 { 3517 return CLBarItemBase::GetStatus(pdwStatus); 3518 } 3519 3520 STDMETHODIMP CLBarItemButtonBase::Show(BOOL fShow) 3521 { 3522 return CLBarItemBase::Show(fShow); 3523 } 3524 3525 STDMETHODIMP CLBarItemButtonBase::GetTooltipString(BSTR *pbstrToolTip) 3526 { 3527 return CLBarItemBase::GetTooltipString(pbstrToolTip); 3528 } 3529 3530 STDMETHODIMP CLBarItemButtonBase::AdviseSink( 3531 REFIID riid, 3532 IUnknown *punk, 3533 DWORD *pdwCookie) 3534 { 3535 return CLBarItemBase::AdviseSink(riid, punk, pdwCookie); 3536 } 3537 3538 STDMETHODIMP CLBarItemButtonBase::UnadviseSink(DWORD dwCookie) 3539 { 3540 return CLBarItemBase::UnadviseSink(dwCookie); 3541 } 3542 3543 /*********************************************************************** 3544 * CLBarInatItem 3545 */ 3546 3547 CLBarInatItem::CLBarInatItem(DWORD dwThreadId) 3548 { 3549 WCHAR szText[256]; 3550 ::LoadStringW(g_hInst, IDS_LANGUAGE, szText, _countof(szText)); 3551 InitNuiInfo(CLSID_SYSTEMLANGBARITEM, GUID_LBI_INATITEM, 0x20001, 0, szText); 3552 3553 ::LoadStringW(g_hInst, IDS_LANGUAGEBUTTON, szText, _countof(szText)); 3554 StringCchCopyW(m_szToolTipText, _countof(m_szToolTipText), szText); 3555 m_dwThreadId = dwThreadId; 3556 m_hKL = ::GetKeyboardLayout(m_dwThreadId); 3557 3558 TF_InitMlngInfo(); 3559 ShowInternal(TF_MlngInfoCount() > 1, 0); 3560 } 3561 3562 STDMETHODIMP CLBarInatItem::GetIcon(HICON *phIcon) 3563 { 3564 HICON hIcon = NULL; 3565 INT iIndex = GetIconIndexFromhKL(m_hKL); 3566 if (iIndex != -1) 3567 hIcon = TF_InatExtractIcon(iIndex); 3568 *phIcon = hIcon; 3569 return S_OK; 3570 } 3571 3572 STDMETHODIMP CLBarInatItem::GetText(BSTR *pbstr) 3573 { 3574 if (!pbstr) 3575 return E_INVALIDARG; 3576 3577 WCHAR szText[256]; 3578 if (!GethKLDesc(m_hKL, szText, _countof(szText))) 3579 return GetText(pbstr); 3580 3581 *pbstr = ::SysAllocString(szText); 3582 return S_OK; 3583 } 3584 3585 STDMETHODIMP CLBarInatItem::InitMenu(ITfMenu *pMenu) 3586 { 3587 TF_InitMlngInfo(); 3588 3589 INT iKL, cKLs = TF_MlngInfoCount(); 3590 for (iKL = 0; iKL < cKLs; ++iKL) 3591 { 3592 HKL hKL; 3593 WCHAR szDesc[128]; 3594 if (TF_GetMlngHKL(iKL, &hKL, szDesc, _countof(szDesc))) 3595 { 3596 HICON hIcon = NULL; 3597 INT iIndex = GetIconIndexFromhKL(hKL); 3598 if (iIndex != -1) 3599 hIcon = TF_InatExtractIcon(iIndex); 3600 3601 LangBarInsertMenu(pMenu, iKL, szDesc, (hKL == m_hKL), hIcon); 3602 } 3603 } 3604 3605 #if 0 // FIXME: g_pTipbarWnd 3606 DWORD dwStatus; 3607 if (g_pTipbarWnd && 3608 g_pTipbarWnd->m_pLangBarMgr && 3609 SUCCEEDED(g_pTipbarWnd->m_pLangBarMgr->GetShowFloatingStatus(&dwStatus)) && 3610 (dwStatus & (TF_SFT_DESKBAND | TF_SFT_MINIMIZED))) 3611 { 3612 LangBarInsertSeparator(pMenu); 3613 3614 WCHAR szText[256]; 3615 ::LoadStringW(g_hInst, IDS_RESTORELANGBAR2, szText, _countof(szText)); 3616 LangBarInsertMenu(pMenu, 2000, szText, FALSE, NULL); 3617 } 3618 #endif 3619 3620 return S_OK; 3621 } 3622 3623 STDMETHODIMP CLBarInatItem::OnMenuSelect(INT nCommandId) 3624 { 3625 HKL hKL; 3626 3627 if (nCommandId == 2000) 3628 { 3629 if (g_pTipbarWnd) 3630 { 3631 #if 0 // FIXME: g_pTipbarWnd 3632 ITfLangBarMgr *pLangBarMgr = g_pTipbarWnd->m_pLangBarMgr; 3633 if (pLangBarMgr) 3634 pLangBarMgr->ShowFloating(TF_SFT_SHOWNORMAL); 3635 #endif 3636 } 3637 } 3638 else if (TF_GetMlngHKL(nCommandId, &hKL, NULL, 0)) 3639 { 3640 #if 0 // FIXME: g_pTipbarWnd 3641 g_pTipbarWnd->RestoreLastFocus(0, (g_pTipbarWnd->m_dwTipbarWndFlags & 2) != 0); 3642 #endif 3643 HWND hwndFore = ::GetForegroundWindow(); 3644 if (m_dwThreadId == ::GetWindowThreadProcessId(hwndFore, NULL)) 3645 { 3646 BOOL FontSig = GetFontSig(hwndFore, hKL); 3647 ::PostMessage(hwndFore, WM_INPUTLANGCHANGEREQUEST, FontSig, (LPARAM)hKL); 3648 } 3649 } 3650 3651 return S_OK; 3652 } 3653 3654 /*********************************************************************** 3655 * CTipbarGripper 3656 */ 3657 3658 CTipbarGripper::CTipbarGripper(CTipbarWnd *pTipbarWnd, LPCRECT prc, DWORD style) 3659 : CUIFGripper((pTipbarWnd ? pTipbarWnd->GetWindow() : NULL), prc, style) 3660 { 3661 m_bInDebugMenu = FALSE; 3662 m_pTipbarWnd = pTipbarWnd; 3663 } 3664 3665 /// @unimplemented 3666 STDMETHODIMP_(void) CTipbarGripper::OnLButtonUp(LONG x, LONG y) 3667 { 3668 m_pTipbarWnd->RestoreFromStub(); 3669 3670 APPBARDATA AppBar = { sizeof(AppBar) }; 3671 AppBar.hWnd = ::FindWindowW(L"Shell_TrayWnd", NULL); 3672 if (::SHAppBarMessage(ABM_GETTASKBARPOS, &AppBar)) 3673 { 3674 RECT rc = AppBar.rc; 3675 POINT pt; 3676 ::GetCursorPos(&pt); 3677 if (g_pTipbarWnd && ::PtInRect(&rc, pt)) 3678 g_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_DESKBAND | TF_SFT_EXTRAICONSONMINIMIZED); 3679 } 3680 3681 CUIFGripper::OnLButtonUp(x, y); 3682 m_pTipbarWnd->UpdatePosFlags(); 3683 } 3684 3685 /// @unimplemented 3686 STDMETHODIMP_(void) CTipbarGripper::OnRButtonUp(LONG x, LONG y) 3687 { 3688 if (g_bShowDebugMenu) 3689 { 3690 // FIXME: Debugging feature 3691 } 3692 } 3693 3694 STDMETHODIMP_(BOOL) CTipbarGripper::OnSetCursor(UINT uMsg, LONG x, LONG y) 3695 { 3696 if (m_bInDebugMenu) 3697 return FALSE; 3698 3699 return CUIFGripper::OnSetCursor(uMsg, x, y); 3700 } 3701 3702 /*********************************************************************** 3703 * CTipbarWnd 3704 */ 3705 3706 /// @unimplemented 3707 CTipbarWnd::CTipbarWnd(DWORD style) 3708 : CUIFWindow(g_hInst, style) 3709 { 3710 m_dwUnknown23_1[4] = 0; 3711 m_dwUnknown23_1[5] = 0; 3712 m_dwUnknown23_1[6] = 0; 3713 m_dwUnknown23_1[7] = 0; 3714 3715 RECT rc; 3716 cicGetScreenRect(g_ptTipbar, &rc); 3717 3718 //FIXME: Fix g_ptTipbar 3719 3720 Move(g_ptTipbar.x, g_ptTipbar.y, 100, 24); 3721 UpdatePosFlags(); 3722 3723 m_hMarlettFont = ::CreateFontW(8, 8, 0, 0, FW_NORMAL, 0, 0, 0, 3724 SYMBOL_CHARSET, 0, 0, 0, 0, L"Marlett"); 3725 3726 ITfLangBarMgr *pLangBarMgr = NULL; 3727 if (SUCCEEDED(TF_CreateLangBarMgr(&pLangBarMgr)) && pLangBarMgr) 3728 { 3729 pLangBarMgr->QueryInterface(IID_ITfLangBarMgr_P, (void **)&m_pLangBarMgr); 3730 pLangBarMgr->Release(); 3731 } 3732 3733 if (style & UIF_WINDOW_ENABLETHEMED) 3734 { 3735 if (g_fTaskbarTheme) 3736 { 3737 m_iPartId = 1; 3738 m_iStateId = 1; 3739 m_pszClassList = L"TASKBAR"; 3740 } 3741 else 3742 { 3743 m_iPartId = 0; 3744 m_iStateId = 1; 3745 m_pszClassList = L"REBAR"; 3746 } 3747 } 3748 3749 SetVertical(g_fVertical); 3750 3751 m_cRefs = 1; 3752 } 3753 3754 /// @unimplemented 3755 CTipbarWnd::~CTipbarWnd() 3756 { 3757 UnInit(); 3758 3759 if (m_hMarlettFont) 3760 ::DeleteObject(m_hMarlettFont); 3761 if (m_hTextFont) 3762 ::DeleteObject(m_hTextFont); 3763 3764 //TFUninitLib_Thread(&g_libTLS); //FIXME 3765 } 3766 3767 /// @unimplemented 3768 void CTipbarWnd::Init(BOOL bChild, CDeskBand *pDeskBand) 3769 { 3770 } 3771 3772 void CTipbarWnd::InitHighContrast() 3773 { 3774 m_dwTipbarWndFlags &= ~0x10; 3775 3776 HIGHCONTRAST HiCon = { sizeof(HiCon) }; 3777 if (::SystemParametersInfo(SPI_GETHIGHCONTRAST, sizeof(HiCon), &HiCon, 0)) 3778 { 3779 if (HiCon.dwFlags & HCF_HIGHCONTRASTON) 3780 m_dwTipbarWndFlags |= 0x10; 3781 } 3782 } 3783 3784 void CTipbarWnd::InitMetrics() 3785 { 3786 m_cxSmallIcon = ::GetSystemMetrics(SM_CXSMICON); 3787 m_cySmallIcon = ::GetSystemMetrics(SM_CYSMICON); 3788 3789 DWORD_PTR style = ::GetWindowLongPtr(m_hWnd, GWL_STYLE); 3790 if (style & WS_DLGFRAME) 3791 { 3792 m_cxDlgFrameX2 = 2 * ::GetSystemMetrics(SM_CXDLGFRAME); 3793 m_cyDlgFrameX2 = 2 * ::GetSystemMetrics(SM_CYDLGFRAME); 3794 } 3795 else if (style & WS_BORDER) 3796 { 3797 m_cxDlgFrameX2 = 2 * ::GetSystemMetrics(SM_CXBORDER); 3798 m_cyDlgFrameX2 = 2 * ::GetSystemMetrics(SM_CYBORDER); 3799 } 3800 else 3801 { 3802 m_cxDlgFrameX2 = m_cyDlgFrameX2 = 0; 3803 } 3804 } 3805 3806 void CTipbarWnd::InitThemeMargins() 3807 { 3808 ZeroMemory(&m_Margins, sizeof(m_Margins)); 3809 3810 CUIFTheme theme; 3811 m_dwUnknown23_5[0] = 6; 3812 m_dwUnknown23_5[1] = 6; 3813 m_dwUnknown23_5[2] = 0; 3814 m_ButtonWidth = GetSystemMetrics(SM_CXSIZE); 3815 3816 theme.m_iPartId = 1; 3817 theme.m_iStateId = 0; 3818 theme.m_pszClassList = L"TOOLBAR"; 3819 if (SUCCEEDED(theme.InternalOpenThemeData(m_hWnd))) 3820 { 3821 ::GetThemeMargins(theme.m_hTheme, NULL, theme.m_iPartId, 1, 3602, NULL, &m_Margins); 3822 m_dwUnknown23_5[0] = 4; 3823 m_dwUnknown23_5[1] = 2; 3824 m_dwUnknown23_5[2] = 1; 3825 } 3826 theme.CloseThemeData(); 3827 3828 theme.m_iPartId = 18; 3829 theme.m_iStateId = 0; 3830 theme.m_pszClassList = L"WINDOW"; 3831 if (SUCCEEDED(theme.InternalOpenThemeData(m_hWnd))) 3832 { 3833 SIZE partSize; 3834 ::GetThemePartSize(theme.m_hTheme, NULL, theme.m_iPartId, 1, 0, TS_TRUE, &partSize); 3835 INT size = ::GetThemeSysSize(theme.m_hTheme, 31); 3836 m_ButtonWidth = MulDiv(size, partSize.cx, partSize.cy); 3837 } 3838 theme.CloseThemeData(); 3839 } 3840 3841 /// @unimplemented 3842 void CTipbarWnd::UnInit() 3843 { 3844 } 3845 3846 BOOL CTipbarWnd::IsFullScreenWindow(HWND hWnd) 3847 { 3848 if (g_fPolicyEnableLanguagebarInFullscreen) 3849 return FALSE; 3850 3851 DWORD_PTR style = ::GetWindowLongPtr(hWnd, GWL_STYLE); 3852 if (!(style & WS_VISIBLE) || (style & WS_CAPTION)) 3853 return FALSE; 3854 3855 DWORD_PTR exstyle = ::GetWindowLongPtr(hWnd, GWL_EXSTYLE); 3856 if (exstyle & WS_EX_LAYERED) 3857 return FALSE; 3858 3859 if ((exstyle & WS_EX_TOOLWINDOW) && (hWnd == m_ShellWndThread.GetWndProgman())) 3860 return FALSE; 3861 3862 return !!cicIsFullScreenSize(hWnd); 3863 } 3864 3865 BOOL CTipbarWnd::IsHKLToSkipRedrawOnNoItem() 3866 { 3867 HKL hKL = GetFocusKeyboardLayout(); 3868 return IsSkipRedrawHKL(hKL); 3869 } 3870 3871 /// @unimplemented 3872 BOOL CTipbarWnd::IsInItemChangeOrDirty(CTipbarThread *pTarget) 3873 { 3874 return FALSE; 3875 } 3876 3877 void CTipbarWnd::AddThreadToThreadCreatingList(CTipbarThread *pThread) 3878 { 3879 m_ThreadCreatingList.Add(pThread); 3880 } 3881 3882 void CTipbarWnd::RemoveThredFromThreadCreatingList(CTipbarThread *pTarget) 3883 { 3884 ssize_t iItem = m_ThreadCreatingList.Find(pTarget); 3885 if (iItem >= 0) 3886 m_ThreadCreatingList.Remove(iItem); 3887 } 3888 3889 /// @unimplemented 3890 void CTipbarWnd::MoveToStub(BOOL bFlag) 3891 { 3892 } 3893 3894 void CTipbarWnd::RestoreFromStub() 3895 { 3896 m_dwTipbarWndFlags &= 0x3F; 3897 KillTimer(1); 3898 KillTimer(2); 3899 } 3900 3901 /// @unimplemented 3902 INT CTipbarWnd::GetCtrlButtonWidth() 3903 { 3904 return 0; 3905 } 3906 3907 INT CTipbarWnd::GetGripperWidth() 3908 { 3909 if (m_dwTipbarWndFlags & 2) 3910 return 0; 3911 3912 if (!m_pTipbarGripper || FAILED(m_pTipbarGripper->EnsureThemeData(m_hWnd))) 3913 return 5; 3914 3915 INT width = -1; 3916 SIZE partSize; 3917 HDC hDC = ::GetDC(m_hWnd); 3918 if (SUCCEEDED(m_pTipbarGripper->GetThemePartSize(hDC, 1, 0, TS_TRUE, &partSize))) 3919 { 3920 INT cx = partSize.cx; 3921 if (m_dwTipbarWndFlags & 4) 3922 cx = partSize.cy; 3923 width = cx + 4; 3924 } 3925 ::ReleaseDC(m_hWnd, hDC); 3926 3927 return ((width < 0) ? 5 : width); 3928 } 3929 3930 INT CTipbarWnd::GetTipbarHeight() 3931 { 3932 SIZE size = { 0, 0 }; 3933 if (m_pWndFrame) 3934 m_pWndFrame->GetFrameSize(&size); 3935 INT cy = m_Margins.cyBottomHeight + m_Margins.cyTopHeight + 2; 3936 if (cy < 6) 3937 cy = 6; 3938 return m_cySmallIcon + cy + (2 * size.cy); 3939 } 3940 3941 /// @unimplemented 3942 BOOL CTipbarWnd::AutoAdjustDeskBandSize() 3943 { 3944 return FALSE; 3945 } 3946 3947 /// @unimplemented 3948 INT CTipbarWnd::AdjustDeskBandSize(BOOL bFlag) 3949 { 3950 return 0; 3951 } 3952 3953 /// @unimplemented 3954 void CTipbarWnd::LocateCtrlButtons() 3955 { 3956 } 3957 3958 void CTipbarWnd::AdjustPosOnDisplayChange() 3959 { 3960 RECT rcWorkArea; 3961 RECT rc = { m_nLeft, m_nTop, m_nLeft + m_nWidth, m_nTop + m_nHeight }; 3962 if (!GetWorkArea(&rc, &rcWorkArea)) 3963 return; 3964 3965 INT x = m_nLeft, y = m_nTop; 3966 if (m_dwTipbarWndFlags & 0x200000) 3967 x = rcWorkArea.left; 3968 if (m_dwTipbarWndFlags & 0x40000) 3969 y = rcWorkArea.top; 3970 if (m_dwTipbarWndFlags & 0x100000) 3971 x = rcWorkArea.right - m_nWidth; 3972 if (m_dwTipbarWndFlags & 0x80000) 3973 y = rcWorkArea.bottom - m_nHeight; 3974 if (x != m_nLeft || y != m_nTop) 3975 Move(x, y, m_nWidth, m_nHeight); 3976 } 3977 3978 void CTipbarWnd::SetVertical(BOOL bVertical) 3979 { 3980 if (bVertical) 3981 m_dwTipbarWndFlags |= 0x4; 3982 else 3983 m_dwTipbarWndFlags &= ~0x4; 3984 3985 if (m_pTipbarGripper) 3986 { 3987 DWORD style = m_pTipbarGripper->m_style; 3988 if (bVertical) 3989 style |= 0x1; 3990 else 3991 style &= 0x1; 3992 m_pTipbarGripper->SetStyle(style); 3993 } 3994 3995 if (g_fTaskbarTheme) 3996 SetActiveTheme(L"TASKBAR", !!(m_dwTipbarWndFlags & 0x4), 1); 3997 3998 if (!(m_dwTipbarWndFlags & 2)) 3999 { 4000 if (m_dwTipbarWndFlags & 4) 4001 { 4002 Move(m_nLeft, m_nTop, GetTipbarHeight(), 0); 4003 } 4004 else 4005 { 4006 Move(m_nLeft, m_nTop, 0, GetTipbarHeight()); 4007 } 4008 } 4009 4010 if (m_hWnd) 4011 { 4012 KillTimer(7); 4013 SetTimer(7, g_uTimerElapseSYSCOLORCHANGED); 4014 } 4015 } 4016 4017 void CTipbarWnd::UpdatePosFlags() 4018 { 4019 if (m_dwTipbarWndFlags & 0x2) 4020 return; 4021 4022 RECT rc = { m_nLeft, m_nTop, m_nLeft + m_nWidth, m_nTop + m_nHeight }, rcWorkArea; 4023 if (!GetWorkArea(&rc, &rcWorkArea)) 4024 return; 4025 4026 if (m_nLeft > rcWorkArea.left + 2) 4027 m_dwTipbarWndFlags &= ~0x200000; 4028 else 4029 m_dwTipbarWndFlags |= 0x200000; 4030 4031 if ( m_nTop> rcWorkArea.top + 2 ) 4032 m_dwTipbarWndFlags &= ~0x40000; 4033 else 4034 m_dwTipbarWndFlags |= 0x40000; 4035 4036 if (m_nLeft + m_nWidth < rcWorkArea.right - 2) 4037 m_dwTipbarWndFlags &= ~0x100000; 4038 else 4039 m_dwTipbarWndFlags |= 0x100000; 4040 4041 if (m_nTop + m_nHeight < rcWorkArea.bottom - 2) 4042 m_dwTipbarWndFlags &= ~0x80000; 4043 else 4044 m_dwTipbarWndFlags |= 0x80000; 4045 } 4046 4047 /// @unimplemented 4048 void CTipbarWnd::CancelMenu() 4049 { 4050 } 4051 4052 BOOL CTipbarWnd::CheckExcludeCaptionButtonMode(LPRECT prc1, LPCRECT prc2) 4053 { 4054 return (prc1->top < prc2->top + 5) && (prc2->right <= prc1->right + (5 * m_ButtonWidth)); 4055 } 4056 4057 /// @unimplemented 4058 void CTipbarWnd::ClearLBItemList() 4059 { 4060 } 4061 4062 HFONT CTipbarWnd::CreateVerticalFont() 4063 { 4064 if (!m_hWnd) 4065 return NULL; 4066 4067 CUIFTheme theme; 4068 theme.m_iPartId = 1; 4069 theme.m_iStateId = 0; 4070 theme.m_pszClassList = L"TOOLBAR"; 4071 4072 LOGFONTW lf; 4073 if (FAILED(theme.InternalOpenThemeData(m_hWnd)) || 4074 FAILED(::GetThemeFont(theme.m_hTheme, NULL, theme.m_iPartId, 0, 210, &lf))) 4075 { 4076 ::GetObject(::GetStockObject(DEFAULT_GUI_FONT), sizeof(lf), &lf); 4077 } 4078 4079 lf.lfEscapement = lf.lfOrientation = 2700; 4080 lf.lfOutPrecision = OUT_TT_ONLY_PRECIS; 4081 4082 if (CheckEAFonts()) 4083 { 4084 WCHAR szText[LF_FACESIZE]; 4085 szText[0] = L'@'; 4086 StringCchCopyW(&szText[1], _countof(szText) - 1, lf.lfFaceName); 4087 StringCchCopyW(lf.lfFaceName, _countof(lf.lfFaceName), szText); 4088 } 4089 4090 return ::CreateFontIndirectW(&lf); 4091 } 4092 4093 void CTipbarWnd::UpdateVerticalFont() 4094 { 4095 if (m_dwTipbarWndFlags & 4) 4096 { 4097 if (m_hTextFont) 4098 { 4099 ::DeleteObject(m_hTextFont); 4100 SetFontToThis(NULL); 4101 m_hTextFont = NULL; 4102 } 4103 m_hTextFont = CreateVerticalFont(); 4104 SetFontToThis(m_hTextFont); 4105 } 4106 else 4107 { 4108 SetFontToThis(NULL); 4109 } 4110 } 4111 4112 /// @unimplemented 4113 void CTipbarWnd::ShowOverScreenSizeBalloon() 4114 { 4115 } 4116 4117 void CTipbarWnd::DestroyOverScreenSizeBalloon() 4118 { 4119 if (m_pBalloon) 4120 { 4121 if (::IsWindow(*m_pBalloon)) 4122 ::DestroyWindow(*m_pBalloon); 4123 delete m_pBalloon; 4124 m_pBalloon = NULL; 4125 } 4126 } 4127 4128 void CTipbarWnd::DestroyWnd() 4129 { 4130 if (::IsWindow(m_hWnd)) 4131 ::DestroyWindow(m_hWnd); 4132 } 4133 4134 /// @unimplemented 4135 HKL CTipbarWnd::GetFocusKeyboardLayout() 4136 { 4137 return NULL; 4138 } 4139 4140 /// @unimplemented 4141 void CTipbarWnd::KillOnTheadItemChangeTimer() 4142 { 4143 } 4144 4145 UINT_PTR CTipbarWnd::SetTimer(UINT_PTR nIDEvent, UINT uElapse) 4146 { 4147 if (::IsWindow(m_hWnd)) 4148 return ::SetTimer(m_hWnd, nIDEvent, uElapse, NULL); 4149 return 0; 4150 } 4151 4152 BOOL CTipbarWnd::KillTimer(UINT_PTR uIDEvent) 4153 { 4154 if (::IsWindow(m_hWnd)) 4155 return ::KillTimer(m_hWnd, uIDEvent); 4156 return FALSE; 4157 } 4158 4159 /// @unimplemented 4160 void CTipbarWnd::MoveToTray() 4161 { 4162 } 4163 4164 void CTipbarWnd::MyClientToScreen(LPPOINT lpPoint, LPRECT prc) 4165 { 4166 if (lpPoint) 4167 ::ClientToScreen(m_hWnd, lpPoint); 4168 4169 if (prc) 4170 { 4171 ::ClientToScreen(m_hWnd, (LPPOINT)prc); 4172 ::ClientToScreen(m_hWnd, (LPPOINT)&prc->right); 4173 } 4174 } 4175 4176 void CTipbarWnd::SavePosition() 4177 { 4178 CicRegKey regKey; 4179 if (regKey.Create(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\"))) 4180 { 4181 POINT pt = { 0, 0 }; 4182 ::ClientToScreen(m_hWnd, &pt); 4183 regKey.SetDword(TEXT("Left"), pt.x); 4184 regKey.SetDword(TEXT("Top"), pt.y); 4185 regKey.SetDword(TEXT("Vertical"), !!(m_dwTipbarWndFlags & 4)); 4186 } 4187 } 4188 4189 /// @unimplemented 4190 void CTipbarWnd::SetAlpha(BYTE bAlpha, BOOL bFlag) 4191 { 4192 } 4193 4194 BOOL CTipbarWnd::SetLangBand(BOOL bDeskBand, BOOL bFlag2) 4195 { 4196 if (bDeskBand == !!(m_dwShowType & TF_SFT_DESKBAND)) 4197 return TRUE; 4198 4199 BOOL ret = TRUE; 4200 HWND hwndTray = m_ShellWndThread.GetWndTray(); 4201 if (bFlag2 && hwndTray) 4202 { 4203 DWORD_PTR dwResult; 4204 HWND hImeWnd = ::ImmGetDefaultIMEWnd(hwndTray); 4205 if (hImeWnd) 4206 ::SendMessageTimeout(hImeWnd, WM_IME_SYSTEM, 0x24 - bDeskBand, (LPARAM)hwndTray, 4207 (SMTO_BLOCK | SMTO_ABORTIFHUNG), 5000, &dwResult); 4208 else 4209 ::SendMessageTimeout(hwndTray, 0x505, 0, bDeskBand, 4210 (SMTO_BLOCK | SMTO_ABORTIFHUNG), 5000, &dwResult); 4211 } 4212 else 4213 { 4214 ret = FALSE; 4215 } 4216 4217 if (!(m_dwTipbarWndFlags & 2)) 4218 { 4219 if (bDeskBand) 4220 { 4221 KillTimer(7); 4222 SetTimer(7, g_uTimerElapseSYSCOLORCHANGED); 4223 } 4224 } 4225 4226 return ret; 4227 } 4228 4229 void CTipbarWnd::SetMoveRect(INT X, INT Y, INT nWidth, INT nHeight) 4230 { 4231 if (m_dwTipbarWndFlags & 0x2) 4232 { 4233 m_nWidth = nWidth; 4234 m_nHeight = nHeight; 4235 return; 4236 } 4237 4238 ++m_bInCallOn; 4239 4240 m_dwTipbarWndFlags |= 0x400; 4241 4242 m_X = X; 4243 m_Y = Y; 4244 m_CX = nWidth; 4245 m_CY = nHeight; 4246 4247 RECT rc; 4248 SIZE size = { 0, 0 }; 4249 if (m_pWndFrame) 4250 { 4251 ::SetRect(&rc, 0, 0, nWidth - m_cxDlgFrameX2, nHeight - m_cyDlgFrameX2); 4252 m_pWndFrame->SetRect(&rc); 4253 m_pWndFrame->GetFrameSize(&size); 4254 } 4255 4256 if (m_pTipbarGripper) 4257 { 4258 if (m_dwTipbarWndFlags & 4) 4259 { 4260 INT GripperWidth = GetGripperWidth(); 4261 ::SetRect(&rc, size.cx, size.cy, nWidth - m_cxDlgFrameX2 - size.cx, size.cy + GripperWidth); 4262 } 4263 else 4264 { 4265 INT GripperWidth = GetGripperWidth(); 4266 INT y1 = nHeight - m_cyDlgFrameX2 - size.cy; 4267 ::SetRect(&rc, size.cx, size.cy, size.cx + GripperWidth, y1); 4268 } 4269 m_pTipbarGripper->SetRect(&rc); 4270 } 4271 4272 --m_bInCallOn; 4273 } 4274 4275 /// @unimplemented 4276 void CTipbarWnd::SetShowText(BOOL bShow) 4277 { 4278 } 4279 4280 void CTipbarWnd::SetShowTrayIcon(BOOL bShow) 4281 { 4282 if (m_dwTipbarWndFlags & 0x20) 4283 m_dwTipbarWndFlags &= ~0x20; 4284 else 4285 m_dwTipbarWndFlags |= 0x20; 4286 4287 if ((m_dwTipbarWndFlags & 0x20) && m_pFocusThread) 4288 { 4289 KillTimer(10); 4290 SetTimer(10, g_uTimerElapseMOVETOTRAY); 4291 } 4292 else if (g_pTrayIconWnd) 4293 { 4294 g_pTrayIconWnd->SetMainIcon(NULL); 4295 g_pTrayIconWnd->RemoveAllIcon(0); 4296 } 4297 } 4298 4299 /// @unimplemented 4300 void CTipbarWnd::ShowContextMenu(POINT pt, LPCRECT prc, BOOL bFlag) 4301 { 4302 } 4303 4304 void CTipbarWnd::StartBackToAlphaTimer() 4305 { 4306 UINT uTime = ::GetDoubleClickTime(); 4307 ::SetTimer(m_hWnd, 3, 3 * uTime, NULL); 4308 } 4309 4310 /// @unimplemented 4311 BOOL CTipbarWnd::StartDoAccDefaultActionTimer(CTipbarItem *pTarget) 4312 { 4313 return FALSE; 4314 } 4315 4316 void CTipbarWnd::StartModalInput(ITfLangBarEventSink *pSink, DWORD dwThreadId) 4317 { 4318 if (!m_pLangBarMgr) 4319 return; 4320 4321 m_pLangBarMgr->SetModalInput(pSink, dwThreadId, 0); 4322 if (g_pTrayIconWnd) 4323 m_pLangBarMgr->SetModalInput(pSink, g_pTrayIconWnd->m_dwTrayWndThreadId, 0); 4324 4325 DWORD dwCurThreadId = ::GetCurrentThreadId(); 4326 m_pLangBarMgr->SetModalInput(pSink, dwCurThreadId, 1); 4327 } 4328 4329 void CTipbarWnd::StopModalInput(DWORD dwThreadId) 4330 { 4331 if (!m_pLangBarMgr) 4332 return; 4333 4334 m_pLangBarMgr->SetModalInput(NULL, dwThreadId, 0); 4335 if (g_pTrayIconWnd) 4336 m_pLangBarMgr->SetModalInput(NULL, g_pTrayIconWnd->m_dwTrayWndThreadId, 0); 4337 4338 DWORD dwCurThreadId = ::GetCurrentThreadId(); 4339 m_pLangBarMgr->SetModalInput(NULL, dwCurThreadId, 0); 4340 } 4341 4342 /// @unimplemented 4343 CTipbarThread *CTipbarWnd::_CreateThread(DWORD dwThreadId) 4344 { 4345 return NULL; 4346 } 4347 4348 /// @unimplemented 4349 CTipbarThread *CTipbarWnd::_FindThread(DWORD dwThreadId) 4350 { 4351 return NULL; 4352 } 4353 4354 void CTipbarWnd::EnsureFocusThread() 4355 { 4356 if (m_pFocusThread) 4357 return; 4358 4359 if (m_dwTipbarWndFlags & 0x12000) 4360 return; 4361 4362 m_dwTipbarWndFlags |= 0x2000; 4363 4364 HWND hwndFore = ::GetForegroundWindow(); 4365 if (!hwndFore) 4366 return; 4367 4368 DWORD dwThreadId = ::GetWindowThreadProcessId(hwndFore, NULL); 4369 if (dwThreadId) 4370 OnSetFocus(dwThreadId); 4371 4372 m_dwTipbarWndFlags &= ~0x2000; 4373 } 4374 4375 /// @unimplemented 4376 HRESULT CTipbarWnd::SetFocusThread(CTipbarThread *pFocusThread) 4377 { 4378 return E_NOTIMPL; 4379 } 4380 4381 /// @unimplemented 4382 HRESULT CTipbarWnd::AttachFocusThread() 4383 { 4384 return E_NOTIMPL; 4385 } 4386 4387 void CTipbarWnd::RestoreLastFocus(DWORD *pdwThreadId, BOOL fPrev) 4388 { 4389 if (m_pLangBarMgr) 4390 m_pLangBarMgr->RestoreLastFocus(pdwThreadId, fPrev); 4391 } 4392 4393 void CTipbarWnd::CleanUpThreadPointer(CTipbarThread *pThread, BOOL bRemove) 4394 { 4395 if (bRemove) 4396 { 4397 ssize_t iItem = m_Threads.Find(pThread); 4398 if (iItem >= 0) 4399 m_Threads.Remove(iItem); 4400 } 4401 4402 if (pThread == m_pFocusThread) 4403 SetFocusThread(NULL); 4404 4405 if (pThread == m_pThread) 4406 m_pThread = NULL; 4407 4408 if (pThread == m_pUnknownThread) 4409 m_pUnknownThread = NULL; 4410 } 4411 4412 /// @unimplemented 4413 void CTipbarWnd::TerminateAllThreads(BOOL bFlag) 4414 { 4415 } 4416 4417 STDMETHODIMP CTipbarWnd::QueryInterface(REFIID riid, void **ppvObj) 4418 { 4419 if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_ITfLangBarEventSink)) 4420 { 4421 *ppvObj = this; 4422 AddRef(); 4423 return S_OK; 4424 } 4425 if (IsEqualIID(riid, IID_ITfLangBarEventSink_P)) 4426 { 4427 *ppvObj = static_cast<ITfLangBarEventSink_P*>(this); 4428 AddRef(); 4429 return S_OK; 4430 } 4431 return E_NOINTERFACE; 4432 } 4433 4434 STDMETHODIMP_(ULONG) CTipbarWnd::AddRef() 4435 { 4436 return ++m_cRefs; 4437 } 4438 4439 STDMETHODIMP_(ULONG) CTipbarWnd::Release() 4440 { 4441 if (--m_cRefs == 0) 4442 { 4443 delete this; 4444 return 0; 4445 } 4446 return m_cRefs; 4447 } 4448 4449 /// @unimplemented 4450 STDMETHODIMP CTipbarWnd::OnSetFocus(DWORD dwThreadId) 4451 { 4452 return E_NOTIMPL; 4453 } 4454 4455 STDMETHODIMP CTipbarWnd::OnThreadTerminate(DWORD dwThreadId) 4456 { 4457 HRESULT hr; 4458 ++m_bInCallOn; 4459 AddRef(); 4460 { 4461 hr = OnThreadTerminateInternal(dwThreadId); 4462 if (!m_pFocusThread) 4463 EnsureFocusThread(); 4464 } 4465 --m_bInCallOn; 4466 Release(); 4467 return hr; 4468 } 4469 4470 /// @unimplemented 4471 HRESULT CTipbarWnd::OnThreadTerminateInternal(DWORD dwThreadId) 4472 { 4473 return E_NOTIMPL; 4474 } 4475 4476 /// @unimplemented 4477 STDMETHODIMP CTipbarWnd::OnThreadItemChange(DWORD dwThreadId) 4478 { 4479 return E_NOTIMPL; 4480 } 4481 4482 STDMETHODIMP CTipbarWnd::OnModalInput(DWORD dwThreadId, UINT uMsg, WPARAM wParam, LPARAM lParam) 4483 { 4484 switch (uMsg) 4485 { 4486 case WM_NCLBUTTONDOWN: 4487 case WM_NCRBUTTONDOWN: 4488 case WM_NCMBUTTONDOWN: 4489 case WM_LBUTTONUP: 4490 case WM_RBUTTONUP: 4491 case WM_MBUTTONUP: 4492 break; 4493 4494 case WM_NCLBUTTONUP: 4495 case WM_NCRBUTTONUP: 4496 case WM_NCMBUTTONUP: 4497 if (m_pThread) 4498 { 4499 CUTBMenuWnd *pMenuUI = m_pModalMenu->m_pMenuUI; 4500 if (pMenuUI) 4501 { 4502 HWND hWnd = *pMenuUI; 4503 if (hWnd) 4504 { 4505 POINT pt = { (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam) }; 4506 ::ScreenToClient(hWnd, &pt); 4507 uMsg += WM_LBUTTONUP - WM_NCLBUTTONUP; 4508 ::PostMessage(m_hWnd, uMsg, wParam, MAKELPARAM(pt.x, pt.y)); 4509 } 4510 } 4511 } 4512 break; 4513 4514 default: 4515 { 4516 if (uMsg == WM_KEYDOWN || uMsg == WM_KEYUP) 4517 { 4518 if (m_pThread) 4519 m_pModalMenu->PostKey(uMsg == WM_KEYUP, wParam, lParam); 4520 } 4521 else 4522 { 4523 CancelMenu(); 4524 } 4525 break; 4526 } 4527 } 4528 4529 return 0; 4530 } 4531 4532 /// @unimplemented 4533 STDMETHODIMP CTipbarWnd::ShowFloating(DWORD dwFlags) 4534 { 4535 return E_NOTIMPL; 4536 } 4537 4538 /// @unimplemented 4539 STDMETHODIMP CTipbarWnd::GetItemFloatingRect(DWORD dwThreadId, REFGUID rguid, RECT *prc) 4540 { 4541 return E_NOTIMPL; 4542 } 4543 4544 /// @unimplemented 4545 STDMETHODIMP CTipbarWnd::OnLangBarUpdate(TfLBIClick click, BOOL bFlag) 4546 { 4547 return E_NOTIMPL; 4548 } 4549 4550 STDMETHODIMP_(BSTR) CTipbarWnd::GetAccName() 4551 { 4552 WCHAR szText[256]; 4553 ::LoadStringW(g_hInst, IDS_LANGUAGEBAR, szText, _countof(szText)); 4554 return ::SysAllocString(szText); 4555 } 4556 4557 STDMETHODIMP_(void) CTipbarWnd::GetAccLocation(LPRECT lprc) 4558 { 4559 GetRect(lprc); 4560 } 4561 4562 /// @unimplemented 4563 STDMETHODIMP_(void) CTipbarWnd::PaintObject(HDC hDC, LPCRECT prc) 4564 { 4565 } 4566 4567 STDMETHODIMP_(DWORD) CTipbarWnd::GetWndStyle() 4568 { 4569 return CUIFWindow::GetWndStyle() & ~WS_BORDER; 4570 } 4571 4572 STDMETHODIMP_(void) CTipbarWnd::Move(INT x, INT y, INT nWidth, INT nHeight) 4573 { 4574 CUIFWindow::Move(x, y, nWidth, nHeight); 4575 } 4576 4577 STDMETHODIMP_(void) CTipbarWnd::OnMouseOutFromWindow(LONG x, LONG y) 4578 { 4579 StartBackToAlphaTimer(); 4580 if ((m_dwTipbarWndFlags & 0x40) && (m_dwTipbarWndFlags & 0x80)) 4581 SetTimer(2, g_uTimerElapseSTUBEND); 4582 } 4583 4584 /// @unimplemented 4585 STDMETHODIMP_(void) CTipbarWnd::OnCreate(HWND hWnd) 4586 { 4587 } 4588 4589 STDMETHODIMP_(void) CTipbarWnd::OnDestroy(HWND hWnd) 4590 { 4591 CancelMenu(); 4592 4593 if (m_pTipbarAccessible) 4594 m_pTipbarAccessible->NotifyWinEvent(EVENT_OBJECT_DESTROY, GetAccItem()); 4595 4596 OnTerminateToolbar(); 4597 if (m_pTipbarAccessible) 4598 { 4599 m_pTipbarAccessible->ClearAccItems(); 4600 m_pTipbarAccessible->Release(); 4601 m_pTipbarAccessible = NULL; 4602 } 4603 4604 m_coInit.CoUninit(); 4605 4606 if (m_pLangBarMgr) 4607 m_pLangBarMgr->UnAdviseEventSink(m_dwSinkCookie); 4608 } 4609 4610 /// @unimplemented 4611 STDMETHODIMP_(void) CTipbarWnd::OnTimer(WPARAM wParam) 4612 { 4613 } 4614 4615 STDMETHODIMP_(void) CTipbarWnd::OnSysColorChange() 4616 { 4617 KillTimer(7); 4618 SetTimer(7, g_uTimerElapseSYSCOLORCHANGED); 4619 } 4620 4621 void CTipbarWnd::OnTerminateToolbar() 4622 { 4623 m_dwTipbarWndFlags |= 0x10000; 4624 DestroyOverScreenSizeBalloon(); 4625 TerminateAllThreads(TRUE); 4626 if (!(m_dwTipbarWndFlags & 0x2)) 4627 SavePosition(); 4628 } 4629 4630 STDMETHODIMP_(void) CTipbarWnd::OnEndSession(HWND hWnd, WPARAM wParam, LPARAM lParam) 4631 { 4632 if (!g_bWinLogon) 4633 OnTerminateToolbar(); 4634 4635 if (wParam) // End session? 4636 { 4637 if (lParam & ENDSESSION_LOGOFF) 4638 { 4639 KillTimer(9); 4640 Show(FALSE); 4641 } 4642 else 4643 { 4644 OnTerminateToolbar(); 4645 4646 AddRef(); 4647 ::DestroyWindow(hWnd); 4648 Release(); 4649 } 4650 } 4651 } 4652 4653 STDMETHODIMP_(void) CTipbarWnd::OnUser(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 4654 { 4655 if (uMsg == WM_USER + 1) 4656 { 4657 POINT pt = { (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam) }; 4658 ::ClientToScreen(m_hWnd, &pt); 4659 ShowContextMenu(pt, NULL, TRUE); 4660 } 4661 else if (uMsg == g_wmTaskbarCreated) 4662 { 4663 m_ShellWndThread.clear(); 4664 } 4665 } 4666 4667 /// @unimplemented 4668 STDMETHODIMP_(LRESULT) 4669 CTipbarWnd::OnWindowPosChanged(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 4670 { 4671 return 0; 4672 } 4673 4674 STDMETHODIMP_(LRESULT) 4675 CTipbarWnd::OnWindowPosChanging(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 4676 { 4677 LPWINDOWPOS pWP = (LPWINDOWPOS)lParam; 4678 if (!(pWP->flags & SWP_NOZORDER)) 4679 { 4680 if (!m_pThread && (!m_pToolTip || !m_pToolTip->m_bShowToolTip)) 4681 pWP->hwndInsertAfter = NULL; 4682 } 4683 return ::DefWindowProc(hWnd, uMsg, wParam, lParam); 4684 } 4685 4686 STDMETHODIMP_(LRESULT) 4687 CTipbarWnd::OnShowWindow(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 4688 { 4689 if (m_pTipbarAccessible) 4690 { 4691 if (wParam) // Show? 4692 { 4693 m_pTipbarAccessible->NotifyWinEvent(EVENT_OBJECT_SHOW, GetAccItem()); 4694 m_pTipbarAccessible->NotifyWinEvent(EVENT_OBJECT_FOCUS, GetAccItem()); 4695 } 4696 else 4697 { 4698 m_pTipbarAccessible->NotifyWinEvent(EVENT_OBJECT_HIDE, GetAccItem()); 4699 } 4700 } 4701 return ::DefWindowProc(hWnd, uMsg, wParam, lParam); 4702 } 4703 4704 STDMETHODIMP_(LRESULT) 4705 CTipbarWnd::OnSettingChange(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 4706 { 4707 if (!wParam || wParam == SPI_SETNONCLIENTMETRICS || wParam == SPI_SETHIGHCONTRAST) 4708 { 4709 KillTimer(7); 4710 SetTimer(7, g_uTimerElapseSYSCOLORCHANGED); 4711 } 4712 return 0; 4713 } 4714 4715 STDMETHODIMP_(LRESULT) 4716 CTipbarWnd::OnDisplayChange(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 4717 { 4718 if (!(m_dwTipbarWndFlags & 2)) 4719 { 4720 KillTimer(12); 4721 SetTimer(12, g_uTimerElapseDISPLAYCHANGE); 4722 } 4723 return ::DefWindowProc(hWnd, uMsg, wParam, lParam); 4724 } 4725 4726 STDMETHODIMP_(HRESULT) 4727 CTipbarWnd::OnGetObject(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 4728 { 4729 if (lParam != -4) 4730 return S_OK; 4731 if (!m_pTipbarAccessible) 4732 return E_OUTOFMEMORY; 4733 4734 if (m_pTipbarAccessible->m_bInitialized) 4735 return m_pTipbarAccessible->CreateRefToAccObj(wParam); 4736 4737 HRESULT hr = S_OK; 4738 if (SUCCEEDED(m_coInit.EnsureCoInit())) 4739 { 4740 hr = m_pTipbarAccessible->Initialize(); 4741 if (FAILED(hr)) 4742 { 4743 m_pTipbarAccessible->Release(); 4744 m_pTipbarAccessible = NULL; 4745 return hr; 4746 } 4747 4748 m_pTipbarAccessible->NotifyWinEvent(EVENT_OBJECT_CREATE, GetAccItem()); 4749 return m_pTipbarAccessible->CreateRefToAccObj(wParam); 4750 } 4751 4752 return hr; 4753 } 4754 4755 STDMETHODIMP_(BOOL) CTipbarWnd::OnEraseBkGnd(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 4756 { 4757 return TRUE; 4758 } 4759 4760 STDMETHODIMP_(void) CTipbarWnd::OnThemeChanged(HWND hWnd, WPARAM wParam, LPARAM lParam) 4761 { 4762 CUIFWindow::OnThemeChanged(hWnd, wParam, lParam); 4763 } 4764 4765 /// @unimplemented 4766 STDMETHODIMP_(void) CTipbarWnd::UpdateUI(LPCRECT prc) 4767 { 4768 } 4769 4770 /// @unimplemented 4771 STDMETHODIMP_(void) CTipbarWnd::HandleMouseMsg(UINT uMsg, LONG x, LONG y) 4772 { 4773 } 4774 4775 /*********************************************************************** 4776 * GetTipbarInternal 4777 */ 4778 BOOL GetTipbarInternal(HWND hWnd, DWORD dwFlags, CDeskBand *pDeskBand) 4779 { 4780 BOOL bParent = !!(dwFlags & 0x80000000); 4781 g_bWinLogon = !!(dwFlags & 0x1); 4782 4783 InitFromReg(); 4784 4785 if (!g_bShowTipbar) 4786 return FALSE; 4787 4788 if (bParent) 4789 { 4790 g_pTrayIconWnd = new(cicNoThrow) CTrayIconWnd(); 4791 if (!g_pTrayIconWnd) 4792 return FALSE; 4793 g_pTrayIconWnd->CreateWnd(); 4794 } 4795 4796 g_pTipbarWnd = new(cicNoThrow) CTipbarWnd(bParent ? g_dwWndStyle : g_dwChildWndStyle); 4797 if (!g_pTipbarWnd || !g_pTipbarWnd->Initialize()) 4798 return FALSE; 4799 4800 g_pTipbarWnd->Init(!bParent, pDeskBand); 4801 g_pTipbarWnd->CreateWnd(hWnd); 4802 4803 ::SetWindowText(*g_pTipbarWnd, TEXT("TF_FloatingLangBar_WndTitle")); 4804 4805 DWORD dwOldStatus = 0; 4806 if (!bParent) 4807 { 4808 g_pTipbarWnd->m_pLangBarMgr->GetPrevShowFloatingStatus(&dwOldStatus); 4809 g_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_DESKBAND); 4810 } 4811 4812 DWORD dwStatus; 4813 g_pTipbarWnd->m_pLangBarMgr->GetShowFloatingStatus(&dwStatus); 4814 g_pTipbarWnd->ShowFloating(dwStatus); 4815 4816 if (!bParent && (dwOldStatus & TF_SFT_DESKBAND)) 4817 g_pTipbarWnd->m_dwTipbarWndFlags |= 0x4000; 4818 4819 g_hwndParent = hWnd; 4820 return TRUE; 4821 } 4822 4823 /*********************************************************************** 4824 * GetLibTls (MSUTB.@) 4825 * 4826 * @unimplemented 4827 */ 4828 EXTERN_C LPVOID WINAPI 4829 GetLibTls(VOID) 4830 { 4831 FIXME("stub:()\n"); 4832 return NULL; 4833 } 4834 4835 /*********************************************************************** 4836 * GetPopupTipbar (MSUTB.@) 4837 * 4838 * @implemented 4839 */ 4840 EXTERN_C BOOL WINAPI 4841 GetPopupTipbar(HWND hWnd, BOOL fWinLogon) 4842 { 4843 TRACE("(%p, %d)\n", hWnd, fWinLogon); 4844 4845 if (!fWinLogon) 4846 TurnOffSpeechIfItsOn(); 4847 4848 return GetTipbarInternal(hWnd, fWinLogon | 0x80000000, NULL); 4849 } 4850 4851 /*********************************************************************** 4852 * SetRegisterLangBand (MSUTB.@) 4853 * 4854 * @implemented 4855 */ 4856 EXTERN_C HRESULT WINAPI 4857 SetRegisterLangBand(BOOL bRegister) 4858 { 4859 TRACE("(%d)\n", bRegister); 4860 4861 if (!(g_dwOSInfo & CIC_OSINFO_XPPLUS)) // Desk band is for XP+ 4862 return E_FAIL; 4863 4864 BOOL bDeskBand = IsDeskBandFromReg(); 4865 if (bDeskBand == bRegister) 4866 return S_OK; 4867 4868 SetDeskBandToReg(bRegister); 4869 4870 if (!RegisterComCat(CLSID_MSUTBDeskBand, CATID_DeskBand, bRegister)) 4871 return TF_E_NOLOCK; 4872 4873 return S_OK; 4874 } 4875 4876 /*********************************************************************** 4877 * ClosePopupTipbar (MSUTB.@) 4878 * 4879 * @implemented 4880 */ 4881 EXTERN_C VOID WINAPI 4882 ClosePopupTipbar(VOID) 4883 { 4884 TRACE("()\n"); 4885 4886 if (g_fInClosePopupTipbar) 4887 return; 4888 4889 g_fInClosePopupTipbar = TRUE; 4890 4891 if (g_pTipbarWnd) 4892 { 4893 g_pTipbarWnd->m_pDeskBand = NULL; 4894 g_pTipbarWnd->DestroyWnd(); 4895 g_pTipbarWnd->Release(); 4896 g_pTipbarWnd = NULL; 4897 } 4898 4899 if (g_pTrayIconWnd) 4900 { 4901 g_pTrayIconWnd->DestroyWnd(); 4902 delete g_pTrayIconWnd; 4903 g_pTrayIconWnd = NULL; 4904 } 4905 4906 UninitSkipRedrawHKLArray(); 4907 4908 g_fInClosePopupTipbar = FALSE; 4909 } 4910 4911 /*********************************************************************** 4912 * DllRegisterServer (MSUTB.@) 4913 * 4914 * @implemented 4915 */ 4916 STDAPI DllRegisterServer(VOID) 4917 { 4918 TRACE("()\n"); 4919 return gModule.DllRegisterServer(FALSE); 4920 } 4921 4922 /*********************************************************************** 4923 * DllUnregisterServer (MSUTB.@) 4924 * 4925 * @implemented 4926 */ 4927 STDAPI DllUnregisterServer(VOID) 4928 { 4929 TRACE("()\n"); 4930 return gModule.DllUnregisterServer(FALSE); 4931 } 4932 4933 /*********************************************************************** 4934 * DllCanUnloadNow (MSUTB.@) 4935 * 4936 * @implemented 4937 */ 4938 STDAPI DllCanUnloadNow(VOID) 4939 { 4940 TRACE("()\n"); 4941 return gModule.DllCanUnloadNow() && (g_DllRefCount == 0); 4942 } 4943 4944 /*********************************************************************** 4945 * DllGetClassObject (MSUTB.@) 4946 * 4947 * @implemented 4948 */ 4949 STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) 4950 { 4951 TRACE("()\n"); 4952 return gModule.DllGetClassObject(rclsid, riid, ppv); 4953 } 4954 4955 /// @implemented 4956 HRESULT APIENTRY 4957 MsUtbCoCreateInstance( 4958 REFCLSID rclsid, 4959 LPUNKNOWN pUnkOuter, 4960 DWORD dwClsContext, 4961 REFIID iid, 4962 LPVOID *ppv) 4963 { 4964 if (IsEqualCLSID(rclsid, CLSID_TF_CategoryMgr)) 4965 return TF_CreateCategoryMgr((ITfCategoryMgr**)ppv); 4966 if (IsEqualCLSID(rclsid, CLSID_TF_DisplayAttributeMgr)) 4967 return TF_CreateDisplayAttributeMgr((ITfDisplayAttributeMgr **)ppv); 4968 return cicRealCoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, ppv); 4969 } 4970 4971 /// @implemented 4972 BOOL ProcessAttach(HINSTANCE hinstDLL) 4973 { 4974 ::InitializeCriticalSectionAndSpinCount(&g_cs, 0); 4975 4976 g_hInst = hinstDLL; 4977 4978 cicGetOSInfo(&g_uACP, &g_dwOSInfo); 4979 4980 TFInitLib(MsUtbCoCreateInstance); 4981 cicInitUIFLib(); 4982 4983 CTrayIconWnd::RegisterClass(); 4984 4985 g_wmTaskbarCreated = RegisterWindowMessageW(L"TaskbarCreated"); 4986 4987 gModule.Init(ObjectMap, hinstDLL, NULL); 4988 ::DisableThreadLibraryCalls(hinstDLL); 4989 4990 return TRUE; 4991 } 4992 4993 /// @implemented 4994 VOID ProcessDetach(HINSTANCE hinstDLL) 4995 { 4996 cicDoneUIFLib(); 4997 TFUninitLib(); 4998 ::DeleteCriticalSection(&g_cs); 4999 gModule.Term(); 5000 } 5001 5002 /// @implemented 5003 EXTERN_C BOOL WINAPI 5004 DllMain( 5005 _In_ HINSTANCE hinstDLL, 5006 _In_ DWORD dwReason, 5007 _Inout_opt_ LPVOID lpvReserved) 5008 { 5009 switch (dwReason) 5010 { 5011 case DLL_PROCESS_ATTACH: 5012 { 5013 TRACE("(%p, %lu, %p)\n", hinstDLL, dwReason, lpvReserved); 5014 if (!ProcessAttach(hinstDLL)) 5015 { 5016 ProcessDetach(hinstDLL); 5017 return FALSE; 5018 } 5019 break; 5020 } 5021 case DLL_PROCESS_DETACH: 5022 { 5023 ProcessDetach(hinstDLL); 5024 break; 5025 } 5026 } 5027 return TRUE; 5028 } 5029