|
16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル
"INI ファイルを使った履歴コンボボックス"
レジストリに履歴を記憶するコンボボックスをどこかで見かけたことが
あるんですが 自分自身、フリーソフトなどでレジストリを触るアプリを
あんまりインストールしたく無いものですから INI ファイルへ
記憶するようにしてみました。
最初、INI からの履歴のロード/セーブをそれぞれ自動で行うために
constructor / destructor で TComboBox の items にアクセスしてみたら
エラーが起きてうまくいきませんでした。TComboBox の TComboBoxStrings の
各メソッドが親ウインドウのハンドルを使おうとするためだそうです。
(MES6 で本田さんに教えてもらいました。m(__)m)
そんなもんですから、それぞれ Loaded と WndProc を override して
INI からのロード/セーブを自動化しています。
THisComboBox に履歴を追加する時だけは、自分で AddHistory しないと
ダメですが。(^^;
unit HCmbBox;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, IniFiles;
type
THisComboBox = class(TComboBox)
private
FHistoryMax : Integer; //ヒストリ数の上限
FIniFileName : String; // ini ファイル名
FIniSection : String; // ini セクション名
procedure ReloadFromINI(Value: String);
protected
procedure Loaded; override;
procedure WndProc(var Message: TMessage); override;
public
constructor Create(AOwner: TComponent); override;
procedure AddHistory;
procedure LoadFromINI;
procedure SaveToINI;
property IniFileName: String read FIniFileName
write ReloadFromINI;
published
property HistoryMax: Integer read FHistoryMax
write FHistoryMax;
property IniSection: String read FIniSection
write FIniSection;
end;
procedure Register;
implementation
function RemoveFirstStr(SubStr: String; var S : String): String;
(* S から最初の SubStr までを取得/削除する *)
var
i : integer;
begin
i := Pos( SubStr, S );
if i=0 then begin
Result := S;
S := '';
Exit;
end;
Result := Copy( S, 1, i-1 );
Delete( S, 1, i );
end;
procedure THisComboBox.ReloadFromINI(Value: String);
(* Value の INI ファイルから履歴を読み直す *)
begin
FIniFileName := Value;
LoadFromINI;
end;
procedure THisComboBox.LoadFromINI;
(* INI からコンボボックスの items へロード *)
var
idx : Integer;
S : String;
begin
// FIniFileName の FIniSection から履歴を読み出し
with TIniFile.Create( FIniFileName ) do begin
try
ReadSectionValues( FIniSection, Self.Items );
finally
Free;
end;
end;
// FHistoryMax 以上のアイテムは削除
for idx := Items.Count-1 downto FHistoryMax do
Items.Delete( idx );
//履歴から 'ident_name=' を削除する
for idx := 0 to Items.Count-1 do begin
S := Items[idx];
RemoveFirstStr( '=', S );
Items[idx] := S;
end;
end;
procedure THisComboBox.SaveToINI;
(* コンボボックスの items を INI へセーブ *)
var
idx : Integer;
begin
with TIniFile.Create( FIniFileName ) do begin
try
// FIniSection をまるごと削除
try
EraseSection( FIniSection );
except
//
end;
//履歴を書き出す
for idx := 0 to Items.Count-1 do
WriteString(
FIniSection,
format( '%s%d', [FIniSection, idx] ),
Items[idx]
);
finally
Free;
end;
end;
end;
procedure THisComboBox.Loaded;
begin
inherited Loaded;
if not ( csDesigning in ComponentState ) then begin
LoadFromINI;
end;
end;
procedure THisComboBox.WndProc(var Message: TMessage);
begin
if Message.MSG=WM_DESTROY then begin
if not ( csDesigning in ComponentState ) then
SaveToINI;
end;
inherited WndProc( Message );
end;
constructor THisComboBox.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FHistoryMax := 10;
FIniSection := ClassName;
FIniFileName := ChangeFileExt( ParamStr( 0 ), '.INI' );
end;
procedure THisComboBox.AddHistory;
(* THisComboBox.Text を items に履歴として追加 *)
var
idx : Integer;
begin
if Text='' then Exit;
idx := Items.IndexOf( Text );
Items.Insert( 0, Text );
if idx<>-1 then
Items.Delete( idx+1 );
ItemIndex := 0;
for idx := Items.Count-1 downto FHistoryMax do
Items.Delete( idx );
end;
procedure Register;
begin
RegisterComponents('Samples', [THisComboBox]);
end;
end.
(PXC07042) - とらじ - URL
http://member.nifty.ne.jp/trazi
Original document by 寅次 氏 ID:(PXC07042)
ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。
Copyright 1996-2002 Delphi Users' Forum
|