자유롭게 질의 및 응답을 할 수 있는 게시판입니다. 개발자 여러분의 답변이 큰 도움이 됩니다.
- 제품설치/등록 오류 문의: 설치/등록 Q&A 이용 (제품 구매 고객 한정)
Delphi [마이그레이션] MaxLength 속성이 이전버전(2007 이전)에서는 한글이 2였는데...
2017.12.14 14:47
Q,
TEdit, TComboBox 등의 MaxLength 속성을 이용해 DB 필드의 길이와 매핑해 데이터 입력을 제한했습니다.
하지만 최신 버전 델파이에서는 한글도 1글자로 인식되어 DB 필드 길이를 초과해 오류가 발생합니다.
예를 들어
"홍길동전123" 입력 시 아래와 같이 입력됩니다.
예전 버전에서는 "홍길동전12"(10 bytes)
최신 버전에서는 "홍길동전123"(11 bytes)
해결방법이 있을까요?
A,
유니코드가 적용된 2009 이후 버전 부터 MaxLength는 글자의 길이를 기준으로 동작합니다.
(2007 이전 버전, 즉 안시스트링 기반에서는 바이트 수 기준으로 동작했습니다.)
이슈를 해결하는 가장 좋은 방법은 DBMS의 캐릭터 셋을 UTF8로 변경하는 것입니다.(하지만 현실적으로 어렵죠^^)
또다른 방법 중 하나로, MaxLength를 Byte 단위로 처리하도록 기능을 수정하는 것입니다.
아래 코드는 TEdit를 상속받아 위 내용을 구현한 내용의 일부입니다.
Vcl.Extension.Edit 유닛에 TEdit를 상속받아 다시 구현했습니다.
TEdit를 사용하는 폼의 유닛의 유즈절에 Vcl.Extension.Edit 유닛을 추가해야 합니다.
이 경우 주의할 점은 Vcl.StdCtrls 유닛보다 뒤에 Vcl.Extension.Edit 유닛을 추가해야 합니다.
유즈절은 뒤에서 읽기 때문에 Vcl.Extension.Edit에 있는 TEdit를 폼에서 읽어야 합니다.
다른 컴포넌트 들도 아래 내용을 참고해 구현할 수 있습니다.
혹시 더 좋은 방법을 알고 계신 분들은 댓글 부탁드립니다.
샘플 프로젝트는 첨부파일에서 받아 볼 수 있습니다.
-----------
unit Vcl.Extension.Edit;
interface
uses
Vcl.StdCtrls, System.Classes, System.SysUtils;
type
TEdit = class(Vcl.StdCtrls.TEdit)
protected
procedure Change; override;
end;
implementation
uses
WinAPI.Windows;
{ TEdit }
function CutString(Value : AnsiString; Len: Integer ) : string;
var
I: Integer;
Ch : AnsiChar;
InChar: Boolean;
Ansi: AnsiString;
begin
InChar := False;
for i := 1 to Len do begin
Ch := Value[i];
Ansi := Ansi + Ch;
if (Ch > #127 ) and (not InChar) then
InChar := True
else if ( ch > #127 ) and ( InChar ) then
InChar := False
end;
if InChar then
Ansi := Copy(Ansi, 1, Length(Ansi) - 1);
Result := string(Ansi);
OutputDebugString(PChar(Result));
end;
procedure TEdit.Change;
begin
inherited;
if Length(AnsiString(Text)) > MaxLength then
begin
Text := CutString(AnsiString(Text), MaxLength);
SelStart := MaxLength;
keybd_event(VK_RIGHT, 0,0,0);
end;
end;
end.
-----------
댓글 0
Delphi [마이그레이션] MaxLength 속성이 이전버전(2007 이전)에서는 한글이 2였는데...
2017.12.14 14:47
Q,
TEdit, TComboBox 등의 MaxLength 속성을 이용해 DB 필드의 길이와 매핑해 데이터 입력을 제한했습니다.
하지만 최신 버전 델파이에서는 한글도 1글자로 인식되어 DB 필드 길이를 초과해 오류가 발생합니다.
예를 들어
"홍길동전123" 입력 시 아래와 같이 입력됩니다.
예전 버전에서는 "홍길동전12"(10 bytes)
최신 버전에서는 "홍길동전123"(11 bytes)
해결방법이 있을까요?
A,
유니코드가 적용된 2009 이후 버전 부터 MaxLength는 글자의 길이를 기준으로 동작합니다.
(2007 이전 버전, 즉 안시스트링 기반에서는 바이트 수 기준으로 동작했습니다.)
이슈를 해결하는 가장 좋은 방법은 DBMS의 캐릭터 셋을 UTF8로 변경하는 것입니다.(하지만 현실적으로 어렵죠^^)
또다른 방법 중 하나로, MaxLength를 Byte 단위로 처리하도록 기능을 수정하는 것입니다.
아래 코드는 TEdit를 상속받아 위 내용을 구현한 내용의 일부입니다.
Vcl.Extension.Edit 유닛에 TEdit를 상속받아 다시 구현했습니다.
TEdit를 사용하는 폼의 유닛의 유즈절에 Vcl.Extension.Edit 유닛을 추가해야 합니다.
이 경우 주의할 점은 Vcl.StdCtrls 유닛보다 뒤에 Vcl.Extension.Edit 유닛을 추가해야 합니다.
유즈절은 뒤에서 읽기 때문에 Vcl.Extension.Edit에 있는 TEdit를 폼에서 읽어야 합니다.
다른 컴포넌트 들도 아래 내용을 참고해 구현할 수 있습니다.
혹시 더 좋은 방법을 알고 계신 분들은 댓글 부탁드립니다.
샘플 프로젝트는 첨부파일에서 받아 볼 수 있습니다.
-----------
unit Vcl.Extension.Edit;
interface
uses
Vcl.StdCtrls, System.Classes, System.SysUtils;
type
TEdit = class(Vcl.StdCtrls.TEdit)
protected
procedure Change; override;
end;
implementation
uses
WinAPI.Windows;
{ TEdit }
function CutString(Value : AnsiString; Len: Integer ) : string;
var
I: Integer;
Ch : AnsiChar;
InChar: Boolean;
Ansi: AnsiString;
begin
InChar := False;
for i := 1 to Len do begin
Ch := Value[i];
Ansi := Ansi + Ch;
if (Ch > #127 ) and (not InChar) then
InChar := True
else if ( ch > #127 ) and ( InChar ) then
InChar := False
end;
if InChar then
Ansi := Copy(Ansi, 1, Length(Ansi) - 1);
Result := string(Ansi);
OutputDebugString(PChar(Result));
end;
procedure TEdit.Change;
begin
inherited;
if Length(AnsiString(Text)) > MaxLength then
begin
Text := CutString(AnsiString(Text), MaxLength);
SelStart := MaxLength;
keybd_event(VK_RIGHT, 0,0,0);
end;
end;
end.
-----------