« なろう系Web小説DL&Kindle mobi化アプリSimpleNovelDownloader | トップページ | 文字コードの自動判定 »

2018.01.20

SaveDialogを拡張してコントロールを追加する

昔、自作のテキストエディタ用にSaveDialogに文字コードと改行コードを選択するComboBoxを追加した拡張コンポーネントを使用していたのを思い出して、Delphi 10.2.2にインストールしたもののそのままではうまく動作しなかったため、あらためて焼き直し版を作成しました。
今回あらためてWeb上を検索したところ、SaveDialogを拡張する方法やコンポーネント等を見つけることが出来なかったため、参考になればということで公開します。

Windows7上
Savedialogex

Windows10上
W10savedlgex
このSaveDialogでは、保存する形式:で文字コードを、改行コード:で改行コードを選択することが出来、選択結果はプロパティCodeTypeとBreakTypeで取得・設定出来ます。

unit SaveDialogEx;
 
interface
 
uses
  System.SysUtils, System.Classes, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls,
  System.Types, Vcl.Controls, Windows;
 
type
  TSaveDialogEx = class(TSaveDialog)
  private
    { Private 宣言 }
	FExtPanel: TPanel;
	FCodeLabel: TLabel;
	FBreakLabel: TLabel;
	FCodeCombo: TComboBox;
	FBreakCombo: TComboBox;
	FCodeType,
	FBreakType: integer;
	procedure ChangeItem(Sender: TObject);
  protected
    { Protected 宣言 }
	procedure DoShow; override;
  public
    { Public 宣言 }
    constructor Create(AOwner: TComponent); override;
	destructor Destroy; override;
	function Execute: Boolean; override;
  published
    { Published 宣言 }
	property CodeType: integer read FCodeType write FCodeType;
	property BreakType: integer read FBreakType write FBreakType;
  end;
 
procedure Register;
 
implementation
 
// Dialogリソースにリソース名DLGEXのパネル(高さ22X幅600、Style=Child)を準備する
// ことで、このパネルサイズでダイアログボックスの下側が拡張される
// 詳しくは、XNResourceEditor等でSAVEDLG.RESを開いて見て下さい
{$R SAVEDLGEX.RES}
 
uses Vcl.Consts, Vcl.Forms, WinApi.CommDlg, WinApi.Dlgs;
 
 
constructor TSaveDialogEx.Create(AOwner: TComponent);
begin
	inherited Create(AOwner);
 
	FExtPanel := TPanel.Create(Self);
	with FExtPanel do
	begin
  	// リソースDLGEXで拡張されたダイアログボックスの位置に合わせてPanelを
    // 生成する
		SetBounds(0, 348, 600, 30);
		Name 				:= 'ExtPanel';
		Caption 		:= '';
		// ダイアログボックスのサイズを変更してもパネルの位置がズレないように
    // パネルの配置をAlign=alBottomにする
    Align 			:= alBottom;
		BevelOuter 	:= bvNone;
		BorderWidth := 6;
		TabOrder 		:= 1;
	end;
  // 生成したパネルにコントロールを生成して貼り付けていく(PanelをParentにする)
	FCodeLabel 		:= TLabel.Create(Self);
	with FCodeLabel do
	begin
		SetBounds(113, 8, 100, 23);
		Name 				:= 'CodeLabel';
		Caption 		:= '保存する形式:';
		Parent 			:= FExtPanel;
	end;
	FCodeCombo 		:= TComboBox.Create(Self);
	with FCodeCombo do
	begin
		SetBounds(225, 4, 130, 20);
		Name 				:= 'CharCodeType';
		Style 			:= csDropDownList;
		TabOrder 		:= 0;
		Parent 			:= FExtPanel;
		OnChange 		:= ChangeItem;
	end;
	FBreakCombo		:= TComboBox.Create(Self);
	with FBreakCombo do
	begin
		SetBounds(440, 4, 72, 20);
		Name 				:= 'LineBreakType';
		Style 			:= csDropDownList;
		TabOrder 		:= 1;
		Parent 			:= FExtPanel;
		OnChange 		:= ChangeItem;
	end;
	FBreakLabel 			:= TLabel.Create(Self);
	with FBreakLabel do
	begin
		SetBounds(380, 8, 100, 23);
		Name 				:= 'CrLabel';
		Caption 		:= '改行コード:';
		Parent 			:= FExtPanel;
	end;
  FCodeType  := 0;
  FBreakType := 0;
end;
 
destructor TSaveDialogEx.Destroy;
begin
	FCodeCombo.Free;
	FBreakCombo.Free;
  FBreakLabel.Free;
	FCodeLabel.Free;
	FExtPanel.Free;
	inherited Destroy;
end;
 
procedure TSaveDialogEx.DoShow;
var
	OptionRect: TRect;
begin
	GetClientRect(Handle, OptionRect);
 
	FExtPanel.ParentWindow := Handle;
	FExtPanel.Top := OptionRect.Height - 40; // ダイアログボックスの高さを元に拡張パネルの高さを決める
	FExtPanel.Visible := True; // Windows98/XPでは不要だったがWindows7では指示が必要
	with FCodeCombo do
	begin
	// アイテムリストを準備する
  	if Items.Count > -1 then
    begin
			Items.Clear;
			Items.Add('Shift-JISコード');
			Items.Add('JISコード');
			Items.Add('EUC-JPコード');
			Items.Add('Unicode(Little Endian)');
			Items.Add('Unicode(Big Endian');
			Items.Add('UTF-8コード');
			Items.Add('UTF-8Nコード');
    end;
    ItemIndex := FCodeType;
	end;
	with FBreakCombo do
	begin
  	// アイテムリストを準備する
  	if Items.Count > -1 then
    begin
			Items.Clear;
			Items.Add('CR+LF');
			Items.Add('CR');
			Items.Add('LF');
    end;
    ItemIndex := FBreakType;
	end;
 
	inherited DoShow;
	DoTypeChange;
end;
 
function TSaveDialogEx.Execute: Boolean;
begin
  if NewStyleControls and not (ofOldStyleDialog in Options) then
		Template := 'DLGEX'	//SAVEDLGEX.RES内のDialogリソースDLGEXを指定する
  else
    Template := nil;    //ofOldStyleDialog=Trueの場合は拡張パネルを表示しない
	Result := DoExecute(@GetSaveFileName);
end;
 
procedure TSaveDialogEx.ChangeItem(Sender: TObject);
begin
	FCodeType 	:= FCodeCombo.ItemIndex;
	FBreakType 	:= FBreakCombo.ItemIndex;
end;
 
procedure Register;
begin
  RegisterComponents('Dialogs', [TSaveDialogEx]);
end;
 
end.

「SaveDialogEx.zip」をダウンロード

SaveDialogEx.pasとsavedlg.resをライブラリパスが通ったフォルダにコピーして、SaveDialogEx.pasをコンポーネントのインストールで登録してください。

|

« なろう系Web小説DL&Kindle mobi化アプリSimpleNovelDownloader | トップページ | 文字コードの自動判定 »

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック


この記事へのトラックバック一覧です: SaveDialogを拡張してコントロールを追加する:

« なろう系Web小説DL&Kindle mobi化アプリSimpleNovelDownloader | トップページ | 文字コードの自動判定 »