Form1から以下のようにForm2、Form2をShowメソッドで呼び出し、それぞれのフォームで作業を行うアプリケーションを作っています。
早速、質問なのですがForm2でShowMessageを呼び、メッセージを表示したままだとForm1、Form3で作業できなくなります。
当たり前の動作なのかも知れませんが、Form2でShowMessageを呼び出してメッセージを表示したままの状態でForm1、Form3で作業できるようにならないでしょうか?
ご指導宜しくお願いします。
procedure TForm1.Button1Click(Sender: TObject);
begin
if Form2 = nil then
begin
Form2 := TForm2.Create(nil);
Form2.Show;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if Form3 = nil then
begin
Form3 := TForm3.Create(nil);
Form3.Show;
end;
end;
>当たり前の動作なのかも知れませんが、Form2でShowMessageを呼び出してメッセージを表示したままの状態で
これをさせたままで別のフォームで作業させたい場合、ShowMessage しないで、
モードレスの自前のForm4とかを作れば簡単。難しいこと無理に考えない。
「勉強」ということなら話は別ですが.....
レス有り難う御座います。
普通さんの言うとおり、Form4を作れば話が早いのは分かっているのですが、この様な状況をどの様な方法で打破できるのかを知りたくて質問しました。
勉強の方向で宜しくお願いします。
・モードレスのFormを作る
ShowMessagge、InputBoxの他にもOpen(Save)Dialogなども有り単純にモードレスで処理できない。
・別EXEにする
これは最後の手段としてお願いします。
・気にしない
・・・・(笑
別DLL化、別スレッド化は実験済みで不可でした。
説明を単純化するあまり言葉足らずになって申し訳ありません。
> この様な状況をどの様な方法で打破できるのかを
モーダルダイアログを表示して、かつ、同一アプリの他のフォームを操作するのは
ウィンドウズの動作として異常です。「打破」すべきじゃないのでは、と思います。
レス有り難う御座います。
>ウィンドウズの動作として異常です。
素人考えで恥ずかしいのですがForm1からForm2、Form3をモードレスで開くと全てのFormで作業が出来るって事は言葉が悪いかも知れませんが別スレッド動いているって事ですよね?
さらにForm2からForm4をモーダルで開いたらForm1とForm2は利用できなくなるのは納得できますがForm3が利用できなくなる方がおかしいような気がします。
しかもForm1からForm2をモーダルで開いた後にTTimerを利用してForm1からForm3をモードレスで開くとForm2とForm3にフォーカスを当てることが出来ます。
多分、Formの作成順が関係してくるんだとは思いますが、これもWindowsの動作としては異常なのでしょうか?
今までこのような状況を体験したことがなく、モードレス、モーダルについて深く考える良い切っ掛けになったと思います。
もう少し自分なりに勉強してみますが引き続きご指導いただければ幸いです。
> 別スレッド動いているって事ですよね?
違います。全部一つのスレッドです。
モーダルダイアログは、それを閉じない限り他のフォームにアクセスできないように
なっています。フォームの作成順序は全く関係ありません。
メッセージループ、モーダルループ、タイマの仕組み、スレッドとプロセス、
これらが分かれば、あなたのおっしゃっていることはすべて Windows の仕組み
として当然の動作であることが理解できるでしょう。
しつこいですが、モーダルダイアログを表示してかつ他フォームにアクセスするような
ことはしない方がいいですよ。タイマでモードレスダイアログを開くのは、
たんにモーダルダイアログからモードレスダイアログを開いているのと同じであり、
最初のモーダルな状態はそのまま続いています。
モーダルで開きかけてるダイアログをフックとかして、モードレスとして開くことはできないものでしょうか?
他のWindowが操作できなくなるのは、単にWindowがEnableでなくなるからです。なので、別スレッドからForm1とForm3に対してEnableWindowすれば操作可能になります。
しかしこんな異常なUIを採用したら、使いにくい上にデバッグもめんどくさそうですね。。。
>かみづさん
レス有り難う御座います。
EnableWindowで希望する動作になりました。
しかし、Form3が何故道連れになってしまうのかが理解できませんのでもう少し勉強してみます。
>えーとさん
2006/05/18(木) 22:49:32と2006/05/18(木) 22:54:22のレスが同一人物として書きますが違う人だったら申し訳ないです。
>フォームの作成順序は全く関係ありません。
と
>タイマでモードレスダイアログを開くのは、
>たんにモーダルダイアログからモードレスダイアログを開いているのと同じであり
って矛盾してますよね?
>メッセージループ、モーダルループ、タイマの仕組み、スレッドとプロセス
モーダルループ以外は理解しているつもりだったのですが・・・。
今回の件でモーダルループも勉強してみます。
結果ばかりではなく、何故しない方が良いのかを詳しく説明していただきたかったです。
最後になりましたが稚拙な質問にお付き合いいただき有り難う御座いました。
> 矛盾してますよね?
矛盾してません。モーダルループ動作中に開いたフォームは、そのモーダルダイアログにとって
モードレスだからです。Form2 から最初のモードダルダイアログを開いたときに
すでに作成済みの Form3 にアクセスできなくなるのは、Form2 より先に作ったか
あとにつくったかに関係ないからです。
> 結果ばかりではなく、何故しない方が良いのかを詳しく説明していただきたかったです。
なぜ、モーダルダイアログを開くと、その時点で既に開いているフォームにアクセス
出来なくなるような仕組みになっているか、を考えれば明らかだと思います。
ユーザに、最優先で知らせる、あるいは操作してもらう必要があって、他を変えて
ほしくない、場合にモーダルダイアログが使われる、と仮定しているからです。
モーダルダイアログ表示中に他のフォームを操作できるようにすると、モーダル
ダイアログで設定した値とモードレスダイアログの操作結果と矛盾した値になる
場合がありえるでしょう?
話が噛み合ってないようなので蛇足お許し下さい。
フォームの作成順序についてですが、えーとさんが言っているのは
Form1 -> Form2(モードレス) -> Form4(モーダル)
で、Form2の前後どちらかでForm1からForm3をモードレスで作るってこと言ってますよね。
その場合、Formの作成順は関係ないと言いたいようですが同感です。
ただ私の発言(2006/05/18(木) 16:02:55の9行目から)をもう一度見直していただけないでしょうか。
上記とは違うやり方を提示しています。
>モーダルダイアログで設定した値とモードレスダイアログの操作結果と
>矛盾した値になる場合がありえるでしょう?
有り得るって話で必ずそうだと言えないでしょう?
最初(2006/05/17(水) 20:32:21)に提示した案件についてもForm2とForm3で矛盾した結果が出るか考えてみてください。
実際、私の作ろうとしている(作った)のはモードレスで開くForm同士干渉し合わない様に複数のスレッドの上に成り立っています。
Form1 -> Form2(モーダル)で開いてForm1を操作したいとは言ってません。
もし、これを見て機嫌を損ねる事がありましたら謝罪いたします。
ですが人は自分の考えを他人に伝えるのは極めて困難な作業です。
それぞれの立場、考え方があるのですから頭ごなしに否定するのは宜しくないと思います。
訂正
>上記とは違うやり方を提示しています。
上記とは違うやり方を提示し、その上で「フォームの作成順が関係している」と言いたかったのです。
また、この動作が「Windowsの動作としては異常」なのかとお聞きしたかっただけです。
はい、異常だとおもいます。上にも書きましたが、モーダルダイアログの意味を
もう一度考えてください。
> ただ私の発言(2006/05/18(木) 16:02:55の9行目から)をもう一度見直していただけないでしょうか。
って、
> さらにForm2からForm4をモーダルで開いたらForm1とForm2は利用できなくなるのは納得できますが
> Form3が利用できなくなる方がおかしいような気がします。
>
> しかもForm1からForm2をモーダルで開いた後にTTimerを利用してForm1からForm3をモードレスで開く
> とForm2とForm3にフォーカスを当てることが出来ます。
これのことですか?
何度も書いてますが、モーダルダイアログを開いたときに既に開いているフォームにアクセス
出来なくなるのであって、既に作成されているフォームの作成順序は関係ないです。
タイマをつかって、モーダルループ中に Form3 を開くのは、モーダルダイアログにたいして
モードレスになるのでアクセスできるのは当たり前です。これも既に回答しました。
> モードレスで開くForm同士干渉し合わない様に複数のスレッドの上に成り立っています。
どうやって複数のスレッドにしているのか興味あります。Delphi でメインスレッド以外で
GUI を持つ初めての例になるかもしれませんね。
えーとさんに一票
もう止めにしましょう。
いつまでたっても平行線です。
最後に一言。
誰がGUIを持つスレッドを作ったと言いましたか?
ここまで小馬鹿にされると呆れてしまいます。
板汚し申し訳ないです <ALL
> いつまでたっても平行線です。
ちっとも平行線ではないですよ。
> 素人考えで恥ずかしいのですがForm1からForm2、Form3をモードレスで開くと全ての
>Formで作業が出来るって事は言葉が悪いかも知れませんが別スレッド動いているって事ですよね?
これでマルチスレッドによる「Form同士干渉し合わない様に複数のスレッドの上に成り立っています。」とどういう関係があるのですか?
質問をしておいて、回答を無視して、一方的に「もう止めにしましょう。」とは、
おかしいでしょう。
何故
>素人考えで恥ずかしいのですがForm1からForm2、Form3をモードレスで開
>くと全てのFormで作業が出来るって事は言葉が悪いかも知れませんが別
>スレッド動いているって事ですよね?
と
>実際、私の作ろうとしている(作った)のはモードレスで開くForm同士干渉
>し合わない様に複数のスレッドの上に成り立っています。
が、同一視されてるんでしょうか?
前者はあくまで私の意見を述べているだけで実際に作成しているアプリケーションではありません。
後者は私が作ったアプリの概要で複数のスレッドを動かし有る条件を満たせば該当するスレッドが該当するFormを表示して作業するってだけで他のFormには干渉していない。
>ちっとも平行線ではないですよ。
平行線です。
フォームの作成順についての意見の相違は
先にも書きましたがえーとさんは
>Form1 -> Form2(モードレス) -> Form4(モーダル)
>で、Form2の前後どちらかでForm1からForm3をモードレスで作
を指してフォームの作成順は関係しないと述べている。
私は
>しかもForm1からForm2をモーダルで開いた後にTTimerを利用してForm1からForm3をモードレスで開くとForm2とForm3にフォーカスを当てることが出来ます。
を指して作成順は関係すると述べている。
えーとさんが書いたように
>タイマをつかって、モーダルループ中に Form3 を開くのは、モーダルダイアログにたいして
>モードレスになるのでアクセスできるのは当たり前です。これも既に回答しました。
では私の意見(作成順は関係する)を肯定するものですよね。
>モーダルダイアログで設定した値とモードレスダイアログの操作結果と
>矛盾した値になる場合がありえるでしょう?
有り得ると言葉を濁しながら結論は異常と言い切るのでは納得のしようもありません。
その後書いた私の意見について無視してますよね。
>有り得るって話で必ずそうだと言えないでしょう?
>最初(2006/05/17(水) 20:32:21)に提示した案件についてもForm2とForm3
>で矛盾した結果が出るか考えてみてください。
こんな状態で話を続けるのは不毛だと思ったからこそ「止めましょう」と書いたまでです。
> その後書いた私の意見について無視してますよね。
わたしは質問者ではないので回答する必要はないですし、意見を求めていません。
> 該当するスレッドが該当するFormを表示して作業するってだけで
> 他のFormには干渉していない。
あなたは、「スレッド」の意味が分かってないと思います。
不毛なのは、プログラミングに使う言葉の意味が、わたしとあなたとは違うからです。
>実際、私の作ろうとしている(作った)のはモードレスで開くForm同士干渉し合わない様に複数のスレッドの上に成り立っています。
これの実現方法はどうなってます? ミューテックスで排他などの具合は?
以下のコードで、Button1、Button2、Button3 の順にクリックすれば、
メッセージBoxを2個同時に出せます。
が、「出せる」というだけで、不具合ありまくりです。
参考までということで・・・
//-------------------------------------------------------
unit Unit1;
interface
uses
Windows, Classes, Controls, Forms, Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
uses Unit2, Unit3;
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
begin
Form2.Show;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
ThreadLoop.Create(False);
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
ShowMessage('1');
end;
end.
//-------------------------------------------------------
unit Unit2;
interface
uses
Windows, Classes, Controls, Forms, Dialogs, StdCtrls;
type
TForm2 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
end;
var
Form2: TForm2;
implementation
{$R *.DFM}
procedure TForm2.Button1Click(Sender: TObject);
begin
ShowMessage('2'); //ここにブレークポイントを置かないと何故か出ない
end;
end.
//-------------------------------------------------------
unit Unit3;
interface
uses
Classes;
type
ThreadLoop = class(TThread)
protected
procedure Execute; override;
end;
implementation
uses Unit2;
procedure ThreadLoop.Execute;
begin
Form2.Button1Click(Form2.Button1);
end;
end.
>わたしは質問者ではないので回答する必要はないですし、意見を求めていません。
だったら最初から書き込まないで下さいね。
>不毛なのは、プログラミングに使う言葉の意味が、わたしとあなたとは違うからです。
読解力の無さを棚に上げてそこに逃げましたか・・・。
読解力ないなりに,がんばって読んでみました。
【えーと 2006/05/19(金) 13:45:46】←この発言で
げん太さんの質問は全て解凍されてると思います。矛盾はありません。
【2006/05/18(木) 16:02:55の9行目】の部分に対しても回答終わってます。
誤字・・・
解凍→回答で・・・。
誰がみても「えーと」さんが正しいですよね
「げん太」さんが何故逆切れしているのかがわかりません
げん太さんは
>読解力の無さ
と仰られていますが、えーとさんのレス以外の回答をお望みでしたらそれはげん太さんの説明が悪いのではないでしょうか
明らかに、違ってますね。初期の論点は、可能かどうか。これは成功しているということで解決。
フォームの作成(表示)順序とモーダルとの関係について、双方の理解で食い違いが見られるようです。この件について、
>タイマをつかって、モーダルループ中に Form3 を開くのは、モーダルダイアログにたいして
>モードレスになるのでアクセスできるのは当たり前です。これも既に回答しました。
>ユーザに、最優先で知らせる、あるいは操作してもらう必要があって、他を変えて
>ほしくない、場合にモーダルダイアログが使われる、と仮定しているからです。
>モーダルダイアログ表示中に他のフォームを操作できるようにすると、モーダル
>ダイアログで設定した値とモードレスダイアログの操作結果と矛盾した値になる
>場合がありえるでしょう?
傍から見ていても、ここが納得できない部分です。
モーダルが必要ないのにモーダルにするというのは、
ATMで、1500円を下ろすとき、
金額を入力すための パネルに触るたびに
「数字 1が入力されました。OKボタンを押してください」
「数字 5が入力されました。OKボタンを押してください」
「数字 0が入力されました。OKボタンを押してください」
「数字 0が入力されました。OKボタンを押してください」
と言っている様なものです。
モーダルをモードレスにするというのは、
「準備ができたら、自爆ボタンを押してください」の
自爆ボタンを勝手に押すようなものでもあり、
賞味期限 1000年のスパゲティを
製造後、わずか1日で開封し、食べてしまうようなもので
もあります。
思想と矛盾とは違います。
蛇足ながらさんの書かれたものは変則的使用法かも知れませんが、身体障害とか、精神障害をかかえている人のためのインターフェースならありえるかと思います。
私もそう思いますよ(=^−^=)
そうですね。否定的に書いてしまいましたね。
私の先入観からです。せっかく考えたのに台無しですね(;;)
でも、どうか否定的にはとらえないでくださいネ☆
そのメッセージはもっと奥が深いんですよ。
表現を変えます。
モーダルにする必要が無い場合で、モーダルにする事
というのは、言い換えれば、
ATMの利用者が、15円を下ろしたい時に、
利用者が、金額を入力すための パネルに触るたびに
「数字 1が入力されました。OKボタンを押してください」
「数字 5が入力されました。OKボタンを押してください」
とユーザーに随時問い合わせるのと等価であり、
モーダルであるダイアログをモードレスにするという事は
利用者に、「準備ができたら、自爆ボタンを押してください」
と確認を求めはするが、システムが自動的に自爆ボタンを
押すのと等価である。
また、システムの開発者に対し、
賞味期限 1000年のスパゲティを製造後、わずか1日で開封し、食べてしまう
のと等価な心理的影響が生じる恐れがある。
これで中立的に読めるようになったかな?
私の気持ちも伝わりました?
げん太さんの分(ぶ)が悪いようなので、擁護派として、お伺いしたいんですが、それができるとどんな時に便利になるでしょうか? 逆にそれができない普通のモーダルでは困る/面倒/手間な状況ってあるのでしょうか?
そこを書けば、なるほどと思えるかも知れません。
単に技術的な興味であるなら、(順番の点を除いて)解決していますよね.....
1.モーダルフォームが表示されたら,既存のフォーム作成の順番に関係なく全ていじれなくなる。
2.ただしTTimer等でモーダルフォーム表示後に作成(表示)されたフォームに関してはいじれる。(ただしあまり好ましくない)
モーダルフォームが表示されたタイミングを境に,フォームがいじれるかどうかが変化すると書いてます。げん太さんは,上記の件に関して1と2の件両方ひっくるめて「フォーム作成の順番は関係している」っといってるのかな?まぁ間違いではないかな・・・
2の操作をした場合データに矛盾が生じる可能性があるという件に関しては,扱うデータの内容や処理ルーチン等,プログラムによって状況が変わるので『可能性』と書いてるのだと思います。
2の操作が異常だという件ですが,モーダルフォームはそのフォームの処理が終えない限り,他のフォーム(データ)を変更させないというのが目的と思います。そのモーダルフォームを使用しているのにも関わらず,別フォームを作成してデータを変更するというのはシステム上異常と言いたいのではないでしょうか?ただ,その別フォームがモーダルフォームのデータと無関係なのであれば影響はないのかもしれないのでしょうが,一般的には望ましくないです。
まだまだビギナーなんですが,これであってるのでしょうか・・・?
基本的にモーダルフォームを使っていながらモーダルではない使い方をしようとしているのだからその発想が矛盾してますよね
やってはいけない様な方法に対してここで論議してもあまり意味ないような・・・
やること自体が間違っているのだから
しかし「擁護派として」さんの意見って擁護にならないような(意図的?)
「開かない扉」って矛盾してるかも知れませんが、利用法はあるものです。
「開かない扉」は矛盾してないのでは?
前提として、「扉は開かなければならない」というのであれば矛盾していますが。
例えを出すなら、それこそ「矛盾」のそのままで、「何でも貫く矛と、何物も通さない盾」でよいかと。
それで、そういう矛と盾って、利用法あります?
# 詐欺以外で
なんだかすげーレス数だったので私も参戦。
> モーダルダイアログを表示して、かつ、同一アプリの他のフォームを
> 操作するのはウィンドウズの動作として異常です。
確かにその通りですが、厳密にいえばアプリはフォームウインドウを複数持つ場合があります。
この場合、アプリからみますと複数のモーダルダイアログを持つことを許容することになります。
例を挙げると、explorer.exe
フォルダを複数開いてそこにモーダルダイアログが平気で出てますよね。
だがしかしです!
Delphi IDEは元々アプリケーションウィンドウを複数持つように設計されていないのです。だからDelphiでこれを作るのは難しいです。
今度時間ができたら挑戦してみようかな。
アプリケーションウィンドウについては下を参考にしてください。
http://www.asahi-net.or.jp/~HA3T-NKMR/vcl3-2.htm
誤爆;;
> 確かにその通りですが、厳密にいえばアプリはフォームウインドウを複数持つ場合があります。
でわなく
厳密にいえばアプリはアプリケーションウインドウを複数持つ場合があります。
>それで、そういう矛と盾って、利用法あります?
ありますよ。
ツイート | ![]() |