본문 바로가기

카테고리 없음

[시스템] 조합중인 한글 얻기

반응형
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls, Buttons, Imm;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Edit1KeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
  private
    { Private declarations }
    FEditProc: Pointer;
    FEditProcOrg: Pointer;
    procedure EditProc(var Message: TMessage);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.EditProc(var Message: TMessage);
var
  Imc: HIMC;
  L: Integer;
  S: String;
begin
  case Message.Msg of
    WM_IME_COMPOSITION:
    begin
      // 조합중이면
      if (Message.lparam and GCS_COMPSTR) = GCS_COMPSTR then
      begin
        Imc := ImmGetContext(Edit1.Handle);
        try
          // 현재 IME의 스트링 길이를 얻는다
          L := ImmGetCompositionString(Imc, GCS_COMPSTR, nil, 0);
          SetLength(S, L+1);
          // 조합중인 문자열을 받아낸다
          ImmGetCompositionString(Imc, GCS_COMPSTR, PChar(S), L+1);
          SetLength(S, L);
          Label1.Caption := S;
        finally
          ImmReleaseContext(Edit1.Handle, Imc);
        end;
      end
      // 한 글자가 완성되면
      else if  (Message.lparam and GCS_RESULTSTR) = GCS_RESULTSTR then
      begin
        Imc := ImmGetContext(Edit1.Handle);
        try
          L := ImmGetCompositionString(Imc, GCS_RESULTSTR, nil, 0);
          SetLength(S, L+1);
          ImmGetCompositionString(Imc, GCS_RESULTSTR, PChar(S), L+1);
          SetLength(S, L);
          Label2.Caption := S;
        finally
          ImmReleaseContext(Edit1.Handle, Imc);
        end;
      end;
    end;
  end;
  Message.Result := CallWindowProc(FEditProcOrg, Edit1.Handle, Message.Msg, Message.WParam, Message.LParam);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FEditProc := MakeObjectInstance(EditProc);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FreeObjectInstance(FEditProc);
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  // Edit1 의 Windows Procedure 를 가로챈다
  FEditProcOrg := Pointer(GetWindowLong(Edit1.Handle, GWL_WNDPROC));
  SetWindowLong(Edit1.Handle, GWL_WNDPROC, Longint(FEditProc));
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  SetWindowLong(Edit1.Handle, GWL_WNDPROC, Longint(FEditProcOrg));
end;

procedure TForm1.Edit1KeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  Label3.Caption := Edit1.Text;
end;

end.
반응형