unit uScrExt;
{ 追加機能:思いついた機能等を追加しています
 #cp のみで現在のコードページ情報 #cp *で一覧 #cp 数字
}
interface
uses windows, SysUtils
  , CalcAnsiScript
  , uAnsiCharTools
  ;
type
  TOnTextOut = procedure(s: AnsiString) of object;
  TuScrExt = class(TCalcuAddition)
  public
 //  function CallFunc(const lab: AnsiString; Labels: TAMyCalLabel): boolean ;override;
 // function ExeLabel(const lab: AnsiString; var ret: Extended; cmd: TGetLabelCmd): boolean; override;
 //   procedure StartEndScript(n: Integer); override; //0:start 1:end;
    function LineCmd(const lab: AnsiString; var p: PChar): boolean; override; //#で始まる行コマンド
  end;
implementation
type
  TCPInfoEx = record
    MaxCharSize: UINT; { max length (bytes) of a char }
    DefaultChar: array[0..MAX_DEFAULTCHAR - 1] of byte; { default character }
    LeadByte: array[0..MAX_LEADBYTES - 1] of byte; { lead byte ranges }
    UnicodeDefaultChar: WideChar;
    CodePage: UINT;
    CodePageName: array[0..MAX_PATH - 1] of AnsiChar;
  end;
function GetCPInfoEx(co: UINT; dwFlags: DWORD; var CpInfo: TCPInfoEx): BOOL; stdcall; external kernel32 name 'GetCPInfoExA';

//コードページ情報の表示

procedure PrintCpInfo(onMsg: TOnTextOut; const CpInfo: TCPInfoEx; addMsg: string);
var
  s: string;
  i: Integer;
begin
   addMsg := addMsg
    + format('%8d,', [CpInfo.CodePage])
    + format('%2d,', [CpInfo.MaxCharSize])
    + '"[';

  for i := 0 to MAX_LEADBYTES div 2 - 1 do begin
    if CpInfo.LeadByte[i * 2] = CpInfo.LeadByte[i * 2 + 1] then
      if CpInfo.LeadByte[i * 2] = 0 then break;
    if i <> 0 then addMsg := addMsg + ',';
    addMsg := addMsg + format('#$%2.2X..#$%2.2X', [CpInfo.LeadByte[i * 2], CpInfo.LeadByte[i * 2 + 1]]);

  end;
  addMsg := addMsg + ']",';

  s := CpInfo.CodePageName;
  s := PChar(s);


  onMsg(addS([addMsg, s]));
end;

procedure PrintCp(onMsg: TOnTextOut; cp: Integer; addMsg: string = '');
var
  CpInfo: TCPInfoEx;
  i: Integer;

begin
  if cp = -1 then begin
    PrintCp(OnMsg, CP_ACP, 'CP_ACP  :');
    PrintCp(OnMsg, CP_OEMCP, 'CP_OEMCP:');
    exit;
  end;
  if cp = -2 then begin    //#cp *
    for i := 0 to $FFFF do
      if GetCPInfoEx(i, 0, CpInfo) then PrintCpInfo(OnMsg, CpInfo, format(',%5d,', [i]));
    exit;
  end;
  if addMsg = '' then addMsg := format('cp %5d:', [cp]);
  if GetCPInfoEx(cp, 0, CpInfo) then PrintCpInfo(OnMsg, CpInfo, addMsg);
end;


{ TPas2JavaScCalc }

function TuScrExt.LineCmd(const lab: AnsiString; var p: PChar): boolean;
var
  s: string;
begin
  Result := False;
  if SameText(lab, 'h') or (lab = '') then //helpの時は処理してもfalseを返す
  begin
    owner.MsgOutLn(cvU(
      '#cp のみで現在のコードページ情報 *で一覧 数字で指定'#13#10 +
      ''));
  end;
  if SameText(lab, 'cp') then begin
    CAnsiSkipBlank(p);
    if p^ = '*' then PrintCp(owner.MsgOutLn, -2) else
      if p^ in ['@'..'Z', 'a'..'z', '+', '0'..'9'] then begin
        owner.addsub;
        PrintCp(owner.MsgOut, round(owner.num));
      end else PrintCp(owner.MsgOutLn, -1);
    Result := True;
    exit;
  end;
end;


initialization
  CalcAddTCalcuAddition(TuScrExt);
end.

