{
  拦截输入法输入的字符串。向编辑框中输入中文查看效果。
  Delphi XE7
}

unit Unit1;

interface

uses
    Winapi.Windows,
    Winapi.Messages,
    System.SysUtils,
    System.Variants,
    System.Classes,
    Vcl.Graphics,
    Vcl.Controls,
    Vcl.Forms,
    Vcl.Dialogs,
    Vcl.StdCtrls,
    Winapi.Imm;

type
    TForm1 = class( TForm )
        edt1 : TEdit;
        procedure FormCreate( Sender : TObject );
        private
            { Private declarations }
        public
            { Public declarations }
    end;

var
    Form1       : TForm1;
    DestHwnd    : HWND;
    DestWinPorc : Pointer;

implementation

{$R *.dfm}

procedure OnWM_IME_COMPOSITION( HWND, msg, wParam, lParam : longint );
var

    ResultStr : string;
    hIMC      : Integer;
    dwSize    : Integer;
    StrLength : Integer;
begin
    if ( lParam and GCS_RESULTSTR ) <> 0 then
        begin
            // 先获取当前正在输入的窗口的输入法句柄
            hIMC := ImmGetContext( Form1.edt1.Handle );
            // 先将ImmGetCompositionString的获取长度设为0来获取字符串大小.
            dwSize := ImmGetCompositionString(
                hIMC,
                GCS_RESULTSTR,
                nil,
                0 );

            // 缓冲区大小要加上字符串的NULL结束符大小,
            // 考虑到UNICODE
            StrLength := dwSize div Integer( sizeof( Char ) );
            OutputDebugString( PWideChar( IntToStr( Length( ResultStr ) ) ) );
            SetLength(
                ResultStr,
                StrLength );
            OutputDebugString( PWideChar( ResultStr ) );
            // 再调用一次.ImmGetCompositionString获取字符串
            ImmGetCompositionString(
                hIMC,
                GCS_RESULTSTR,
                PChar( ResultStr ),
                dwSize );
            // 现在ResultStr里面即是输入的汉字了。
            OutputDebugString( '-------------------' );
            OutputDebugString( PWideChar( ResultStr ) );
            OutputDebugString( '-------------------' );
            ImmReleaseContext(
                HWND,
                hIMC );
        end;

end;

function WinProc( HWND, msg, wParam, lParam : longint ) : LRESULT; stdcall;
begin
    case msg of
        WM_IME_COMPOSITION :
            OnWM_IME_COMPOSITION( HWND, msg, wParam, lParam );
    end;
    result := CallWindowProc(
        DestWinPorc,
        HWND,
        msg,
        wParam,
        lParam );
end;

procedure TForm1.FormCreate( Sender : TObject );
begin
    DestHwnd    := Self.edt1.Handle;
    DestWinPorc := Pointer( GetWindowLong( Self.edt1.Handle, GWL_WNDPROC ) );
    SetWindowLong(
        DestHwnd,
        GWL_WNDPROC,
        longint( @WinProc ) );
end;

end.

 

posted on 2018-12-16 21:53  IT菜鸟的博客  阅读(913)  评论(0编辑  收藏  举报