Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2016年10月20日] [更新 2016年11月02日] Delphi サンプルプログラム集
504_コマンドプロンプトのフォント変更コマンドツール
動作確認等 Windows 7 U64(SP1) + Delphi XE(UP1) Pro
Windows Vista 以降専用
504_CmdPromptFont.zip [1,376 KB] 2016年11月02日版 (EXE 同梱)



  • 2016年10月29日
  • 画面バッファのサイズの設定用パラメータ等を追加




コマンドプロンプトのフォントサイズ変更コマンドツール


コマンドプロンプトのフォントサイズ等を変更するためのプログラムです.
コンソール関係の関数類を使用して操作します.

コマンドプロンプトには,フォントのサイズを変更するコマンド類がないようです.そこで,コマンドプロンプトから設定できるコマンドラインアプリケーションを作成してみました.バッチファイルを作成して実行すれば,常に同じ設定にすることもできます.

ただし,常に期待通りに設定できるとは限りません.変更前のフォントの設定によっては別のフォント名や違うフォントサイズになってしまうこともあります.特にラスターフォントの Terminal は設定可能なフォントサイズが限られています.

下表が使用可能な起動オプションの一覧です.パラメータは半角の空白で区切り,値は = で指定します.起動オプションと指定の順番は任意です.大文字と小文字の区別はありません.
起動パラメータなしで実行した場合は,現在のフォントの設定値を表示します.
/ スラッシュなしで,plCmdfont の後に,半角の空白,数字にすると,フォントサイズを指定したものと見なし,フォントサイズだけを変更します.



[備考 1]
コマンドプロンプトには color コマンドがあり,背景色と文字の色を変更できます.使用方法は,コマンドプロンプトで color /? で表示することができます.
また,コマンドプロンプトの起動時に,/T オプションで /T:1B のように指定できます.


[備考 2]
提供しているプログラムのファイル名は plCmdFont.exe となっています.pl というプリフィックスを付けることにより,同じような名前のプログラムと区別できるようにしています.
plCmdFont の部分を任意の名前に変更しても動作します.必要であれば変更してください.




起動オプション 説明
/wndleft= コマンドプロンプト画面の表示位置.左上の X 座標値.単位はピクセル
/wndtop= コマンドプロンプト画面の表示位置.左上の Y 座標値.単位はピクセル
/buffw= 画面バッファのサイズの幅.半角の文字数
ウィンドウのサイズの幅より小さい値にはできない
/buffh= 画面バッファのサイズの高さ.行数
ウィンドウのサイズの高さより小さい値にはできない
/wndw= ウィンドウのサイズの幅.半角の文字数
画面バッファのサイズの幅よりも大きな値にはできない
/wndh= ウィンドウのサイズの高さ.行数
画面バッファのサイズの高さより大きな値にはできない
/fontname= フォント名." (ダブルクォーテーション) で括って指定する
プロパティのダイアログのフォントのリストにないフォントは指定できない
指定すると別のフォントが使われる
/fontsize= フォントサイズ.この値はフォントの高さ
Terminal 等のラスターフォントには設定できないサイズがあるので注意
設定できないサイズを指定すると,別のフォントが使われる
/color= 画面の背景色とフォントの色の指定.16進数で指定する
先頭の 4 ビットが背景色,下位の 4 ビットがフォントの色の設定値
例 : plCmdfont /color=0F (背景色が黒 (0) でフォントの色が白 (F))
PowerShell の場合は $ なしで指定しないと設定できない
/hide = なしで指定する.このオプションを追加すると設定結果を表示しない
/ / だけにするとコマンドプロンプトのプロパティのダイアログを表示する
他のオプションは同時には指定できない
ダイアログは [ESC] キーで閉じることができる
/? 使用可能なパラメータの一覧を表示
   / なしで数字だけをパラメータにした場合は,フォントサイズの指定となる
ただし,他の起動オプションと同時には指定できない
例 : plCmdfont 16 (フォントサイズを 16 にするコマンド)


ウィンドウのサイズの幅または高さは,画面バッファのサイズの値より大きくはできません.
コマンドプロンプトのプロパティのダイアログで設定する時は,大きな値を指定すると,画面バッファの値を調整して大きくしてくれますが,本プログラムにはその機能はありません.
例えば画面バッファのサイズの幅が 90 より小さい時に,ウィンドウのサイズの幅を 90 にしたい場合は,以下のように,画面バッファのサイズの幅も指定します.

一般的には,画面バッファのサイズの幅とウィンドウのサイズの幅を同じにしておく方が使いやすいと思われます.画面バッファのサイズの幅の方が大きいと,水平スクロールバーが表示されます.


plCmdFont /wndw=90 /buffw=90




01_使用方法と実行例


コマンドプロンプトの画面からコマンドとして実行するプログラムです.
プログラム名は plCmdFont です.下図はフォントサイズだけを変更する例です.plCmdFont.exe をディレクトリ D:\000 に置いてテストしています.
実行結果の FontSize.X は設定後のフォントの幅,FontSize.Y はフォントの高さです.


[備考 1]
plCmdFont.exe を Windows ディレクトリ等,システム的にパスの通ったディレクトリに置けば,ディレクトリ名を省略して plCmdFont.exe を使用することができます.


[備考 2]
下図で使用しているのは [Osaka-等幅] というフォントです.パスの区切り文字はバックスラッシュで,0 (ゼロ) に斜線が入るスラッシュドゼロというフォントです.また,大文字の I (アイ) と小文字の l (エル) の区別もしやすくなっています.
ただし,ユニコードには対応していません.



図1
変更前
図2
変更後

フォントのサイズの変更だけであれば,下図のように plCmdFont の後にフォントサイズを指定すれば変更できます.
下図は,plCmdFont.exe ファイルを (コピーして貼り付けで) C:\Windows ディレクトリ内に置いて実行しています.C:\Windows ディレクトリ内に置いておくと,plCmdFont.exe があるディレクトリ名を省略して利用できます.


図3
フォントサイズだけの変更
  • この図は plCmdFont.exe を C:\Windows ディレクトリに置いて実行している




02_使用方法と実行例 - バッチファイルを使用する方法


設定内容を記述した次のようなバッチファイルを作成して,それを実行するようにすると便利です.
このバッチファイルは,バッチファイルと plCmdFont.exe を同じディレクトリ内に置いてあるものと仮定しています.このテストでは D:\000\300 内に置いて Setfont.bat を実行しています.


リスト1
テストに使用したバッチファイル SetFont.bat の内容
本コマンドラインツール plCmdFont.exe を,このバッチファイルと同じ場所に置く
@echo off
set thisdir=%~dp0
set exepath="%thisdir%plCmdFont.exe"
%exepath% /color=$0B /fontname="MS ゴシック" /fontsize=25
@echo on


バッチファイルと plCmdFont.exe の場所が別の場合は,以下のように plCmdFont.exe をフルパスで指定します.Windows ディレクトリ内に plCmdFont.exe を置いた場合は,%windir%\plCmdFont.exe としますが,%windir%\ は省略できます.

@echo off
D:\000\plCmdFont.exe /color=$0B /fontname="MS ゴシック" /fontsize=25
@echo on


図4
バッチファイルの実行結果

[備考]
上の図では D:\000\TEST から cmd.exe を起動しています.





03_プログラムからコマンドプロンプトを起動する場合


ShellExecute 関数等でコマンドプロンプトを起動する時も,設定内容を記述したバッチファイルを実行することができます.この時,cmd.exe の起動オプションに /k が必要です.
このコードは,cmd.exe を起動するプログラム Project1.exe とSetFont.bat, plCmdFont.exe が全て同じディレクトリ内にあると仮定しています.



リスト2
コマンドプロンプトを起動時に,作成したバッチファイルを実行する
//=============================================================================
//  バッチファイルを指定してコマンドプロンプトを起動
//  バッチファイルはコマンドプロンプトのフォントサイズ等の設定用
//
//  usesにShellAPIが必要
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LAppPath  : string;
  LParamStr : string;
begin
  LAppPath  := 'cmd.exe';
  LParamStr := '/k ' + AnsiQuotedStr(ExpandFileName('SetFont.bat'), '"');

  ShellExecute(Handle, '', Pchar(LAppPath), PChar(LParamStr), nil, SW_SHOW);
end;


下図は上のコードを実行した結果です.
フォントサイズは全て 12 として,フォント名だけを変更した結果ですが,Terminal には 12 というフォントサイズがないため 13 になっています.


図5
Terminal
図6
MS ゴシック
図7
Osaka-等幅




04_" ( ダブルクォーテーション ) 付きパラメータの扱い


前項では,プログラムから ShellExecute 関数で cmd.exe を起動する際に,設定内容を記述したバッチファイルを指定しています.
バッチファイルではなく,plCmdFont.exe をパラメータ付きで指定することもできます.その際," (ダブルクォーテーション) の扱いには注意が必要です.cmd.exe は,空白文字をパラメータの区切りとして解釈します.plCmdFont では空白を含むフォント名を扱えるようにするために,フォント名を " (ダブルクォーテーション) で括ることにしています.

cmd.exe にパラメータとして設定する場合,フォント名の文字列を " で括っただけでは 1 つの文字列として認識してくれません.以下のコードのように," が必要な cmd.exe の起動オプションは,その起動オプション全体を " で括る必要があります.

次項のように,起動するプログラムのショートカットのリンク先で指定する場合は,このような処理は必要ありません.



リスト3
cmd.exe 起動時に " (ダブルクォーテーション) 付きパラメータが必要な例
" が必要な cmd.exe の起動オプションは,そのオプション全体を " で括る
//=============================================================================
//  plCmdFont.exeのパラメータを指定してコマンドプロンプトを起動する例
//
//  usesにShellAPIが必要
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
  LAppPath  : string;
  LParamStr : string;
begin
  LAppPath  := 'cmd.exe';

  //起動パラメータの中に"(ダブルクォーテーション)が必要な場合
  //全体を"(ダブルクォーテーション)で括る
  LParamStr := '/k '
             + '"' + AnsiQuotedStr(ExpandFileName('plCmdFont.exe'), '"')
             + ' /color=$1F /fontname="MS ゴシック" /fontsize=16' + '"';

  ShellExecute(Handle, '', Pchar(LAppPath), PChar(LParamStr), 'C:\', SW_SHOW);
end;




05_コマンドプロンプトの起動時に設定を自動実行 - ショートカット


cmd.exe のショートカットを作成して,上記のバッチファイルを起動時に実行するようにできます.あるいは plCmdFont.exe をパラメータ付きで指定します.この時,cmd.exe の起動オプションに /k が必要です.
こうしておくと,コマンドプロンプトを使用している時にフォント等を設定を変更しても,このショートカットから起動する時はいつでも同じ設定で起動できます.



図8
cmd.exe のショートカットの設定
  • cmd.exe の起動パラメータにバッチファイルを指定する
  • cmd.exe の起動オプションに /k が必要
  • 作業フォルダが起動した時のカレントディレクトリになる




06_コマンドプロンプトの起動時に設定を自動実行 - AutoRun


上の設定はショートカットでしたが,cmd.exe の起動時にも自動で実行するようにバッチファイル,あるいは plCmdFont の起動パラメータを設定することができます.
以下のレジストリのキーに,AutoRun という名前の文字列の項目を作成します.その文字列を,起動時に実行するバッチファイルのパス等にします.これは cmd.exe の起動パラメータですから,必要があれば & を使用して複数指定できます.

HKEY_CURRENT_USER\Software\Microsoft\Command Processor


図9
レジストリの設定
  • AutoRum と言う名前の文字列の項目を追加
  • その文字列を,起動時に実行するパス名にする
図10
AutoRun の設定で起動した場合
  • 設定内容を非表示にするには /hide オプションを指定する




07_コマンドプロンプトで使用可能なフォントを追加する方法


コマンドプロンプトで使用可能なフォントは,コマンドプロンプトのプロパティのダイアログの [フォント] タブに表示されているフォントだけです.
デフォルトでは,ラスターフォントの Terminal と TrueType フォントのMS ゴシックだけです.


図11
使用可能なフォントの一覧

コマンドプロンプトで使用できるようにフォントを追加するには,レジストリの以下のキーに項目を追加します.
日本語フォントの場合は,項目の名前を 932 としますが,同じ名前は登録できません.
932.0, 932.1, 932, 2, ... のようにピリオドの後に,重複しない数字を追加します.データの型は文字列型とします.追加した項目をダブルクリックして表示されるダイアログで実際のフォント名を入力します.ただし,どんなフォントでも使用可能になるとは限らないようです.


HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFont




図12
使用可能なフォントを追加
  • [TrueTypeFont] キーに文字列型の項目名を追加
  • 追加した項目をダブルクリック
  • ダイアログでフォント名を入力




08_ソースコード


ソースコードです.コンソールアプリケーションです.
コンソール関係の関数類を使用して,標準出力のフォントの設定を変更すると,コマンドプロンプトのフォントも変更されることを利用しています.



リスト4
コマンドラインツール plCmdFont.exe のソースコード
program plCmdFont;
{$APPTYPE CONSOLE}



{$R *.dres}

uses
  Dialogs,
  SysUtils,
  Windows,
  DWMAPI,
  Messages,
  Classes;

//-----------------------------------------------------------------------------
//  SetCurrentConsoleFontEx関数とこの関数で使用する構造体の定義
//  これらはDelphi XE7 までは実装されていない.Windows Vista以降で使用可能
//-----------------------------------------------------------------------------
type
  PConsoleFontInfoEx = ^TConsoleFontInfoEx;
  _CONSOLE_FONT_INFOEX = record
    cbSize     : ULONG;
    nFont      : DWORD;
    dwFontSize : TCoord;
    FontFamily : UINT;
    FontWeigth : UINT;
    FontName   : array [0..LF_FACESIZE-1] of WideChar;
  end;
  TConsoleFontInfoEx = _CONSOLE_FONT_INFOEX;

  function GetCurrentConsoleFontEx(
            hConsoleOutput : THandle;
            bMaximumWindow : BOOL;
            lpConsoleCurrentFontEx : PConsoleFontInfoEx):
            BOOL; stdcall; external 'kernel32.dll';

  function SetCurrentConsoleFontEx(
            hConsoleOutput : THandle;
            bMaximumWindow : BOOL;
            lpConsoleCurrentFontEx : PConsoleFontInfoEx):
            BOOL; stdcall; external 'kernel32.dll';

const
  FMaxValue = MaxInt div 2;
  FWndClassName = 'ConsoleWindowClass';

//-----------------------------------------------------------------------------
//  Windows Vista以降では,フォームのフレームの仕様が拡張されている
//  これを考慮したウィンドウのTRect構造体の値を取得
//  usesにDWMAPIが必要
//-----------------------------------------------------------------------------
function GetWindowRectForVista(hWindow: HWND): TRect;
var
  LRect : TRect;
begin
  //拡張したウィンドウのフレームのTRect構造体の値を取得
  DwmGetWindowAttribute(hWindow,
                        DWMWA_EXTENDED_FRAME_BOUNDS,
                        @LRect,
                        SizeOf(TRect));
  Result := LRect;
end;

//=============================================================================
//  コマンドライン起動オプションの指定例
//
//  plCmdFont.exe /color=$9F /fontname="MS ゴシック" /fontsize=16
//  plCmdFont.exe /color=$1F /fontname="Terminal" /fontsize=16
//  plCmdFont.exe /color=$0F /wndleft=0 /wndtop=0
//=============================================================================
var
  LArgList      : TStringList;
  LResStream    : TResourceStream;
  LArgText      : string;
  LiPos         : Integer;
  LLeftStr      : string;
  LRightStr     : string;
  LWndRect      : TRect;
  LArgWndLeft   : Integer;
  LArgWndTop    : Integer;
  LArgBuffW     : Integer;
  LArgBuffH     : Integer;
  LArgWndW      : Integer;
  LArgWndH      : Integer;
  LArgFontH     : Integer;
  LArgFontName  : string;
  LArgColor     : Integer;
  LColorWord    : Word;
  LConsoleWnd   : HWND;
  LhStdout      : THandle;
  LCurPos       : TCoord;
  LBuffCoord    : TCoord;
  LWndCoord     : TCoord;
  LSmallRect    : TSmallRect;
  LFontInfo     : TConsoleFontInfoEx;
  LBuffInfo     : TConsoleScreenBufferInfo;
  LBuffLength   : Cardinal;
  LOutCnt       : Cardinal;
  i             : Integer;
  LShowHide     : Boolean;
  LShowBuffInto : Boolean;
  LShowWndInfo  : Boolean;
  LShowFontInfo : Boolean;
begin
  LArgWndLeft   := FMaxValue;
  LArgWndTop    := FMaxValue;
  LArgBuffW     := FMaxValue;
  LArgBuffH     := FMaxValue;
  LArgWndW      := FMaxValue;
  LArgWndH      := FMaxValue;
  LArgFontH     := FMaxValue;
  LArgColor     := FMaxValue;
  LArgFontName  := '';
  LShowHide     := False;
  LShowBuffInto := False;
  LShowWndInfo  := False;
  LShowFontInfo := False;

  //起動オプション全体を文字列として取得
  LArgText := '';
  for i := 1 to ParamCount do begin
    LArgText := LArgText + ParamStr(i);
  end;

  //プロパティのダイアログを表示
  if (Trim(LArgText) = '/') then begin
    keybd_event(VK_MENU,  MapVirtualKey(VK_MENU, 0),  0, 0);
    keybd_event(VK_SPACE, MapVirtualKey(VK_SPACE, 0), 0, 0);
    keybd_event(Ord('P'), MapVirtualKey(Ord('P'), 0), 0, 0);

    keybd_event(VK_MENU,  MapVirtualKey(VK_MENU, 0),  KEYEVENTF_KEYUP, 0);
    keybd_event(VK_SPACE, MapVirtualKey(VK_SPACE, 0), KEYEVENTF_KEYUP, 0);
    keybd_event(Ord('P'), MapVirtualKey(Ord('P'), 0), KEYEVENTF_KEYUP, 0);
  end;

  //パラメータの説明を表示
  //テキストはリソースとしてEXEに埋め込んでいる
  if (Trim(LArgText) = '/?') or (Trim(LArgText) = '?') then begin
    LResStream := TResourceStream.Create(hInstance,'Resource_1','TEXT');
    LArgList := TStringList.Create;
    try
      LArgList.LoadFromStream(LResStream);
      Writeln(LArgList.Text);
    finally
      FreeAndNil(LArgList);
      FreeAndNil(LResStream);
    end;
    exit;
  end;

  //------------------------------------------------------------------------
  //  各起動パラメータ(起動オプション)の値を取り出す処理
  //------------------------------------------------------------------------

  LArgList := TStringList.Create;
  try
    LArgList.Delimiter       := '/';
    LArgList.StrictDelimiter := True;
    LArgList.DelimitedText   := LArgText;

    try
      if ParamCount = 0 then begin
        LShowFontInfo := True;
      end else
      if (ParamCount = 1) and (LArgList.Count = 1) then begin
        LArgFontH := StrToIntDef(ParamStr(1), FMaxValue);;
        LShowFontInfo := True;
      end else begin
        for i := 0 to LArgList.Count - 1 do begin
          LArgText  := LArgList[i];
          if Pos('fontname', LowerCase(LArgText)) <= 0 then begin
            LArgText := LowerCase(LArgList[i]);
          end;
          LiPos     := Pos('=', LArgText);
          LLeftStr  := Copy(LArgText, 1, LiPos);
          LLeftStr  := StringReplace(LLeftStr, ' ', '', [rfReplaceAll]);
          LRightStr := Trim(Copy(LArgText, LiPos + 1, Length(LArgText)));
          if Length(LRightStr) = 0 then Continue;

          //ウィンドウの左端X座標値
          if (LLeftStr ='wndleft=') or (LLeftStr = 'windowleft=') then begin
            LArgWndLeft := StrToIntDef(LRightStr, FMaxValue);
          end;
          //ウィンドウの上端Y座標値
          if (LLeftStr = 'wndtop=') or (LLeftStr = 'wndowtop=') then begin
            LArgWndtop := StrToIntDef(LRightStr, FMaxValue);
          end;
          //画面バッファのサイズの幅
          if (LLeftStr = 'buffw=') or (LLeftStr = 'bufferw=') then begin
            LArgBuffW := StrToIntDef(LRightStr, FMaxValue);
          end;
          //画面バッファのサイズの高さ
          if (LLeftStr = 'buffh=') or (LLeftStr = 'bufferh=') then begin
            LArgBuffH:= StrToIntDef(LRightStr, FMaxValue);
          end;
          //ウィンドウのサイズの幅
          if (LLeftStr = 'wndw=') or (LLeftStr = 'windoww=') then begin
            LArgWndW := StrToIntDef(LRightStr, FMaxValue);
          end;
          //ウィンドウのサイズの高さ
          if (LLeftStr = 'wndh=') or (LLeftStr = 'windowh=') then begin
            LArgWndH:= StrToIntDef(LRightStr, FMaxValue);
          end;
          //フォント高さ
          if LLeftStr = 'fontsize=' then begin
            LArgFontH := StrToIntDef(LRightStr, FMaxValue);;
          end;
          //背景色とフォントの色
          if LLeftStr = 'color=' then begin
            if LRightStr[1] <> '$' then LRightStr := '$' + LRightStr;
            LArgColor := StrToIntDef(LRightStr, FMaxValue);
          end;
          //フォント名
          if LLeftStr = 'fontname=' then begin
            LArgFontName := Trim(LRightStr);
          end;
          //非表示オプション
          if LRightStr = 'hide' then begin
            LShowHide := True;
          end;
        end;
      end;
    finally
      FreeAndNil(LArgList);
    end;
  except
    exit;
  end;
  //以上で起動パラメータの値が変数に代入された.これ以降は実際の設定コード


  //------------------------------------------------------------------------
  //  ウインドウの位置の設定
  //------------------------------------------------------------------------

  //ウインドウハンドルを取得
  LConsoleWnd := FindWindow(PChar(FWndClassName), nil);
  if LConsoleWnd > 0 then begin
    //コンソールウィンドウのサイズ(ピクセル)を取得して位置を設定
    LWndRect := GetWindowRectForVista(LConsoleWnd);

    if LArgWndLeft >= FMaxValue then begin
      LArgWndLeft := LWndRect.Left;
    end;
    if LArgWndTop >= FMaxValue then begin
      LArgWndTop := LWndRect.Top;
    end;
    MoveWindow(LConsoleWnd,
               LArgWndLeft,
               LArgWndTop,
               LWndRect.Right  - LWndRect.Left,
               LWndRect.Bottom - LWndRect.Top,
               True);
  end;


  //標準出力デバイスのハンドルを取得
  LhStdout := GetStdHandle(STD_OUTPUT_HANDLE);
  if LhStdout > 0 then begin

    //------------------------------------------------------------------------
    //  画面バッファのサイズの幅と高さ
    //  ウィンドウの幅と高さよりも小さい値にはできない
    //  システムが設定している最小値より小さい値にはできない(SM_CXMIN, SM_CYMIN)
    //  システムが設定している最大値よりも大きな値にはできない
    //------------------------------------------------------------------------

    if (LArgBuffW < FMaxValue) or (LArgBuffH < FMaxValue) then begin
      if not LShowHide then LShowBuffInto := True;

      //バッファの情報取得
      GetConsoleScreenBufferInfo(LhStdout, LBuffInfo);

      LBuffCoord.X := LBuffInfo.dwSize.X;
      LBuffCoord.Y := LBuffInfo.dwSize.Y;
      if LArgBuffW < FMaxValue then LBuffCoord.X := LArgBuffW;
      if LArgBuffH < FMaxValue then LBuffCoord.Y := LArgBuffH;
      SetConsoleScreenBufferSize(LhStdout, LBuffCoord);

      //設定結果の表示
      if LShowBuffInto then begin
        GetConsoleScreenBufferInfo(LhStdout, LBuffInfo);
        writeln('');
        Writeln('Buffer W : ' + IntToStr(LBuffInfo.dwSize.X));
        Writeln('Buffer H : ' + IntToStr(LBuffInfo.dwSize.Y));
      end;
    end;

    //------------------------------------------------------------------------
    //  ウィンドウのサイズの幅と高さ
    //  画面バッファのサイズよりも大きな値にはできない
    //  大きな値を設定したい場合は,画面バッファのサイズを設定してから変更する
    //
    //  ネット上に
    //  TConsoleScreenBufferInfo.srWindow.Left
    //  TConsoleScreenBufferInfo.srWindow.Top
    //  の値を(0, 0) または(1,1)にするサンプルコードがある.それでも変更は可能
    //  ただし,その値で設定を繰り返すと例外が発生する
    //  例外が発生すると,コマンドプロンプトが終了できなくなる
    //  システム関係のこの例外はtry-exceptでは捕捉できない
    //------------------------------------------------------------------------

    if (LArgWndW < FMaxValue) or (LArgWndH < FMaxValue) then begin
      if not LShowHide then LShowWndInfo := True;
      //バッファの情報取得
      GetConsoleScreenBufferInfo(LhStdout, LBuffInfo);

      LSmallRect := LBuffInfo.srWindow;
      if LArgWndW < FMaxValue then LSmallRect.Right  := LSmallRect.Left + LArgWndW - 1;
      if LArgWndH < FMaxValue then LSmallRect.Bottom := LSmallRect.Top + LArgWndH - 1;
      SetConsoleWindowInfo(LhStdout, True, LSmallRect);

      //設定結果の表示
      if LShowWndInfo then begin
        GetConsoleScreenBufferInfo(LhStdout, LBuffInfo);
        LWndCoord.X := LBuffInfo.srWindow.Right - LBuffInfo.srWindow.Left + 1;
        LWndCoord.Y := LBuffInfo.srWindow.Bottom - LBuffInfo.srWindow.Top + 1;
        if not LShowBuffInto then writeln('');
        Writeln('Window W : ' + IntToStr(LWndCoord.X));
        Writeln('Window H : ' + IntToStr(LWndCoord.Y));
      end;
    end;

    //------------------------------------------------------------------------
    //  フォントサイズとフォント名の取得と設定
    //  フォント名とサイズの組み合わせによっては設定できない組み合せもある
    //  プロパティのフォントのリストにないフォント名は指定できない
    //------------------------------------------------------------------------

    //フォント情報構造体のサイズ設定
    LFontInfo.cbSize := SizeOf(TConsoleFontInfoEx);

    if (LArgFontH < FMaxValue) or (LArgFontName <> '') then begin
      if not LShowHide then LShowFontInfo := True;

      //現在のフォント情報を取得
      GetCurrentConsoleFontEx(LhStdout, False, @LFontInfo);

      //フォントサイズ
      if (LArgFontH <= 72) then begin
        LFontInfo.dwFontSize.X := 0;
        LFontInfo.dwFontSize.Y := LArgFontH;
      end;
      //フォント名
      if LArgFontName <> '' then begin
        StrPCopy(LFontInfo.FontName, LArgFontName);
        LFontInfo.nFont        := 0;
        LFontInfo.FontFamily   := FF_DONTCARE;
        LFontInfo.FontWeigth   := FW_DONTCARE;
      end;
      //新しいフォントを設定
      SetCurrentConsoleFontEx(LhStdout, False, @LFontInfo);
    end;

    //現在のフォントの設定値を表示
    if LShowFontInfo then begin
      //フォントの設定を取得
      GetCurrentConsoleFontEx(LhStdout, False, @LFontInfo);
      if not (LShowBuffInto and LShowWndInfo) then writeln('');
      Writeln('FontName   : ' + LFontInfo.FontName);
      Writeln('FontSize.X : ' + IntToStr( LFontInfo.dwFontSize.X));
      Writeln('FontSize.Y : ' + IntToStr( LFontInfo.dwFontSize.Y));
    end;

    //------------------------------------------------------------------------
    //  画面の背景色と文字の色の設定
    //  cmd.exeにはcolorという内部コマンドがある.そのコマンドで設定可能
    //  cmd.exeの起動オプションの/Tでも設定可能
    //------------------------------------------------------------------------

    //最初の4ビットが背景色.下位の4ビットが文字の色
    if LArgColor <= $FF then begin
      //バッファの情報取得
      GetConsoleScreenBufferInfo(LhStdout, LBuffInfo);
      LBuffCoord := LBuffInfo.dwSize;

      LColorWord := LArgColor and $FF;
      LCurPos.X := 0;
      LCurPos.Y := 0;
      LBuffLength := LBuffCoord.X * LBuffCoord.Y;
      FillConsoleOutputAttribute(LhStdout, LColorWord, LBuffLength, LCurPos, LOutCnt);
      SetConsoleTextAttribute(LhStdout, LColorWord);
    end;
  end;
end.




09_起動中のコマンドプロンプトのフォントサイズを変更


外部のプログラムからコマンドプロンプトのフォントサイズだけを変更するサンプルです.これと同じ方法で,コマンドプロンプトの他のプロパティも設定できます.

多くの等倍フォントは,その幅が高さの半分になります.そのようなフォントでは,コマンドプロンプトのプロパティで確認すると,設定可能なフォント高さが偶数になっています.本サンプルでは奇数の値も設定できますが,フォントの高さが奇数の時はシステムがフォントの表示幅を決定します.そのため,フォントのサイズを変更しても,ウィンドウの幅が変わらないことがあります.

ラスターフォントの Terminal でテストすると,途中でフォントが変わります.Terminal フォントには設定できないサイズがあるためです.





図13
外部のプログラムからフォントサイズを変更
  • [Button1] クリックでコマンドプロンプト起動
  • 既にコマンドプロンプトが起動中なら [Button1] クリックは不要
  • [↑] [↓] キーでフォントサイズ変更

リスト5
起動中のコマンドプロンプトのフォントサイズを,外部のプログラムから変更するサンプル
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Spin;

type
  TForm1 = class(TForm)
    Button1: TButton;
    SpinEdit1: TSpinEdit;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure SpinEdit1Change(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
    FhCmdWindow : HWND;
  end;

var
  Form1: TForm1;

implementation

uses
  ShellAPI;

{$R *.dfm}

//-----------------------------------------------------------------------------
//  SetCurrentConsoleFontEx関数とこの関数で使用する構造体の定義
//  これらはDelphi XE7 までは実装されていない.Windows Vista以降で使用可能
//-----------------------------------------------------------------------------
type
  PConsoleFontInfoEx = ^TConsoleFontInfoEx;
  _CONSOLE_FONT_INFOEX = record
    cbSize     : ULONG;
    nFont      : DWORD;
    dwFontSize : TCoord;
    FontFamily : UINT;
    FontWeigth : UINT;
    FontName   : array [0..LF_FACESIZE-1] of WideChar;
  end;
  TConsoleFontInfoEx = _CONSOLE_FONT_INFOEX;

  function GetCurrentConsoleFontEx(
            hConsoleOutput : THandle;
            bMaximumWindow : BOOL;
            lpConsoleCurrentFontEx : PConsoleFontInfoEx):
            BOOL; stdcall; external 'kernel32.dll';

  function SetCurrentConsoleFontEx(
            hConsoleOutput : THandle;
            bMaximumWindow : BOOL;
            lpConsoleCurrentFontEx : PConsoleFontInfoEx):
            BOOL; stdcall; external 'kernel32.dll';

  function AttachConsole(dwProcess: DWORD): BOOL; stdcall; external 'kernel32.dll';


//=============================================================================
//  フォーム生成時の処理
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  SpinEdit1.MinValue := 10;
  SpinEdit1.MaxValue := 72;
  SpinEdit1.Value    := 16;
end;

//=============================================================================
//  フォーム破棄時の処理
//=============================================================================
procedure TForm1.FormDestroy(Sender: TObject);
begin
  if FhCmdWindow > 0 then begin
    if IsWindowVisible(FhCmdWindow) then begin
      PostMessage(FhCmdWindow, WM_CLOSE, 0, 0);
    end;
  end;
end;

//=============================================================================
//  コマンドプロンプトを起動
//
//  usesにShellAPIが必要
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LAppPath  : string;
  LParamStr : string;
begin
  FhCmdWindow := FindWindow('ConsoleWindowClass', nil);
  if IsWindowVisible(FhCmdWindow) then begin
    SpinEdit1.SetFocus;
    exit;
  end;

  LAppPath  := 'cmd.exe';
  LParamStr := '';

  ShellExecute(Handle, '', Pchar(LAppPath), PChar(LParamStr), 'C:\', SW_SHOW);

  //起動待ちのタイムラグ(簡易版)
  Sleep(200);
  SetForegroundWindow(Handle);
  SpinEdit1.SetFocus;
end;

//=============================================================================
//  SpinEdit1のOnChangeイベント
//  コマンドプロンプトのフォントサイズをSpinEdit1の値にする
//=============================================================================
procedure TForm1.SpinEdit1Change(Sender: TObject);
var
  LProcessID  : Cardinal;
  LhStdout    : THandle;
  LFontInfo   : TConsoleFontInfoEx;
begin
  //コマンドプロンプトのウインドウハンドルを取得
  FhCmdWindow := FindWindow('ConsoleWindowClass', nil);
  if FhCmdWindow = 0 then exit;
  //スレッドのプロセスIDを取得
  GetWindowThreadProcessId(FhCmdWindow, @LProcessID);

  //コンソールのスレッドにアタッチ
  if AttachConsole(LProcessID) then begin
    //標準出力デバイスのハンドルを取得
    LhStdout := GetStdHandle(STD_OUTPUT_HANDLE);
    if LhStdout > 0 then begin

      //------------------------------------------------------------------------
      //  フォントサイズとフォント名の取得と設定
      //  フォント名とサイズの組み合わせによっては設定できない組み合せもある
      //------------------------------------------------------------------------

      //フォント情報構造体のサイズ設定
      LFontInfo.cbSize := SizeOf(TConsoleFontInfoEx);
      //現在のフォント情報を取得
      GetCurrentConsoleFontEx(LhStdout, False, @LFontInfo);

      //フォントサイズ
      LFontInfo.dwFontSize.X := 0;
      LFontInfo.dwFontSize.Y := SpinEdit1.Value;
      LFontInfo.nFont        := 0;
      LFontInfo.FontFamily   := FF_DONTCARE;
      LFontInfo.FontWeigth   := FW_DONTCARE;

      //新しいフォントを設定
      SetCurrentConsoleFontEx(LhStdout, False, @LFontInfo);
    end;

    //FreeConsoleでデアタッチしておく
    FreeConsole;
  end;
end;

end.