意見交換において起動しているアプリをリスト表示して切り替えたいが思うように動作するアプリが無い
とのことで、2024年に似たようなアプリを作ったことがあったので応用して作れないか?と思ったが悪戦苦闘するのは目に見えているのでそれを記事にしておく
どんなとき使うの?
Windowsで開発していると様々なアプリを切り替えながら使います
でもそのときってタスクバーのアイコンをマウスでクリックする操作が必要です
これってもっと簡単で便利に出来ないの?と思っていたので丁度良い意見交換でした
自分の場合このアプリの切り替え操作を1日1万回ぐらいしているので何とか出来ると効率が良くなりそうです
あとタスクバーだと起動させたくないアプリを誤クリックしてしまうのでそれも防げると思われます
0.5日目
似たようなアプリから必要最低限の部分を取り出し表示するときにアプリの一覧を表示する
参考にしたのは下記のサイトの3番目
http://mrxray.on.coocan.jp/Delphi/plSamples/320_AppList.htm
0.5日目の結果
タスクトレイに常駐し、クリックするとこのようになる※実際はホットキーによる起動
一見うまくいっているように見えるがうまく言っていない
表示する必要がないものが表示されたり表示したいものが表示されていない
アイコンが16x16のものしか取得できず見た目が悪い
AIに大きいアイコンの取得を作らせたが取得できないのとサイズが指定出来ない
原因は古いAPIを古い方法で使っているためと思われる
1日目
Windows10用の起動中アプリを表示する仕組みに差し替える。
ついでにアイコンサイズが16ピクセルじゃ無くて大きいのを取得する※この処理が思いのほかめんどくさい
1日目の結果
起動しているアプリが正しく取得されているのとアイコンサイズが大きくなって見やすくなった
2日目
アプリ一覧の処理がジャマなのでフレームとして分離。
常駐型アプリとしてメニューからの終了以外は終了しない処理を追加。
キーボードのグローバルフックでキーを取得してキーを判断してアプリ一覧を表示
問題点
wParam に WM_KEYDOWNが入ってくるタイミングでlParam: LPARAMにキーコードが入ると思ったが入ってこないようだ
下記の方法でグローバルキーフックが出来たので採用
RegisterHotKey(Handle, 1, MOD_CONTROL + MOD_SHIFT, Ord('G'));
設定画面
配布
下記リンクからDL可能
https://drive.google.com/uc?id=1jEf-jZDktQV3N0Yfc78r36hf47NwaPS5
使い方
実行すると右下のアイコントレイに常駐。
アイコントレイにあるアイコンをクリックするとアプリ一覧が表示される。
アイコントレイから右クリックメニューでアプリ一覧を表示するキーの設定が出来る。
有効にしてキーを入力するとマウスの位置を中心としてアプリ一覧が表示
使用するアプリを選ぶとそのアプリがアクティブに
そして本体は密かに隠れるので必要な時にまた呼び出す
アプリ一覧の右側のキーをダブルクリックするとショートカットキーが選べる
ショートカットキーを押すとアプリがアクティブになる
終了するときは右クリックからの終了で行う
最後に
なんだかんだで4日で完成
ついでにGeminiでアイコンを作ってもらった
キーのフックはもう少し学習する必要がありそうなのとAIに問い合わせると存在しない命令を使えと言われる。
キーの厳密チェックはしてないので変なキーを登録しないように
ショートカットキーの設定を標準機能に切り替えたので設定はやりなおし
ソース
unit MainForm;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics,Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls,
Vcl.ComCtrls,DMStanderd, Vcl.Menus,AppListFrame,DataConfig;
type
TFormMainPos = class(TDMStanderdWindow)
private
protected
function GetFilename() : string;override;
end;
type
TFormMain = class(TForm)
MenuPop: TPopupMenu;
Menuconfig: TMenuItem;
MenuClose: TMenuItem;
N1: TMenuItem;
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure MenuCloseClick(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure MenuconfigClick(Sender: TObject);
private
{ Private 宣言 }
FPos : TFormMainPos; // Window位置データ
FTrayIconMain : TTrayIcon; // トレイアイコン操作クラス
FFolder : string; // データ保存先フォルダ
FHandleSelf : HWND; // 自分自身のハンドル
FShowed : Boolean; // True:描画済み
FToolHide : Boolean; // True : 手動で非表示中
FFrameAppList : TFrameAppList;
FProcClosed : Boolean; // True : メニューから終了指示あり
FConfig : TDataConfig;
FHotkeyUsed : Boolean;
procedure ShowList();
procedure HotkeyStart();
procedure HotkeyStop();
//procedure WMNchiltTest(var Msg : TWMNchitTest);Message WM_NCHITTEST;
procedure OnTrayIconClick(Sender: TObject);
procedure OnAppSelect(Sender: TObject);
protected
//procedure CreateParams(var Params: TCreateParams); override;
public
{ Public 宣言 }
procedure WndProc(var Message: TMessage); override;
end;
var
FormMain: TFormMain;
var
WndProc : Pointer;
implementation
uses FolderLib,
Winapi.Dwmapi,
Winapi.propSys,
Winapi.PropKey,
ConfigForm;
{$R *.dfm}
//--------------------------------------------------------------------------//
// フォーム生成 //
//--------------------------------------------------------------------------//
procedure TFormMain.FormCreate(Sender: TObject);
begin
FHandleSelf := Self.Handle;
SetFolder('WinReplace'); // 設定値保存フォルダを指定
FFolder := GetMyDocFolder();
CheckFolderAndMake(FFolder); // 設定値保存フォルダを作成
FPos := TFormMainPos.Create;
FPos.LoadFromFile;
FConfig := TDataConfig.Create;
FConfig.LoadFromFile(FFolder+'config.ini');
FTrayIconMain := TTrayIcon.Create(Self);
FTrayIconMain.Icon := Application.Icon;
FTrayIconMain.Visible := True;
FTrayIconMain.Hint := Application.Title;
FTrayIconMain.PopupMenu := MenuPop;
FTrayIconMain.OnClick := OnTrayIconClick;
FFrameAppList := TFrameAppList.Create(Self);
FFrameAppList.Parent := Self;
FFrameAppList.Align := alClient;
FFrameAppList.OnAppSelect := OnAppSelect;
HotkeyStart();
FPos.Pos.DataToForm(Self);
end;
//--------------------------------------------------------------------------//
// フォーム破棄イベント //
//--------------------------------------------------------------------------//
procedure TFormMain.FormDestroy(Sender: TObject);
begin
HotkeyStop();
FFrameAppList.Free;
FTrayIconMain.Visible := False;
FTrayIconMain.Free;
FConfig.Free;
FPos.Free;
end;
//--------------------------------------------------------------------------//
// フォーム表示イベント //
//--------------------------------------------------------------------------//
procedure TFormMain.FormShow(Sender: TObject);
begin
{
ShowWindow(Application.Handle, SW_HIDE);
SetWindowLong(Application.Handle, GWL_EXSTYLE,
GetWindowLong(Application.Handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW);
}
FShowed := True;
ShowList();
end;
procedure TFormMain.HotkeyStart;
var
ModKey : Cardinal;
begin
if not FConfig.HotKeyed then exit;
FHotkeyUsed := True;
ModKey := 0;
if FConfig.KeyShift then ModKey := ModKey + MOD_SHIFT;
if FConfig.KeyCtrl then ModKey := ModKey + MOD_CONTROL;
if FConfig.KeyAlt then ModKey := ModKey + MOD_ALT;
RegisterHotKey(Handle, 1, ModKey, Ord(FConfig.HotKey));
//RegisterHotKey(Handle, 1, MOD_CONTROL + MOD_SHIFT, Ord('G'));
end;
procedure TFormMain.HotkeyStop;
begin
if not FHotkeyUsed then exit;
FHotkeyUsed := False;
end;
//--------------------------------------------------------------------------//
// フォーム閉じるイベント //
//--------------------------------------------------------------------------//
procedure TFormMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if not FShowed then exit; // 描画していない場合未処理
FPos.Pos.FormToData(Self); // フォームサイズと位置を取得
FPos.SaveToFile; // フォームサイズと位置を保存
Action := caMinimize;
end;
procedure TFormMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
if FProcClosed then begin
exit;
end;
CanClose := False;
Hide();
end;
//--------------------------------------------------------------------------//
// 終了メニュー //
//--------------------------------------------------------------------------//
procedure TFormMain.MenuCloseClick(Sender: TObject);
begin
FProcClosed := True;
Close;
Application.ProcessMessages;
end;
procedure TFormMain.MenuconfigClick(Sender: TObject);
var
df : TFormConfig;
begin
df := TFormConfig.Create(Self);
try
df.Config.Assign(FConfig);
if df.ShowModal <> mrOk then exit;
FConfig.Assign(df.Config);
FConfig.SaveToFile(FFolder+'config.ini');
HotkeyStop();
HotkeyStart();
finally
df.Free;
end;
end;
procedure TFormMain.OnAppSelect(Sender: TObject);
begin
Hide();
end;
//--------------------------------------------------------------------------//
// トレイアイコンクリック操作イベント //
//--------------------------------------------------------------------------//
procedure TFormMain.OnTrayIconClick(Sender: TObject);
begin
if Self.Visible then exit;
FToolHide := False;
Self.Visible := True;
end;
procedure TFormMain.ShowList;
begin
FFrameAppList.ShowList();
end;
procedure TFormMain.WndProc(var Message: TMessage);
var
MousePos: TPoint;
FormWidth, FormHeight: Integer;
// Left, Top: Integer;
begin
inherited WndProc(Message);
if Message.Msg = WM_HOTKEY then
begin
if Message.WParam = 1 then
begin
// 1. マウス座標の取得
GetCursorPos(MousePos);
// 2. フォームの位置計算
FormWidth := Width;
FormHeight := Height;
Left := MousePos.X - FormWidth div 2;
Top := MousePos.Y - FormHeight div 2;
// Ctrl+Shift+G が押されたときの処理
ShowList();
Show();
// 3. フォームの位置設定
//SetBounds(Left, Top, FormWidth, FormHeight);
// または
//Left := Left;
//Top := Top;
end;
end;
end;
//--------------------------------------------------------------------------//
// タイトルバーの無いフォームを移動させる処理 //
//--------------------------------------------------------------------------//
{
procedure TFormMain.WMNchiltTest(var Msg: TWMNchitTest);
const
h = 6;
begin
Msg.Result := HTCAPTION;
end;
}
{ TFormMainPos }
function TFormMainPos.GetFilename: string;
begin
result := GetMyDocFolder + 'WindowPos.ini';
end;
end.
unit AppListFrame;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics,Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls,
Winapi.ShellAPI, Winapi.ActiveX, Winapi.ShlObj, Winapi.CommCtrl, Vcl.ImgList,
Vcl.ComCtrls,DMStanderd, Vcl.Menus;
type
TFrameAppList = class(TFrame)
ListView1: TListView;
ImageList1: TImageList;
private
{ Private 宣言 }
public
{ Public 宣言 }
constructor Create(AOwner: TComponent); override;
destructor Destroy;override;
procedure ShowList();
end;
function QueryFullProcessImageNameW(Process: THandle; Flags: DWORD; Buffer: PChar;
Size: PDWORD): DWORD; stdcall; external 'kernel32.dll';
function EnumWindowProc(hWindow: HWND; lPara: TListView): Boolean; stdcall;
function GetWindowTitle(hWindow: HWND): string;
function GetWindowClassName(hWindow: HWND): string;
implementation
{$R *.dfm}
uses FolderLib,
Winapi.Dwmapi,
Winapi.propSys,
Winapi.PropKey;
{ TFrameAppList }
constructor TFrameAppList.Create(AOwner: TComponent);
begin
inherited;
ImageList1.Width := 32;
ImageList1.Height := 32;
ImageList1.BkColor := ListView1.Color;
ListView1.ViewStyle := vsReport;
ListView1.SmallImages := ImageList1;
ListView1.Columns.Add;
ListView1.Columns[0].Caption :=' アプリケーション';
ListView1.Columns[0].Width := ListView1.ClientWidth;
end;
destructor TFrameAppList.Destroy;
begin
inherited;
end;
procedure TFrameAppList.ShowList;
begin
ListView1.Items.Clear;
ListView1.Items.BeginUpdate;
ListView1.Columns[0].Width := ListView1.ClientWidth-32;
ImageList1.Clear;
EnumWindows(Addr(EnumWindowProc), LPARAM(ListView1));
ListView1.Items.EndUpdate;
end;
function GetIconHandleFromWindow(hWindow: HWND): HICON;
begin
Result := SendMessage(hWindow, WM_GETICON, ICON_SMALL2, 0);
if Result = 0 then begin
Result := SendMessage(hWindow, WM_GETICON, ICON_SMALL, 0);
if Result = 0 then begin
Result := GetClassLong(hWindow, GCL_HICONSM);
end;
end;
end;
// AIの提案 こっちはボツ
function GetWindowIcon(WindowHandle: HWND; Size: Integer): TIcon;
var
IconHandle: HICON;
begin
IconHandle := HICON(SendMessage(WindowHandle, WM_GETICON, WPARAM(Size), 0));
if IconHandle <> 0 then
begin
Result := TIcon.Create;
Result.Handle := IconHandle;
end
else
Result := nil;
end;
//-----------------------------------------------------------------------------
// SHGetImageList関数を使用してシステムのイメージリストを取得
// 取得するアイコンのサイズを引数で指定する
// 定数名はShellAPI.pasに定義されている
//
// Delphi XEにはSHGetImageList関数が実装されているが,32ビットのEXEを64ビット
// Windowsで実行すると,「特権命令」違反が発生する
// 本コードのようにLoadLivraryでDLLをロードし関数のアドレスを取得して実行する
// と例外が発生しない
// 64ビットのEXEで実行すれば「特恵命令」は発生しない
//-----------------------------------------------------------------------------
function GetSystemImageList(ASHILValue: Cardinal): HIMAGELIST;
type
TSHGetImageList = function(iImageList: integer;
const riid: TGUID;
var ppv: Pointer): HRESULT; stdcall;
const
IID_IImageList: TGUID= '{46EB5926-582E-4017-9FDF-E8998DAA0950}';
var
LDllHandle : THandle;
LSHGetImageList : TSHGetImageList;
begin
Result := 0;
LDllHandle := LoadLibrary('Shell32.dll');
if LDllHandle <> 0 then begin
try
LSHGetImageList := GetProcAddress(LDllHandle, 'SHGetImageList');
if @LSHGetImageList <> nil then begin
LSHGetImageList(ASHILValue, IID_IImageList, Pointer(Result));
end;
finally
FreeLibrary(LDllHandle);
end;
end;
end;
//-----------------------------------------------------------------------------
// EnumWindows のコールバック関数
// このコールバック内で現在起動中のアプリの一覧を作成
// 必要なユニット類は uses 部の記述を参照
//-----------------------------------------------------------------------------
function EnumWindowProc(hWindow: HWND; lPara: TListView): Boolean; stdcall;
const
UWP_FRAMEWND = 'ApplicationFrameWindow';
UWP_COREWND = 'Windows.UI.Core.CoreWindow';
PROCESS_QUERY_LIMITED_INFORMATION = $1000;
DWMWA_CLOAKED = 14;
CLASS_BRIDGE = 'Windows.UI.Composition.DesktopWindowContentBridge';
var
LIsUWPApp : Boolean;
LAppWindow : HWND;
LAppTitle : string;
LCloaked : BOOL;
LPropStore : IPropertyStore;
LPropVar : TPropVariant;
LProcessID : DWORD;
LhProcess : THandle;
LBuffer : array [0..MAX_PATH - 1] of Char;
LSTR_SIZE : DWORD;
LAppPath : string;
LITemIDPath : PItemIDList;
LSHFileInfo : TSHFileInfo;
LIcon : TIcon;
LItem : TListItem;
i : Integer;
list : HIMAGELIST;
begin
Result := True;
LAppWindow := hWindow;
if GetWindow(LAppWindow, GW_OWNER) <> 0 then exit;
if not IsWindowVisible(LAppWindow) then exit;
// 待機中またはバックグラウンドのウィンドウは対象外
// クラス名 Windows.UI.Core.CoreWindow のウインドウはバックグラウンド扱い
DwmGetWindowAttribute(LAppWindow, DWMWA_CLOAKED, @LCloaked, SizeOf(LCloaked));
if LCloaked then Exit;
LAppTitle := GetWindowTitle(LAppWindow);
if LAppTitle = '' then Exit;
if SameText(LAppTitle, 'Program Manager') then Exit;
if SameText(LAppTitle, 'Winreplace') then Exit;
if FindWindowEx(LAppWindow, 0, PChar(CLASS_BRIDGE), nil) <> 0 then Exit;
// クラス名 ApplicationFrameWindow のウインドウは UWP アプリ
LIsUWPApp := GetWindowClassName(LAppWindow) = UWP_FRAMEWND;
if LIsUWPApp then begin
// AppUserModelId の値を取得
if SHGetPropertyStoreForWindow(LAppWindow,
IID_IPropertyStore,
Pointer(LPropStore)) <> S_OK then Exit;
if LPropStore.GetValue(PKEY_AppUserModel_ID, LPropVar) <> S_OK then Exit;
LAppPath := LPropVar.bstrVal;
LAppPath := 'shell:AppsFolder\' + LAppPath;
end else begin
// プロセスIDを取得
// その値からプロセスのオープンハンドル取得
GetWindowThreadProcessId(LAppWindow, Addr(LProcessID));
LhProcess := OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, False, LProcessID);
try
// EXE のフルパスを取得
FillChar(LBuffer, SizeOf(LBuffer), #0);
LSTR_SIZE := Length(LBuffer);
LAppPath:='';
if QueryFullProcessImageNameW(LhProcess,
0,
@LBuffer[0],
@LSTR_SIZE) = 0 then Exit;
LAppPath := LBuffer;
finally
CloseHandle(LhProcess);
end;
end;
// ウィンドウのアイコンを取得して TListView に表示
// TListView の Item の Data プロパティにウィンドウハンドルの値を代入
LIcon := TIcon.Create;
try
if LIsUWPApp then begin
LITemIDPath := ILCreateFromPath(PWideChar(LAppPath));
SHGetFileInfo(Pointer(LITemIDPath),
0,
LSHFileInfo,
SizeOf(TSHFileInfo),
SHGFI_PIDL or SHGFI_ICON or SHGFI_SMALLICON);
LIcon.Handle := LSHFILeInfo.hIcon;
CoTaskMemFree(LITemIDPath);
end else begin
// ファイル名 (またはファイルの関連付け) から取得
SHGetFileInfo(PChar(LAppPath),
0,
LSHFileInfo,
SizeOf(LSHFileInfo),
SHGFI_ICON or SHGFI_SMALLICON or SHGFI_SHELLICONSIZE);
i := LSHFileInfo.iIcon;
if i = -1 then i := 0; // アイコンデータがない場合は未処理
list := GetSystemImageList(SHIL_LARGE); // 指定サイズのアイコンを格納したシステムのイメージリストを取得
LIcon.Handle := ImageList_GetIcon(list, i, ILD_NORMAL); // イメージリストから指定インデックスのアイコンのハンドルを取得
//LIcon.Handle := LSHFileInfo.hIcon;
end;
LItem := lPara.Items.Add;
LItem.Caption := GetWindowTitle(LAppWindow);
LItem.Data := PNativeUInt(LAppWindow);
LItem.ImageIndex := lPara.SmallImages.AddIcon(LIcon);
finally
FreeAndNil(LIcon);
end;
end;
//-----------------------------------------------------------------------------
// ウィンドウのタイトルを取得する関数
//-----------------------------------------------------------------------------
function GetWindowTitle(hWindow: HWND): string;
var
LBuff : array [0..MAX_PATH - 1] of Char;
begin
Result := '';
FillChar(LBuff, SizeOf(LBuff), #0);
if (GetWindowText(hWindow, @LBuff, MAX_PATH) > 0) then begin
Result := LBuff;
end;
end;
//-----------------------------------------------------------------------------
// ウィンドウのクラス名を取得する関数
//-----------------------------------------------------------------------------
function GetWindowClassName(hWindow: HWND): string;
var
LBuff : array [0..MAX_PATH - 1] of Char;
begin
Result := '';
FillChar(LBuff, SizeOf(LBuff), #0);
if (GetClassName(hWindow, @LBuff, MAX_PATH) > 0) then begin
Result := LBuff;
end;
end;
end.
unit ConfigForm;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.CheckLst,DataConfig;
type
TFormConfig = class(TForm)
btnOk: TButton;
ChkKey: TCheckListBox;
EdithotKey: TEdit;
Label2: TLabel;
ChkHotKey: TCheckBox;
procedure EdithotKeyKeyPress(Sender: TObject; var Key: Char);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure ChkKeyClickCheck(Sender: TObject);
procedure ChkHotKeyClick(Sender: TObject);
private
{ Private 宣言 }
FConfig: TDataConfig;
public
{ Public 宣言 }
property Config : TDataConfig read FConfig;
end;
var
FormConfig: TFormConfig;
implementation
{$R *.dfm}
procedure TFormConfig.ChkHotKeyClick(Sender: TObject);
begin
FConfig.HotKeyed := ChkHotKey.Checked;
end;
procedure TFormConfig.ChkKeyClickCheck(Sender: TObject);
begin
FConfig.KeyShift := ChkKey.Checked[0];
FConfig.KeyCtrl := ChkKey.Checked[1];
FConfig.KeyAlt := ChkKey.Checked[2];
end;
procedure TFormConfig.EdithotKeyKeyPress(Sender: TObject; var Key: Char);
begin
if (Key >= 'a') and (Key <= 'z') then begin
Key := Char(Ord(Key) - Ord('a') + Ord('A'));
end;
EdithotKey.Text := Key;
FConfig.HotKey := Key;
end;
procedure TFormConfig.FormCreate(Sender: TObject);
begin
FConfig := TDataConfig.Create;
end;
procedure TFormConfig.FormDestroy(Sender: TObject);
begin
FConfig.Free;
end;
procedure TFormConfig.FormShow(Sender: TObject);
begin
ChkHotKey.Checked := FConfig.HotKeyed;
ChkKey.Checked[0] := FConfig.KeyShift;
ChkKey.Checked[1] := FConfig.KeyCtrl;
ChkKey.Checked[2] := FConfig.KeyAlt;
EdithotKey.Text := FConfig.HotKey;
end;
end.
unit DataConfig;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls,StringListEx,StringListKey,DMStanderd;
type
TDataConfig = class(TDMPersistent)
private
{ Private 宣言 }
FHotKeyed : Boolean;
FHotKey : Char; // 表示する操作キー
FKeyShift : Boolean; // True:重複禁止
FKeyCtrl : Boolean;
FKeyAlt : Boolean;
public
{ Public 宣言 }
constructor Create();virtual;
destructor Destroy;override;
//procedure Assign(Source : TPersistent);override;
published
function LoadFromFile(const Filename : string) : Boolean;
function SaveToFile(const Filename : string) : Boolean;
property HotKeyed : Boolean read FHotKeyed write FHotKeyed;
property HotKey : Char read FHotKey write FHotKey;
//
property KeyShift : Boolean read FKeyShift write FKeyShift;
//
property KeyAlt : Boolean read FKeyAlt write FKeyAlt;
//
property KeyCtrl : Boolean read FKeyCtrl write FKeyCtrl;
end;
implementation
uses StringListRtti;
{ TDataConfig }
constructor TDataConfig.Create;
begin
end;
destructor TDataConfig.Destroy;
begin
inherited;
end;
function TDataConfig.LoadFromFile(const Filename: string): Boolean;
var
tss : TStringListRtti;
begin
result := False;
tss := TStringListRtti.Create; // RTTI保存クラス生成
try
if not FileExists(FileName) then exit; // ファイルが無ければ処理終了
tss.LoadFromFile(FileName); // ファイルを読み込む
tss.LoadFromObject(Self); // オブジェクトに読み込み
result := True;
finally
tss.Free;
end;
end;
function TDataConfig.SaveToFile(const Filename: string): Boolean;
var
tss : TStringListRtti;
begin
tss := TStringListRtti.Create; // RTTI保存クラス生成
try
tss.SaveToObject(Self); // RTTI管理クラスにオブジェクトを保存
tss.SaveToFile(FileName); // ファイルに保存
result := True;
finally
tss.Free;
end;
end;
end.