在編寫全屏應用程式時,為了充分利用螢幕空間,將IME面板取消。但是沒有IME面板,怎麼進行輸入,如何設定輸入面板顯示的位置呢?其中一種可行的方法是進行P/Invoke調用,在程式中調用IME,介面如下:
代碼如下所示:
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace SmartDeviceProject1
{
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
public struct SIPINFO
{
public int cbSize; // Set to 48
public int fdwFlags; // Set to 0
public Rectangle rcVisibleDesktop; // set to 0,0,0,0
public Rectangle rcSipRect;
public int dwImDataSize; // Set to 0
public IntPtr pvImData; // Set to IntPtr.Zero
public SIPINFO(int anyOne)
{
cbSize = Marshal.SizeOf(typeof(SIPINFO));
fdwFlags = 0; // Set to 0
rcVisibleDesktop = new Rectangle(0, 0, 0, 0);
rcSipRect = new Rectangle(0, 0, 0, 0);
dwImDataSize = 0;
pvImData = IntPtr.Zero;
}
}
public partial class Form1 : Form
{
[DllImport("coredll.dll")]
public extern static void SipShowIM(uint dwFlag);
[DllImport("coredll.dll")]
public extern static bool SipSetDefaultRect(ref RECT rectf);
[DllImport("coredll.dll")]
public extern static bool SipSetCurrentIM(ref IntPtr cslid);
[DllImport("coredll.dll")]
public extern static bool SipGetCurrentIM(ref IntPtr cslid);
[DllImport("coredll")]
public extern static bool SipGetInfo(ref SIPINFO sipInfo);
public static uint SIPF_OFF = 0x00;
public static uint SIPF_ON = 0x01;
private RECT originalRect;
private int sipClsid;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//將輸入面板上移50,開啟IME
SIPINFO sipInfo = new SIPINFO(0);
SipGetInfo(ref sipInfo);
originalRect = new RECT();
originalRect.Left = sipInfo.rcSipRect.X;
originalRect.Top = sipInfo.rcSipRect.Y;
originalRect.Right = sipInfo.rcSipRect.Right;
originalRect.Bottom = sipInfo.rcSipRect.Height;
RECT newRect = new RECT();
newRect.Left = sipInfo.rcSipRect.X;
newRect.Top = sipInfo.rcSipRect.Y - 50;
newRect.Right = sipInfo.rcSipRect.Right;
newRect.Bottom = sipInfo.rcSipRect.Height - 50;
SipSetDefaultRect(ref newRect);
sipClsid = inputPanel1.InputMethods[1].Clsid.GetHashCode();
IntPtr pointClsid = new IntPtr(sipClsid);
if (SipGetCurrentIM(ref pointClsid))
{
SipSetCurrentIM(ref pointClsid);
}
pointClsid = IntPtr.Zero;
SipShowIM(SIPF_ON);
}
private void Form1_Closing(object sender, CancelEventArgs e)
{
//還原原始輸入面板位置,關閉IME
SipSetDefaultRect(ref originalRect);
sipClsid = inputPanel1.InputMethods[1].Clsid.GetHashCode();
IntPtr pointClsid = new IntPtr(sipClsid);
if (SipGetCurrentIM(ref pointClsid))
{
SipSetCurrentIM(ref pointClsid);
}
pointClsid = IntPtr.Zero;
SipShowIM(SIPF_OFF);
}
}
}
更多內容,請參考Alex Gusev的文章:Managing the Software Input Panel in Your Applications