String Conversion in Delphi Using LCMapStringEx: Half‑Width/Full‑Width, Hiragana/Katakana, Uppercase/Lowercase
This page explains how to use the Windows API LCMapStringEx in Delphi to convert strings into the following formats:
– Half-width ⇔ Full-width
– Hiragana ⇔ Katakana
– Uppercase ⇔ Lowercase
LCMapStringEx is an API designed for locale-based string mapping and is more flexible and recommended over the older LCMapString. With Delphi implementation examples, this page introduces how to use each mapping flag and highlights important considerations.
Practical use cases are also included, such as converting only half-width katakana to full-width katakana.
LCMapStringEx(
LOCALE_NAME_SYSTEM_DEFAULT,
MappingFlags,
PChar(SourceString), LengthOfSourceString,
PChar(DestinationBuffer), LengthOfDestinationBuffer,
nil, nil, 0
);
The MappingFlags parameter can be set using combinations such as the following.
For details, see: https://learn.microsoft.com/ja-jp/windows/win32/api/winnls/nf-winnls-lcmapstringex
- LCMAP_FULLWIDTH
- Convert to full-width characters
- LCMAP_HALFWIDTH
- Convert to half-width characters
- LCMAP_HIRAGANA
- Convert to hiragana
- LCMAP_KATAKANA
- Convert to katakana
- LCMAP_UPPERCASE
- Convert to uppercase
- LCMAP_LOWERCASE
- Convert to lowercase
Creating a New Project and Designing the Form
From the menu, select File → New → Windows VCL Application, choose an empty application, and click OK to create the project.
Drag and drop a TButton and a TMemo onto the form.
Writing the Source Code
Double‑click "Button1" and write the following source code.
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var s,d:String;
buf:array of char;
begin
//Change the font for better readability
Memo1.Font.Name:='MS Gothic';
Memo1.Font.Size:=16;
Memo1.Clear;
Memo1.ScrollBars:=ssBoth;
//Source string
s:='"abcABCカナカナひらがな##"';
Memo1.Lines.Add('【Before Conversion】');
Memo1.Lines.Add(s);
//Allocate a sufficiently large buffer
SetLength(buf,Length(s)+1);
//Convert to full-width
LCMapStringEx(
LOCALE_NAME_SYSTEM_DEFAULT,
LCMAP_FULLWIDTH,
PChar(s),Length(s),
PChar(@buf[0]),Length(buf),
nil,nil,0
);
d:=PChar(buf);
Memo1.Lines.Add('【Full-width Conversion】');
Memo1.Lines.Add(d);
//Convert to full-width + hiragana + uppercase
LCMapStringEx(
LOCALE_NAME_SYSTEM_DEFAULT,
LCMAP_FULLWIDTH or LCMAP_HIRAGANA or LCMAP_UPPERCASE,
PChar(s),Length(s),
PChar(@buf[0]),Length(buf),
nil,nil,0
);
d:=PChar(buf);
Memo1.Lines.Add('【Full-width Hiragana Uppercase Conversion】');
Memo1.Lines.Add(d);
//Convert to full-width + katakana + lowercase
LCMapStringEx(
LOCALE_NAME_SYSTEM_DEFAULT,
LCMAP_FULLWIDTH or LCMAP_KATAKANA or LCMAP_LOWERCASE,
PChar(s),Length(s),
PChar(@buf[0]),Length(buf),
nil,nil,0
);
d:=PChar(buf);
Memo1.Lines.Add('【Full-width Katakana Lowercase Conversion】');
Memo1.Lines.Add(d);
//Convert to half-width
LCMapStringEx(
LOCALE_NAME_SYSTEM_DEFAULT,
LCMAP_HALFWIDTH,
PChar(s),Length(s),
PChar(@buf[0]),Length(buf),
nil,nil,0
);
d:=PChar(buf);
Memo1.Lines.Add('【Half-width Conversion】');
Memo1.Lines.Add(d);
//Convert to half-width + katakana + lowercase
LCMapStringEx(
LOCALE_NAME_SYSTEM_DEFAULT,
LCMAP_HALFWIDTH or LCMAP_KATAKANA or LCMAP_LOWERCASE,
PChar(s),Length(s),
PChar(@buf[0]),Length(buf),
nil,nil,0
);
d:=PChar(buf);
Memo1.Lines.Add('【Half-width Katakana Lowercase Conversion】');
Memo1.Lines.Add(d);
Memo1.Lines.Add('');
end;
end.
Running the Application
Click Run → Run, or press the Run button to execute the application.
(The project will be compiled and then executed.)
When you click “Button1,” the original string and each converted result will be displayed.
Advanced Example: Converting Only Half‑Width Katakana to Full‑Width Katakana
To convert only half‑width katakana to full‑width katakana, extract the consecutive half‑width katakana segments from the string and convert only those parts.
Half‑width katakana characters range from 「。」 (UTF‑16LE code 65377) to 「゚」 (UTF‑16LE code 65439).
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
//Convert only half-width katakana to full-width
function HanKanaToZen(st:string):string;
function ToZen(hst:string):string;
var buf:array of char;
begin
//Allocate a sufficiently large buffer
SetLength(buf,Length(hst)+1);
LCMapStringEx(
LOCALE_NAME_SYSTEM_DEFAULT,
LCMAP_FULLWIDTH,
PChar(hst),Length(hst),
PChar(@buf[0]),Length(buf),
nil,nil,0
);
result:=PChar(buf);
end;
var i:Integer;
s:char;
HanKana:string;
begin
HanKana:='';
result:='';
for i := 1 to Length(st) do
begin
s:=st[i];//Extract one character
//Extract consecutive half-width katakana [。(65377) to ゚(65439)]
if (ord(s)>=Ord(Char('。'))) and (Ord(s)<=Ord(Char('゚'))) then
begin
HanKana:=HanKana+s;
end
else
begin
if HanKana<>'' then
begin
result:=result+ToZen(HanKana);//Convert only half-width katakana
HanKana:='';
end;
result:=result+s;
end;
end;
if HanKana<>'' then
result:=result+ToZen(HanKana);//Convert remaining half-width katakana
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Edit1.Text:=HanKanaToZen('アイウabcdバビあいうバABCプペポプペポABCパピプ。');
end;
end.
