Q&A

  • [질문]한글 1글자에 대한 한자목록을 가져오는 ImmGetConversionList 사용은 어떻게?
use imm;

var
  hKL : LongInt;
  byteBuf : PByte;
  hImc: THandle;
  lngLen : integer;
  lngRet : LongInt;
  dwSize : LongInt;

begin
  edtAnswer.Text := '가';

  hKL := GetKeyboardLayout(0);
  hImc := ImmGetDefaultIMEWnd(edtAnswer.Handle);
  lngLen := ImmGetConversionList(hKL,hImc,PChar(edtAnswer.Text),nil,0,GCL_CONVERSION);
  if lngLen > 0 then
     lngRet := ImmGetConversionList(hKL,hImc,PChar(edtAnswer.Text),@byteBuf,lngLen, GCL_CONVERSION);

  dwSize := byteBuf^;

  ImmReleaseContext(Handle, hImc);
end;

위와 같이 하였더니 에러는 나지 않는데 @byteBuf에 $140이라는 값이 들어오는데 이후 어떻게 변환하나요?
dwSize := byteBuf^ 에서 0x0000dd 에러가 나네요.
무엇이 잘못 되었는지 고수님들의 고견 부탁드립니다.
6  COMMENTS
  • Profile
    최용일 2009.07.22 22:58
    메모리 할당부터 해야죠...

    procedure TfrmMain.Button1Click(Sender: TObject);
    var
    IMC: HIMC;
    KL: HKL;
    ErrorCode: LongWord;
    Buffer: PByteArray;
    BufferSize: Integer;
    HanjaList: string;
    CandidateList: PCandidateList absolute Buffer;
    Index: Integer;
    begin
    Edit1.Text := '가';

    KL := GetKeyboardLayout(0);
    Imc := ImmGetDefaultIMEWnd(Edit1.Handle);
    BufferSize := ImmGetConversionList(KL, IMC, PChar(Edit1.Text), nil, 0, GCL_CONVERSION);
    if BufferSize <> 0 then
    begin
    GetMem(Buffer, BufferSize);
    FillChar(Buffer^, BufferSize, 0);
    try
    ErrorCode := ImmGetConversionList(KL, IMC, PChar(Edit1.Text), CandidateList, BufferSize, GCL_CONVERSION);
    SetLength(HanjaList, BufferSize - CandidateList.dwOffset[1]);
    Move(Buffer[CandidateList.dwOffset[1]], HanjaList[1], BufferSize - CandidateList.dwOffset[1]);
    for Index := 1 to Length(HanjaList) do
    begin
    if HanjaList[Index] = #0 then
    HanjaList[Index] := #32;
    end;
    Memo1.Lines.Add(HanjaList);
    finally
    FreeMem(Buffer, BufferSize)
    end;
    end;
    ImmReleaseContext(Handle, IMC);
    end;

  • Profile
    신철우 2009.07.23 00:36
    답변주셔서 감사합니다.
    우찌하다가 아래처럼 만들었더니 괜찮게 실행됩니다.
    charBuf를 array of char 로 주니까 에러나네요. 그래서 넉넉하게 512를 할당했는데 동적할당 방법은 어떻게 되나요.

    var
    hKL,lngRet : LongInt; //signed 4bytes
    charBuf: array[0..511] of char;
    hImc: THandle;
    intLen,iStart,i : integer;
    hjList : string;

    begin
    edtAnswer.Text := '가';

    hKL := GetKeyboardLayout(0);
    hImc := ImmGetDefaultIMEWnd(edtAnswer.Handle);
    intLen := ImmGetConversionList(hKL,hImc,PChar(edtAnswer.Text),nil,0,GCL_CONVERSION);
    if intLen > 0 then
    begin
    FillChar(charBuf, 512, 0);
    lngRet := ImmGetConversionList(hKL,hImc,PChar(edtAnswer.Text),@charBuf,intLen,GCL_CONVERSION);
    if lngRet > 0 then
    begin
    //dwOffset 적용(24~27 low->high)
    iStart := byte(charBuf[24]) + byte(charBuf[25]) * 256;

    for i := iStart to intLen - 1 do
    AppendStr(hjList,charBuf[i]);

    for i := 1 to (length(hjList) div 3) do
    Memo1.Lines.Add(copy(hjList,(i-1)*3+1,2));
    end;
    ImmReleaseContext(Handle,hImc);
    end;
    end;
  • Profile
    최용일 2009.07.23 06:33
    위 코드가 동적할당하는 코드인데요...
    array of char로 잡으실려면 FillChar위에 SetLength(charBuf, intLen); 을 추가해 주시면 될것같네요...
  • Profile
    신철우 2009.07.23 15:32
    거듭 감사드립니다.


    charBuf : array of char;

    .
    .
    SetLength(charBuf, intLen);
    FillChar(charBuf, intLen, 0);
    lngRet := ImmGetConversionList(hKL,hImc,PChar(edtAnswer.Text),@charBuf,intLen,GCL_CONVERSION);
    .
    하면 lngRet 값은 나오지만 charBuf에 아무것도 담기지 않아 iStart에서 에러가 납니다.
    동적할당 때문에 번지수가 잘못되었는지?
  • Profile
    최용일 2009.07.23 18:53
    FillChar(charBuf[0], intLen, 0);
  • Profile
    신철우 2009.07.24 23:30
    드디어 해결되어 기쁩니다. 감사합니다.
    문제는 @charBuf => @charBuf[0] 으로 변경하니까 오케이.

    charBuf : array of char;
    .
    .
    SetLength(charBuf, intLen);
    FillChar(charBuf[0], intLen, 0);
    lngRet := ImmGetConversionList(hKL,hImc,PChar(edtAnswer.Text),@charBuf[0],intLen,GCL_CONVERSION);