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