Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,59 +1,32 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

//
//
//
// Description: Creates ITfInputProcessorProfiles instances.
//
//

using System.Runtime.InteropServices;
using System.Globalization;
using System.Threading;
using MS.Win32;
using System.Globalization;
using System.Collections;

namespace System.Windows.Input
{
//------------------------------------------------------
//
// InputProcessorProfiles class
//
//------------------------------------------------------

/// <summary>
/// The InputProcessorProfiles class is always associated with
/// hwndInputLanguage class.
/// The <see cref="InputProcessorProfiles"/> class is always associated with hwndInputLanguage class.
/// </summary>
internal class InputProcessorProfiles
internal sealed class InputProcessorProfiles
{
//------------------------------------------------------
//
// Constructors
//
//------------------------------------------------------

/// <summary>
/// InputProcessorProfiles Constructor;
/// </summary>
/// Critical - as this sets the value for _ipp.
/// Safe - as this just initializes it to null.
internal InputProcessorProfiles()
{
// _ipp is a ValueType, hence no need for new.
_ipp = null;
_cookie = UnsafeNativeMethods.TF_INVALID_COOKIE;
}

//------------------------------------------------------
//
// Internal Methods
//
//------------------------------------------------------

#region Internal Methods

/// <summary>
/// Initialize an interface and notify sink.
/// </summary>
Expand Down Expand Up @@ -81,19 +54,11 @@ internal void Uninitialize()
{
Debug.Assert(_ipp != null, "Uninitialize called without initializing");

UnadviseNotifySink();
UnadviseNotifySink();
Marshal.ReleaseComObject(_ipp);
_ipp = null;
}

#endregion Internal Methods

//------------------------------------------------------
//
// Internal Properties
//
//------------------------------------------------------

/// <summary>
/// Get the current input language of the current thread.
/// </summary>
Expand All @@ -112,7 +77,7 @@ internal short CurrentInputLanguage
IntPtr[] hklList = null;

int count = (int)SafeNativeMethods.GetKeyboardLayoutList(0, null);
if (count > 1)
if (count > 1)
{
hklList = new IntPtr[count];

Expand All @@ -123,7 +88,7 @@ internal short CurrentInputLanguage
{
if (value == (short)hklList[i])
{
SafeNativeMethods.ActivateKeyboardLayout(new HandleRef(this,hklList[i]), 0);
SafeNativeMethods.ActivateKeyboardLayout(new HandleRef(this, hklList[i]), 0);
break;
}
}
Expand All @@ -134,43 +99,29 @@ internal short CurrentInputLanguage
}

/// <summary>
/// Get the list of the input languages that are available in the
/// current thread.
/// Get the list of the input languages that are available in the current thread.
/// </summary>
internal ArrayList InputLanguageList
internal unsafe CultureInfo[] InputLanguageList
{
get
{
int nCount;
IntPtr langids;

// ITfInputProcessorProfiles::GetLanguageList returns the pointer that was allocated by
// CoTaskMemAlloc().
_ipp.GetLanguageList(out langids, out nCount);
get
{
// ITfInputProcessorProfiles::GetLanguageList returns the pointer that was allocated by CoTaskMemAlloc().
_ipp.GetLanguageList(out nint ptrLanguageIDs, out int nCount);

ArrayList arrayLang = new ArrayList();
ReadOnlySpan<short> languageIDs = new((void*)ptrLanguageIDs, nCount);
CultureInfo[] langArray = new CultureInfo[nCount];

for (int i = 0; i < nCount; i++)
{
// Unmarshal each langid from short array.
short langid = Marshal.PtrToStructure<short>((IntPtr)((Int64)langids + sizeof(short) * i));
arrayLang.Add(new CultureInfo(langid));
}
// Create CultureInfo from each ID and store it
for (int i = 0; i < langArray.Length; i++)
langArray[i] = new CultureInfo(languageIDs[i]);

// Call CoTaskMemFree().
Marshal.FreeCoTaskMem(langids);
// Call CoTaskMemFree().
Marshal.FreeCoTaskMem(ptrLanguageIDs);

return arrayLang;
}
return langArray;
}
}


//------------------------------------------------------
//
// Private Methods
//
//------------------------------------------------------

/// <summary>
/// This advices the input language notify sink to
/// ITfInputProcessorProfile.
Expand Down Expand Up @@ -201,16 +152,14 @@ private void UnadviseNotifySink()
_cookie = UnsafeNativeMethods.TF_INVALID_COOKIE;
}

//------------------------------------------------------
//
// Private Fields
//
//------------------------------------------------------

// The reference to ITfInputProcessorProfile.
/// <summary>
/// The reference to <see cref="UnsafeNativeMethods.ITfInputProcessorProfiles"/>.
/// </summary>
private UnsafeNativeMethods.ITfInputProcessorProfiles _ipp;

// The cookie for the advised sink.
/// <summary>
/// The cookie for the advised sink.
/// </summary>
private int _cookie;
}
}