[表示 : 全て 最新50 1-99 101- 201- 301- 2chのread.cgiへ]
Update time : 04/19 05:10 / Filesize : 113 KB / Number-of Response : 389
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

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



1 名前:デフォルトの名無しさん mailto:sage [2007/08/03(金) 12:18:00 ]
Delphi(デルファイ)について、他のスレッドでは書き込めない超低レベル、
もしくは質問者自身何が何だか分からない質問を
勇気を持って書き込むスレッドです。
Delphi使いが優しくコメントを返しますが
お礼はDelphiの布教と初心者の救済をお願いします。

<前スレ>
くだすれDelphi(超初心者用)その42
pc11.2ch.net/test/read.cgi/tech/1180613145/

<過去スレ>
DelWiki避難所
delwiki.info/?Delphi 関連の過去スレッド


101 名前:デフォルトの名無しさん mailto:sage [2007/08/08(水) 02:13:59 ]
>>100
あらかじめ件数分かってるなら配列でいいんじゃない?
すっきりするしポインタで悩むこともなくなる
ちなみに>>99の言ってることは間違ってるから無視していいよ
クラスにしてもCreateする度に内部でメモリ確保してるわけで変わらない
むしろ余計なものが付く分そんなに件数あると有意な差が出てくる

ただその前に、全部メモリに読み込む必要あるの?300MB弱くらいにならない?
SQLで完結しそうにも思えるんだけど

102 名前:89 [2007/08/08(水) 02:27:26 ]
>>101
データを一覧表とグラフに集計してまとめるんです。
横浜市の学校で1990年以降に出来た小学校限定とか、
関西地区を除く地区の生徒数2000人以下の学校限定とか、
これを検索ボタンを押したら、条件変更ボタンですぐに一覧表とグラフを変えないといけないんです。
2秒以内に表示しなおすことが前提なのでいちいちSQLを使って取得している時間が無くて、
メモリに確保したままにしてグローバルから読み込もうと思ったんです。

103 名前:デフォルトの名無しさん [2007/08/08(水) 02:27:37 ]
> 14430000件
ふつうは、DB使う罠w

104 名前:89 [2007/08/08(水) 02:40:36 ]
>>103 使ってますよ。
SQLで取得したデータをどうするかで悩んでるんです。

105 名前:デフォルトの名無しさん mailto:sage [2007/08/08(水) 02:41:15 ]
>>102
やっぱりSQL発行すれば済む問題じゃないかな
ひょっとしてDBから1件ずつ取得して比較してると時間がない、なんて思ってるのかもしれないけど、
SQLってのはそういう条件で絞り込んで結果だけ返してくれる道具ですよ?
コード見てる限り高速検索アルゴリズムを自分で実装するってわけでもなさそうだし、
素直にSQL出しといた方がよっぽど早いかと思われます。

106 名前:89 [2007/08/08(水) 02:47:00 ]
>>105 SQLは使ってますよ。
SQL使って取得したデータをいち早く表示するために考えたのが、
「取得したらグローバル変数に格納する」なんです。
ですけど、いちいちSQLでデータを取得して書き込みだと、
データを一時変数に代入するのに時間がかかりすぎていて困っているのです。
条件ボタンを押すたびに一千万件以上のデータをSQLから取得していくと、
時間がかかりすぎといわれるのです。

107 名前:デフォルトの名無しさん [2007/08/08(水) 03:01:33 ]
バックエンドにDB使ってて、その中身をまんま持ってきて、
フロントエンドの言語のデータ構造に入れ込む状況が思い浮かばん

108 名前:89 [2007/08/08(水) 03:15:30 ]
>>107
DBへのアクセスは専用のフォームを使っているんです。
ですけどデータ表示とかはおのおののフレームが担当しているんです。
DBへアクセスした後そのフォームが別のグリッドやリストビュー、グラフにアクセスするのはおかしいし、
引数に渡すのも不自然だし、フレームに書いていくと修正が大変なので。

109 名前:デフォルトの名無しさん [2007/08/08(水) 04:27:16 ]
>>106
どうも読んでる限りではDBを使いこなせてないみたいだね
SQLは色んな書き方があるから、まずはそれを学ぶといいよ
SQLってのは単にレコードを1件1件読むためのものじゃない

また、1000万件以上の処理ということに変な思い込みを持ってるようだけど、
DBを使う場面ってのは大抵それと同じかそれ以上の件数のレコードを扱うよ
だからそれぞれのDBだってほとんどの場合それに耐えうるように設計されてる



110 名前:89 [2007/08/08(水) 04:38:09 ]
>>109
分かりました。もうちょっとSQLも勉強したいと思います。
そういえば此処に来たら何を調べていたのか忘れていましたが、
今思い出しました。

TListだとSQLに変わるので、TObjectListを使おうと思ったのですが、
var
Ob:TObject;
begin
Ob:=TObject.Create;
ObjectList1.Add(Ob);
Ob:=TObject.Create;
ObjectList1.Add(Ob);
end;
と言うように同じ変数にCreateを複数回も使ってもエラーとか言わないでしょうか?
また前にObjectListにAddしたオブジェクトは破棄されたり変な値が入らないでしょうか?
それと共にグローバルにおいて、関数が終了したら不正なデータに代わるとか無いでしょうか?

111 名前:デフォルトの名無しさん mailto:sage [2007/08/08(水) 08:34:19 ]
Q 同じ変数にCreateを複数回も使ってもエラーとか言わないでしょうか?
A 同じ変数にCreateしたものを複数回代入してもエラーにはならない。 
  ただメモリーリークに注意しなければいけないが、この場合は他の管理方法に委ねているので大丈夫

Q 前にObjectListにAddしたオブジェクトは破棄されたり変な値が入らないでしょうか
A Createによりヒープにオブジェクトが作成され  Addでその参照が管理されるだけなので、それは杞憂

Q 関数が終了したら不正なデータに代わるとか無いでしょうか?
A オブジェクトはヒープにしか作成されない(スタックには作成されない)ので杞憂


なおTObjectのインスタンスを作成してるけど、これは単なる例?
TObjectList を使うより、record を使って型を作り
array of TMyRecord ; のような、動的配列の方が扱い易いよ


112 名前:デフォルトの名無しさん mailto:sage [2007/08/08(水) 11:07:18 ]
2秒以内か。データベースサーバー何使って、Delphi側はからデータベースに接続するのに
BDE使ってるの?ADO使ってるの?BDEのこと忘れたけど、ADOならTADODataSetのCacheSizeプロパティで
一度に取り出す行数制限できるからそれ使えば?一度に1千万のデータなんか画面に表示できないから、
一度に1千万のデータなんて読み込まなきゃいいだけ。

113 名前:ななしへたぐらま ◆XcB18Bks.Y mailto:sage [2007/08/08(水) 11:45:03 ]
>>110-111
TObjectListはデフォルトで項目オブジェクトを所有します.
つまりリストをクリアしたりオブジェクトを解放すると全項目のオブジェクトを解放します.

TListのような参照するだけのリストを作りたい場合は
コンストラクタで引数にFalseを指定するか
(ナントカ := TObjectList.Create(False) )
生成後にOwnsObjectsプロパティにFalseを代入すると
(ナントカ.OwnsObjects := False )
所有しなくなります.
つまりリストをクリアしたりオブジェクトを解放しても項目のオブジェクトは解放されなくなります.


114 名前:デフォルトの名無しさん [2007/08/08(水) 12:11:06 ]
Turbo Delphi Explorerで
Delphi 7と同じ規格?で作ることできますでしょうか?

115 名前:89 [2007/08/08(水) 12:37:31 ]
>>111
詳しい情報有難うございます。
TObjectは例で実際には構造体を使うのですが、動的配列のほうが速いのですか?

>>112
FireBirdとIBQueryを使っています。

>>113
標準だと参照型じゃないんですね。
参照型だと関数が終了した時に代入していたローカル変数をうやむやにして、
変な所を参照してしまうみたいで。でもそんな心配ないのですよね?

116 名前:ななしへたぐらま ◆XcB18Bks.Y mailto:sage [2007/08/08(水) 15:35:15 ]
>>115
Delphiのオブジェクト変数(キーワードclassを使うもの)は常にポインタです.
つまりDelphiのオブジェクト変数はそのオブジェクトの場所を覚えているに過ぎません.

そしてTObjectListはオブジェクトの場所の一覧です.
TObjectListのAddメソッドではオブジェクトの場所が渡されて内部のリストにこの場所を書き足します.

たとえば以下のようなコードだと

TMyForm = class(TForm)
private
 FList: TObjectList;
 procedure Nantoka;
end;

procedure TMyForm.Nantoka;
begin
 obj := TMyObject.Create; // @
 FList.Add(obj); // A
end;

@でオブジェクトが生成されてその場所が変数objに書き込まれます.
Aでリストにそのオブジェクトの場所が渡ります.
メソッドNantokaを抜けると変数objは消滅しますがオブジェクトそのものは残ります.
(目的のビルの場所を書いたメモが捨てられてもそのビルが消滅するわけではないのと同じです)

リストはオブジェクトの場所しか見ていないので
変数objが消滅しても見てはいけないところを見てしまう心配はありません.

これはリストが項目オブジェクトを所有する場合もしない場合も全く同じです.


117 名前:デフォルトの名無しさん mailto:sage [2007/08/08(水) 15:38:02 ]
>>114
 コンパイラそのものはD7から殆ど変わってない。ライブラリも殆ど同じ。

>>115
>TObjectは例で実際には構造体を使うのですが、動的配列のほうが速いのですか?

いちいちオブジェクトをCreateするより、構造体の動的配列の方が一度にメモリを確保するから
多少速度も上がると思うよ。

サイズが判らない場合でも、動的配列は最初に多めにとって、足らなくなったらまた多めにとって
というようにやればいい。

118 名前:89 [2007/08/08(水) 15:48:00 ]
>>116
だと本来出てこない値が出てきてしまうのは何故でしょう?

>>117
procedure TFrame1.ListSwitch(List1: TList; var List2: array of TSeitoSuu_Rec);
var
i:integer;
p:PSeitoSuu_Rec;
begin
SetLength(List2,List1.Count);←互換性の無い型です。
for i:=0 to List1.Count-1 do
begin
p:=POPE004_Rec(ListA[i]);
list2[i]:=p^;
end;
end;

と成ってしまいます。
どうしたら再定義できますか?

119 名前:デフォルトの名無しさん mailto:sage [2007/08/08(水) 15:55:18 ]
>>118
関数の引数でソレをやったら、動的配列ではなくなる
Type TArraySeitoSuu_Rec = array of TSeitoSuu_Rec; と動的配列型を定義しておいてから

procedure TFrame1.ListSwitch(List1: TList; var List2: TArraySeitoSuu_Rec);

とやらないと




120 名前:89 [2007/08/08(水) 15:59:06 ]
>>119解決しました。
皆さん有難うございました。

121 名前:デフォルトの名無しさん mailto:sage [2007/08/08(水) 16:06:21 ]
こんなレベルの人が学校関係のDB扱う仕事やってんのか…
そりゃ情報流出しまくるよなとおもた

122 名前:デフォルトの名無しさん mailto:sage [2007/08/08(水) 16:19:47 ]
引数で 動的配列のような格好の定義が出たら、ソレはオープン配列パラメータだ

123 名前:デフォルトの名無しさん [2007/08/08(水) 19:11:06 ]
また匿名でコテハン叩きか

キャノンかダかな?



124 名前:デフォルトの名無しさん [2007/08/09(木) 10:19:34 ]
Delphi4 Pro を使ってます。
それでKOL(EXEのサイズが小さくなるやつ)を使いたいと思って
KOLとMCKをDLして同じフォルダに解凍、「開く」からDelphi4用の
パッケージ(.dpk)を開き、インストールを選択。
でもKOLaddが無いと怒られてしまった。
オフィシャルからKOLadd.zipを何度DLしても
解凍しようとすると「破損してる」って言われるし・・・

どこが間違ってるんでしょうか?

125 名前:デフォルトの名無しさん [2007/08/09(木) 17:00:21 ]
メモ:

TNT Unicode Controls 配布場所

Silverpoint Development
club.telepolis.com/silverpointdev/sptbxlib/support.htm#installation

club.telepolis.com/silverpointdev/sptbxlib/TntUnicodeControls.2.3.0.zip



126 名前:デフォルトの名無しさん [2007/08/09(木) 17:03:09 ]
>>114
Explorer版は、コンポーネントのインストールができないので、
Delphi7で、コンポーネントを使っている場合は、そのままは移植できない。
THoge.Create(Self)のような、動的生成はできるので、無理やり移すことは一応可能。

(Explorer版ではない有償版や、同規格のDelphi2006では、ほぼ修正なしでコンパイルは通る)

127 名前:デフォルトの名無しさん [2007/08/09(木) 17:05:46 ]
>>124
ちょっと聞きたいのですが、
KOLってどういう理由で使いたいのですか?
ただ、EXEが小さくなる、という理由だと、はっきりいって、
茨の道を火を付けて歩くことになるので、やめた方がいいです。

128 名前:デフォルトの名無しさん [2007/08/09(木) 18:49:40 ]
コンポーネントのツールパレットを、キーボードで、検索したいのですが、
部分一致で検索する方法はなかったでしょうか?
通常は前方一致だけのようです(というか、THogeなら、hogeにヒットする)

環境は、Delphi2006

129 名前:デフォルトの名無しさん mailto:sage [2007/08/09(木) 21:18:58 ]
>>127
だな。
UPXMask を勧めとく



130 名前:ななしへたぐらま ◆XcB18Bks.Y mailto:sage [2007/08/09(木) 22:27:40 ]
>>118
本来出てこない値について結局わからなかったので適切な答を出せませんでした(すいません).


131 名前:89 [2007/08/09(木) 23:55:07 ]
>>130
本来出てこない値とは取得したデータが>>97のレコードだった場合に、
本来、Modelは-1〜1しかないのに適当な値(118927354等)や
>>97では書き忘れていたんですけど、F_KT_GakkoMei:String;があって、
そのF_KT_GakkoMeiに取得用SQLがそのまま書かれていたりするんです。

解決したんですが、新たな所でつまずいてここにもう一度来ました。
TFrame1のプライベート静的配列を宣言したんです。
ListA:array[1..3]of char;と言う具合に
そして>>118のListSwitchの中で
ListA[0]:='0';
ListA[1]:='T';
ListA[2]:='F';
代入するようにしてButton1Clickの中でListSwitchを呼ぶのですけど、
Button1Clickの関数を一度通り抜けるとListFは('','','','','','','',...)となって、
次にアクセスしようとするとおかしくなるのです。
解決する方法は無いのでしょうか?
どうか教えてください。

132 名前:デフォルトの名無しさん mailto:sage [2007/08/10(金) 00:09:13 ]
ListFって何?

133 名前:89 [2007/08/10(金) 00:22:57 ]
>>132
ListAでした。結構打ち間違えますね。

134 名前:デフォルトの名無しさん mailto:sage [2007/08/10(金) 00:33:55 ]
Button1Clickからその後のListAの確認するまでの間でぶっ壊してるんだろ
コードも晒さずに解決法など出るわけ無いと何度

135 名前:デフォルトの名無しさん mailto:sage [2007/08/10(金) 00:34:44 ]
あとコード出す時は再現できる最小のコードでな

136 名前:デフォルトの名無しさん mailto:sage [2007/08/10(金) 04:03:24 ]
>>131
ご自分で宣言した添え字をお忘れですか?

137 名前:デフォルトの名無しさん mailto:sage [2007/08/10(金) 04:38:35 ]
>>134-135
わかったか?能無しは黙ってろってことだ。

138 名前:ななしへたぐらま ◆XcB18Bks.Y mailto:sage [2007/08/10(金) 12:11:35 ]
>>131
>>118のコードですが
3バイトの文字配列であるListAの内容を無理矢理POPE004_Rec型だと解釈させていることになります.
POPE004_Rec型は恐らくTOPE004_Recっていうレコード型を定義していて
それに対するポインタ型(レコードのある場所を指す型)なのだと思いますが

> ListA[0]:='0';
> ListA[1]:='T';
> ListA[2]:='F';

という文字の並びを4バイトのアドレスだと解釈すると$??465430番地になります.
当然この場所は意味をなしませんからList2[i]にはでたらめな値が入っていると思われます.

このコードはコピー元がでたらめになるだけなのでListAの内容を壊しているわけではないと思われます.
しかし似たようなミスをほかの場所でもやらかしてListAの内容を壊している可能性は低くないと思います.


139 名前:デフォルトの名無しさん mailto:sage [2007/08/10(金) 15:22:57 ]
フォームからドラッグしてデスクトップやエクスプローラにドロップする
処理はどうしたら良いんでしょうか?
エクスプローラからアイテムをドラッグしてフォームにドロップする
処理は彼方此方で見かけるんですが、その逆が見つかりません・・・



140 名前:デフォルトの名無しさん mailto:sage [2007/08/10(金) 15:43:19 ]
ドロップして単にショートカット を作るというような事なら、そのままマウスイベントで処理すればいい
ドロップして独自の動作をさせるものを貼り付けるというような事なら シェルエクステンションを作成しないといけない


141 名前:デフォルトの名無しさん [2007/08/10(金) 17:04:51 ]
みなさんは、
・配置したコンポーネント名:
・フォーム名:
・フォームのユニット名:
をどのように決めてますか?

コーディング規約に属すると思いますが、
参考までにお聞きしたく。
(どこかに記述あったかなあ?)

私の場合は、
・配置したコンポーネント名:TPanelなら、 HogePanel
・フォーム名:メインフォームなら MainForm、他、HogeForm
・フォームのユニット名:MainFormUnit、HogeFormUnit
としてます


142 名前:128 [2007/08/10(金) 17:27:44 ]
Delphi 7以降の IDEの新機能
dn.codegear.com/no/article/34361

これによると、
dn.codegear.com/article/images/34323/ToolPalette.gif
部分一致検索が標準でできるように見えるのですが、
どうやったらいいんでしょ・・・

143 名前:128 [2007/08/10(金) 17:42:45 ]
こちらのプラグインで部分一致検索はできるようですが、
>>142のアニメーションが解せないなあ・・・

D_DevLog DDevExtensions
ddev.blog46.fc2.com/blog-entry-57.html

DelphiSpeedUp Delphi/BCB/BDS IDE plugin
andy.jgknet.de/dspeedup/index.php?page=DDevExtensions



144 名前:デフォルトの名無しさん mailto:sage [2007/08/10(金) 18:00:53 ]
デルファイはもうやめtロケ、最近、ザイリンクスのハードウエアみたいなプログラミング
が面白い

145 名前:デフォルトの名無しさん mailto:sage [2007/08/10(金) 18:24:56 ]
確かに VHDLはpascalに似てるけど、このスレで話題にするより他のスレでお願いね

146 名前:デフォルトの名無しさん [2007/08/10(金) 19:16:13 ]
ヘルプの表示項目をカスタマイズすることはできないでしょうか?
具体的には、Win32のDelphiだけを表示したいです。

WinHelpの時代は、手動でカスタマイズできたのですが・・・

環境は、Delphi2006です。

147 名前:146 [2007/08/10(金) 19:22:10 ]
メニューの「ヘルプ」「ページのフィルタの編集」で、
デフォルトの表示を編集しようとしたのですが、フィルタなしを
 ("DevLang"="Delphi") OR ("DocSet"="bds_Win32")
に、カスタマイズして、Saveをしても、

>このページのスクリプトでエラーが発生しました。
>'undefined'は、Nullまたはオブジェクトではありません。

と出てしまいます。


148 名前:146 [2007/08/10(金) 19:40:48 ]
("DevLang"="Delphi")
だけにしたら、Saveできたけど、
空欄にしたり、変更するとエラーが出て、もどせなくなってしまった。

orz

「フィルタなし」を空欄にしてSaveした場合
---------------------------
Microsoft Internet Explorer
---------------------------
Filter cannot be saved without a definition
---------------------------
OK
---------------------------

("DocSet"="bds_Win32")で、Saveした場合
---------------------------
Microsoft Internet Explorer
---------------------------
All keywords and attributes must be enclosed with in double quotes ( " ).
Please correct your text for this filter definition.
---------------------------
OK
---------------------------
ちゃんと " つけてるよ・・・ orz

149 名前:146 [2007/08/10(金) 19:50:24 ]
試行錯誤していたら、うまく設定を保存できました。

「ページのフィルタの編集」で、
Newして、
 ("DevLang"="Delphi")
と書いて、Save Asで、「(デフォルト)」と書いて保存したらうまくいきましたヽ( ´ー`)ノ
括弧()つけると最初の項目になり、デフォルトで選択されるようです。

さらに、
("DocSet"="bds_Win32") OR ("DevLang"="Delphi")
にすると、うまくエラーが出ずに保存できました。
(エラー出たりでなかったりするので、うまくいかないかもしれませんけど)



150 名前:デフォルトの名無しさん mailto:sage [2007/08/10(金) 22:26:19 ]
>>142-143
つ インクリメンタルサーチ

151 名前:デフォルトの名無しさん mailto:sage [2007/08/10(金) 22:54:52 ]
ドキュメントのない開発環境はドキュンだな・・・

152 名前:デフォルトの名無しさん mailto:sage [2007/08/10(金) 23:01:32 ]
座布団一枚...

食え

153 名前:デフォルトの名無しさん mailto:sage [2007/08/11(土) 05:06:14 ]
>>139
OLE Drag&Drop

>>141
それがいいと思う。

154 名前:デフォルトの名無しさん [2007/08/11(土) 13:33:07 ]
>>150
だから困るんですよ
なんで、部分一致検索じゃないかと・・・

155 名前:デフォルトの名無しさん mailto:sage [2007/08/11(土) 17:30:58 ]
>>154
別に誰も部分一致検索じゃないなんて言ってないけど

156 名前:デフォルトの名無しさん [2007/08/11(土) 18:29:36 ]
いやだから、部分一致検索じゃないから、困ってるんです。


157 名前:デフォルトの名無しさん mailto:sage [2007/08/11(土) 19:50:48 ]
ドキュメントのない開発環境はドキュンだな・・・

158 名前:デフォルトの名無しさん mailto:sage [2007/08/11(土) 20:06:02 ]
>>156
はぁ?部分一致検索じゃん
勝手な思い込みで困ると書かれても困るんですけど
第一プラグインで解決したんじゃないの?じゃあもういいだろ

159 名前:デフォルトの名無しさん [2007/08/11(土) 21:02:44 ]
>>158
プラグインで問題は、解決はしましたが、
うちの2007では部分一致ではなく、前方一致です。
解せません。




160 名前:デフォルトの名無しさん [2007/08/11(土) 21:03:30 ]
すみません、2006でした。

161 名前:デフォルトの名無しさん [2007/08/11(土) 21:05:31 ]
二つの環境で試しましたが、両方とも、前方一致検索でした。
なんで、デフォルトでこんな不便な仕様なんだろう・・・

162 名前:デフォルトの名無しさん mailto:sage [2007/08/11(土) 22:23:05 ]
画像を任意の角度だけ回転させるような手続き
Rotate(TImage, kakudo) みたいなのは標準でありますか?

163 名前:デフォルトの名無しさん mailto:sage [2007/08/11(土) 22:30:02 ]
ない。

164 名前:デフォルトの名無しさん mailto:sage [2007/08/11(土) 22:31:11 ]
そうですか
じぶんで描くしかないみたいですね

165 名前:デフォルトの名無しさん [2007/08/11(土) 22:37:48 ]
コンポーネントさがす

166 名前:デフォルトの名無しさん mailto:sage [2007/08/11(土) 22:42:58 ]
GDI+を使う

167 名前:デフォルトの名無しさん mailto:sage [2007/08/11(土) 23:15:38 ]
TImage は画像じゃないよ

168 名前:デフォルトの名無しさん mailto:sage [2007/08/12(日) 10:29:47 ]
www.asahi-net.or.jp/~HA3T-NKMR/DGS/

169 名前:デフォルトの名無しさん mailto:sage [2007/08/12(日) 12:08:42 ]
TBigBitmapCanvas って塗りつぶしうまくいかないよね。



170 名前:デフォルトの名無しさん mailto:sage [2007/08/12(日) 13:13:58 ]
回転にCanvasはつかわないしょ。
普通に補間関数書いて、座標変換するだけ。

171 名前:デフォルトの名無しさん mailto:sage [2007/08/12(日) 15:50:19 ]
>>170
> 普通に補間関数書いて
それが意外と難しい罠。

172 名前:デフォルトの名無しさん [2007/08/12(日) 23:47:28 ]

Threadの扱いで困っています。

Thread内でエラーが出た時に、ユーザーにしらせたいのですが、
どうするのがよいのでしょうか?

今は、Threadは、ひとつだけなので、
メインスレッドで、FThread: THogeThread; として、
サブスレッドの変数をもたせ、

開始時は、

FThread := THogeThread.Create(False);

とし、サブスレッド停止時には、スレッドの終了を待つように、

procedure TMainThread.StopThread;
begin
 if Assigned(FThread) then begin
  FThread.Terminate;
  FThread.WaitFor;
  FreeAndNil(FThread);
 end;
end;

としています。



173 名前:172 [2007/08/12(日) 23:48:21 ]
そして、サブスレッド内で、エラーが起きた場合
Synchronize で、メインスレッドでエラーをポップアップし、
Terminate; を呼び出しています。

しかし、こうすると、メインスレッドから、停止処理(StopThread)を呼ぶのはよいのですが
サブスレッドで、エラーが起きた場合は、
FThread が、終了したにも関わらず、FThreadが、保持された状態になります。
次に開始したときは、また生成してしまい、メモリリークになります。

こういうときはどうするのが良い方法なのでしょうか?
それとも、FThreadを持たない方法がよいのでしょうか?
(その場合、どうやってスレッドの終了を待てばよいのか……?)

174 名前:172 [2007/08/12(日) 23:49:04 ]
あ、よく考えたら、

サブスレッド開始時に、StopThread呼べばいいのか・・・

175 名前:172 [2007/08/12(日) 23:55:04 ]
もしくは、スレッド一個なら、最初から生成しておく方法でもいいですね。
メインスレッド(メインフォーム)生成時に、生成しておいて、

SyncObj.TSimpleEvent を使って、イベント待ちにして、
スレッド開始時には、TSimpleEvent .SetEvent;する。
スレッド停止時は、フラグを立てて、ループを抜け、イベント待ちにもどる、と。

で、メインスレッド破棄時のみ、TMainThread.StopThread を呼び出すと。

176 名前:172 [2007/08/13(月) 00:17:03 ]
結局、
FreeOnTerminate = True; を使って、スレッドを自動的に破棄するようにしたのですが、
アプリケーション終了時に、メモリリークが起きてしまいます。
(ReportMemoryLeaksOnShutdown := True;で確認)

TMainThread.StopThread;のように、スレッドの解放を待つにはどうしたらよいのでしょうか?

177 名前:172 [2007/08/13(月) 00:27:39 ]
>>176に関して、メインスレッド終了時(Destory)に、

 if Assigned(FThread) then begin
  FThread.Terminate;
  FThread.WaitFor;
  FThread := nil;
 end

としていたのですが、
スレッドを起動した状態で、終了すると
「スレッドエラー:ハンドルが無効です。 (6)」というエラー
と言われて、正常に終了できませんでした。

たぶん、Terminateで、スレッドが破棄されているからだと思います。

そこで、

  if Assigned(FThread) then begin
    FThread.FreeOnTerminate := False;
    FThread.Terminate;
    FThread.WaitFor;
    FreeAndNil(FThread);
  end;
としたところ、無事に正常に終了できました。
ありがとうございました。

でも、FThreadを持たず、複数Createする時はどうやって待つんだろ……



178 名前:デフォルトの名無しさん mailto:sage [2007/08/13(月) 01:53:30 ]
TTabControlのDragModeをdmAutomaticにすると
タブをクリックしても選択されないのは仕様ですか?
そうするとOnMouseDownやOnMouseUpイベントも呼び出されてないみたいだし、
自前でやるしかないんですか?

179 名前:デフォルトの名無しさん mailto:sage [2007/08/13(月) 02:09:09 ]
自前でやるのがプログラミングなんだぜ



180 名前:178 mailto:sage [2007/08/13(月) 02:17:21 ]
>>179
そうですか・・・><

181 名前:デフォルトの名無しさん mailto:sage [2007/08/13(月) 03:33:12 ]
Delphi2007でTNT Unicode Control使うにはどうしたらいんでしょ?
無償版はだめっぽいし、最新の有償版ですら
パッケージ C:\Program Files\tmssoftware\TMSUnicode\Packages\TMSUnicodeDED2006.bpl を読み込めません。
指定されたモジュールが見つかりません。.
ってエラーがでる。(ちゃんとあんのに)

182 名前:デフォルトの名無しさん [2007/08/13(月) 10:49:40 ]
>>181
パスとおせよ。

183 名前:デフォルトの名無しさん mailto:sage [2007/08/13(月) 13:18:40 ]
>>182
すみません、通ってるようです。

184 名前:デフォルトの名無しさん mailto:sage [2007/08/13(月) 14:58:38 ]
>>172-177
Threadから自前のメッセージをポストしてメインスレッドでユーザーに知らせればいいの
では? そしてその時にエラー処理なども一緒にすれば、Threadの方はシンプルにできる
と思うんだけど。

185 名前:デフォルトの名無しさん [2007/08/13(月) 16:13:30 ]
rsdn.ru/article/delphi/Handlers.xml
ページみてるんですが、

type
 TCalcFunction = function(const A, B : integer) : integer;

function Add(const A, B : integer) : integer;
begin Result := A + B;end;

procedure Example;
var CalcFunction : TCalcFunction;
begin
 CalcFunction := Add;
 ShowMessageFmt('CalcFunction(2, 3) = %d', [CalcFunction (2, 3)]);

なんでこういうふうにわざわざやるんでしょうか?
どういうときにこういうのを使うんでしょうか?

186 名前:デフォルトの名無しさん mailto:sage [2007/08/13(月) 16:25:16 ]
いや別にいやだったら本人の好きなようにやればいいんじゃないの?

187 名前:デフォルトの名無しさん mailto:sage [2007/08/13(月) 16:26:25 ]
>>185
自由に関数を切り替えるためじゃない?例えば
var


188 名前:デフォルトの名無しさん mailto:sage [2007/08/13(月) 16:28:05 ]
>>185
理由はそのページの説明文に書いてあるぞ

189 名前:187 mailto:sage [2007/08/13(月) 16:37:52 ]
ごめん、途中で送信しちゃった。

var
  SomeFunction : array[0..3] of TCalcFunction;
として
  SomeFunction[0] := Add;
  SomeFunction[1] := Sub;
  SomeFunction[2] := Multi;
  SomeFunction[3] := divi;
と代入すると(それぞれの関数は宣言してあるとする)。
  SomeFunction[a](2, 3) でaの値を変えるだけで関数を切り替える事ができる。



190 名前:デフォルトの名無しさん mailto:sage [2007/08/13(月) 16:43:46 ]
関数ポインタの使いどころって意味なら
C言語の例だけどqsortで検索してみたら。

191 名前:デフォルトの名無しさん [2007/08/13(月) 17:11:48 ]
>>185 えーそうなんですけ?
>>189 条件分岐を不要にできるんですか。これは使ってみたいです。
>>190 かえってわかんなくなってしまいました><
ありがとうございました。

192 名前:ななしへたぐらま ◆XcB18Bks.Y mailto:sage [2007/08/13(月) 22:29:46 ]
>>189 Delphiだと「手続き型」になりますがTListやTObjectListのSortメソッドがそれに相当しますね.
サンプルを作ってみたのですがちょっと長すぎるのでぐぐってみました.
(ほかのサンプルは Delphi TList Sort でぐぐるとよいかも)
www.smart-bbl.info/CQN/FAQ/delphi/d0009394.html

TList.Sortでは手続き型を使うことによって「データをどういう順番に並べ替えるかを決める処理と,
その条件に従って実際に並べ替える処理とが完全に分離」しています.

どんな形式のデータを並べ替えさせる場合でも,どんな順序で並べ替えさせる場合でも,
その条件に従って並べ替える方法はほぼ決まっているので,
結果としてリストを使うプログラマーは前者のコードを書くだけで済むようになり,
プログラマーが毎回並べ替えのコードを書くという無駄な作業から解放されるのです.

ちなみに上のページのサンプルコードではスタッフを年齢順にソートしていますが名前順にソートすることもできます.

function StaffSortCompareByName(Item1, Item2: Pointer): Integer;
begin
 Result := AnsiCompareText(PStaff(Item1)^.Name, PStaff(Item2)^.Name);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 StaffList.Sort(StaffSortCompareByName);
end;

ボタン1を押すと年齢順でソートされてボタン2を押すと名前順でソートされます.実質1行で.


193 名前:デフォルトの名無しさん mailto:sage [2007/08/13(月) 23:27:52 ]
一番身近な関数ポインタは「イベント」ですわ。OnClickとか。





194 名前:Delフサギコ ◆A6VzDeLphI mailto:sage [2007/08/14(火) 01:26:03 ]
             ___________
    ∧,,∧     /こんな風にすると
   ミ,,゚Д゚彡 <  おもしろいよ。
   ミ つ日   \
 〜ミ,,,,,, ,,ミ       ̄ ̄

type
 TCheckLineFunction = function(Line: String): Boolean;
 TStringListFunction = record
  FStrings: TStrings;
  constructor Create(Strings: TStrings);
  procedure DeleteLine(f: TCheckLineFunction);
 end;
constructor TStringListFunction.Create(Strings: TStrings);
begin
FStrings := Strings;
end;
procedure TStringListFunction.DeleteLine(f: TCheckLineFunction);
var
 i: Integer;
begin
 for i := FStrings.Count - 1 downto 0 do
 begin
  if f(FStrings[i]) then
  begin
   FStrings.Delete(i);
  end;
 end;
end;


195 名前:Delフサギコ ◆A6VzDeLphI mailto:sage [2007/08/14(火) 02:14:32 ]
             ___________
    ∧,,∧     /
   ミ,,゚Д゚彡 <  以下、使い方。
   ミ つ日   \
//空行を判定している
function CheckEmptyTextLine(Line: String): Boolean;
begin
 if Line=EmptyStr then
  Result := True
 else
  Result := False;
end;

var
 StringListFunc: TStringListFunction;
begin
   StringListFunc.Create(OutputMemo.Lines);
   StringListFunc.DeleteLine(CheckEmptyTextLine);

end;

関数側で、Lineの内容を判定して、判定がTrueなら
行削除する処理を行えるわけです。



196 名前:デフォルトの名無しさん [2007/08/14(火) 11:39:22 ]
指定のアプリーションに、アクティブにせずに、キー入力を送りたいのですが、
可能でしょうか?
可能ならば、どのようにやったらよいのでしょうか?
検索単語でもいいので、ご享受ください

197 名前:デフォルトの名無しさん mailto:sage [2007/08/14(火) 11:39:43 ]
最近は1つ質問すると10回答が来たり、自問自答がはやってるのか?
いやぁ、夏枯れですねぇ。

よきかな、よきかな・・・

198 名前:デフォルトの名無しさん mailto:sage [2007/08/14(火) 13:58:05 ]
>>196
sendmessage

199 名前:デフォルトの名無しさん [2007/08/14(火) 14:51:59 ]
>>198
サンクソ。
PostMessageと、SendMessageっぽいですね。
調べてみます。



200 名前:デフォルトの名無しさん [2007/08/14(火) 16:22:30 ]
>>194 動かしてみたらなるほどおもしろいと思いました。
ありがとうございました。


201 名前:デフォルトの名無しさん [2007/08/14(火) 16:32:17 ]
最近は1つ質問すると10回答が来たり、自問自答がはやってるのか?
いやぁ、夏枯れですねぇ。

よきかな、よきかな・・・






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<113KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef