[휴대폰에서 문자보낼때 한글 초성 "ㄱ" 만 입력해도 2바이트가 계산된 그림]
응용프로그램에서도 SMS 문자전송 등을 할 때 키입력시 바로 바로 현재 글자 바이트 수를 계산하고 제한하려고 한다.
또한 TRichEdit, TMemo 등의 MaxLength 속성은 byte단위가 아니라 글자수 단위다. 입력되는 글자가 숫자나 영문자로 제한되는 경우는
관계가 없지만 한글이 포함된다면 byte단위로 제어해야 할때 사용에 어려움이 있다.
따라서 바이트수를 계산하여 제어해야하는데 바이트 수를 어느 시점(이벤트)에서 조사하는 것이 정확한지 검토해본다.
1. 숫자, 영문일 때 (TRichEdit , TMemo 동일)
onKeyDown
onKeyPress
onChange
onKeyUp
2. 한글일 때 , 한글은 2byte 문자(LeadByte, TrailByte)라 조합중일 때와 조합이 끝났을 때 이벤트가 발생한다.
예를 들어 "가" 를 입력할때 (TRichEdit, TMemo 이벤트가 차이남)
TRichEdit | TMemo | |
"ㄱ" 입력할 때 | onKeyDown onKeyUp | onKeyDown onChange (변경전 텍스트 + "ㄱ") onKeyUp |
"가" 완성될 때 | onKeyDown onKeyUp | OnKeyDown onChange (변경전 텍스트) onChange (변경전 텍스트 + "가") onKeyUp |
한글조합이 끝남, 포커스이동 | onChange (변경전 텍스트) onChange (변경전 텍스트 + "가") | OnChange (변경전 텍스트) |
( 한글의 경우는 초성, 중성, 종성 입력할 때와 한글 조합이 끝났을 때 이벤트가 발생한다.)
결국 휴대폰 처럼 "ㄱ" 만 입력해도 바로 2바이트를 계산하려면
TRichEdit는 onKeyUp 이벤트에서 계산해야 한글 초성만 입력해도 바로 반영되고
TMemo는 onChange 이벤트에서 계산해도 바로 반영된다.
예를 들어 TMemo의 OnChange 이벤트처리는 다음과 같다.
procedure TfrmTestMain.Memo1Change(Sender: TObject);
var t_length, i : integer;
begin
t_length := length(AnsiString(Memo1.Text));
lbCount.Caption := IntToStr(t_length) + ' byte' ;
end;
또한 바이트수를 제한 하는 코딩까지 추가한다면 (예를 들어 90 바이트 제한)
TMemo의 onChange 이벤트에서 Copy함수나 Delete 메소드로 90바이트 까지만 자르면된다.
참고로
OnKeyPress에서 입력된 Key는 char타입 이고
OnKeyDown onKeyUp 의 Key 는 virtual key값의 word타입이다.
OnPress에서는 Key값을 바꿀 수 있지만 onKeyDown onKeyUp 에서는 Key 값을 바꿀 수 없다.
또한 방향키와, Del키, Ins키, 한/영키는 네비게이션키로 Key값으로 제어할 수 없다.
단지 BackSpace (#8, VK_BACK) 키만 제어할 수 있다.
----------------------------------------------------------------------------
(추가 2019-01-04)
아래는 깔끔하게 90바이트 제한하는 코드이다.
TMemo onChange 이벤트에 할당하면 된다.
CopyK는 사용자 함수로 Copy함수를 응용하여 바이트단위로 자르는 함수이다. 한글이 중간에서 짤리면 스페이스로 채우는 함수다.
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | var vByteCnt : integer; begin // 베리 굿~ 딱 90바이튼 되었을 때는 MaxLength 사용하고, 90바이트 초과는 잘라내는 방식사용 // Tag 에 최대 바이트수 설정한 후에 vByteCnt := Length(AnsiString(TMemo(Sender).Text)); lbByteCount.Caption := IntToStr(vByteCnt) + ' byte' ; if vByteCnt = TMemo(Sender).Tag then // 한 글자씩 영문,숫자(1바이트씩), 한글(2바이트씩) 입력하여 딱 90바이트가 되었을 때 TMemo(Sender).MaxLength := Length(TMemo(Sender).Text) // 입력제한 글자수로 , 바이트수 아님 else if vByteCnt > TMemo(Sender).Tag then // Ctrl + V 로 붙여넣기 하여 값자기 90바이트를 초과했을 때는 짤라서 90바이트 맞추기 begin TMemo(Sender).Text := CopyK(TMemo(Sender).Text, 1, TMemo(Sender).Tag, True); // 한글 반바이트를 스페이스로 채워 90바이트 맞춘다. // TMemo 마지막라인, 마지막컬럼으로 이동하기, 그래야 짤린 부분을 알수있으므로 *********** TMemo(Sender).SelStart := SendMessage(TMemo(Sender).Handle, EM_LINEINDEX, TMemo(Sender).Lines.Count-1, 0) + Length(TMemo(Sender).Text) - TMemo(Sender).Perform(EM_LINEINDEX, TMemo(Sender).Lines.Count-1, 0); ; SendMessage(TMemo(Sender).handle, EM_SCROLLCARET, 0, 0); //************************************************** end else TMemo(Sender).MaxLength := 0; end; |
'델파이' 카테고리의 다른 글
dpi와 출력 (0) | 2010.05.25 |
---|---|
웹PHP- GET과 POST차이 (0) | 2010.04.01 |
델파이IDE 단축키_ virtual key (0) | 2010.03.18 |
ftp명령어 도움말 (0) | 2010.02.16 |
ms sql 스크립트로 Agent 작업시 'owner_sid' NULL 값 에러.. 해결 (0) | 2010.02.06 |