カテゴリ:Delphi Programming( 42 )

[解決しました] Delphi XE Pro - 2つのボタンを procedureを使って一時的に無効にしたい。
2つのボタンを procedureを使って一時的に無効にしたいと思って作ってみたけど無効にならなくて何故だ?と思ったので記事にしてみた。
フォームにButtonを2つ置く。
b0003577_1231565.png

以下のようなコードを書いて、それぞれ1つ目のButtonOnOff(Sender);にブレイクポイントを置いて実行してみた。
unit Unit1;

interface

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

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure ButtonOnOff(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
ButtonOnOff(Sender);
Form1.Caption := '1111111';
ButtonOnOff(Sender);
end;


procedure TForm1.Button2Click(Sender: TObject);
begin
ButtonOnOff(Sender);
Form1.Caption := '2222222';
ButtonOnOff(Sender);
end;

procedure TForm1.ButtonOnOff(Sender: TObject);
begin
if Button1.Enabled = True then
begin
Button1.Enabled := False;
Button2.Enabled := False;
end
else
begin
Button1.Enabled := True;
Button2.Enabled := True;
end;
end;

end.
しかし、Form1.Caption := の所に戻ってくると押したボタンだけが無効になっている。
そんで2回目の ButtonOnOff(Sender); で不可解な動きになるので
理由がわかる方はコメントかトラックバックをお願いします(≧_≦)

追記:「Button2.Enabled := False;」の次に ShowMessage(''); を書くと2つのボタンがちゃんと無効になる。

2013年5月17日追記 2013年5月23日にも追記
[PR]

by arigayas | 2013-05-16 12:43 | Delphi Programming | Trackback | Comments(0)
Delphi XE Pro - RadioGroup コンポーネントの仕様を把握していなかった。
YouTube に書いた説明文とほぼ同じです。

RadioGroup コンポーネントの仕様を把握していなかった為につまづいたので記録しました。

RadioGroup の選択項目をクリックすることによって 「Edit」 や「ボタン」を
有効(ボタンON)/無効(ボタンOFF)にするコードを書いたつもりでした。

しかし、RadioGroup の項目の横に「Edit」や「ボタン」を置いて
その間とかをクリックすると無効状態でも有効になってしまって
ボタンが動いてしまうバグ(**)というか仕様に遭遇したので
RadioGroup を使わない方式で作り直すことにした。[**]

(**):筆者が想定していた動きと違うという意味でバグかな。
[**]:このブログを書いた時点ではUIを変えることを決めただけです。
    おそらく GroupBox と RadioButton を使うことにします。



ちなみに動画のために作ったソフトとソースコードは削除済み。
動画作成に使ったソフト→AG-デスクトップレコーダー ダウンロードページ
[PR]

by arigayas | 2013-05-14 12:55 | Delphi Programming | Trackback | Comments(0)
Delphi XE Pro - ステータスバーの表示を数秒後に消すには?[3秒後にしました]
ステータスバーの表示を数秒後に消すには?
と任意の秒数後に表示を消したい的な質問して回答をいただました。

しかし処理した内容(途中経過)の表示に使おうとして実行したら例外が出るようになってしまって
どうしたらいいのかわからないので手に負えないのでソースから削除しました(´;ω;`)

でTwitterでDEKOさんの回答の参照先の筆者さんのLynaさんから以下のような助言をもらった。
「OnTimer内でTimer1.Enabled:=False;とした上で目的の処理を続けて書くと良いと思います。」
ので書き直してみた。

フォームに Timer を貼ってプロパティの Interval には 3秒 という意味の3000と入れてます。
b0003577_21221434.png
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if not (StatusBar1.SimpleText ='') then
begin
Timer1.Enabled := false;
StatusBar1.SimpleText :='';
end;
end;
として試しにFormCreateする時に
StatusBar1.SimpleText :='テスト中'; 
と入れると起動後3秒後にステータスバーから「テスト中」という文字列は消えました。
しかしこれだとTimerが止まっているので他のところのボタンとかに
StatusBar1.SimpleText :='2回目のテスト'; 
と入れても消えてくれません。
消えるようにするにはTimerを動かすようにするために
StatusBar1.SimpleText :='2回目のテスト'; 
と書く前に
Timer1.Enabled := True;
を入れないといけません。

しかしいちいちいろんなところで
Timer1.Enabled := True;
StatusBar1.SimpleText :='hogehoge';
を書き込むのは面倒なので以下のようにまとめてみました。
procedure TForm1.StatusBarInfo(i: Integer);
begin
Timer1.Enabled := True;
case i of
0 : StatusBar1.SimpleText :=''; // Clear
1 : StatusBar1.SimpleText :='ファイルパスを確認しました';
2 : StatusBar1.SimpleText :='ファイルをダウンロードが完了しました';
3 : StatusBar1.SimpleText :='';
4 : StatusBar1.SimpleText :='';
5 : StatusBar1.SimpleText :='';
6 : StatusBar1.SimpleText :='';
7 : StatusBar1.SimpleText :='';
8 : StatusBar1.SimpleText :='';
9 : StatusBar1.SimpleText :='99999';
else
begin
ShowMessage('無設定ですよ');

StatusBarInfo(0);
end;
end;

end;

Timerを動かして文字列を書き込んでTForm1.Timer1TimerでTimerを止めた後にステータスバーから文字列を削除されるはず。
で他のところからは「StatusBarInfo(数字)」で呼びたいメッセージ番号を書くという感じにしてみました。
たぶんこのソース、まだ改良点があるんだろうなぁ・・・。

2013年4月30日追記その1: with do文を使ってみた。
procedure TForm1.StatusBarInfo(i: Integer);
begin
Timer1.Enabled := True;
with StatusBar1 do
begin
case i of
0 : SimpleText :=''; // Clear
1 : SimpleText :='ファイルパスを確認しました';
2 : SimpleText :='ファイルをダウンロードが完了しました';
3 : SimpleText :='';
4 : SimpleText :='';
5 : SimpleText :='';
6 : SimpleText :='';
7 : SimpleText :='';
8 : SimpleText :='';
9 : SimpleText :='99999';
10: SimpleText :='';
else
begin
ShowMessage('無設定');

StatusBarInfo(0);
end;
end;
end
end;
上記のようなwith do文を使っている中に
10:StatusBar1.SimpleText :='';
として潜り込ませてみも動いたのはちょっとビックリしたw

2013年4月30日追記その2:
button1をクリックして「StatusBarInfo(1) の文字列」と「StatusBarInfo(2) の文字列」を続けて表示したい場合に
処理;
StatusBarInfo(1);
処理;
処理;
StatusBarInfo(2);
処理;
と書くとStatusBarInfo(1);のタイマーが有効のままStatusBarInfo(2);が呼ばれるので実行時には一瞬変わったかも?と思うぐらいの時間しか「StatusBarInfo(2) の文字列」が表示されません。
ぼけーっと見ていたら「StatusBarInfo(2) の文字列」が表示されずに消えますw
この様にならない為に
処理;
StatusBarInfo(1);
処理;
処理;
Timer1.Enabled := False; // 一旦タイマーを止める意味で無効にする。
StatusBarInfo(2);
処理;
と書くと「StatusBarInfo(1) の文字列」と「StatusBarInfo(2) の文字列」がちゃんと表示される。
// 2013年4月30日追記終わり

以下は勘違いかもですが、
[PR]

by arigayas | 2013-04-27 21:18 | Delphi Programming | Trackback | Comments(0)
Delphi XE Pro - XMLファイルの値取得がわからない 【"略"を変更】
例えば以下のようなXMLファイルがあったとする。
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description>
<em:description>ソフト説明</em:description>
<em:name>テスト</em:name>
<em:version>0.0.1</em:version>
</Description>
</RDF>
追記:2013年4月18日21時13分xmlns:em のURI?を略さずに書くことにしました。


これの<em:name>テスト</em:name>の「テスト」という値(文字列)を取得方法がわからない。
しかも<em:name>の位置は不確定なので決め打ちが出来ないので困りもの。
試しに以下のようなDelphiのコードを書いた。
procedure TForm2.Button1Click(Sender: TObject);
var
DirPath: string;
document1: IXMLDocument;
Description1st: IXMLNode;
node: IXMLNode;
numString: int16;

begin
if OpenDialog1.Execute then
begin
DirPath := OpenDialog1.FileName;

Form2.Caption := DirPath;

document1 := LoadXMLDocument(DirPath);
Memo1.Lines.Add('+++++++++++');

node := document1.DocumentElement;
Memo1.Lines.Add(node.NodeName); // RDF

node := document1.DocumentElement.ChildNodes.First;
Memo1.Lines.Add(node.NodeName); // Description

node := document1.DocumentElement.ChildNodes.First.ChildNodes.First;
Memo1.Lines.Add(node.NodeName); // em:description

numString := document1.DocumentElement.ChildNodes.First.ChildNodes.Count;
Memo1.Lines.Add(IntToStr(numString)); // 4

numString := document1.DocumentElement.ChildNodes.First.ChildNodes.First.ChildNodes.Count;
Memo1.Lines.Add(IntToStr(numString)); // 1

node := document1.DocumentElement.ChildNodes.First.ChildNodes.First.ChildNodes.First;
Memo1.Lines.Add(node.NodeName); // #text
Memo1.Lines.Add(node.Text); // ソフト説明

node := document1.DocumentElement.ChildNodes.First.ChildNodes.First.ChildNodes['name'];
Memo1.Lines.Add(node.NodeName); // em:name
Memo1.Lines.Add(node.Text); // null

node := document1.DocumentElement.ChildNodes[0].ChildNodes.First.ChildNodes['em:name'].ChildNodes.First;
Memo1.Lines.Add(node.NodeName); // #text
Memo1.Lines.Add(node.Text); // null
Memo1.Lines.Add(BoolToStr(node.HasChildNodes)); // 0 って


Memo1.Lines.Add('+++++++++++');
end;

end;

end.

node := document1.DocumentElement.ChildNodes[0].ChildNodes.First.ChildNodes['em:name'].ChildNodes.First.Textがnullになるのは何故?

まぁXMLをわかっていないのがバレバレですけどね(苦笑)

山本隆 さんの回答を元にアレンジしてみました。
[PR]

by arigayas | 2013-04-18 01:19 | Delphi Programming | Trackback(1) | Comments(4)
Delphi XE Pro - XML ファイルを ini ファイルのように使うには? (読み込み編)
Delphi XE Pro - XML ファイルを ini ファイルのように使うには? (保存編)

保存されている XML ファイルは以下のようなXMLファイルです。
<Project1>
<Form>
<Form Name="Width">651</Form>
<Form Name="Height">338</Form>
</Form>
<Path>
<Path Name="TempSaveFolder"></Path>
</Path>
</Project1>

保存したXMLファイルをiniファイル的に読み取るソースコード:
一応書いておきますが、uses XMLIniFile XMLIntfXMLDoc を追加しておくこと。
procedure TForm1.Button2Click(Sender: TObject);
var
Root : IXMLDocument;
SettingsXML: TXMLIniFile;
int : Integer;
Str : string;
begin
Root := LoadXMLDocument(ChangeFileExt(Application.ExeName, '.xml')); // 読み込むファイル名を指定

Root.Active := True;
SettingsXML := TXmlIniFile.Create(Root.DocumentElement);

try
self.Height := SettingsXML.ReadInteger('Form', 'Width' , int );
Self.Width := SettingsXML.ReadInteger('Form', 'Height', int );
self.Caption := SettingsXML.ReadString('Path', 'TempSaveFolder', Str);
finally
SettingsXML.Free;
end;
end;


保存編で書いたソースコードも合わせて実行するとフォームサイズが変わるプログラムが出来るはずです。
[PR]

by arigayas | 2013-03-03 07:04 | Delphi Programming | Trackback | Comments(0)
Delphi XE Pro - XML ファイルを ini ファイルのように使うには? (保存編)
「XML ファイルを ini ファイルのように使うには?」と同じタイトルで
とある掲示板に投稿してヒントをもらって解決したので自分のブログにも書いておく。
まだ読み込み方法を調べないといけないんですけどね・・・。

それにしてもXMLファイルに書き込めるようになるまで時間が掛かったなぁ・・・。
日本語サイトだけの解決は厳しかった・・・。
以下の方法はXE1以降で使えます。

2013年3月2日 追加:
この記事を書いた翌日に質問した掲示板に追加の返答があったのを見て追加しました。
 // 実行結果は同じですがちょっとスマートになったかとw

uses XMLIniFile を追加して
フォームに XMLDocument (これがないと実行時にエラーになる)を貼付けて
XMLIntfXMLDoc uses に追加して
以下のようなソースを書いてXMLファイルをiniファイルのように出来ました。
改変前:
procedure TForm1.Button1Click(Sender: TObject);
var
Root : TXMLDocument;
settingsXML: TXMLIniFile;
RootTag : string;
SaveFolder: string;
begin
// XMLiniファイルに書き込む。
Root := XMLDocument1; // XMLDocument1の名前を変更した時の影響を減らすため。
RootTag := ExtractFileName(ChangeFileExt(Application.ExeName, ''));

Root.XML.Text := '<' + RootTag + '></' + RootTag + '>'; // XMLのルート部分をEXEファイル名に
Root.Options := [doNodeAutoIndent]; // オートインデントをON
Root.Active := True; // Active を True にしないと書き込まれない

settingsXML := TXmlIniFile.Create(Root.DocumentElement);
try
settingsXML.WriteInteger('Form', 'Width' , Form1.Width );
settingsXML.WriteInteger('Form', 'Height', Form1.Height );

settingsXML.WriteString('Path', 'TempSaveFolder', SaveFolder);

Root.SaveToFile(ChangeFileExt(Application.ExeName, '.xml')); // 書き込み実行

finally
settingsXML.Free;
end;
end;


質問した掲示板を見て2013年3月2日 改変:
procedure TForm1.Button1Click(Sender: TObject);
var
Root : IXMLDocument;
SettingsXML: TXMLIniFile;
RootTag : string;
SaveFolder: string;
begin
// XMLiniファイルに書き込む。
RootTag := ExtractFileName(ChangeFileExt(Application.ExeName, ''));
Root := NewXMLDocument();

Root.AddChild( RootTag ); // XMLのルート部分をEXEファイル名に
Root.Options := [doNodeAutoIndent]; // オートインデントをON
Root.Active := True; // Active を True にしないと書き込まれない

SettingsXML := TXmlIniFile.Create(Root.DocumentElement);
try
SettingsXML.WriteInteger('Form', 'Width' , Self.Width );
SettingsXML.WriteInteger('Form', 'Height', Self.Height );

SettingsXML.WriteString('Path', 'TempSaveFolder', SaveFolder);

Root.SaveToFile(ChangeFileExt(Application.ExeName, '.xml')); // 書き込み実行

finally
SettingsXML.Free;
end;
end;



で保存されるXMLは
[PR]

by arigayas | 2013-03-01 10:33 | Delphi Programming | Trackback(1) | Comments(0)
Delphi XE Pro - コンボボックスやリストボックスで項目の文字列を取得する
b0003577_782341.png
procedure TForm1.Button1Click(Sender: TObject);
var
val: Int8; // 何番目のリストか取得用
vals: string; // 項目の文字列
begin
val := ComboBox1.ItemIndex;
ShowMessage(IntToStr(val));

vals := ComboBox1.Items[ComboBox1.ItemIndex];
ShowMessage(vals);
end;

[PR]

by arigayas | 2012-06-06 03:50 | Delphi Programming | Trackback | Comments(0)
[2ch] くだすれDelphi(超初心者用)その54 [コピペ] - ウィンドウ終了時に行われる処理?
くだすれDelphi(超初心者用)その54
http://toro.2ch.net/test/read.cgi/tech/1325028195/515-516

515 デフォルトの名無しさん [sage] 2012/05/07(月) 21:48:20.26 ID: Be:
  なんか荒れてるけどスレタイに沿って超低レベル質問を・・・

  Delphi6 Personalを使ってWindowsXP上で色々と試している最中なんですが
  アプリケーションのFormの右上に出てくる×ボタンを押した時、
  なんのイベントが発生するのでしょうか。

  ×ボタンを押したらonCloseに設定した正常終了の流れに
  載せたいのに、無視されてそのまま終了してしまふ

516 デフォルトの名無しさん [sage] 2012/05/07(月) 22:00:46.91 ID: Be:
  OnCloseQuery→OnClose→OnDestroy

Delphi とかの本には書いていそうだけどメモ。
[PR]

by arigayas | 2012-05-08 01:15 | Delphi Programming | Trackback | Comments(0)
Delphi XE Pro - SelectDirectory を使って(マイ) コンピュータを開く
Twitter に
SelectDirectory 関数?を使う時に(マイ) コンピュータを初期値として開きたいけど、どうすれば良いんだろう?
と書いた。

特になにも引数を与えずに SelectDirectory を使うとWindows 7では
b0003577_1838074.png
このようなダイアログが開かれるんだけどネットワークフォルダーとかを選択されると
エラー処理すべきことが増えそうなので制限したいと思って聞いてみた。

しばらくして
DirがStringの変数として。こんな感じの謎の呪文を
SelectDirectory('', '::{20D04FE0-3AEA-1069-A2D8-08002B30309D}', Dir);
とするといいよ。とReplyをいただいたので実際にやってみたら、
b0003577_18402097.png

やりたいことが出来ました。
Windows XP SP3 なパソコンでも動いたので Vista でも問題ないと思う。

以下コード。

More
[PR]

by arigayas | 2012-04-25 19:13 | Delphi Programming | Trackback | Comments(0)
Delphi XE Pro - バルーンヒントを動的に書き換える
Edit の幅が狭いというか 短くて見えない場合の対処方法としてバルーンヒントを出すことにした。

標準機能でEdit のイベントの onChange をクリックして以下を記述する。
procedure TForm1.EditChange(Sender: TObject);
begin
Edit.Hint := Edit.Text;
end;



BalloonHint を使った場合のコード。

BalloonHint の関連づけのやり方はこの動画を見た。


procedure TForm1.EditChange(Sender: TObject);
begin
Edit.Hint := 'URLは |' + Edit.Text + '|1';
end;

最後の「1」はヒントタイトルの位置を表していて1だと中央になって
0」にすると左寄せになる。


embarcadero のドキュメント:Controls.TCustomHint - XE2 API Documentation

バグがあったらごめんなさい。
[PR]

by arigayas | 2012-04-13 21:21 | Delphi Programming | Trackback | Comments(0)