トップへ(mam-mam.net/)

String Conversion in Delphi Using LCMapStringEx: Half‑Width/Full‑Width, Hiragana/Katakana, Uppercase/Lowercase

Japanese

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.