C#
一种面向对象的类型安全的编程语言,它起源于 C 语言系列,包括对面向组件的编程的支持。
225 个问题
项目很简单,就一个主窗口。xaml代码:
<Window x:Class="输入法测试.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:输入法测试"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid Background="LightBlue">
</Grid>
</Window>
C#代码:
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;
namespace 输入法测试
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Loaded += MainWindow_Loaded;
}
#region Win32
[DllImport("imm32.dll")]
public static extern IntPtr ImmGetContext(IntPtr hWnd);
[DllImport("imm32.dll", CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool ImmSetCompositionFont(IntPtr hIMC, ref LOGFONT font);
[DllImport("imm32.dll")]
public static extern bool ImmSetCompositionWindow(IntPtr hIMC, ref COMPOSITIONFORM lpCompForm);
[DllImport("imm32.dll")]
public static extern bool ImmReleaseContext(IntPtr hWnd, IntPtr hIMC);
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left, top, right, bottom;
}
[StructLayout(LayoutKind.Sequential)]
public struct COMPOSITIONFORM
{
public int dwStyle;
public POINT ptCurrentPos;
public RECT rcArea;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct LOGFONT
{
public int lfHeight, lfWidth, lfEscapement, lfOrientation, lfWeight;
public byte lfItalic,
lfUnderline,
lfStrikeOut,
lfCharSet,
lfOutPrecision,
lfClipPrecision,
lfQuality,
lfPitchAndFamily;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string lfFaceName;
}
public const int CFS_POINT = 0x0002;
public const int WM_IME_COMPOSITION = 0x010F;
#endregion
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
InputMethod.SetIsInputMethodSuspended(this, true);
// 获取窗口句柄源
HwndSource hwndSource = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
// 监听窗口消息
hwndSource.AddHook(WndProc);
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
switch (msg)
{
case WM_IME_COMPOSITION:
// 字号,用于调整候选框垂直偏移
LOGFONT font = new LOGFONT();
font.lfHeight = 16;
// 坐标,调整候选框相对于客户区左上角的偏移
COMPOSITIONFORM point = new COMPOSITIONFORM
{
dwStyle = CFS_POINT,
ptCurrentPos = new POINT { x = 0, y = 0 }
};
// 获取输入法上下文
IntPtr context = ImmGetContext(hwnd);
// 设置字体
ImmSetCompositionFont(context, ref font);
// 设置候选框位置
ImmSetCompositionWindow(context, ref point);
// 释放输入法上下文
ImmReleaseContext(hwnd, context);
handled = true;
break;
}
return IntPtr.Zero;
}
}
}
编译并运行后,必需切换至其他应用(或点击桌面)再切回来,才可以在中文输入状态下唤出候选框: