ReactOS 0.4.15-dev-7934-g1dc8d80
msutb.cpp
Go to the documentation of this file.
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
11
12//#define ENABLE_DESKBAND
13
14typedef struct LANGBARITEMSTATE
15{
22
24 {
25 return m_dwDemoteLevel < 2;
26 }
28
39#ifdef ENABLE_DESKBAND
41#else
43#endif
44
51UINT g_uTimeOutIntentional = 10 * 60 * 1000;
52UINT g_uTimeOutMax = 60 * 60 * 1000;
54POINT g_ptTipbar = { -1, -1 };
81
82#define TIMER_ID_DOACCDEFAULTACTION 11
83
85{
86 ERR("__cxa_pure_virtual\n");
87}
88
89class CMsUtbModule : public CComModule
90{
91};
92
94
95class CCicLibMenuItem;
96class CTipbarAccItem;
97class CUTBMenuItem;
98class CMainIconItem;
99class CTrayIconItem;
100class CTipbarWnd;
101class CButtonIconItem;
102class CTrayIconWnd;
103
106
108
110{
112 return FALSE; // Japanese HKL will be skipped
114 return FALSE;
115
116 for (size_t iItem = 0; iItem < g_prghklSkipRedrawing->size(); ++iItem)
117 {
118 if ((*g_prghklSkipRedrawing)[iItem] == hSkipKL)
119 return TRUE; // To be skipped
120 }
121
122 return FALSE; // To be not skipped
123}
124
126{
127 LOCALESIGNATURE Sig;
129 if (!LangID)
130 return FALSE;
131
132 INT size = sizeof(Sig) / sizeof(WCHAR);
134 return FALSE;
135 return (Sig.lsUsb[3] & 0x8000000) != 0;
136}
137
139{
140 LOCALESIGNATURE Sig;
141 INT size = sizeof(Sig) / sizeof(WCHAR);
143 return FALSE;
144
145 HDC hDC = ::GetDC(hWnd);
147 CHARSETINFO CharSetInfo;
150
151 return !!(CharSetInfo.fs.fsCsb[0] & Sig.lsCsbSupported[0]);
152}
153
155{
158 return;
159
161 {
162 // Japanese IME will be skipped
163 g_prghklSkipRedrawing->Add((HKL)UlongToHandle(0xE0010411));
164 }
165
166 CicRegKey regKey;
168 TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\SkipRedrawHKL"));
169 if (error != ERROR_SUCCESS)
170 return;
171
172 TCHAR szValueName[256];
173 for (DWORD dwIndex = 0; ; ++dwIndex)
174 {
175 error = regKey.EnumValue(dwIndex, szValueName, _countof(szValueName));
176 if (error != ERROR_SUCCESS)
177 break;
178
179 if (szValueName[0] == TEXT('0') &&
180 (szValueName[1] == TEXT('x') || szValueName[1] == TEXT('X')))
181 {
182 HKL hKL = (HKL)UlongToHandle(_tcstoul(szValueName, NULL, 16));
183 g_prghklSkipRedrawing->Add(hKL); // This hKL will be skipped
184 }
185 }
186}
187
189{
191 {
194 }
195}
196
198{
201 if (FAILED(hr))
202 return hr;
203
204 if (!pCompMgr)
205 return E_FAIL;
206
207 hr = pCompMgr->GetCompartment(rguid, ppComp);
208 pCompMgr->Release();
209 return hr;
210}
211
213{
214 *pdwValue = 0;
215 ITfCompartment *pComp;
216 HRESULT hr = GetGlobalCompartment(rguid, &pComp);
217 if (SUCCEEDED(hr))
218 {
219 VARIANT vari;
220 hr = pComp->GetValue(&vari);
221 if (hr == S_OK)
222 *pdwValue = V_I4(&vari);
223 pComp->Release();
224 }
225 return hr;
226}
227
229{
230 VARIANT vari;
231 ITfCompartment *pComp;
232 HRESULT hr = GetGlobalCompartment(rguid, &pComp);
233 if (SUCCEEDED(hr))
234 {
235 V_VT(&vari) = VT_I4;
236 V_I4(&vari) = dwValue;
237 hr = pComp->SetValue(0, &vari);
238 pComp->Release();
239 }
240 return hr;
241}
242
244{
245 DWORD dwValue = 0;
247 if (SUCCEEDED(hr) && dwValue)
249}
250
252{
253 ITfLangBarMgr *pLangBarMgr = NULL;
254 HRESULT hr = TF_CreateLangBarMgr(&pLangBarMgr);
255 if (FAILED(hr))
256 return;
257
258 if (pLangBarMgr)
259 {
260 hr = pLangBarMgr->ShowFloating(TF_SFT_HIDDEN);
261 pLangBarMgr->Release();
262 }
263
264 if (SUCCEEDED(hr))
266
267 CicRegKey regKey;
269 TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Run"),
271 if (error == ERROR_SUCCESS)
272 ::RegDeleteValue(regKey, TEXT("ctfmon.exe"));
273}
274
276{
277 HKL hGotKL;
278
279 INT iKL, cKLs = TF_MlngInfoCount();
280 for (iKL = 0; iKL < cKLs; ++iKL)
281 {
282 if (TF_GetMlngHKL(iKL, &hGotKL, NULL, 0) && hKL == hGotKL)
283 return TF_GetMlngIconIndex(iKL);
284 }
285
286 if (!TF_GetMlngHKL(0, &hGotKL, NULL, 0))
287 return -1;
288
289 return TF_GetMlngIconIndex(0);
290}
291
292BOOL GethKLDesc(_In_ HKL hKL, _Out_ LPWSTR pszDesc, _In_ UINT cchDesc)
293{
294 HKL hGotKL;
295
296 INT iKL, cKLs = TF_MlngInfoCount();
297 for (iKL = 0; iKL < cKLs; ++iKL)
298 {
299 if (TF_GetMlngHKL(iKL, &hGotKL, pszDesc, cchDesc) && hKL == hGotKL)
300 return TRUE;
301 }
302
303 return TF_GetMlngHKL(0, &hGotKL, pszDesc, cchDesc);
304}
305
308 _In_ ITfMenu *pMenu,
309 _In_ UINT uId,
310 _In_ LPCWSTR pszText,
311 _In_ BOOL bChecked,
313{
314 HBITMAP hbmp = NULL, hbmpMask = NULL;
315 if (hIcon)
316 {
318 SIZE iconSize = { 16, 16 };
319 if (!hIconNew)
320 hIconNew = hIcon;
321 if (!cicGetIconBitmaps(hIconNew, &hbmp, &hbmpMask, &iconSize))
322 return E_FAIL;
323 if (hIconNew)
324 ::DestroyIcon(hIconNew);
326 }
327
328 INT cchText = lstrlenW(pszText);
329 DWORD dwFlags = (bChecked ? TF_LBMENUF_CHECKED : 0);
330 return pMenu->AddMenuItem(uId, dwFlags, hbmp, hbmpMask, pszText, cchText, NULL);
331}
332
334{
335 return pMenu->AddMenuItem(-1, TF_LBMENUF_SEPARATOR, NULL, NULL, NULL, 0, NULL);
336}
337
338// Is it a Far-East language ID?
340{
341 switch (LangID)
342 {
343 case MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED): // Chinese (Simplified)
344 case MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL): // Chinese (Traditional)
345 case MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT): // Japanese
346 case MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT): // Korean
347 return TRUE;
348 default:
349 return FALSE;
350 }
351}
352
354{
355 BOOL ret = FALSE;
356 ITfInputProcessorProfiles *pProfiles = NULL;
357 LANGID *pLangIds = NULL;
358 ULONG iItem, cItems;
359
361 return FALSE;
362
364 return TRUE;
365
367 SUCCEEDED(pProfiles->GetLanguageList(&pLangIds, &cItems)))
368 {
369 for (iItem = 0; iItem < cItems; ++iItem)
370 {
371 if (IsFELangId(pLangIds[iItem]))
372 break;
373 }
374
375 ret = (iItem == cItems);
376 }
377
378 if (pLangIds)
379 CoTaskMemFree(pLangIds);
380 if (pProfiles)
381 pProfiles->Release();
382
383 return ret;
384}
385
388{
389 return FALSE;
390}
391
392static INT CALLBACK
394{
395 if ((nFontType != TRUETYPE_FONTTYPE) || (pLF->elfLogFont.lfFaceName[0] != '@'))
396 return TRUE;
397 *(BOOL*)lParam = TRUE;
398 return FALSE;
399}
400
403{
404 BOOL bHasVertical = FALSE;
405 HDC hDC = ::GetDC(NULL);
408 return bHasVertical;
409}
410
412{
413 if (!g_bEnableDeskBand || !(g_dwOSInfo & CIC_OSINFO_XPPLUS)) // Desk band is for XP+
414 return FALSE;
415
416 CicRegKey regKey;
417 if (regKey.Open(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\")))
418 {
419 DWORD dwValue = 0;
420 regKey.QueryDword(TEXT("ShowDeskBand"), &dwValue);
421 return !!dwValue;
422 }
423
424 return FALSE;
425}
426
428{
429 CicRegKey regKey;
430 if (regKey.Open(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\"), KEY_ALL_ACCESS))
431 regKey.SetDword(TEXT("ShowDeskBand"), bShow);
432}
433
434BOOL RegisterComCat(REFCLSID rclsid, REFCATID rcatid, BOOL bRegister)
435{
437 return FALSE;
438
439 ICatRegister *pCat;
440 HRESULT hr = ::CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER,
441 IID_ICatRegister, (void**)&pCat);
442 if (SUCCEEDED(hr))
443 {
444 if (bRegister)
445 hr = pCat->RegisterClassImplCategories(rclsid, 1, const_cast<CATID*>(&rcatid));
446 else
447 hr = pCat->UnRegisterClassImplCategories(rclsid, 1, const_cast<CATID*>(&rcatid));
448
449 pCat->Release();
450 }
451
453
454 //if (IsIE5())
455 // ::RegDeleteKey(HKEY_CLASSES_ROOT, TEXT("Component Categories\\{00021492-0000-0000-C000-000000000046}\\Enum"));
456
457 return SUCCEEDED(hr);
458}
459
461{
462 DWORD dwValue;
464
465 CicRegKey regKey1;
466 error = regKey1.Open(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\"));
467 if (error == ERROR_SUCCESS)
468 {
469 error = regKey1.QueryDword(TEXT("ShowTipbar"), &dwValue);
470 if (error == ERROR_SUCCESS)
471 g_bShowTipbar = !!dwValue;
472 }
473
474 CicRegKey regKey2;
475 error = regKey2.Open(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\"));
476 if (error == ERROR_SUCCESS)
477 {
478 error = regKey2.QueryDword(TEXT("ShowDebugMenu"), &dwValue);
479 if (error == ERROR_SUCCESS)
480 g_bShowDebugMenu = !!dwValue;
481 error = regKey2.QueryDword(TEXT("NewLook"), &dwValue);
482 if (error == ERROR_SUCCESS)
483 g_bNewLook = !!dwValue;
484 error = regKey2.QueryDword(TEXT("IntelliSense"), &dwValue);
485 if (error == ERROR_SUCCESS)
486 g_bIntelliSense = !!dwValue;
487 error = regKey2.QueryDword(TEXT("ShowCloseMenu"), &dwValue);
488 if (error == ERROR_SUCCESS)
489 g_bShowCloseMenu = !!dwValue;
490 error = regKey2.QueryDword(TEXT("TimeOutNonIntentional"), &dwValue);
491 if (error == ERROR_SUCCESS)
492 g_uTimeOutNonIntentional = 1000 * dwValue;
493 error = regKey2.QueryDword(TEXT("TimeOutIntentional"), &dwValue);
494 if (error == ERROR_SUCCESS)
495 {
496 g_uTimeOutIntentional = 1000 * dwValue;
497 g_uTimeOutMax = 6000 * dwValue;
498 }
499 error = regKey2.QueryDword(TEXT("ShowMinimizedBalloon"), &dwValue);
500 if (error == ERROR_SUCCESS)
501 g_bShowMinimizedBalloon = !!dwValue;
502 error = regKey2.QueryDword(TEXT("Left"), &dwValue);
503 if (error == ERROR_SUCCESS)
504 g_ptTipbar.x = dwValue;
505 error = regKey2.QueryDword(TEXT("Top"), &dwValue);
506 if (error == ERROR_SUCCESS)
507 g_ptTipbar.y = dwValue;
508 error = regKey2.QueryDword(TEXT("ExcludeCaptionButtons"), &dwValue);
509 if (error == ERROR_SUCCESS)
510 g_bExcludeCaptionButtons = !!dwValue;
511 error = regKey2.QueryDword(TEXT("ShowShadow"), &dwValue);
512 if (error == ERROR_SUCCESS)
513 g_bShowShadow = !!dwValue;
514 error = regKey2.QueryDword(TEXT("TaskbarTheme"), &dwValue);
515 if (error == ERROR_SUCCESS)
516 g_fTaskbarTheme = !!dwValue;
517 error = regKey2.QueryDword(TEXT("Vertical"), &dwValue);
518 if (error == ERROR_SUCCESS)
519 g_fVertical = !!dwValue;
520 error = regKey2.QueryDword(TEXT("TimerElapseSTUBSTART"), &dwValue);
521 if (error == ERROR_SUCCESS)
522 g_uTimerElapseSTUBSTART = dwValue;
523 error = regKey2.QueryDword(TEXT("TimerElapseSTUBEND"), &dwValue);
524 if (error == ERROR_SUCCESS)
525 g_uTimerElapseSTUBEND = dwValue;
526 error = regKey2.QueryDword(TEXT("TimerElapseBACKTOALPHA"), &dwValue);
527 if (error == ERROR_SUCCESS)
529 error = regKey2.QueryDword(TEXT("TimerElapseONTHREADITEMCHANGE"), &dwValue);
530 if (error == ERROR_SUCCESS)
532 error = regKey2.QueryDword(TEXT("TimerElapseSETWINDOWPOS"), &dwValue);
533 if (error == ERROR_SUCCESS)
535 error = regKey2.QueryDword(TEXT("TimerElapseONUPDATECALLED"), &dwValue);
536 if (error == ERROR_SUCCESS)
538 error = regKey2.QueryDword(TEXT("TimerElapseSYSCOLORCHANGED"), &dwValue);
539 if (error == ERROR_SUCCESS)
541 error = regKey2.QueryDword(TEXT("TimerElapseDISPLAYCHANGE"), &dwValue);
542 if (error == ERROR_SUCCESS)
544 error = regKey2.QueryDword(TEXT("TimerElapseUPDATEUI"), &dwValue);
545 if (error == ERROR_SUCCESS)
546 g_uTimerElapseUPDATEUI = dwValue;
547 error = regKey2.QueryDword(TEXT("TimerElapseSHOWWINDOW"), &dwValue);
548 if (error == ERROR_SUCCESS)
549 g_uTimerElapseSHOWWINDOW = dwValue;
550 error = regKey2.QueryDword(TEXT("TimerElapseMOVETOTRAY"), &dwValue);
551 if (error == ERROR_SUCCESS)
552 g_uTimerElapseMOVETOTRAY = dwValue;
553 error = regKey2.QueryDword(TEXT("TimerElapseTRAYWNDONDELAYMSG"), &dwValue);
554 if (error == ERROR_SUCCESS)
556 error = regKey2.QueryDword(TEXT("TimerElapseDOACCDEFAULTACTION"), &dwValue);
557 if (error == ERROR_SUCCESS)
559 error = regKey2.QueryDword(TEXT("TimerElapseENSUREFOCUS"), &dwValue);
560 if (error == ERROR_SUCCESS)
563 {
564 error = regKey2.QueryDword(TEXT("ShowDeskBand"), &dwValue);
565 if (error == ERROR_SUCCESS)
566 g_bShowDeskBand = !!dwValue;
567 error = regKey2.QueryDword(TEXT("TimerElapseSHOWWDESKBAND"), &dwValue);
568 if (error == ERROR_SUCCESS)
570 }
571 }
572
573 CicRegKey regKey3;
574 error = regKey3.Open(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Policies\\Microsoft\\MSCTF"));
575 if (error == ERROR_SUCCESS)
576 {
577 error = regKey3.QueryDword(TEXT("DisableCloseButton"), &dwValue);
578 if (error == ERROR_SUCCESS)
579 g_fPolicyDisableCloseButton = !!dwValue;
580 }
581
582 CicRegKey regKey4;
583 error = regKey4.Open(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Policies\\Microsoft\\MSCTF"));
584 if (error == ERROR_SUCCESS)
585 {
586 error = regKey4.QueryDword(TEXT("EnableLanguagebarInFullscreen"), &dwValue);
587 if (error == ERROR_SUCCESS)
589 }
590
592
593 if (g_bNewLook)
594 {
597 if (g_bShowShadow)
601 }
602 else
603 {
607 }
608
611
613 {
617 g_fRTL = TRUE;
618 }
619
620 return TRUE;
621}
622
623/***********************************************************************/
624
626{
629
631 {
633 m_hTrayWnd = ::FindWindowW(L"Shell_TrayWnd", NULL);
634 return m_hTrayWnd;
635 }
636
638 {
640 m_hProgmanWnd = ::FindWindowW(L"Progman", NULL);
641 return m_hProgmanWnd;
642 }
643
644 void clear()
645 {
647 }
648};
649
650/***********************************************************************/
651
653{
654protected:
657
658public:
660 virtual ~CUTBLangBarDlg() { }
661
662 static CUTBLangBarDlg *GetThis(HWND hDlg);
663 static void SetThis(HWND hDlg, CUTBLangBarDlg *pThis);
664 static DWORD WINAPI s_ThreadProc(LPVOID pParam);
666
668 LONG _Release();
669
670 STDMETHOD_(BOOL, DoModal)(HWND hDlg) = 0;
672 STDMETHOD_(BOOL, IsDlgShown)() = 0;
673 STDMETHOD_(void, SetDlgShown)(BOOL bShown) = 0;
675};
676
677/***********************************************************************/
678
680{
681public:
683
685
686 STDMETHOD_(BOOL, DoModal)(HWND hDlg) override;
688 STDMETHOD_(BOOL, IsDlgShown)() override;
689 STDMETHOD_(void, SetDlgShown)(BOOL bShown) override;
690};
691
693
694/***********************************************************************/
695
697{
698public:
700
702
703 STDMETHOD_(BOOL, DoModal)(HWND hDlg) override;
705 STDMETHOD_(BOOL, IsDlgShown)() override;
706 STDMETHOD_(void, SetDlgShown)(BOOL bShown) override;
708};
709
711
712/***********************************************************************/
713
714class CCicLibMenu : public ITfMenu
715{
716protected:
719
720public:
721 CCicLibMenu();
722 virtual ~CCicLibMenu();
723
724 STDMETHOD(QueryInterface)(REFIID riid, LPVOID *ppvObj) override;
725 STDMETHOD_(ULONG, AddRef)() override;
728 UINT uId,
731 HBITMAP hbmpMask,
732 const WCHAR *pch,
733 ULONG cch,
734 ITfMenu **ppSubMenu) override;
735 STDMETHOD_(CCicLibMenu*, CreateSubMenu)();
736 STDMETHOD_(CCicLibMenuItem*, CreateMenuItem)();
737};
738
739/***********************************************************************/
740
742{
743protected:
750
751public:
753 virtual ~CCicLibMenuItem();
754
755 BOOL Init(
756 UINT uId,
759 HBITMAP hbmpMask,
760 const WCHAR *pch,
761 ULONG cch,
762 ITfMenu *pMenu);
764};
765
766/***********************************************************************/
767
769{
770protected:
778 friend class CUTBMenuWnd;
779 friend class CTipbarWnd;
780
781public:
783 virtual ~CTipbarAccessible();
784
786
789 void ClearAccItems();
792
796 void SetWindow(HWND hWnd);
797
798 // IUnknown methods
802
803 // IDispatch methods
806 UINT iTInfo,
807 LCID lcid,
808 ITypeInfo **ppTInfo);
810 REFIID riid,
811 LPOLESTR *rgszNames,
812 UINT cNames,
813 LCID lcid,
814 DISPID *rgDispId);
816 DISPID dispIdMember,
817 REFIID riid,
818 LCID lcid,
819 WORD wFlags,
820 DISPPARAMS *pDispParams,
821 VARIANT *pVarResult,
822 EXCEPINFO *pExcepInfo,
823 UINT *puArgErr);
824
825 // IAccessible methods
826 STDMETHOD(get_accParent)(IDispatch **ppdispParent);
827 STDMETHOD(get_accChildCount)(LONG *pcountChildren);
828 STDMETHOD(get_accChild)(VARIANT varChildID, IDispatch **ppdispChild);
829 STDMETHOD(get_accName)(VARIANT varID, BSTR *pszName);
830 STDMETHOD(get_accValue)(VARIANT varID, BSTR *pszValue);
832 STDMETHOD(get_accRole)(VARIANT varID, VARIANT *role);
835 STDMETHOD(get_accHelpTopic)(BSTR *helpfile, VARIANT varID, LONG *pidTopic);
840 STDMETHOD(accSelect)(LONG flagsSelect, VARIANT varID);
842 LONG *left,
843 LONG *top,
844 LONG *width,
845 LONG *height,
846 VARIANT varID);
847 STDMETHOD(accNavigate)(LONG dir, VARIANT varStart, VARIANT *pvarEnd);
852};
853
854/***********************************************************************/
855
857{
858public:
860 virtual ~CTipbarAccItem() { }
861
862 STDMETHOD_(BSTR, GetAccName)()
863 {
864 return SysAllocString(L"");
865 }
866 STDMETHOD_(BSTR, GetAccValue)()
867 {
868 return NULL;
869 }
870 STDMETHOD_(INT, GetAccRole)()
871 {
872 return 10;
873 }
874 STDMETHOD_(INT, GetAccState)()
875 {
876 return 256;
877 }
878 STDMETHOD_(void, GetAccLocation)(LPRECT lprc)
879 {
880 *lprc = { 0, 0, 0, 0 };
881 }
882 STDMETHOD_(BSTR, GetAccDefaultAction)()
883 {
884 return NULL;
885 }
886 STDMETHOD_(BOOL, DoAccDefaultAction)()
887 {
888 return FALSE;
889 }
890 STDMETHOD_(BOOL, DoAccDefaultActionReal)()
891 {
892 return FALSE;
893 }
894};
895
896/***********************************************************************/
897
899{
900public:
902
905
907 {
908 if (m_bCoInit)
909 return S_OK;
911 if (FAILED(hr))
912 return hr;
913 m_bCoInit = TRUE;
914 return S_OK;
915 }
916
917 void CoUninit()
918 {
919 if (m_bCoInit)
920 {
923 }
924 }
925};
926
927/***********************************************************************/
928
929class CUTBMenuWnd : public CTipbarAccItem, public CUIFMenu
930{
931protected:
935 friend class CUTBMenuItem;
936
937public:
939
941
943 {
944 return static_cast<CTipbarAccItem*>(this);
945 }
947 {
948 return static_cast<CUIFMenu*>(this);
949 }
950
951 STDMETHOD_(BSTR, GetAccName)() override;
952 STDMETHOD_(INT, GetAccRole)() override;
954 STDMETHOD_(void, OnCreate)(HWND hWnd) override;
955 STDMETHOD_(void, OnDestroy)(HWND hWnd) override;
958 STDMETHOD_(void, OnTimer)(WPARAM wParam) override;
959};
960
961/***********************************************************************/
962
964{
965protected:
967 friend class CUTBMenuWnd;
968
969public:
970 CUTBMenuItem(CUTBMenuWnd *pMenuUI);
971 ~CUTBMenuItem() override;
972
974 {
975 return static_cast<CUIFMenuItem*>(this);
976 }
977
978 STDMETHOD_(BOOL, DoAccDefaultAction)() override;
979 STDMETHOD_(BOOL, DoAccDefaultActionReal)() override;
980 STDMETHOD_(BSTR, GetAccDefaultAction)() override;
981 STDMETHOD_(void, GetAccLocation)(LPRECT lprc) override;
982 STDMETHOD_(BSTR, GetAccName)() override;
983 STDMETHOD_(INT, GetAccRole)() override;
984};
985
986/***********************************************************************/
987
989{
990public:
993
994public:
996 virtual ~CModalMenu() { }
997
998 CUTBMenuItem *InsertItem(CUTBMenuWnd *pMenuUI, INT nCommandId, INT nStringID);
1000 void CancelMenu();
1001};
1002
1003/***********************************************************************/
1004
1005class CTipbarThread;
1006
1008{
1009public:
1012
1013public:
1014 CUTBContextMenu(CTipbarWnd *pTipbarWnd);
1015
1016 BOOL Init();
1018
1020 CUIFWindow *pWindow,
1021 POINT pt,
1022 LPCRECT prc,
1023 BOOL bFlag);
1024
1025 BOOL SelectMenuItem(UINT nCommandId);
1026};
1027
1028/***********************************************************************/
1029
1030class CUTBLBarMenuItem;
1031
1033{
1034protected:
1037
1038public:
1040 ~CUTBLBarMenu() override;
1041
1043 INT ShowPopup(CUIFWindow *pWindow, POINT pt, LPCRECT prcExclude);
1044
1045 STDMETHOD_(CCicLibMenuItem*, CreateMenuItem)() override;
1046 STDMETHOD_(CCicLibMenu*, CreateSubMenu)() override;
1047};
1048
1049/***********************************************************************/
1050
1052{
1053public:
1055
1056public:
1058 BOOL InsertToUI(CUTBMenuWnd *pMenuUI);
1059};
1060
1061/***********************************************************************/
1062
1064{
1065protected:
1068 friend class CTipbarWnd;
1069
1070public:
1072
1073 STDMETHOD_(void, OnLButtonUp)(LONG x, LONG y) override;
1074 STDMETHOD_(void, OnRButtonUp)(LONG x, LONG y) override;
1075 STDMETHOD_(BOOL, OnSetCursor)(UINT uMsg, LONG x, LONG y) override;
1076};
1077
1078/***********************************************************************/
1079
1080class CLangBarItemList : public CicArray<LANGBARITEMSTATE>
1081{
1082public:
1084
1086 void Clear();
1087 BOOL SetDemoteLevel(REFCLSID rclsid, DWORD dwDemoteLevel);
1088
1091
1092 void Load();
1093 void SaveItem(CicRegKey *pRegKey, const LANGBARITEMSTATE *pState);
1094
1095 void StartDemotingTimer(REFCLSID rclsid, BOOL bIntentional);
1097};
1098
1099/***********************************************************************/
1100
1102{
1103protected:
1120 friend class CTipbarWnd;
1121
1124
1125public:
1126 CTrayIconWnd();
1127 ~CTrayIconWnd();
1128
1129 static BOOL RegisterClass();
1130 static CTrayIconWnd *GetThis(HWND hWnd);
1131 static void SetThis(HWND hWnd, LPCREATESTRUCT pCS);
1132
1133 HWND CreateWnd();
1134 void DestroyWnd();
1135
1136 BOOL SetMainIcon(HKL hKL);
1137 BOOL SetIcon(REFGUID rguid, DWORD dwUnknown24, HICON hIcon, LPCWSTR psz);
1138
1140 void RemoveUnusedIcons(int unknown);
1141
1143 BOOL FindTrayEtc();
1146
1147 void CallOnDelayMsg();
1148};
1149
1150/***********************************************************************/
1151
1153{
1154protected:
1165 friend class CTrayIconWnd;
1166
1167public:
1168 CTrayIconItem(CTrayIconWnd *pTrayIconWnd);
1169 virtual ~CTrayIconItem() { }
1170
1171 BOOL _Init(HWND hWnd, UINT uCallbackMessage, UINT uNotifyIconID, const GUID& rguid);
1173 BOOL RemoveIcon();
1174
1177 STDMETHOD_(BOOL, OnDelayMsg)(UINT uMsg) { return 0; };
1178};
1179
1180/***********************************************************************/
1181
1183{
1184protected:
1187 friend class CTrayIconWnd;
1188
1189public:
1190 CButtonIconItem(CTrayIconWnd *pWnd, DWORD dwUnknown24);
1191
1193 STDMETHOD_(BOOL, OnDelayMsg)(UINT uMsg) override;
1194};
1195
1196/***********************************************************************/
1197
1199{
1200public:
1202
1203 BOOL Init(HWND hWnd);
1204 STDMETHOD_(BOOL, OnDelayMsg)(UINT uMsg) override;
1205};
1206
1207/***********************************************************************/
1208
1210{
1211protected:
1217
1218public:
1219 CLBarItemBase();
1220 virtual ~CLBarItemBase();
1221
1222 HRESULT ShowInternal(BOOL bShow, BOOL bUpdate);
1223
1224 void InitNuiInfo(
1225 REFIID clsidService,
1226 REFGUID guidItem,
1227 DWORD dwStyle,
1228 DWORD ulSort,
1229 LPCWSTR Source);
1230
1232 HRESULT GetStatus(DWORD *pdwStatus);
1233 HRESULT Show(BOOL fShow);
1234 HRESULT GetTooltipString(BSTR *pbstrToolTip);
1235
1236 HRESULT AdviseSink(REFIID riid, IUnknown *punk, DWORD *pdwCookie);
1237 HRESULT UnadviseSink(DWORD dwCookie);
1238};
1239
1240/***********************************************************************/
1241
1243 : public CLBarItemBase
1244 , public ITfLangBarItem
1245 , public ITfLangBarItemButton
1246 , public ITfSource
1247{
1248public:
1250
1251public:
1253 ~CLBarItemButtonBase() override;
1254
1255 // IUnknown methods
1256 STDMETHOD(QueryInterface)(REFIID riid, void **ppvObject) override;
1259
1260 // ITfLangBarItem methods
1261 STDMETHOD(GetInfo)(TF_LANGBARITEMINFO *pInfo) override;
1262 STDMETHOD(GetStatus)(DWORD *pdwStatus) override;
1263 STDMETHOD(Show)(BOOL fShow) override;
1264 STDMETHOD(GetTooltipString)(BSTR *pbstrToolTip) override;
1265
1266 // ITfLangBarItemButton methods
1267 STDMETHOD(OnClick)(TfLBIClick click, POINT pt, LPCRECT prc) override;
1268 STDMETHOD(InitMenu)(ITfMenu *pMenu) override;
1269 STDMETHOD(OnMenuSelect)(UINT wID) override;
1270 STDMETHOD(GetIcon)(HICON *phIcon) override;
1271 STDMETHOD(GetText)(BSTR *pbstr) override;
1272
1273 // ITfSource methods
1274 STDMETHOD(AdviseSink)(REFIID riid, IUnknown *punk, DWORD *pdwCookie) override;
1275 STDMETHOD(UnadviseSink)(DWORD dwCookie) override;
1276};
1277
1278/***********************************************************************/
1279
1282{
1283protected:
1286
1287public:
1289
1290 STDMETHOD(InitMenu)(ITfMenu *pMenu) override;
1291 STDMETHOD(OnMenuSelect)(INT nCommandId);
1292 STDMETHOD(GetIcon)(HICON *phIcon) override;
1293 STDMETHOD(GetText)(BSTR *pbstr) override;
1294};
1295
1296/***********************************************************************/
1297
1298class CTipbarItem;
1299class CTipbarBalloonItem;
1300
1302{
1303protected:
1317 friend class CTipbarWnd;
1318 friend class CTipbarItem;
1319
1320public:
1321 CTipbarThread(CTipbarWnd *pTipbarWnd);
1322 virtual ~CTipbarThread();
1323
1325
1327 HRESULT _UninitItemList(BOOL bUnAdvise);
1328
1331 BOOL IsVertical();
1332
1333 void AddAllSeparators();
1334 void RemoveAllSeparators();
1335
1336 void AddUIObjs();
1337 void RemoveUIObjs();
1338
1339 CTipbarItem *GetItem(REFCLSID rclsid);
1340 void GetTextSize(BSTR bstr, LPSIZE pSize);
1341 void LocateItems();
1342 void MyMoveWnd(LONG xDelta, LONG yDelta);
1343
1345 LONG _AddRef() { return ++m_cRefs; }
1346 LONG _Release();
1347
1349 BOOL SetFocus(CTipbarBalloonItem *pTarget)
1350 {
1351 return FALSE;
1352 }
1353
1356 {
1357 return E_NOTIMPL;
1358 }
1359
1360 //FIXME
1361};
1362
1363/***********************************************************************/
1364
1366{
1367protected:
1378 friend class CTipbarThread;
1379 friend class CTipbarWnd;
1380
1381public:
1383 CTipbarThread *pThread,
1384 ITfLangBarItem *pLangBarItem,
1385 TF_LANGBARITEMINFO *pItemInfo,
1386 DWORD dwUnknown16);
1387 ~CTipbarItem() override;
1388
1389 void _AddedToUI();
1390 void _RemovedToUI();
1391 void AddRemoveMeToUI(BOOL bFlag);
1392
1393 BOOL IsConnected();
1394 void ClearConnections();
1395
1396 void StartDemotingTimer(BOOL bStarted);
1397
1400
1401 STDMETHOD_(BSTR, GetAccName)() override;
1402 STDMETHOD_(void, GetAccLocation)(LPRECT prc) override;
1403 STDMETHOD_(BOOL, DoAccDefaultAction)() override;
1408 STDMETHOD(OnUpdate)(DWORD dwDirty);
1410 STDMETHOD_(void, OnUnknown45)(DWORD dwDirty, DWORD dwStatus) { }
1411 STDMETHOD_(void, OnUpdateHandler)(ULONG, ULONG);
1412 STDMETHOD(OnUnknown46)(CUIFWindow *pWindow) { return S_OK; }
1413 STDMETHOD(OnUnknown47)(CUIFWindow *pWindow) { return S_OK; }
1419 STDMETHOD(OnUnknown53)(BSTR bstr) { return S_OK; }
1420 STDMETHOD_(LPCWSTR, OnUnknown55)() { return NULL; }
1422 STDMETHOD_(LPCWSTR, GetToolTip)();
1425 STDMETHOD_(void, OnUnknown59)() { }
1426 STDMETHOD_(void, OnUnknown60)() { }
1427 STDMETHOD_(void, OnUnknown61)(HWND) { }
1428 STDMETHOD_(void, OnUnknown62)(HWND) { }
1430};
1431
1432/***********************************************************************/
1433
1434class CTipbarCtrlButtonHolder;
1435class CDeskBand;
1436
1437// Flags for m_dwTipbarWndFlags
1438enum
1439{
1449 TIPBAR_TOPFIT = 0x40000,
1452 TIPBAR_LEFTFIT = 0x200000,
1453};
1454
1456 : public ITfLangBarEventSink
1457 , public ITfLangBarEventSink_P
1458 , public CTipbarAccItem
1459 , public CUIFWindow
1460{
1485 CTipbarCtrlButtonHolder *m_pTipbarCtrlButtonHolder;
1499 CDeskBand *m_pDeskBand;
1502 friend class CUTBContextMenu;
1503 friend class CTipbarGripper;
1504 friend class CTipbarThread;
1505 friend class CTipbarItem;
1506 friend class CLBarInatItem;
1507 friend class CMainIconItem;
1509 friend BOOL GetTipbarInternal(HWND hWnd, DWORD dwFlags, CDeskBand *pDeskBand);
1510 friend LONG MyWaitForInputIdle(DWORD dwThreadId, DWORD dwMilliseconds);
1511
1512public:
1514 ~CTipbarWnd() override;
1515
1517 {
1518 return static_cast<CUIFWindow*>(this);
1519 }
1520
1522 {
1523 return static_cast<CTipbarAccItem*>(this);
1524 }
1525
1526 void Init(BOOL bChild, CDeskBand *pDeskBand);
1527 void InitHighContrast();
1528 void InitMetrics();
1529 void InitThemeMargins();
1530 void UnInit();
1531
1535
1538
1539 void MoveToStub(BOOL bFlag);
1540 void RestoreFromStub();
1541
1547 void LocateCtrlButtons();
1549 void SetVertical(BOOL bVertical);
1550 void UpdatePosFlags();
1551
1552 void CancelMenu();
1554 void ClearLBItemList();
1555
1557 void UpdateVerticalFont();
1558
1561 void DestroyWnd();
1562
1565
1566 UINT_PTR SetTimer(UINT_PTR nIDEvent, UINT uElapse);
1567 BOOL KillTimer(UINT_PTR uIDEvent);
1568
1569 void MoveToTray();
1570 void MyClientToScreen(LPPOINT lpPoint, LPRECT prc);
1571 void SavePosition();
1572 void SetAlpha(BYTE bAlpha, BOOL bFlag);
1573 BOOL SetLangBand(BOOL bDeskBand, BOOL bFlag2);
1575 void SetShowText(BOOL bShow);
1576 void SetShowTrayIcon(BOOL bShow);
1577
1578 void ShowContextMenu(POINT pt, LPCRECT prc, BOOL bFlag);
1579 void StartBackToAlphaTimer();
1581
1584
1587 void EnsureFocusThread();
1588 HRESULT SetFocusThread(CTipbarThread *pFocusThread);
1590 void RestoreLastFocus(DWORD *pdwThreadId, BOOL fPrev);
1591 void CleanUpThreadPointer(CTipbarThread *pThread, BOOL bRemove);
1592 void TerminateAllThreads(BOOL bFlag);
1593 void OnTerminateToolbar();
1595
1598 {
1599 return E_NOTIMPL;
1600 }
1601
1602 // IUnknown methods
1603 STDMETHOD(QueryInterface)(REFIID riid, void **ppvObj);
1606
1607 // ITfLangBarEventSink methods
1614
1615 // ITfLangBarEventSink_P methods
1616 STDMETHOD(OnLangBarUpdate)(TfLBIClick click, BOOL bFlag) override;
1617
1618 // CTipbarAccItem methods
1619 STDMETHOD_(BSTR, GetAccName)() override;
1620 STDMETHOD_(void, GetAccLocation)(LPRECT lprc) override;
1621
1622 // CUIFWindow methods
1623 STDMETHOD_(void, PaintObject)(HDC hDC, LPCRECT prc) override;
1624 STDMETHOD_(DWORD, GetWndStyle)() override;
1625 STDMETHOD_(void, Move)(INT x, INT y, INT nWidth, INT nHeight) override;
1626 STDMETHOD_(void, OnMouseOutFromWindow)(LONG x, LONG y) override;
1627 STDMETHOD_(void, OnCreate)(HWND hWnd) override;
1628 STDMETHOD_(void, OnDestroy)(HWND hWnd) override;
1630 STDMETHOD_(void, OnSysColorChange)() override;
1631 STDMETHOD_(void, OnEndSession)(HWND hWnd, WPARAM wParam, LPARAM lParam) override;
1633 STDMETHOD_(LRESULT, OnWindowPosChanged)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override;
1634 STDMETHOD_(LRESULT, OnWindowPosChanging)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override;
1637 STDMETHOD_(LRESULT, OnDisplayChange)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) override;
1640 STDMETHOD_(void, OnThemeChanged)(HWND hWnd, WPARAM wParam, LPARAM lParam) override;
1641 STDMETHOD_(void, UpdateUI)(LPCRECT prc) override;
1642 STDMETHOD_(void, HandleMouseMsg)(UINT uMsg, LONG x, LONG y) override;
1643};
1644
1645/***********************************************************************/
1646
1647#ifdef ENABLE_DESKBAND
1648class CDeskBand
1649{
1650public:
1651 // FIXME: Implement this
1652};
1653#endif
1654
1655/***********************************************************************
1656 * CUTBLangBarDlg
1657 */
1658
1660{
1662}
1663
1665{
1666 ::SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pThis);
1667}
1668
1670{
1671 return ((CUTBLangBarDlg *)pParam)->ThreadProc();
1672}
1673
1675{
1676 if (IsDlgShown())
1677 return FALSE;
1678
1679 SetDlgShown(TRUE);
1680
1683 if (!hThread)
1684 {
1685 SetDlgShown(FALSE);
1686 return TRUE;
1687 }
1688
1689 ++m_cRefs;
1691 return TRUE;
1692}
1693
1695{
1696 if (--m_cRefs == 0)
1697 {
1698 delete this;
1699 return 0;
1700 }
1701 return m_cRefs;
1702}
1703
1704STDMETHODIMP_(BOOL) CUTBLangBarDlg::ThreadProc()
1705{
1706 extern HINSTANCE g_hInst;
1708 SetDlgShown(FALSE);
1709 _Release();
1710 return TRUE;
1711}
1712
1715{
1716 if (uMsg == WM_INITDIALOG)
1717 {
1718 SetThis(hDlg, (CUTBLangBarDlg *)lParam);
1719 ::ShowWindow(hDlg, SW_RESTORE);
1720 ::UpdateWindow(hDlg);
1721 return TRUE;
1722 }
1723
1724 if (uMsg == WM_COMMAND)
1725 {
1727 pThis->OnCommand(hDlg, wParam, lParam);
1728 return TRUE;
1729 }
1730
1731 return FALSE;
1732}
1733
1734/***********************************************************************
1735 * CUTBCloseLangBarDlg
1736 */
1737
1739{
1740 m_cRefs = 1;
1741
1744 else
1746}
1747
1748STDMETHODIMP_(BOOL) CUTBCloseLangBarDlg::DoModal(HWND hDlg)
1749{
1750 CicRegKey regKey;
1751 LSTATUS error;
1752 DWORD dwValue = FALSE;
1753 error = regKey.Open(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\"));
1754 if (error == ERROR_SUCCESS)
1755 regKey.QueryDword(TEXT("DontShowCloseLangBarDlg"), &dwValue);
1756
1757 if (dwValue)
1758 return FALSE;
1759
1760 StartThread();
1761 return TRUE;
1762}
1763
1764STDMETHODIMP_(BOOL) CUTBCloseLangBarDlg::OnCommand(HWND hDlg, WPARAM wParam, LPARAM lParam)
1765{
1766 switch (LOWORD(wParam))
1767 {
1768 case IDOK:
1771 {
1772 CicRegKey regKey;
1773 LSTATUS error;
1774 error = regKey.Create(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\"));
1775 if (error == ERROR_SUCCESS)
1776 regKey.SetDword(TEXT("DontShowCloseLangBarDlg"), TRUE);
1777 }
1778 ::EndDialog(hDlg, TRUE);
1779 break;
1780
1781 case IDCANCEL:
1782 ::EndDialog(hDlg, FALSE);
1783 break;
1784
1785 default:
1786 return FALSE;
1787 }
1788 return TRUE;
1789}
1790
1791STDMETHODIMP_(BOOL) CUTBCloseLangBarDlg::IsDlgShown()
1792{
1793 return s_bIsDlgShown;
1794}
1795
1796STDMETHODIMP_(void) CUTBCloseLangBarDlg::SetDlgShown(BOOL bShown)
1797{
1798 s_bIsDlgShown = bShown;
1799}
1800
1801/***********************************************************************
1802 * CUTBMinimizeLangBarDlg
1803 */
1804
1806{
1807 m_cRefs = 1;
1810 else
1812}
1813
1814STDMETHODIMP_(BOOL) CUTBMinimizeLangBarDlg::DoModal(HWND hDlg)
1815{
1816 CicRegKey regKey;
1817 LSTATUS error;
1818
1819 DWORD dwValue = FALSE;
1820 error = regKey.Open(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\"));
1821 if (error == ERROR_SUCCESS)
1822 regKey.QueryDword(TEXT("DontShowMinimizeLangBarDlg"), &dwValue);
1823
1824 if (dwValue)
1825 return FALSE;
1826
1827 StartThread();
1828 return TRUE;
1829}
1830
1831STDMETHODIMP_(BOOL) CUTBMinimizeLangBarDlg::OnCommand(HWND hDlg, WPARAM wParam, LPARAM lParam)
1832{
1833 switch (LOWORD(wParam))
1834 {
1835 case IDOK:
1837 {
1838 LSTATUS error;
1839 CicRegKey regKey;
1840 error = regKey.Create(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\CTF\\MSUTB\\"));
1841 if (error == ERROR_SUCCESS)
1842 regKey.SetDword(TEXT("DontShowMinimizeLangBarDlg"), TRUE);
1843 }
1844 ::EndDialog(hDlg, TRUE);
1845 break;
1846 case IDCANCEL:
1847 ::EndDialog(hDlg, FALSE);
1848 break;
1849 default:
1850 return FALSE;
1851 }
1852 return TRUE;
1853}
1854
1855STDMETHODIMP_(BOOL) CUTBMinimizeLangBarDlg::IsDlgShown()
1856{
1857 return s_bIsDlgShown;
1858}
1859
1860STDMETHODIMP_(void) CUTBMinimizeLangBarDlg::SetDlgShown(BOOL bShown)
1861{
1862 s_bIsDlgShown = bShown;
1863}
1864
1865STDMETHODIMP_(BOOL) CUTBMinimizeLangBarDlg::ThreadProc()
1866{
1867 ::Sleep(700);
1868 return CUTBLangBarDlg::ThreadProc();
1869}
1870
1871/***********************************************************************
1872 * CCicLibMenu
1873 */
1874
1876{
1877}
1878
1880{
1881 for (size_t iItem = 0; iItem < m_MenuItems.size(); ++iItem)
1882 {
1883 delete m_MenuItems[iItem];
1884 m_MenuItems[iItem] = NULL;
1885 }
1886}
1887
1889{
1890 static const QITAB c_tab[] =
1891 {
1893 { NULL }
1894 };
1895 return ::QISearch(this, c_tab, riid, ppvObj);
1896}
1897
1899{
1900 return ++m_cRefs;
1901}
1902
1904{
1905 if (--m_cRefs == 0)
1906 {
1907 delete this;
1908 return 0;
1909 }
1910 return m_cRefs;
1911}
1912
1913STDMETHODIMP_(CCicLibMenu*) CCicLibMenu::CreateSubMenu()
1914{
1915 return new(cicNoThrow) CCicLibMenu();
1916}
1917
1918STDMETHODIMP_(CCicLibMenuItem*) CCicLibMenu::CreateMenuItem()
1919{
1920 return new(cicNoThrow) CCicLibMenuItem();
1921}
1922
1924 UINT uId,
1925 DWORD dwFlags,
1926 HBITMAP hbmp,
1927 HBITMAP hbmpMask,
1928 const WCHAR *pch,
1929 ULONG cch,
1930 ITfMenu **ppSubMenu)
1931{
1932 if (ppSubMenu)
1933 *ppSubMenu = NULL;
1934
1935 CCicLibMenu *pSubMenu = NULL;
1937 {
1938 if (!ppSubMenu)
1939 return E_INVALIDARG;
1940 pSubMenu = CreateSubMenu();
1941 }
1942
1943 CCicLibMenuItem *pMenuItem = CreateMenuItem();
1944 if (!pMenuItem)
1945 return E_OUTOFMEMORY;
1946
1947 if (!pMenuItem->Init(uId, dwFlags, hbmp, hbmpMask, pch, cch, pSubMenu))
1948 return E_FAIL;
1949
1950 if (ppSubMenu && pSubMenu)
1951 {
1952 *ppSubMenu = pSubMenu;
1953 pSubMenu->AddRef();
1954 }
1955
1956 m_MenuItems.Add(pMenuItem);
1957 return S_OK;
1958}
1959
1960/***********************************************************************
1961 * CCicLibMenuItem
1962 */
1963
1965{
1966 m_uId = 0;
1967 m_dwFlags = 0;
1968 m_hbmp = NULL;
1969 m_hbmpMask = NULL;
1970 m_bstrText = NULL;
1971 m_pMenu = NULL;
1972}
1973
1975{
1976 if (m_pMenu)
1977 {
1978 m_pMenu->Release();
1979 m_pMenu = NULL;
1980 }
1981
1982 if (m_hbmp)
1983 {
1985 m_hbmp = NULL;
1986 }
1987
1988 if (m_hbmpMask)
1989 {
1991 m_hbmpMask = NULL;
1992 }
1993
1995 m_bstrText = NULL;
1996}
1997
1999 UINT uId,
2000 DWORD dwFlags,
2001 HBITMAP hbmp,
2002 HBITMAP hbmpMask,
2003 const WCHAR *pch,
2004 ULONG cch,
2005 ITfMenu *pMenu)
2006{
2007 m_uId = uId;
2010 if (!m_bstrText && cch)
2011 return FALSE;
2012
2013 m_pMenu = pMenu;
2015 m_hbmpMask = CreateBitmap(hbmpMask);
2016 if (hbmp)
2018 if (hbmpMask)
2019 ::DeleteObject(hbmpMask);
2020
2021 return TRUE;
2022}
2023
2025{
2026 if (!hBitmap)
2027 return NULL;
2028
2029 HDC hDC = ::CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
2030 if (!hDC)
2031 return NULL;
2032
2033 HBITMAP hbmMem = NULL;
2034
2035 BITMAP bm;
2036 ::GetObject(hBitmap, sizeof(bm), &bm);
2037
2038 HGDIOBJ hbmOld1 = NULL;
2039 HDC hdcMem1 = ::CreateCompatibleDC(hDC);
2040 if (hdcMem1)
2041 hbmOld1 = ::SelectObject(hdcMem1, hBitmap);
2042
2043 HGDIOBJ hbmOld2 = NULL;
2044 HDC hdcMem2 = ::CreateCompatibleDC(hDC);
2045 if (hdcMem2)
2046 {
2047 hbmMem = ::CreateCompatibleBitmap(hDC, bm.bmWidth, bm.bmHeight);
2048 hbmOld2 = ::SelectObject(hdcMem2, hbmMem);
2049 }
2050
2051 ::BitBlt(hdcMem2, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem1, 0, 0, SRCCOPY);
2052
2053 if (hbmOld1)
2054 ::SelectObject(hdcMem1, hbmOld1);
2055 if (hbmOld2)
2056 ::SelectObject(hdcMem2, hbmOld2);
2057
2058 ::DeleteDC(hDC);
2059 if (hdcMem1)
2060 ::DeleteDC(hdcMem1);
2061 if (hdcMem2)
2062 ::DeleteDC(hdcMem2);
2063
2064 return hbmMem;
2065}
2066
2067/***********************************************************************
2068 * CTipbarAccessible
2069 */
2070
2072{
2073 m_cRefs = 1;
2074 m_hWnd = NULL;
2075 m_pTypeInfo = NULL;
2078 m_cSelection = 1;
2079 m_AccItems.Add(pItem);
2080 ++g_DllRefCount;
2081}
2082
2084{
2086 if (m_pTypeInfo)
2087 {
2089 m_pTypeInfo = NULL;
2090 }
2091 if (m_pStdAccessible)
2092 {
2095 }
2096 --g_DllRefCount;
2097}
2098
2100{
2102
2104 (void **)&m_pStdAccessible);
2105 if (FAILED(hr))
2106 return hr;
2107
2108 ITypeLib *pTypeLib;
2109 hr = ::LoadRegTypeLib(LIBID_Accessibility, 1, 0, 0, &pTypeLib);
2110 if (FAILED(hr))
2111 hr = ::LoadTypeLib(L"OLEACC.DLL", &pTypeLib);
2112
2113 if (SUCCEEDED(hr))
2114 {
2115 hr = pTypeLib->GetTypeInfoOfGuid(IID_IAccessible, &m_pTypeInfo);
2116 pTypeLib->Release();
2117 }
2118
2119 return hr;
2120}
2121
2123{
2124 return m_AccItems.Add(pItem);
2125}
2126
2128{
2129 for (size_t iItem = 0; iItem < m_AccItems.size(); ++iItem)
2130 {
2131 if (m_AccItems[iItem] == pItem)
2132 {
2133 m_AccItems.Remove(iItem, 1);
2134 break;
2135 }
2136 }
2137 return S_OK;
2138}
2139
2141{
2142 m_AccItems.clear();
2143}
2144
2146{
2147 if (iItem < 0 || (INT)m_AccItems.size() <= iItem)
2148 return NULL;
2149 return m_AccItems[iItem];
2150}
2151
2153{
2154 for (size_t iItem = 0; iItem < m_AccItems.size(); ++iItem)
2155 {
2156 if (pTarget == m_AccItems[iItem])
2157 return (INT)iItem;
2158 }
2159 return -1;
2160}
2161
2163{
2164 return ::LresultFromObject(IID_IAccessible, wParam, this);
2165}
2166
2168{
2169 CTipbarAccItem *pItem = AccItemFromID(nID);
2170 if (!pItem)
2171 return FALSE;
2172 return pItem->DoAccDefaultActionReal();
2173}
2174
2176{
2177 INT nID = GetIDOfItem(pItem);
2178 if (nID < 0)
2179 return;
2180
2181 ::NotifyWinEvent(event, m_hWnd, -4, nID);
2182}
2183
2185{
2186 m_hWnd = hWnd;
2187}
2188
2190 REFIID riid,
2191 void **ppvObject)
2192{
2193 static const QITAB c_tab[] =
2194 {
2197 { NULL }
2198 };
2199 return ::QISearch(this, c_tab, riid, ppvObject);
2200}
2201
2203{
2204 return ::InterlockedIncrement(&m_cRefs);
2205}
2206
2208{
2210 if (count == 0)
2211 {
2212 delete this;
2213 return 0;
2214 }
2215 return count;
2216}
2217
2219{
2220 if (!pctinfo)
2221 return E_INVALIDARG;
2222 *pctinfo = (m_pTypeInfo == NULL);
2223 return S_OK;
2224}
2225
2227 UINT iTInfo,
2228 LCID lcid,
2229 ITypeInfo **ppTInfo)
2230{
2231 if (!ppTInfo)
2232 return E_INVALIDARG;
2233 *ppTInfo = NULL;
2234 if (iTInfo != 0)
2236 if (!m_pTypeInfo)
2237 return E_NOTIMPL;
2238 *ppTInfo = m_pTypeInfo;
2240 return S_OK;
2241}
2242
2244 REFIID riid,
2245 LPOLESTR *rgszNames,
2246 UINT cNames,
2247 LCID lcid,
2248 DISPID *rgDispId)
2249{
2250 if (!m_pTypeInfo)
2251 return E_NOTIMPL;
2252 return m_pTypeInfo->GetIDsOfNames(rgszNames, cNames, rgDispId);
2253}
2254
2256 DISPID dispIdMember,
2257 REFIID riid,
2258 LCID lcid,
2259 WORD wFlags,
2260 DISPPARAMS *pDispParams,
2261 VARIANT *pVarResult,
2262 EXCEPINFO *pExcepInfo,
2263 UINT *puArgErr)
2264{
2265 if (!m_pTypeInfo)
2266 return E_NOTIMPL;
2267 return m_pTypeInfo->Invoke(this,
2268 dispIdMember,
2269 wFlags,
2270 pDispParams,
2271 pVarResult,
2272 pExcepInfo,
2273 puArgErr);
2274}
2275
2277{
2278 return m_pStdAccessible->get_accParent(ppdispParent);
2279}
2280
2282{
2283 if (!pcountChildren)
2284 return E_INVALIDARG;
2285 INT cItems = (INT)m_AccItems.size();
2286 if (!cItems)
2287 return E_FAIL;
2288 *pcountChildren = cItems - 1;
2289 return S_OK;
2290}
2291
2293 VARIANT varChildID,
2294 IDispatch **ppdispChild)
2295{
2296 if (!ppdispChild)
2297 return E_INVALIDARG;
2298 *ppdispChild = NULL;
2299 return S_FALSE;
2300}
2301
2303 VARIANT varID,
2304 BSTR *pszName)
2305{
2306 if (!pszName)
2307 return E_INVALIDARG;
2308 CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID));
2309 if (!pItem)
2310 return E_INVALIDARG;
2311 *pszName = pItem->GetAccName();
2312 if (!*pszName)
2313 return DISP_E_MEMBERNOTFOUND;
2314 return S_OK;
2315}
2316
2318 VARIANT varID,
2319 BSTR *pszValue)
2320{
2321 if (!pszValue)
2322 return E_INVALIDARG;
2323 CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID));
2324 if (!pItem)
2325 return E_INVALIDARG;
2326 *pszValue = pItem->GetAccValue();
2327 if (!*pszValue)
2328 return DISP_E_MEMBERNOTFOUND;
2329 return S_OK;
2330}
2331
2333 VARIANT varID,
2335{
2336 if (!description)
2337 return E_INVALIDARG;
2338 return m_pStdAccessible->get_accDescription(varID, description);
2339}
2340
2342 VARIANT varID,
2343 VARIANT *role)
2344{
2345 if (!role)
2346 return E_INVALIDARG;
2347 CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID));
2348 if (!pItem)
2349 return E_INVALIDARG;
2350 V_VT(role) = VT_I4;
2351 V_I4(role) = pItem->GetAccRole();
2352 return S_OK;
2353}
2354
2356 VARIANT varID,
2357 VARIANT *state)
2358{
2359 if (!state)
2360 return E_INVALIDARG;
2361 CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID));
2362 if (!pItem)
2363 return E_INVALIDARG;
2364 V_VT(state) = VT_I4;
2365 V_I4(state) = pItem->GetAccState();
2366 return S_OK;
2367}
2368
2370{
2371 return DISP_E_MEMBERNOTFOUND;
2372}
2373
2375 BSTR *helpfile,
2376 VARIANT varID,
2377 LONG *pidTopic)
2378{
2379 return DISP_E_MEMBERNOTFOUND;
2380}
2381
2383{
2384 return DISP_E_MEMBERNOTFOUND;
2385}
2386
2388{
2389 if (!pvarID)
2390 return E_INVALIDARG;
2391 V_VT(pvarID) = VT_EMPTY;
2392 return S_FALSE;
2393}
2394
2396{
2397 if (!pvarID)
2398 return E_INVALIDARG;
2399
2400 V_VT(pvarID) = VT_EMPTY;
2401
2402 INT cItems = (INT)m_AccItems.size();
2403 if (cItems < m_cSelection)
2404 return S_FALSE;
2405
2406 if (cItems > m_cSelection)
2407 {
2408 V_VT(pvarID) = VT_I4;
2409 V_I4(pvarID) = m_cSelection;
2410 }
2411
2412 return S_OK;
2413}
2414
2416 VARIANT varID,
2417 BSTR *action)
2418{
2419 if (!action)
2420 return E_INVALIDARG;
2421 *action = NULL;
2422
2423 if (V_VT(&varID) != VT_I4)
2424 return E_INVALIDARG;
2425
2426 CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID));
2427 if (!pItem)
2428 return DISP_E_MEMBERNOTFOUND;
2429 *action = pItem->GetAccDefaultAction();
2430 if (!*action)
2431 return S_FALSE;
2432 return S_OK;
2433}
2434
2436 LONG flagsSelect,
2437 VARIANT varID)
2438{
2439 if ((flagsSelect & SELFLAG_ADDSELECTION) && (flagsSelect & SELFLAG_REMOVESELECTION))
2440 return E_INVALIDARG;
2441 if (flagsSelect & (SELFLAG_TAKEFOCUS | SELFLAG_ADDSELECTION | SELFLAG_EXTENDSELECTION))
2442 return S_FALSE;
2443 if (flagsSelect & SELFLAG_REMOVESELECTION)
2444 return S_OK;
2445 if (V_VT(&varID) != VT_I4)
2446 return E_INVALIDARG;
2447 if (flagsSelect & SELFLAG_TAKESELECTION)
2448 {
2449 m_cSelection = V_I4(&varID);
2450 return S_OK;
2451 }
2452 return S_FALSE;
2453}
2454
2456 LONG *left,
2457 LONG *top,
2458 LONG *width,
2459 LONG *height,
2460 VARIANT varID)
2461{
2462 if (!left || !top || !width || !height)
2463 return E_INVALIDARG;
2464
2465 if (!V_I4(&varID))
2466 return m_pStdAccessible->accLocation(left, top, width, height, varID);
2467
2468 RECT rc;
2469 CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID));
2470 pItem->GetAccLocation(&rc);
2471
2472 *left = rc.left;
2473 *top = rc.top;
2474 *width = rc.right - rc.left;
2475 *height = rc.bottom - rc.top;
2476 return S_OK;
2477}
2478
2480 LONG dir,
2481 VARIANT varStart,
2482 VARIANT *pvarEnd)
2483{
2484 if (m_AccItems.size() <= 1)
2485 {
2486 V_VT(pvarEnd) = VT_EMPTY;
2487 return S_OK;
2488 }
2489
2490 switch (dir)
2491 {
2492 case NAVDIR_UP:
2493 case NAVDIR_LEFT:
2494 case NAVDIR_PREVIOUS:
2495 V_VT(pvarEnd) = VT_I4;
2496 V_I4(pvarEnd) = V_I4(&varStart) - 1;
2497 if (V_I4(&varStart) - 1 <= 0)
2498 V_I4(pvarEnd) = (INT)(m_AccItems.size() - 1);
2499 return S_OK;
2500
2501 case NAVDIR_DOWN:
2502 case NAVDIR_RIGHT:
2503 case NAVDIR_NEXT:
2504 V_VT(pvarEnd) = VT_I4;
2505 V_I4(pvarEnd) = V_I4(&varStart) + 1;
2506 if ((INT)m_AccItems.size() <= V_I4(&varStart) + 1)
2507 V_I4(pvarEnd) = 1;
2508 return S_OK;
2509
2510 case NAVDIR_FIRSTCHILD:
2511 V_VT(pvarEnd) = VT_I4;
2512 V_I4(pvarEnd) = 1;
2513 return S_OK;
2514
2515 case NAVDIR_LASTCHILD:
2516 V_VT(pvarEnd) = VT_I4;
2517 V_I4(pvarEnd) = (INT)(m_AccItems.size() - 1);
2518 return S_OK;
2519
2520 default:
2521 break;
2522 }
2523
2524 V_VT(pvarEnd) = VT_EMPTY;
2525 return S_OK;
2526}
2527
2529{
2530 if (!pvarID)
2531 return E_INVALIDARG;
2532 POINT Point = { left, top };
2533 RECT Rect;
2536
2537 if (!::PtInRect(&Rect, Point))
2538 {
2539 V_VT(pvarID) = VT_EMPTY;
2540 return S_OK;
2541 }
2542
2543 V_VT(pvarID) = VT_I4;
2544 V_I4(pvarID) = 0;
2545
2546 for (size_t iItem = 1; iItem < m_AccItems.size(); ++iItem)
2547 {
2548 CTipbarAccItem *pItem = m_AccItems[iItem];
2549 if (pItem)
2550 {
2551 pItem->GetAccLocation(&Rect);
2552 if (::PtInRect(&Rect, Point))
2553 {
2554 V_I4(pvarID) = iItem;
2555 break;
2556 }
2557 }
2558 }
2559
2560 return S_OK;
2561}
2562
2564{
2565 if (V_VT(&varID) != VT_I4)
2566 return E_INVALIDARG;
2567 CTipbarAccItem *pItem = AccItemFromID(V_I4(&varID));
2568 if (!pItem)
2569 return DISP_E_MEMBERNOTFOUND;
2570 return (pItem->DoAccDefaultAction() ? S_OK : S_FALSE);
2571}
2572
2574{
2575 return S_FALSE;
2576}
2577
2579{
2580 return S_FALSE;
2581}
2582
2583/***********************************************************************
2584 * CUTBMenuWnd
2585 */
2586
2588 : CUIFMenu(hInst, style, dwUnknown14)
2589{
2590}
2591
2593{
2594 if (!m_pAccessible)
2595 return FALSE;
2596
2598 if (!m_nMenuWndID || m_nMenuWndID == (UINT)-1)
2599 return FALSE;
2600
2601 if (::IsWindow(m_hWnd))
2602 {
2605 }
2606
2607 return TRUE;
2608}
2609
2610STDMETHODIMP_(BSTR) CUTBMenuWnd::GetAccName()
2611{
2612 WCHAR szText[64];
2613 LoadStringW(g_hInst, IDS_MENUWND, szText, _countof(szText));
2614 return ::SysAllocString(szText);
2615}
2616
2617STDMETHODIMP_(INT) CUTBMenuWnd::GetAccRole()
2618{
2619 return 9;
2620}
2621
2622STDMETHODIMP_(BOOL) CUTBMenuWnd::Initialize()
2623{
2625 if (pAccessible)
2626 m_pAccessible = pAccessible;
2627
2628 return CUIFObject::Initialize();
2629}
2630
2631STDMETHODIMP_(void) CUTBMenuWnd::OnCreate(HWND hWnd)
2632{
2633 if (m_pAccessible)
2635}
2636
2637STDMETHODIMP_(void) CUTBMenuWnd::OnDestroy(HWND hWnd)
2638{
2639 if (m_pAccessible)
2640 {
2641 m_pAccessible->NotifyWinEvent(EVENT_OBJECT_DESTROY, GetAccItem());
2645 }
2647}
2648
2650CUTBMenuWnd::OnGetObject(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
2651{
2652 if (lParam != -4)
2653 return S_OK;
2654
2655 if (!m_pAccessible)
2656 return E_OUTOFMEMORY;
2657
2660
2662 {
2664 if (FAILED(hr))
2665 {
2668 return hr;
2669 }
2670
2671 m_pAccessible->NotifyWinEvent(EVENT_OBJECT_CREATE, GetAccItem());
2673 }
2674
2675 return S_OK;
2676}
2677
2679CUTBMenuWnd::OnShowWindow(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
2680{
2681 if (m_pAccessible)
2682 {
2683 if (wParam)
2684 {
2685 m_pAccessible->NotifyWinEvent(EVENT_OBJECT_SHOW, GetAccItem());
2686 m_pAccessible->NotifyWinEvent(EVENT_OBJECT_FOCUS, GetAccItem());
2687 }
2688 else
2689 {
2690 m_pAccessible->NotifyWinEvent(EVENT_OBJECT_HIDE, GetAccItem());
2691 }
2692 }
2693
2694 return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
2695}
2696
2697STDMETHODIMP_(void) CUTBMenuWnd::OnTimer(WPARAM wParam)
2698{
2700 {
2703 {
2705 m_nMenuWndID = 0;
2706 }
2707 }
2708}
2709
2710/***********************************************************************
2711 * CUTBMenuItem
2712 */
2713
2715 : CUIFMenuItem(pMenuUI ? pMenuUI->GetMenu() : NULL)
2716{
2717 m_pMenuUI = pMenuUI;
2718}
2719
2721{
2722 if (m_hbmColor)
2723 {
2725 m_hbmColor = NULL;
2726 }
2727 if (m_hbmMask)
2728 {
2730 m_hbmMask = NULL;
2731 }
2732}
2733
2734STDMETHODIMP_(BOOL) CUTBMenuItem::DoAccDefaultAction()
2735{
2736 if (!m_pMenuUI)
2737 return FALSE;
2738
2740 return TRUE;
2741}
2742
2743STDMETHODIMP_(BOOL) CUTBMenuItem::DoAccDefaultActionReal()
2744{
2745 if (!m_pSubMenu)
2746 OnLButtonUp(0, 0);
2747 else
2748 ShowSubPopup();
2749 return TRUE;
2750}
2751
2752STDMETHODIMP_(BSTR) CUTBMenuItem::GetAccDefaultAction()
2753{
2754 WCHAR szText[64];
2755 ::LoadStringW(g_hInst, IDS_LEFTCLICK, szText, _countof(szText));
2756 return ::SysAllocString(szText);
2757}
2758
2759STDMETHODIMP_(void) CUTBMenuItem::GetAccLocation(LPRECT lprc)
2760{
2761 GetRect(lprc);
2764}
2765
2766STDMETHODIMP_(BSTR) CUTBMenuItem::GetAccName()
2767{
2768 return ::SysAllocString(m_pszMenuItemLeft);
2769}
2770
2772STDMETHODIMP_(INT) CUTBMenuItem::GetAccRole()
2773{
2774 if (FALSE) //FIXME
2775 return 21;
2776 return 12;
2777}
2778
2779/***********************************************************************
2780 * CModalMenu
2781 */
2782
2784CModalMenu::InsertItem(CUTBMenuWnd *pMenuUI, INT nCommandId, INT nStringID)
2785{
2786 CUTBMenuItem *pMenuItem = new(cicNoThrow) CUTBMenuItem(pMenuUI);
2787 if (!pMenuItem)
2788 return NULL;
2789
2790 WCHAR szText[256];
2791 ::LoadStringW(g_hInst, nStringID, szText, _countof(szText));
2792
2793 if (pMenuItem->Initialize() &&
2794 pMenuItem->Init(nCommandId, szText) &&
2795 pMenuUI->InsertItem(pMenuItem))
2796 {
2797 return pMenuItem;
2798 }
2799
2800 delete pMenuItem;
2801 return NULL;
2802}
2803
2805{
2807}
2808
2810{
2811 if (m_pMenuUI)
2813}
2814
2815/***********************************************************************
2816 * CUTBContextMenu
2817 */
2818
2820{
2821 m_pTipbarWnd = pTipbarWnd;
2822}
2823
2826{
2828 return !!m_pTipbarThread;
2829}
2830
2833{
2834 DWORD dwStatus = 0;
2835
2837 return NULL;
2838
2840 if (!pMenuUI)
2841 return NULL;
2842
2843 pMenuUI->Initialize();
2844
2845 if (dwStatus & (TF_SFT_DESKBAND | TF_SFT_MINIMIZED))
2846 {
2847 CUTBMenuItem *pRestoreLangBar = InsertItem(pMenuUI, ID_RESTORELANGBAR, IDS_RESTORELANGBAR2);
2848 if (pRestoreLangBar && !m_pTipbarWnd->m_dwUnknown20)
2849 pRestoreLangBar->Gray(TRUE);
2850 }
2851 else
2852 {
2854
2855 if (bFlag)
2856 {
2858 {
2859 if (dwStatus & TF_LBI_BALLOON)
2860 {
2862 }
2863 else
2864 {
2865 CUTBMenuItem *pTransparency = InsertItem(pMenuUI, ID_NOTRANS, IDS_TRANSPARENCY);
2866 if (pTransparency)
2867 pTransparency->Check(TRUE);
2868 }
2869 }
2870
2871 if (!(dwStatus & TF_SFT_LABELS))
2872 {
2874 }
2875 else
2876 {
2877 CUTBMenuItem *pTextLabels = InsertItem(pMenuUI, ID_NOLABELS, IDS_TEXTLABELS);
2878 if (pTextLabels)
2879 pTextLabels->Check(TRUE);
2880 }
2881
2882 CUTBMenuItem *pVertical = InsertItem(pMenuUI, ID_VERTICAL, IDS_VERTICAL);
2883 if (pVertical)
2885 }
2886 }
2887
2888 if (bFlag)
2889 {
2890 CUTBMenuItem *pExtraIcons = NULL;
2891
2892 if (dwStatus & TF_SFT_EXTRAICONSONMINIMIZED)
2893 {
2894 pExtraIcons = InsertItem(pMenuUI, ID_NOEXTRAICONS, IDS_EXTRAICONS);
2895 if (pExtraIcons)
2896 pExtraIcons->Check(TRUE);
2897 }
2898 else
2899 {
2900 pExtraIcons = CModalMenu::InsertItem(pMenuUI, ID_EXTRAICONS, IDS_EXTRAICONS);
2901 }
2902
2903 if (pExtraIcons)
2904 {
2905 if (::GetKeyboardLayoutList(0, NULL) == 1)
2906 {
2907 pExtraIcons->Check(TRUE);
2908 pExtraIcons->Gray(TRUE);
2909 }
2910 else
2911 {
2912 pExtraIcons->Gray(FALSE);
2913 }
2914 }
2915
2916 if (dwStatus & TF_SFT_DESKBAND)
2918
2920
2923 }
2924
2925 return pMenuUI;
2926}
2927
2928UINT
2930 CUIFWindow *pWindow,
2931 POINT pt,
2932 LPCRECT prc,
2933 BOOL bFlag)
2934{
2935 if (g_bWinLogon)
2936 return 0;
2937
2938 if (m_pMenuUI)
2939 return -1;
2940
2941 m_pMenuUI = CreateMenuUI(bFlag);
2942 if (!m_pMenuUI)
2943 return 0;
2944
2945 UINT nCommandId = m_pMenuUI->ShowModalPopup(pWindow, prc, TRUE);
2946
2947 if (m_pMenuUI)
2948 {
2949 delete m_pMenuUI;
2950 m_pMenuUI = NULL;
2951 }
2952
2953 return nCommandId;
2954}
2955
2958{
2959 switch (nCommandId)
2960 {
2961 case ID_TRANS:
2962 m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_LOWTRANSPARENCY);
2963 break;
2964
2965 case ID_NOTRANS:
2966 m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_NOTRANSPARENCY);
2967 break;
2968
2969 case ID_LABELS:
2970 m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_LABELS);
2971 break;
2972
2973 case ID_NOLABELS:
2974 m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_NOLABELS);
2975 break;
2976
2977 case ID_DESKBAND:
2978 {
2980 {
2981 m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_MINIMIZED);
2982 }
2983 else
2984 {
2987
2988 if (dwStatus & TF_SFT_DESKBAND)
2989 break;
2990
2991 m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_DESKBAND);
2992 }
2993
2995 if (pDialog)
2996 {
2997 pDialog->DoModal(*m_pTipbarWnd->GetWindow());
2998 pDialog->_Release();
2999 }
3000 break;
3001 }
3002
3003 case ID_CLOSELANGBAR:
3004 {
3006 if (pDialog)
3007 {
3008 BOOL bOK = pDialog->DoModal(*m_pTipbarWnd->GetWindow());
3009 pDialog->_Release();
3010 if (!bOK)
3012 }
3013 break;
3014 }
3015
3016 case ID_EXTRAICONS:
3017 m_pTipbarWnd->m_dwTipbarWndFlags &= ~TIPBAR_NODESKBAND;
3018 m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_EXTRAICONSONMINIMIZED);
3019 break;
3020
3021 case ID_NOEXTRAICONS:
3022 m_pTipbarWnd->m_dwTipbarWndFlags &= ~TIPBAR_NODESKBAND;
3023 m_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_NOEXTRAICONSONMINIMIZED);
3024 break;
3025
3026 case ID_RESTORELANGBAR:
3028 break;
3029
3030 case ID_VERTICAL:
3032 break;
3033
3034 case ID_ADJUSTDESKBAND:
3036 break;
3037
3038 case ID_SETTINGS:
3040 break;
3041
3042 default:
3043 break;
3044 }
3045
3046 return TRUE;
3047}
3048
3049/***********************************************************************
3050 * CTrayIconItem
3051 */
3052
3054{
3056 m_pTrayIconWnd = pTrayIconWnd;
3057}
3058
3059BOOL
3061 HWND hWnd,
3062 UINT uCallbackMessage,
3063 UINT uNotifyIconID,
3064 const GUID& rguid)
3065{
3066 m_hWnd = hWnd;
3067 m_uCallbackMessage = uCallbackMessage;
3068 m_uNotifyIconID = uNotifyIconID;
3069 m_guid = rguid;
3070 return TRUE;
3071}
3072
3074{
3076 {
3077 NOTIFYICONDATAW NotifyIcon = { sizeof(NotifyIcon), m_hWnd, m_uNotifyIconID };
3078 NotifyIcon.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
3080 ::Shell_NotifyIconW(NIM_DELETE, &NotifyIcon);
3081 }
3082
3085 return TRUE;
3086}
3087
3088BOOL CTrayIconItem::SetIcon(HICON hIcon, LPCWSTR pszTip)
3089{
3090 if (!hIcon)
3091 return FALSE;
3092
3093 NOTIFYICONDATAW NotifyIcon = { sizeof(NotifyIcon), m_hWnd, m_uNotifyIconID };
3094 NotifyIcon.uFlags = NIF_ICON | NIF_MESSAGE;
3096 NotifyIcon.hIcon = hIcon;
3097 if (pszTip)
3098 {
3099 NotifyIcon.uFlags |= NIF_TIP;
3100 StringCchCopyW(NotifyIcon.szTip, _countof(NotifyIcon.szTip), pszTip);
3101 }
3102
3104
3107 return TRUE;
3108}
3109
3111{
3112 HWND hNotifyWnd = m_pTrayIconWnd->GetNotifyWnd();
3113 ::GetClientRect(hNotifyWnd, &m_rcMenu);
3114 ::ClientToScreen(hNotifyWnd, (LPPOINT)&m_rcMenu);
3115 ::ClientToScreen(hNotifyWnd, (LPPOINT)&m_rcMenu.right);
3117 return TRUE;
3118}
3119
3120/***********************************************************************
3121 * CButtonIconItem
3122 */
3123
3125 : CTrayIconItem(pWnd)
3126{
3127 m_dwUnknown24 = dwUnknown24;
3128}
3129
3131STDMETHODIMP_(BOOL) CButtonIconItem::OnMsg(WPARAM wParam, LPARAM lParam)
3132{
3133 switch (lParam)
3134 {
3135 case WM_LBUTTONDOWN:
3136 case WM_RBUTTONDOWN:
3137 case WM_LBUTTONDBLCLK:
3138 case WM_RBUTTONDBLCLK:
3139 break;
3140 default:
3141 return TRUE;
3142 }
3143
3144 //FIXME
3145 return TRUE;
3146}
3147
3149STDMETHODIMP_(BOOL) CButtonIconItem::OnDelayMsg(UINT uMsg)
3150{
3151 //FIXME
3152 return FALSE;
3153}
3154
3155/***********************************************************************
3156 * CMainIconItem
3157 */
3158
3161 : CButtonIconItem(pWnd, 1)
3162{
3163}
3164
3167{
3168 return CTrayIconItem::_Init(hWnd, WM_USER, 0, GUID_LBI_TRAYMAIN);
3169}
3170
3172STDMETHODIMP_(BOOL) CMainIconItem::OnDelayMsg(UINT uMsg)
3173{
3174 if (!CButtonIconItem::OnDelayMsg(uMsg))
3175 return 0;
3176
3177 if (uMsg == WM_LBUTTONDBLCLK)
3178 {
3180 g_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_SHOWNORMAL);
3181 }
3182 else if (uMsg == WM_LBUTTONDOWN || uMsg == WM_RBUTTONDOWN)
3183 {
3185 }
3186 return TRUE;
3187}
3188
3189/***********************************************************************
3190 * CTrayIconWnd
3191 */
3192
3194{
3195 m_uCallbackMsg = WM_USER + 0x1000;
3196 m_uNotifyIconID = 0x1000;
3197}
3198
3200{
3201 for (size_t iItem = 0; iItem < m_Items.size(); ++iItem)
3202 {
3203 auto& pItem = m_Items[iItem];
3204 if (pItem)
3205 {
3206 delete pItem;
3207 pItem = NULL;
3208 }
3209 }
3210}
3211
3213{
3214 for (size_t iItem = 0; iItem < m_Items.size(); ++iItem)
3215 {
3216 auto pItem = m_Items[iItem];
3217 if (pItem && m_uCallbackMessage == pItem->m_uCallbackMessage)
3218 {
3219 pItem->OnDelayMsg(m_uMsg);
3220 break;
3221 }
3222 }
3223}
3224
3226{
3227 m_hWnd = ::CreateWindowEx(0, TEXT("CTrayIconWndClass"), NULL, WS_DISABLED,
3228 0, 0, 0, 0, NULL, NULL, g_hInst, this);
3229 FindTrayEtc();
3230
3232 if (m_pMainIconItem)
3233 {
3236 }
3237
3238 return m_hWnd;
3239}
3240
3242{
3244 m_hWnd = NULL;
3245}
3246
3248{
3249 CTrayIconWnd *pWnd = (CTrayIconWnd *)lParam;
3250
3251 TCHAR ClassName[60];
3252 ::GetClassName(hWnd, ClassName, _countof(ClassName));
3253 if (lstrcmp(ClassName, TEXT("TrayNotifyWnd")) != 0)
3254 return TRUE;
3255
3256 pWnd->m_hNotifyWnd = hWnd;
3257 return FALSE;
3258}
3259
3261{
3262 for (size_t iItem = 0; iItem < m_Items.size(); ++iItem)
3263 {
3264 auto pItem = m_Items[iItem];
3265 if (IsEqualGUID(rguid, pItem->m_guid))
3266 return pItem;
3267 }
3268 return NULL;
3269}
3270
3272{
3273 m_hTrayWnd = ::FindWindow(TEXT("Shell_TrayWnd"), NULL);
3274 if (!m_hTrayWnd)
3275 return FALSE;
3276
3278 if (!m_hNotifyWnd)
3279 return FALSE;
3281 m_hwndProgman = FindWindow(TEXT("Progman"), NULL);
3283 return TRUE;
3284}
3285
3287{
3289 FindTrayEtc();
3290 return m_hNotifyWnd;
3291}
3292
3295{
3296 if (g_pTipbarWnd)
3298
3299 for (size_t iItem = 0; iItem < m_Items.size(); ++iItem)
3300 {
3301 auto *pItem = m_Items[iItem];
3302 if (pItem)
3303 {
3304 if (uMsg == pItem->m_uCallbackMessage)
3305 {
3306 pItem->OnMsg(wParam, lParam);
3307 return TRUE;
3308 }
3309 }
3310 }
3311 return FALSE;
3312}
3313
3315{
3316 WNDCLASSEX wc = { sizeof(wc) };
3318 wc.hInstance = g_hInst;
3321 wc.lpszClassName = TEXT("CTrayIconWndClass");
3322 ::RegisterClassEx(&wc);
3323 return TRUE;
3324}
3325
3327{
3328 for (size_t iItem = 0; iItem < m_Items.size(); ++iItem)
3329 {
3330 auto pItem = m_Items[iItem];
3331 if (dwFlags & 0x1)
3332 {
3333 if (IsEqualGUID(pItem->m_guid, GUID_LBI_INATITEM) ||
3334 IsEqualGUID(pItem->m_guid, GUID_LBI_CTRL))
3335 {
3336 continue;
3337 }
3338 }
3339
3340 if (dwFlags & 0x2)
3341 {
3342 if (IsEqualGUID(pItem->m_guid, GUID_TFCAT_TIP_KEYBOARD))
3343 continue;
3344 }
3345
3346 if (pItem->m_uNotifyIconID < 0x1000)
3347 continue;
3348
3349 pItem->RemoveIcon();
3350 }
3351}
3352
3355{
3356 //FIXME
3357}
3358
3360{
3361 CButtonIconItem *pItem = FindIconItem(rguid);
3362 if (!pItem)
3363 {
3364 if (!hIcon)
3365 return FALSE;
3366 pItem = new(cicNoThrow) CButtonIconItem(this, dwUnknown24);
3367 if (!pItem)
3368 return FALSE;
3369
3370 pItem->_Init(m_hWnd, m_uCallbackMsg, m_uNotifyIconID, rguid);
3371 m_uCallbackMsg += 2;
3373 m_Items.Add(pItem);
3374 }
3375
3376 if (!hIcon)
3377 return pItem->RemoveIcon();
3378
3379 return pItem->SetIcon(hIcon, psz);
3380}
3381
3383{
3384 if (!hKL)
3385 {
3388 return TRUE;
3389 }
3390
3391 if (hKL != m_pMainIconItem->m_hKL)
3392 {
3393 WCHAR szText[64];
3394 HICON hIcon = TF_GetLangIcon(LOWORD(hKL), szText, _countof(szText));
3395 if (hIcon)
3396 {
3397 m_pMainIconItem->SetIcon(hIcon, szText);
3399 }
3400 else
3401 {
3404 m_pMainIconItem->SetIcon(hIcon, szText);
3405 }
3406
3407 m_pMainIconItem->m_hKL = hKL;
3408 }
3409
3410 return TRUE;
3411}
3412
3414{
3416}
3417
3419{
3420 if (pCS)
3422 else
3423 ::SetWindowLongPtr(hWnd, GWL_USERDATA, 0);
3424}
3425
3428{
3429 CTrayIconWnd *pThis;
3430 switch (uMsg)
3431 {
3432 case WM_CREATE:
3434 break;
3435 case WM_DESTROY:
3437 break;
3438 case WM_TIMER:
3439 if (wParam == 100)
3440 {
3441 ::KillTimer(hWnd, 100);
3442 pThis = CTrayIconWnd::GetThis(hWnd);
3443 if (pThis)
3444 pThis->CallOnDelayMsg();
3445 }
3446 break;
3447 default:
3448 {
3449 if (uMsg < WM_USER)
3450 return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
3451 pThis = CTrayIconWnd::GetThis(hWnd);
3452 if (pThis && pThis->OnIconMessage(uMsg, wParam, lParam))
3453 break;
3454 return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
3455 }
3456 }
3457 return 0;
3458}
3459
3460/***********************************************************************
3461 * CLBarItemBase
3462 */
3463
3465{
3466 m_dwItemStatus = 0;
3467 m_szToolTipText[0] = 0;
3468 m_cRefs = 1;
3470}
3471
3473{
3476}
3477
3478HRESULT
3480 REFIID riid,
3481 IUnknown *punk,
3482 DWORD *pdwCookie)
3483{
3484 if (IsEqualIID(riid, IID_ITfLangBarItemSink) || m_pLangBarItemSink)
3485 return TF_E_NOOBJECT;
3486
3487 HRESULT hr = punk->QueryInterface(IID_ITfLangBarItemSink, (void **)&m_pLangBarItemSink);
3488 if (SUCCEEDED(hr))
3489 *pdwCookie = 0x80000001;
3490 return hr;
3491}
3492
3494{
3495 if (dwCookie != 0x80000001)
3496 return E_FAIL;
3497
3498 if (!m_pLangBarItemSink)
3499 return E_UNEXPECTED;
3500
3503 return S_OK;
3504}
3505
3506void
3508 REFIID clsidService,
3509 REFGUID guidItem,
3510 DWORD dwStyle,
3511 DWORD ulSort,
3513{
3514 m_NewUIInfo.clsidService = clsidService;
3515 m_NewUIInfo.guidItem = guidItem;
3516 m_NewUIInfo.dwStyle = dwStyle;
3517 m_NewUIInfo.ulSort = ulSort;
3519}
3520
3521HRESULT
3523{
3524 DWORD dwOldStatus = m_dwItemStatus;
3525
3526 if (bShow)
3527 m_dwItemStatus &= ~TF_LBI_STATUS_HIDDEN;
3528 else
3529 m_dwItemStatus |= TF_LBI_STATUS_HIDDEN;
3530
3531 if (bUpdate && (dwOldStatus != m_dwItemStatus))
3532 {
3534 m_pLangBarItemSink->OnUpdate(TF_LBI_STATUS);
3535 }
3536
3537 return S_OK;
3538}
3539
3541{
3542 CopyMemory(pInfo, &m_NewUIInfo, sizeof(*pInfo));
3543 return S_OK;
3544}
3545
3547{
3548 *pdwStatus = m_dwItemStatus;
3549 return S_OK;
3550}
3551
3553{
3554 return ShowInternal(fShow, TRUE);
3555}
3556
3558{
3559 if (!pbstrToolTip)
3560 return E_INVALIDARG;
3562 *pbstrToolTip = bstr;
3563 return bstr ? S_OK : E_OUTOFMEMORY;
3564}
3565
3566/***********************************************************************
3567 * CUTBLBarMenu
3568 */
3569
3571{
3572 m_hInst = hInst;
3573}
3574
3576{
3577}
3578
3579STDMETHODIMP_(CCicLibMenuItem*) CUTBLBarMenu::CreateMenuItem()
3580{
3582 if (!pItem)
3583 return NULL;
3584 pItem->m_pLBarMenu = this;
3585 return pItem;
3586}
3587
3589{
3591 if (!pMenuUI)
3592 return NULL;
3593
3594 pMenuUI->Initialize();
3595 for (size_t iItem = 0; iItem < m_MenuItems.size(); ++iItem)
3596 {
3598 pItem->InsertToUI(pMenuUI);
3599 }
3600
3601 return pMenuUI;
3602}
3603
3604STDMETHODIMP_(CCicLibMenu*) CUTBLBarMenu::CreateSubMenu()
3605{
3606 return new(cicNoThrow) CUTBLBarMenu(m_hInst);
3607}
3608
3610{
3611 if (m_pMenuUI)
3612 return 0;
3613
3615 if (!m_pMenuUI)
3616 return -1;
3617
3618 INT nCommandId = m_pMenuUI->ShowModalPopup(pWindow, prcExclude, TRUE);
3619
3620 if (m_pMenuUI)
3621 {
3622 delete m_pMenuUI;
3623 m_pMenuUI = NULL;
3624 }
3625
3626 return nCommandId;
3627}
3628
3629/***********************************************************************
3630 * CUTBLBarMenuItem
3631 */
3632
3635{
3636 if ((m_dwFlags & 4) != 0)
3637 {
3638 pMenuUI->InsertSeparator();
3639 return TRUE;
3640 }
3641 if (m_dwFlags & 2)
3642 {
3643 //FIXME
3644 }
3645 else
3646 {
3647 //FIXME
3648 }
3649 return FALSE;
3650}
3651
3652/***********************************************************************
3653 * CLBarItemButtonBase
3654 */
3655
3657{
3658 if (m_hIcon)
3659 {
3661 m_hIcon = NULL;
3662 }
3663}
3664
3666{
3667 static const QITAB c_tab[] =
3668 {
3672 { NULL }
3673 };
3674 return ::QISearch(this, c_tab, riid, ppvObject);
3675}
3676
3678{
3679 return ++m_cRefs;
3680}
3681
3683{
3684 if (--m_cRefs == 0)
3685 {
3686 delete this;
3687 return 0;
3688 }
3689 return m_cRefs;
3690}
3691
3694{
3695 if (click == TF_LBI_CLK_RIGHT)
3696 {
3697 return E_NOTIMPL; //FIXME
3698 }
3699 if (click == TF_LBI_CLK_LEFT)
3700 {
3701 return E_NOTIMPL; //FIXME
3702 }
3703 return E_NOTIMPL;
3704}
3705
3707{
3708 return E_NOTIMPL;
3709}
3710
3712{
3713 return E_NOTIMPL;
3714}
3715
3717{
3718 return E_NOTIMPL;
3719}
3720
3722{
3723 if (!pbstr)
3724 return E_INVALIDARG;
3726 return (*pbstr ? S_OK : E_OUTOFMEMORY);
3727}
3728
3730{
3731 return CLBarItemBase::GetInfo(pInfo);
3732}
3733
3735{
3736 return CLBarItemBase::GetStatus(pdwStatus);
3737}
3738
3740{
3741 return CLBarItemBase::Show(fShow);
3742}
3743
3745{
3746 return CLBarItemBase::GetTooltipString(pbstrToolTip);
3747}
3748
3750 REFIID riid,
3751 IUnknown *punk,
3752 DWORD *pdwCookie)
3753{
3754 return CLBarItemBase::AdviseSink(riid, punk, pdwCookie);
3755}
3756
3758{
3759 return CLBarItemBase::UnadviseSink(dwCookie);
3760}
3761
3762/***********************************************************************
3763 * CLBarInatItem
3764 */
3765
3767{
3768 WCHAR szText[256];
3769 ::LoadStringW(g_hInst, IDS_LANGUAGE, szText, _countof(szText));
3770 InitNuiInfo(CLSID_SYSTEMLANGBARITEM, GUID_LBI_INATITEM, 0x20001, 0, szText);
3771
3776
3779}
3780
3782{
3783 HICON hIcon = NULL;
3784 INT iIndex = GetIconIndexFromhKL(m_hKL);
3785 if (iIndex != -1)
3786 hIcon = TF_InatExtractIcon(iIndex);
3787 *phIcon = hIcon;
3788 return S_OK;
3789}
3790
3792{
3793 if (!pbstr)
3794 return E_INVALIDARG;
3795
3796 WCHAR szText[256];
3797 if (!GethKLDesc(m_hKL, szText, _countof(szText)))
3798 return GetText(pbstr);
3799
3800 *pbstr = ::SysAllocString(szText);
3801 return S_OK;
3802}
3803
3805{
3807
3808 INT iKL, cKLs = TF_MlngInfoCount();
3809 for (iKL = 0; iKL < cKLs; ++iKL)
3810 {
3811 HKL hKL;
3812 WCHAR szDesc[128];
3813 if (TF_GetMlngHKL(iKL, &hKL, szDesc, _countof(szDesc)))
3814 {
3815 HICON hIcon = NULL;
3816 INT iIndex = GetIconIndexFromhKL(hKL);
3817 if (iIndex != -1)
3818 hIcon = TF_InatExtractIcon(iIndex);
3819
3820 LangBarInsertMenu(pMenu, iKL, szDesc, (hKL == m_hKL), hIcon);
3821 }
3822 }
3823
3825 if (g_pTipbarWnd &&
3828 (dwStatus & (TF_SFT_DESKBAND | TF_SFT_MINIMIZED)))
3829 {
3831
3832 WCHAR szText[256];
3834 LangBarInsertMenu(pMenu, 2000, szText, FALSE, NULL);
3835 }
3836
3837 return S_OK;
3838}
3839
3841{
3842 HKL hKL;
3843
3844 if (nCommandId == 2000)
3845 {
3846 if (g_pTipbarWnd)
3847 {
3849 if (pLangBarMgr)
3850 pLangBarMgr->ShowFloating(TF_SFT_SHOWNORMAL);
3851 }
3852 }
3853 else if (TF_GetMlngHKL(nCommandId, &hKL, NULL, 0))
3854 {
3856 HWND hwndFore = ::GetForegroundWindow();
3858 {
3859 BOOL FontSig = GetFontSig(hwndFore, hKL);
3860 ::PostMessage(hwndFore, WM_INPUTLANGCHANGEREQUEST, FontSig, (LPARAM)hKL);
3861 }
3862 }
3863
3864 return S_OK;
3865}
3866
3867/***********************************************************************
3868 * CTipbarGripper
3869 */
3870
3872 : CUIFGripper((pTipbarWnd ? pTipbarWnd->GetWindow() : NULL), prc, style)
3873{
3875 m_pTipbarWnd = pTipbarWnd;
3876}
3877
3879STDMETHODIMP_(void) CTipbarGripper::OnLButtonUp(LONG x, LONG y)
3880{
3882
3884 {
3885 APPBARDATA AppBar = { sizeof(AppBar) };
3886 AppBar.hWnd = ::FindWindowW(L"Shell_TrayWnd", NULL);
3888 {
3889 RECT rc = AppBar.rc;
3890 POINT pt;
3892 if (g_pTipbarWnd && ::PtInRect(&rc, pt))
3893 g_pTipbarWnd->m_pLangBarMgr->ShowFloating(TF_SFT_DESKBAND |
3894 TF_SFT_EXTRAICONSONMINIMIZED);
3895 }
3896 }
3897
3898 CUIFGripper::OnLButtonUp(x, y);
3900}
3901
3903STDMETHODIMP_(void) CTipbarGripper::OnRButtonUp(LONG x, LONG y)
3904{
3905 if (g_bShowDebugMenu)
3906 {
3907 // FIXME: Debugging feature
3908 }
3909}
3910
3911STDMETHODIMP_(BOOL) CTipbarGripper::OnSetCursor(UINT uMsg, LONG x, LONG y)
3912{
3913 if (m_bInDebugMenu)
3914 return FALSE;
3915
3916 return CUIFGripper::OnSetCursor(uMsg, x, y);
3917}
3918
3919/***********************************************************************
3920 * CLangBarItemList
3921 */
3922
3924{
3925 auto *pItem = FindItem(rclsid);
3926 if (!pItem)
3927 return FALSE;
3928 return pItem->m_bStartedIntentionally;
3929}
3930
3932{
3933 auto *pItem = FindItem(rclsid);
3934 if (pItem)
3935 return pIt