くだすれDelphi(超初心者用)その43

このエントリーをはてなブックマークに追加
952デフォルトの名無しさん:2007/10/03(水) 10:34:50
BringToFront
コントロールを親コントロール内のそれ以外のすべてのコントロールの前に移動します。

こんなのがある
953デフォルトの名無しさん:2007/10/03(水) 11:52:18
ZOrderいぢればいいんでないかい?
954デフォルトの名無しさん:2007/10/03(水) 17:24:54
955デフォルトの名無しさん:2007/10/03(水) 21:06:23
コード上からTTreeViewのノードを展開してやろうと思い、

TreeView1.Items[1].Expand(true);
とか
TreeView1.Items[1].Expanded := true;

とかやっても開いてくれません。AllowExpansionはtrueのようです。
考えられる原因はなんでしょうか? バージョンはDelphi7Proです。
956デフォルトの名無しさん:2007/10/03(水) 22:38:50
>>946
F8 で実行〜すぐに IDE でメニューの「健作」〜「エラの健作」で「00D76854」を探す
957デフォルトの名無しさん:2007/10/04(木) 09:00:27
あるプロジェクトを元に修正をしたい場合、プロジェクトのフォルダの
ファイルを全部別のフォルダにコピーすればいいのでしょうか。
それともプロジェクトを開いて、ユニットなどを全て別名で保存する方が
いいのでしょうか。
958デフォルトの名無しさん:2007/10/04(木) 11:26:36
基本的に単純コピーでOK。
プロジェクト固有のユニットは相対パスで見てるから。
959デフォルトの名無しさん:2007/10/04(木) 13:19:35
コンパイルはコピー先のフォルダじゃなくて実はコピー元を参照してたりして
960デフォルトの名無しさん:2007/10/04(木) 14:22:14
簡単な物作って公表しようとしたらフリー版で作ったEXEやDLLは配布できないんですね。
古いバージョン(3とか4とか)でもいいので一番安くライセンスを得る方法って何でしょうか?
961デフォルトの名無しさん:2007/10/04(木) 17:04:15
作った奴公開できないのはアカデミック版だけでフリー版は別に問題ないんじゃないの。6でもTurboでも
962デフォルトの名無しさん:2007/10/04(木) 18:07:19
>>958
ありがと。今まで後者のやり方でずっとやってきてバカみたいでした。
963デフォルトの名無しさん:2007/10/04(木) 21:35:41
ただし作業状態を保存(拡張子dskだったかな?)してて、さらにそれもコピーしちゃうと、
IDEが以前のファイルを開いてしまい、修正したつもりがコピーした方は全く変更なしという状態になりかねないので注意
964デフォルトの名無しさん:2007/10/04(木) 21:39:25
妄想乙
965デフォルトの名無しさん:2007/10/05(金) 00:02:05
フリーはシェアとか製品がダメなだけだったか……
どもでした。
966デフォルトの名無しさん:2007/10/05(金) 00:20:39
TurboDelphiならシェアでもいいんじゃなかったっけ?
967デフォルトの名無しさん:2007/10/05(金) 00:44:36
>>963
あるあ・・・・あるw

俺も前にそれやって、爆死した

バージョン管理ソフトでのコミット時にも、*.dskは、除外対象に指定している。
Subversionとか使うと、フォルダ名違うのって当たり前だからな
968デフォルトの名無しさん:2007/10/05(金) 00:45:24
というか、dskってできるだけ相対ファイルパスで、記録すべきだと思うんだ、俺は
要望出してみようかしら・・・
969デフォルトの名無しさん:2007/10/05(金) 07:45:33
VMWare Player上で動作しているゲストOSをホストOSシャットダウン時に
同時にシャットダウンしたいのですが何かよい方法あるでしょうか。
ゲストOSの右上のバツボタンを押せばゲストがシャットダウンするので何とかなりそうな気はするのですが・・・
970デフォルトの名無しさん:2007/10/05(金) 12:37:25
VMWareって使ったこと無いけどただのウィンドウならWM_CLOSE送ればいい
971デフォルトの名無しさん:2007/10/05(金) 12:44:49
ミ田+R
shutdown -s -t 0
でもSendMessageで送ったら。
VMWareがそれを受け付けるかは知らないけど。
972デフォルトの名無しさん:2007/10/05(金) 13:05:10
finalization に判断含んだコード書いたりすると
BPレジスタの保存・復帰が旨くゆかない事があるみたい。
結果、systemユニットの  FInitUnits で例外が出る事があったよ。

だから終了手続きを書いてから finalizationではそれを呼ぶだけにするべきみたい
973デフォルトの名無しさん:2007/10/05(金) 15:54:13
>>972
レジスタやスタックの中身破壊するコード書いてただけじゃね?
974デフォルトの名無しさん:2007/10/05(金) 16:32:05
>>973
いや、そんなコードは書いてないよ。

今しらべた範囲では、判断が問題じゃなくて、
何かの条件+finalization で帰り値が文字列の関数を呼び出た場合のよう。
その条件を満たすと

push ebp
mov ebp,esp
push $00 <------- この命令が挿入される。
xor eax,eax
push ebp
push 例外ハンドラ
push dword ptr fs:[eax]
mov fs:[eax],esp
inc dword ptr [ユニット]
jnz Finalization + $4A

他は同じだから、帰りのEBPが0になってしまうって事みたい。

普通に新規作成したフォームにfinalizationを書いた場合は起きなかった。
コンポーネントを作った時に起きたけど、必ず起きるわけじゃないみたい。
975972:2007/10/05(金) 16:44:42
再現コードが作れた。
D5 と D7 では起きる。 D2006では起きない。

フォームを新規作成して、end. の前に以下の8行を追加

var TestName:string='Test.txt';
function SaveFileName: string;
begin
Result := 'abc.txt';
end;
initialization
finalization
SaveFileName; //<--- ここにブレークポイントをかけて CPU窓でステップ実行すると EBPが最後に0になるのが見える

どうやら、
文字列変数を定義して、それを初期化する行があって、
finalizationで で帰り値が文字列の関数を呼び出すコードを追加したら起きる
条件判断で実際にその関数を呼び出さない場合も同じ。

D2006では起きないから修正されてるみたい。
976デフォルトの名無しさん:2007/10/05(金) 16:48:02
>end. の前に以下の8行を追加

何のジョークだ?
つりか?
977デフォルトの名無しさん:2007/10/05(金) 16:48:58
検証乙
Delphi BugList Projectに登録世路
978デフォルトの名無しさん:2007/10/05(金) 16:52:30
Delphi6あたりで、
*.dpr の begin end部に、string変数宣言するとリークするという問題もあったな
いつも、もう一段、Main関数つくって、読んでたわ
979デフォルトの名無しさん:2007/10/05(金) 16:53:34
>>976は何が気に入らなかったんだろう・・・
980デフォルトの名無しさん:2007/10/05(金) 17:05:52
EBPが0になるとどーなんの?
981デフォルトの名無しさん:2007/10/05(金) 17:52:38
>>980
困る
982デフォルトの名無しさん:2007/10/05(金) 18:08:09
>>975
QC8360かな?
文字列のクリーンアップに関する問題みたいだから、自前でやれば解決するかもしれない
983デフォルトの名無しさん:2007/10/05(金) 18:15:19
>976
984デフォルトの名無しさん:2007/10/05(金) 18:20:45
>>970
>>971
すみません、まったく意味がわからないっす・・・
985デフォルトの名無しさん:2007/10/05(金) 18:21:58
986デフォルトの名無しさん:2007/10/05(金) 18:22:39
>>979 BPはスタックフレームを示す。
つまりスタック上に変数を取ってる所までリターンしてエラーになるから
全然関係ない所でアクセスエラーなんかが起きる事になる。


>>972 が書いてるように、finalizationでは
単なるprocedure を呼び出すようにしておけば安全。
987デフォルトの名無しさん:2007/10/05(金) 20:10:05
>>986
なんか微妙に説明おかしくね?
要するにPOPが不変なのにPUSHされる値が1つ増えるせいでエラーになるってだけ
988デフォルトの名無しさん:2007/10/05(金) 21:18:49
>>987 いや、>>974 が勘違いだろう。
ステップ実行して試したが、スタックのpush/pop数は合ってる
壊れるのは、 call @LStrArrayClr が呼ばれた時。
989デフォルトの名無しさん:2007/10/06(土) 01:44:24
どうでもええわ
990デフォルトの名無しさん:2007/10/06(土) 03:44:14
そうでもない
991デフォルトの名無しさん:2007/10/06(土) 05:47:23
ちゃんと知ってないと、原因不明のメモリリークに悩むことになるよ。
992デフォルトの名無しさん:2007/10/06(土) 07:40:24
超初心者用
993デフォルトの名無しさん:2007/10/06(土) 08:23:13
Turboで直ってるならそれでいいや
994デフォルトの名無しさん:2007/10/06(土) 12:15:43
質問! INIファイルに引数付きのアプリのパスを登録し、それを読み込んでShellExecuteで
起動させようと思ったんだけどうまくいかない!

------------------------test.ini-------------------------------
[Path]
APP="C:\WINDOWS\notepad.exe" "C:\WINDOWS\setuplog.txt"
------------------------test.ini-------------------------------

uses節 に IniFiles, ShellAPI を追加。

procedure TForm1.Button1Click(Sender: TObject);
var IniFile : TIniFile; AppPath, IniPath : String;
begin
IniFile := nil; // 初期化
// INIファイルのパスを格納
IniPath := ExtractFilePath(Application.ExeName) + 'test.ini';
try
IniFile := TIniFile.Create(inipath); // INIファイルの読み込み
AppPath := IniFile.ReadString('Path', 'APP', '');
finally
IniFile.Free;
end;
if AppPath <> '' then
begin
ShellExecute(Form1.handle,'open', PChar(AppPath), nil , nil , SW_SHOWNORMAL);
end
else
begin
ShowMessage('AppPathはカラです。');
end;
ShowMessage('AppPath=' + AppPath);
end;
995944:2007/10/06(土) 12:21:12
AppPathの中身を見たら 「C:\WINDOWS\notepad.exe" "C:\WINDOWS\setuplog.txt」 でした。
何故が最初と最後の 「"」 が勝手に削除されてしまってます。

ShellExecute の PChar(AppPath) では引数付きのパスの指定はNGみたいです。
ということは AppPath の中からアプリのパス部分を抜き取る文字列操作をしないとダメなんでしょうか?

上の 「"」 が勝手に削除されることもあり、元から 「"」 が付いていたかどうかの判定や、それによって
分岐を作らなければいけないとなるとかなり手間がかかりそうです。

もっと簡単な方法はないのでしょうか、もしあればご教授下さいませ^^;
996944:2007/10/06(土) 12:23:53
PS、ShellExecute で起動引数を指定するときは PChar(AppPath) の次の要素(上では1つ目のnil)で指定する
ということは知っています。 やはり文字列操作をして引数の部分を取り出す処理を書かなければいけないのでしょうか・・。
997デフォルトの名無しさん:2007/10/06(土) 12:36:22
普通取り出しやすいように書き出すだろ
998944:2007/10/06(土) 12:49:43
>>997
うーん、こんなことで悩むのは自分だけなのかな。
「アプリのパス 引数」 を一行で書けたらINIに手動で追加するときに便利で良いかと思ったんですが・・。

他の方法も考えてみます。 INIでなくLoadFromFileで読み取れば 「"」 が消えたりしませんし。
INIでやるなら

[APP1]
path=
param1=
param2=

のようにしたほうがコーディングは格段に楽ですね^^; ひとまずこの2択で考えてみます、どもでした。
999デフォルトの名無しさん:2007/10/06(土) 14:36:52
INIのAPIは両端に""がついていたら取っ払って読み込むという仕様なんで
途中にスペースがあり、両端が""でなければ両端に""をつけるというコードでいけたはず。
複合データはTStringListで読み書きするようにして
TInifileEx.ReadStrings
TInifileEx.WriteStrings
みたいに一度ラップしておけばいろいろ使いまわせるよ。

INIファイルをLoadFromFileで読み込むのはAPIとの不整合が起こる危険があるから下策。
1000994:2007/10/06(土) 15:14:43
>>999 レスありがとうございます。

>途中にスペースがあり、両端が""でなければ両端に""をつけるというコードでいけたはず。

それがそう単純にはいかないようで、例えば↓の場合、↑の条件を満たしていますが
両端に "" を付けると "notepad.exe "A" B" となってしまいマズいことになってしまいます。
こういうケースに対応させていくことも出来ますが無駄に骨が折れそうです・・。
I
------------------------test.ini-------------------------------
[Path]
APP=notepad.exe "A" B
------------------------test.ini-------------------------------

>TInifileEx.ReadStrings
なるほど、とても参考になりました、ありがとうございます^^

>APIとの不整合
これは知りませんでした、どもです。

INIの自動カットに憤慨しつつ1000ゲット!
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。