Q&A

  • 예제를 보고 만들어봤는데... 도저히...이해가..
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Edit2: TEdit;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

const
ChoSungTbl: PChar = 'ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ';
JungSungTbl: PChar = 'ㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣ';
JongSungTbl: PChar = '  ㄱ  ㄲ  ㄳ  ㄴ  ㄵ  ㄶ  ㄷ  ㄹ  ㄺ  ㄻ  ㄼ  ㄽ  ㄾ  ㄿ  ㅀ  ㅁ  ㅂ  ㅄ  ㅅ  ㅆ  ㅇ  ㅈ  ㅊ  ㅋ  ㅌ  ㅍ  ㅎ  ';

UniCodeHangeulBase = $AC00;
UniCodeHangeulLast = $D79F;


function HanDiv(const Han: PChar; Han3: PChar): Boolean;
var
UniCode: Integer;

ChoSung, JungSung, JongSung: Integer;
begin
Result := False;
// if StrLen(Han) < 2 then Exit;

MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, Han, 2, @UniCode, 1);

//UniCode = UniCode and $FFFF; // <--- 이 줄을 추가하세요. *****

if (UniCode < UniCodeHangeulBase) or
(UniCode > UniCodeHangeulLast) then Exit;

UniCode := UniCode - UniCodeHangeulBase;
ChoSung := UniCode div (21 * 28);
UniCode := UniCode mod (21 * 28);
JungSung := UniCode div 28;
UniCode := UniCode mod 28;
JongSung := UniCode;

StrLCopy(Han3, ChoSungTbl + ChoSung * 2, 2);
StrLCopy(Han3 + 2, JungSungTbl + JungSung * 2, 2);
StrLCopy(Han3 + 4, JongSungTbl + JongSung * 2, 2);

Result := True;
end;

function HanCom(const Han3: PChar; Han: PChar): Boolean;
var
UniCode: Integer;
ChoSung, JungSung, JongSung: Integer;
ChoSungPos, JungSungPos, JongSungPos: Integer;
begin
Result := False;
// if StrLen(Han3) < 6 then Exit;

ChoSungPos := Pos(Copy(String(Han3), 1, 2), ChoSungTbl);
JungSungPos := Pos(Copy(String(Han3), 3, 2), JungSungTbl);
JongSungPos := Pos(Copy(String(Han3), 5, 2), JongSungTbl);

if (ChoSungPos and JungSungPos and JongSungPos) = 0 then Exit;

ChoSung := (ChoSungPos - 1) div 2;
JungSung := (JungSungPos - 1) div 2;
JongSung := (JongSungPos - 1) div 2;

UniCode := UniCodeHangeulBase +
(ChoSung * 21 + JungSung) * 28 + JongSung;

WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK,
@UniCode, 1, Han, 2, nil, nil);

Result := True;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
Dest: array[0..6] of Char;
begin
if HanDiv(PChar(Edit1.Text), @Dest) then begin
Dest[6] := Char(0);
Edit2.Text := String(Dest);
end else
Edit2.Text := '?';

end;

procedure TForm1.Button2Click(Sender: TObject);
var
Dest: array[0..2] of Char;
begin
if HanCom(PChar(Edit1.Text), @Dest) then begin
Dest[2] := Char(0);
Edit2.Text := String(Dest);
end else
Edit2.Text := '?';

end;

end.

위의 소스는 여기서 구한 소스로 했는데요..

윈도우xp에선 변환하지 않고 무슨 글을 넣든지 ?가 되는데..

도저히 제 머리로는 이해가 안되서 이러헥 질문 올립니다.

답변 부탁드려요.. ㅜ.ㅜ
1  COMMENTS
  • Profile
    선종욱 2009.03.31 08:48
    // if StrLen(Han) < 2 then Exit;

    // if StrLen(Han3) < 6 then Exit;

    //UniCode = UniCode and $FFFF; // <--- 이 줄을 추가하세요. *****

    위에 두개 주석은 왜 빼셨는 모르겠으나 호출 하는 부분에서 배열 크기에 제약이 있는것으로 보아 필요한 부분으로 보입니다.

    문제는 세번째 주석은 없으면 질문하신것 처럼 무조건 ? 가 나오던데요;;

    프로그램 방식은 Button1을 실행하면 Edit1에 한글 한자를 Edit2에 자음 모음을 분리해서 보여주고
    Button2를 실행하면 반대로 합친다 인거 같은데 분리는 잘 되지만 합치는것은 잘 않되네요;; 글자가 약간 깨지더라구요;;