void FWindowsTextInputMethodSystem::Terminate() { HRESULT Result; // Get source from thread manager, needed to uninstall profile processor related sinks. TComPtr<ITfSource> TSFSource; Result = TSFSource.FromQueryInterface(IID_ITfSource, TSFThreadManager); if(FAILED(Result) || !TSFSource) { UE_LOG(LogWindowsTextInputMethodSystem, Error, TEXT("Terminating failed while acquiring the TSF source from the TSF thread manager.")); } if(TSFSource && TSFActivationProxy) { // Uninstall language notification sink. if(TSFActivationProxy->TSFLanguageCookie != TF_INVALID_COOKIE) { Result = TSFSource->UnadviseSink(TSFActivationProxy->TSFLanguageCookie); if(FAILED(Result)) { UE_LOG(LogWindowsTextInputMethodSystem, Error, TEXT("Terminating failed while unadvising the language notification sink from the TSF source.")); } } // Uninstall profile notification sink. if(TSFActivationProxy->TSFProfileCookie != TF_INVALID_COOKIE) { Result = TSFSource->UnadviseSink(TSFActivationProxy->TSFProfileCookie); if(FAILED(Result)) { UE_LOG(LogWindowsTextInputMethodSystem, Error, TEXT("Terminating failed while unadvising the profile notification sink from the TSF source.")); } } } TSFActivationProxy.Reset(); Result = TSFThreadManager->Deactivate(); if(FAILED(Result)) { UE_LOG(LogWindowsTextInputMethodSystem, Error, TEXT("Terminating failed while deactivating the TSF thread manager.")); } TSFThreadManager.Reset(); ::ImmDestroyContext(IMMContextId); }
bool FWindowsTextInputMethodSystem::InitializeTSF() { UE_LOG(LogWindowsTextInputMethodSystem, Verbose, TEXT("Initializing TSF...")); HRESULT Result = S_OK; // Input Processors { // Get input processor profiles. ITfInputProcessorProfiles* RawPointerTSFInputProcessorProfiles; Result = ::CoCreateInstance(CLSID_TF_InputProcessorProfiles, nullptr, CLSCTX_INPROC_SERVER, IID_ITfInputProcessorProfiles, reinterpret_cast<void**>(&(RawPointerTSFInputProcessorProfiles))); if(FAILED(Result)) { UE_LOG(LogWindowsTextInputMethodSystem, Error, TEXT("Initialzation failed while creating the TSF input processor profiles.")); return false; } TSFInputProcessorProfiles.Attach(RawPointerTSFInputProcessorProfiles); // Get input processor profile manager from profiles. Result = TSFInputProcessorProfileManager.FromQueryInterface(IID_ITfInputProcessorProfileMgr, TSFInputProcessorProfiles); if(FAILED(Result)) { UE_LOG(LogWindowsTextInputMethodSystem, Error, TEXT("Initialzation failed while acquiring the TSF input processor profile manager.")); TSFInputProcessorProfiles.Reset(); return false; } } // Thread Manager { // Create thread manager. ITfThreadMgr* RawPointerTSFThreadManager; Result = ::CoCreateInstance(CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, IID_ITfThreadMgr, reinterpret_cast<void**>(&(RawPointerTSFThreadManager))); if(FAILED(Result)) { UE_LOG(LogWindowsTextInputMethodSystem, Warning, TEXT("Initialzation failed while creating the TSF thread manager.")); TSFInputProcessorProfiles.Reset(); TSFInputProcessorProfileManager.Reset(); return false; } TSFThreadManager.Attach(RawPointerTSFThreadManager); // Activate thread manager. Result = TSFThreadManager->Activate(&(TSFClientId)); if(FAILED(Result)) { UE_LOG(LogWindowsTextInputMethodSystem, Error, TEXT("Initialzation failed while activating the TSF thread manager.")); TSFInputProcessorProfiles.Reset(); TSFInputProcessorProfileManager.Reset(); TSFThreadManager.Reset(); return false; } // Get source from thread manager, needed to install profile processor related sinks. TComPtr<ITfSource> TSFSource; Result = TSFSource.FromQueryInterface(IID_ITfSource, TSFThreadManager); if(FAILED(Result)) { UE_LOG(LogWindowsTextInputMethodSystem, Error, TEXT("Initialzation failed while acquiring the TSF source from TSF thread manager.")); TSFInputProcessorProfiles.Reset(); TSFInputProcessorProfileManager.Reset(); TSFThreadManager.Reset(); return false; } TSFActivationProxy = new FTSFActivationProxy(this); #pragma warning(push) #pragma warning(disable : 4996) // 'function' was was declared deprecated CA_SUPPRESS(28159) const DWORD WindowsVersion = ::GetVersion(); #pragma warning(pop) const DWORD WindowsMajorVersion = LOBYTE(LOWORD(WindowsVersion)); const DWORD WindowsMinorVersion = HIBYTE(LOWORD(WindowsVersion)); static const DWORD WindowsVistaMajorVersion = 6; static const DWORD WindowsVistaMinorVersion = 0; // Install profile notification sink for versions of Windows Vista and after. if(WindowsMajorVersion > WindowsVistaMajorVersion || (WindowsMajorVersion == WindowsVistaMajorVersion && WindowsMinorVersion >= WindowsVistaMinorVersion)) { Result = TSFSource->AdviseSink(IID_ITfInputProcessorProfileActivationSink, static_cast<ITfInputProcessorProfileActivationSink*>(TSFActivationProxy), &(TSFActivationProxy->TSFProfileCookie)); if(FAILED(Result)) { UE_LOG(LogWindowsTextInputMethodSystem, Error, TEXT("Initialzation failed while advising the profile notification sink to the TSF source.")); TSFInputProcessorProfiles.Reset(); TSFInputProcessorProfileManager.Reset(); TSFThreadManager.Reset(); TSFActivationProxy.Reset(); return false; } } // Install language notification sink for versions before Windows Vista. else { Result = TSFSource->AdviseSink(IID_ITfActiveLanguageProfileNotifySink, static_cast<ITfActiveLanguageProfileNotifySink*>(TSFActivationProxy), &(TSFActivationProxy->TSFLanguageCookie)); if(FAILED(Result)) { UE_LOG(LogWindowsTextInputMethodSystem, Error, TEXT("Initialzation failed while advising the language notification sink to the TSF source.")); TSFInputProcessorProfiles.Reset(); TSFInputProcessorProfileManager.Reset(); TSFThreadManager.Reset(); TSFActivationProxy.Reset(); return false; } } } // Disabled Document Manager Result = TSFThreadManager->CreateDocumentMgr(&(TSFDisabledDocumentManager)); if(FAILED(Result)) { UE_LOG(LogWindowsTextInputMethodSystem, Warning, TEXT("Initialzation failed while creating the TSF thread manager.")); TSFInputProcessorProfiles.Reset(); TSFInputProcessorProfileManager.Reset(); TSFThreadManager.Reset(); TSFActivationProxy.Reset(); return false; } // Default the focus to the disabled document manager. Result = TSFThreadManager->SetFocus(TSFDisabledDocumentManager); if(FAILED(Result)) { UE_LOG(LogWindowsTextInputMethodSystem, Error, TEXT("Initialzation failed while activating the TSF thread manager.")); TSFInputProcessorProfiles.Reset(); TSFInputProcessorProfileManager.Reset(); TSFThreadManager.Reset(); TSFActivationProxy.Reset(); TSFThreadManager.Reset(); return false; } UE_LOG(LogWindowsTextInputMethodSystem, Verbose, TEXT("Initialized TSF!")); return true; }
/** Accesses the correct visual studio instance if possible. */ EAccessVisualStudioResult AccessVisualStudioViaDTE(TComPtr<EnvDTE::_DTE>& OutDTE, const FString& InSolutionPath, const TArray<FVisualStudioSourceCodeAccessor::VisualStudioLocation>& InLocations) { EAccessVisualStudioResult AccessResult = EAccessVisualStudioResult::VSInstanceIsNotOpen; // Open the Running Object Table (ROT) IRunningObjectTable* RunningObjectTable; if(SUCCEEDED(GetRunningObjectTable(0, &RunningObjectTable)) && RunningObjectTable) { IEnumMoniker* MonikersTable; if(SUCCEEDED(RunningObjectTable->EnumRunning(&MonikersTable))) { MonikersTable->Reset(); // Look for all visual studio instances in the ROT IMoniker* CurrentMoniker; while(AccessResult != EAccessVisualStudioResult::VSInstanceIsOpen && MonikersTable->Next(1, &CurrentMoniker, NULL) == S_OK) { IBindCtx* BindContext; LPOLESTR OutName; if(SUCCEEDED(CreateBindCtx(0, &BindContext)) && SUCCEEDED(CurrentMoniker->GetDisplayName(BindContext, NULL, &OutName))) { if(IsVisualStudioDTEMoniker(FString(OutName), InLocations)) { TComPtr<IUnknown> ComObject; if(SUCCEEDED(RunningObjectTable->GetObject(CurrentMoniker, &ComObject))) { TComPtr<EnvDTE::_DTE> TempDTE; if (SUCCEEDED(TempDTE.FromQueryInterface(__uuidof(EnvDTE::_DTE), ComObject))) { // Get the solution path for this instance // If it equals the solution we would have opened above in RunVisualStudio(), we'll take that TComPtr<EnvDTE::_Solution> Solution; BSTR OutPath = nullptr; if (SUCCEEDED(TempDTE->get_Solution(&Solution)) && SUCCEEDED(Solution->get_FullName(&OutPath))) { FString Filename(OutPath); FPaths::NormalizeFilename(Filename); if (Filename == InSolutionPath) { OutDTE = TempDTE; AccessResult = EAccessVisualStudioResult::VSInstanceIsOpen; } SysFreeString(OutPath); } else { UE_LOG(LogVSAccessor, Warning, TEXT("Visual Studio is open but could not be queried - it may be blocked by a modal operation")); AccessResult = EAccessVisualStudioResult::VSInstanceIsBlocked; } } else { UE_LOG(LogVSAccessor, Warning, TEXT("Could not get DTE interface from returned Visual Studio instance")); AccessResult = EAccessVisualStudioResult::VSInstanceIsBlocked; } } else { UE_LOG(LogVSAccessor, Warning, TEXT("Couldn't get Visual Studio COM object")); AccessResult = EAccessVisualStudioResult::VSInstanceUnknown; } } } else { UE_LOG(LogVSAccessor, Warning, TEXT("Couldn't get display name")); AccessResult = EAccessVisualStudioResult::VSInstanceUnknown; } BindContext->Release(); CurrentMoniker->Release(); } MonikersTable->Release(); } else { UE_LOG(LogVSAccessor, Warning, TEXT("Couldn't enumerate ROT table")); AccessResult = EAccessVisualStudioResult::VSInstanceUnknown; } RunningObjectTable->Release(); } else { UE_LOG(LogVSAccessor, Warning, TEXT("Couldn't get ROT table")); AccessResult = EAccessVisualStudioResult::VSInstanceUnknown; } return AccessResult; }