Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4958478
  • 博文数量: 1696
  • 博客积分: 10870
  • 博客等级: 上将
  • 技术积分: 18357
  • 用 户 组: 普通用户
  • 注册时间: 2007-03-30 15:16
文章分类
文章存档

2017年(1)

2016年(1)

2015年(1)

2013年(1)

2012年(43)

2011年(17)

2010年(828)

2009年(568)

2008年(185)

2007年(51)

分类: 嵌入式

2010-08-10 19:58:35

在使用WindowsMobile设备的时候,经常会涉及到SIP(软键盘)的操作,相关问题如下:
  • 若当SIP弹出,而窗体大小不变,就会出现窗体被SIP遮盖,无法进行操作;
解决方案:在.NET精简框架中提供了InputPanel控件来进行SIP的相关操作,InputPanel控件给我们提供了EnabledChanged(即输入法打开/关闭)事件,在该事件中可以控制相关控件大小以免出现控件被SIP遮住的情况。相关示例如下:
private voidinputPanelMain_EnabledChanged(object sender, EventArgs e)
       {
          RectangleVisibleRect = new Rectangle();

        //获得DataGrid控件(dgFirebase)的位置及大小
          VisibleRect= this.dgFirebase.Bounds;
         VisibleRect.Size = this.dgFirebase.Size;
          if(this.inputPanelMain.Enabled == true)
         {//若SIP被打开则将软键盘未遮盖的区域SIZE赋给dgFirebase(注:控件的Size是只读的,只能用对象赋值)
             Size si =new Size(this.inputPanelMain.VisibleDesktop.Width,this.inputPanelMain.VisibleDesktop.Height);
            VisibleRect.Size = si;
            this.dgFirebase.Bounds = VisibleRect;
          }
          else if(this.inputPanelMain.Enabled == false)
         {//若SIP被关闭则将dgFirebase的Size恢复
             Size si =new Size(this.inputPanelMain.VisibleDesktop.Width,VisibleRect.Height + this.inputPanelMain.Bounds.Height);
            VisibleRect.Size = si;
            this.dgFirebase.Bounds = VisibleRect;
          }
       }



 
     2.在.NET精简框架中提供了InputPanel控件来进行SIP的相关操作,但是InputPanel控件只给我们提供了EnabledChanged(即输入法打开/关闭)事件。而输入法的不同,则SIP的大小也不同,这就意味着在Enabled属性没有发生变化的情况下进行输入法切换,我们便无法及时获取新的面板高度以做出相应处理。就又会出现1.中的问题。
     有过Windows窗体程序编程经验的朋友都知道,用户对应用程序产生的动作是首先以消息的形式传递给操作系统,操作系统根据消息中的窗口句柄(hWnd)回调该窗口的的消息响应函数而得到应用程序的反馈的。既然.Net精简框架没有对此消息进行封装,那么我们只好自己手动处理消息了。

  在 Windows环境下我们可以通过重写System.Windows.Forms.Form类的WndProc()函数来实现对该窗体消息的控制。但 WindowsMobile环境下,WndProc()函数被挪到了Microsoft.WindowsCE.Forms.MessageWindow 类,我们可以继承此类并在WndProc()函数中处理0x001A(WM_WININICHANGE或WM_SETTINGCHANGE)消息来实现输 入法改变事件。

  下面是网上实现的一个InputPanel扩展类,增加了InputMethodChanged事件。相关示例如下:

using System;
using Microsoft.WindowsCE.Forms;
using System.Collections.Generic;
using System.Text;
using System.Data;



public class InputPanelEx : InputPanel
    {
       #regionFields

      ///
       ///当输入法切换时发生。
       ///

       public eventEventHandler InputMethodChanged;
       privateMsgHook Msg;
       internalclass MsgHook : MessageWindow
       {
          #regionFields

         privateconst int WM_SETTINGCHANGE = 0x001A;
          privateInputPanelEx BaseObject;

        #endregion
         #regionMethods
         publicMsgHook(InputPanelEx baseObj)
          {
             BaseObject= baseObj;
         }

         protectedoverride void WndProc(ref Message m)
          {
             if (m.Msg== WM_SETTINGCHANGE)
               BaseObject.InputMethodChanged(this,EventArgs.Empty);
            base.WndProc(ref m);
         }

        #endregion
       }

      #endregion
      #regionMethods
      publicInputPanelEx()
       {
          Msg = newMsgHook(this);
       }

      #endregion
    }



OK,有了这个扩展类,就可以解决2中的问题了。相关示例如下:
//先声明一个InputPanelEx类,为输入法切换事件添加方法
public staticInputPanelEx m_InputPanelEx = new InputPanelEx();
private void Form1_Load(object sender,EventArgs e)
       {
          if(this.inputPanelMain.Enabled == true)
           //inputPanelMain_EnabledChanged();这个函数在上面哈
            inputPanelMain_EnabledChanged(null, null);
          }
                 //
         m_InputPanelEx.InputMethodChanged+=newEventHandler(this.m_InputPanelEx_InputMethodChanged);
       }


public voidm_InputPanelEx_InputMethodChanged(object sender, EventArgs e)
       {
         this.inputPanelMain_EnabledChanged(null,null);
       }
阅读(861) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~