原创文章,转载请保留信息 得闲笔记欢迎您 www.cnblogs.com/dxsoft
作者:不得闲
今天,有个朋友问,如何去实现让一个输入控件,比如Edit中不能输入中文!而且不能让用户切换到任何其他输入法,始终保持为英文输入!群中很多人都说用ImeCode等来控制,这个控制是没错!但是,本控制无法控制使用的过程中用户自己切换输入法的问题,此时我们应该不让用户去切换输入法!所以最终的实现方式,应该对系统的IME的消息进行拦截来达到目的,在以前做游戏中弹出窗口输入信息时,需要自己模拟输入法的信息,然后在游戏内部窗口中绘制出输入法的相关信息,那时对输入法的控制有研究过几天,而且也基本上实现了对输入法的输出信息进行捕捉和控制等!现在将那个东西开源出来,以便于大家共同探讨提高!示例截图:
从图中可以看出,基本上实现了将输入法的信息截获显示在下面的Label控件中,并且有对每个Edit的输入法做相应的控制!
详细代码:
(*
****************************************************
*)
(* 得闲工作室 *)
(* 输入法截获与控制单元库 *)
(* *)
(* DxImeOperControl Unit *)
(* DxImeOperControl Version 1.x *)
(* Copyright(c) 2009-2010 不得闲 *)
(* email:appleak46@yahoo.com.cn QQ:75492895 *)
(* **************************************************** *)
unit DxImeOperControl;
interface
uses Windows,SysUtils,Messages,Classes,Imm,Controls,Forms;
type
TDxImeControl = class ;
pControlRec = ^TControlRec;
TControlRec = record
LinkControl: TWinControl;
OldWndProc: Pointer;
OldWndMethod: TWndMethod;
OwnIme: TDxImeControl;
end ;
TImeChangeEvent = procedure (Sender: TObject;ImeControl: TWinControl;ImeName: string ;ImeFileName: string ; var AcceptChange: Boolean) of object ;
TImeKeyChangeEvent = procedure (Sender: TObject;ImeControl: TWinControl;KeyInputStr: string ;CursorPos: integer;InResult: string ) of object ;
TImeKeyResultEvent = procedure (Sender: TObject;ImeControl: TWinControl;InputResult: string ) of object ;
TImeCandListOpenEvent = procedure (Sender: TObject;ImeControl: TWinControl;List: TStrings) of object ;
TNotifyInfo = (SetConversionModeInfo,OpenCandDateInfo,ChangeCandDateInfo,CloseCandDateInfo);
{ 通知类型:全半角/中英文标点变化,进入选字,翻页,关闭选字列表 }
TImeNotifyEvent = procedure (Sender: TObject;NotifyInfo: TNotifyInfo) of object ;
TDxImeControl = class (TComponent)
private
FLinkHandle: THandle;
FImc: HIMC;
FLinkForm: TCustomForm;
FOnImeActive: TNotifyEvent;
FEnabled: boolean;
FOnImeChange: TImeChangeEvent;
FOnKeyInput: TImeKeyChangeEvent;
FPageCount: Integer;
FCurrentPage: Integer;
CandList: TStringList;
KeyBoardLayOut: Integer;
FShowSoftKeyBoard: Boolean;
FOnKeyInputed: TImeKeyResultEvent;
FOnStartKeyInput: TNotifyEvent;
FCurrentHwnd: THandle;
FImeName: array [ 0 .. 50 ] of char;
FOnImeNotify: TImeNotifyEvent;
FOnCandListOpen: TImeCandListOpenEvent;
FShowOpenStatus: Boolean;
FKeyListStr: string ;
procedure SetLinkHandle( const Value: THandle);
function GetImeCompositonString: string ;
function GetImeResult: string ;
function GetImeOpen: Boolean;
procedure SetLinkForm( const Value: TCustomForm);
procedure SetEnabled( const Value: boolean);
procedure RestoreLinkWndProc;
procedure SetShowSoftKeyBoard( const Value: Boolean);
procedure setCurrentHwnd( const Value: THandle);
procedure SetShowOpenStatus( const Value: Boolean);
function GetShowOpenStatus: Boolean;
function GetImeName: string ;
public
constructor Create(AOwner: TComponent); override ;
destructor Destroy; override ;
function SetInputIme(Control: TWinControl;ToImeFileName: string ): Boolean; // 设置输入法
procedure SetIme(Control: TWinControl;AImeName: string );
procedure SetCompositionString(Control: TWinControl;SetStr: string ); // 设定组字字符
property InputStr: string read GetImeCompositonString; // 获得正在输入的字符串
property InputResult: string read GetImeResult; // 获得输入的选字结果
property LinkForm: TCustomForm read FLinkForm write SetLinkForm; // 指定连接上哪个窗体,连接上的窗体都会被处理
property Imc: HIMC read FImc;
property ImeName: string read GetImeName;
property ImeOpen: Boolean read GetImeOpen;
property PageCount: Integer read FPageCount;
property CurrentPage: Integer read FCurrentPage;
procedure GetCandList(FCandList: TStrings;Page: Integer = 0 ); // 获得侯选字列表
property CurrentHwnd: THandle read FCurrentHwnd write setCurrentHwnd;
procedure ChangeToChinese(ChangeControl: TWinControl;ChangeChildren: Boolean = true;ToChinese: Boolean = true);
procedure NextIme;
property KeyListStr: string read FKeyListStr;
published
property Enabled: boolean read FEnabled write SetEnabled; // 是否可用,捕获输入法消息
property OnImeActive: TNotifyEvent read FOnImeActive write FOnImeActive; // 输入法激活时触发
property OnImeChange: TImeChangeEvent read FOnImeChange write FOnImeChange; // 输入法改变时触发事件
property OnKeyInput: TImeKeyChangeEvent read FOnKeyInput write FOnKeyInput; // 输入时触发
property OnKeyInputed: TImeKeyResultEvent read FOnKeyInputed write FOnKeyInputed;
property OnStartKeyInput: TNotifyEvent read FOnStartKeyInput write FOnStartKeyInput;
// property ShowSoftKeyBoard: Boolean read FShowSoftKeyBoard write SetShowSoftKeyBoard; // 是否显示小键盘
property OnImeNotify: TImeNotifyEvent read FOnImeNotify write FOnImeNotify;
property OnCandListOpen: TImeCandListOpenEvent read FOnCandListOpen write FOnCandListOpen;
property ShowOpenStatus: Boolean read GetShowOpenStatus write SetShowOpenStatus;
end ;
implementation
var
WndList: TList;
end .
(* 得闲工作室 *)
(* 输入法截获与控制单元库 *)
(* *)
(* DxImeOperControl Unit *)
(* DxImeOperControl Version 1.x *)
(* Copyright(c) 2009-2010 不得闲 *)
(* email:appleak46@yahoo.com.cn QQ:75492895 *)
(* **************************************************** *)
unit DxImeOperControl;
interface
uses Windows,SysUtils,Messages,Classes,Imm,Controls,Forms;
type
TDxImeControl = class ;
pControlRec = ^TControlRec;
TControlRec = record
LinkControl: TWinControl;
OldWndProc: Pointer;
OldWndMethod: TWndMethod;
OwnIme: TDxImeControl;
end ;
TImeChangeEvent = procedure (Sender: TObject;ImeControl: TWinControl;ImeName: string ;ImeFileName: string ; var AcceptChange: Boolean) of object ;
TImeKeyChangeEvent = procedure (Sender: TObject;ImeControl: TWinControl;KeyInputStr: string ;CursorPos: integer;InResult: string ) of object ;
TImeKeyResultEvent = procedure (Sender: TObject;ImeControl: TWinControl;InputResult: string ) of object ;
TImeCandListOpenEvent = procedure (Sender: TObject;ImeControl: TWinControl;List: TStrings) of object ;
TNotifyInfo = (SetConversionModeInfo,OpenCandDateInfo,ChangeCandDateInfo,CloseCandDateInfo);
{ 通知类型:全半角/中英文标点变化,进入选字,翻页,关闭选字列表 }
TImeNotifyEvent = procedure (Sender: TObject;NotifyInfo: TNotifyInfo) of object ;
TDxImeControl = class (TComponent)
private
FLinkHandle: THandle;
FImc: HIMC;
FLinkForm: TCustomForm;
FOnImeActive: TNotifyEvent;
FEnabled: boolean;
FOnImeChange: TImeChangeEvent;
FOnKeyInput: TImeKeyChangeEvent;
FPageCount: Integer;
FCurrentPage: Integer;
CandList: TStringList;
KeyBoardLayOut: Integer;
FShowSoftKeyBoard: Boolean;
FOnKeyInputed: TImeKeyResultEvent;
FOnStartKeyInput: TNotifyEvent;
FCurrentHwnd: THandle;
FImeName: array [ 0 .. 50 ] of char;
FOnImeNotify: TImeNotifyEvent;
FOnCandListOpen: TImeCandListOpenEvent;
FShowOpenStatus: Boolean;
FKeyListStr: string ;
procedure SetLinkHandle( const Value: THandle);
function GetImeCompositonString: string ;
function GetImeResult: string ;
function GetImeOpen: Boolean;
procedure SetLinkForm( const Value: TCustomForm);
procedure SetEnabled( const Value: boolean);
procedure RestoreLinkWndProc;
procedure SetShowSoftKeyBoard( const Value: Boolean);
procedure setCurrentHwnd( const Value: THandle);
procedure SetShowOpenStatus( const Value: Boolean);
function GetShowOpenStatus: Boolean;
function GetImeName: string ;
public
constructor Create(AOwner: TComponent); override ;
destructor Destroy; override ;
function SetInputIme(Control: TWinControl;ToImeFileName: string ): Boolean; // 设置输入法
procedure SetIme(Control: TWinControl;AImeName: string );
procedure SetCompositionString(Control: TWinControl;SetStr: string ); // 设定组字字符
property InputStr: string read GetImeCompositonString; // 获得正在输入的字符串
property InputResult: string read GetImeResult; // 获得输入的选字结果
property LinkForm: TCustomForm read FLinkForm write SetLinkForm; // 指定连接上哪个窗体,连接上的窗体都会被处理
property Imc: HIMC read FImc;
property ImeName: string read GetImeName;
property ImeOpen: Boolean read GetImeOpen;
property PageCount: Integer read FPageCount;
property CurrentPage: Integer read FCurrentPage;
procedure GetCandList(FCandList: TStrings;Page: Integer = 0 ); // 获得侯选字列表
property CurrentHwnd: THandle read FCurrentHwnd write setCurrentHwnd;
procedure ChangeToChinese(ChangeControl: TWinControl;ChangeChildren: Boolean = true;ToChinese: Boolean = true);
procedure NextIme;
property KeyListStr: string read FKeyListStr;
published
property Enabled: boolean read FEnabled write SetEnabled; // 是否可用,捕获输入法消息
property OnImeActive: TNotifyEvent read FOnImeActive write FOnImeActive; // 输入法激活时触发
property OnImeChange: TImeChangeEvent read FOnImeChange write FOnImeChange; // 输入法改变时触发事件
property OnKeyInput: TImeKeyChangeEvent read FOnKeyInput write FOnKeyInput; // 输入时触发
property OnKeyInputed: TImeKeyResultEvent read FOnKeyInputed write FOnKeyInputed;
property OnStartKeyInput: TNotifyEvent read FOnStartKeyInput write FOnStartKeyInput;
// property ShowSoftKeyBoard: Boolean read FShowSoftKeyBoard write SetShowSoftKeyBoard; // 是否显示小键盘
property OnImeNotify: TImeNotifyEvent read FOnImeNotify write FOnImeNotify;
property OnCandListOpen: TImeCandListOpenEvent read FOnCandListOpen write FOnCandListOpen;
property ShowOpenStatus: Boolean read GetShowOpenStatus write SetShowOpenStatus;
end ;
implementation
var
WndList: TList;
end .