エディットボックスとモーダルダイアログを連携させるには

解決


初心者服部  2006-06-21 07:23:39  No: 62255

質問があります。よろしくお願いします

環境は  Windows2000 VisualStudio.net2003 /VisualC+ /MFC/SDIアプリケーション

エディットコントロールに一行ずつ表示させた文字列によるメッセージと
それに対するユーザーのレスポンスをダイアログで入力させたいと思っていますが
そのロジックがなかなかうまく出来ません。
今の状況から・モーダルダイアログを使い制御を維持する方法
でそれなりに機能は実現出来ているのですが、モーダルダイアログの
表示場所に問題があります。そこで質問ですが

1・  ダイアログをモーダルで表示させ、利用者の意思確認を随時行う仕組みにしているのですが、DoModal()でダイアログを表示させると、どうしてもダイアログの場所(座標)がメイン(フレーム)ウィンドウの真ん中になってしまい、変更する事が出来ません(分かりません)どうすれば、場所などを移動させる事が出来るのでしょうか

2・また、モーダレスにすれば簡単に場所やスタイルの変更が出来る(分かる)のですが、
エディットボックスには様々なメッセージの組み合わせをその都度、制御して組み合わせ、一行ずつ順番に表示させる「会話風」の実装としているのですが、モーダルダイアログのようにアプリケーションの制御を完全に保持する関数を途中で呼び出さないと、エディットボックスに一行ずつ順番に表示させたい文字列が一気に表示され(というより、最後の文字列のみ見える状態で、それ以外は見えない状態になり機能しなくなる)、エディットボックスにゆっくりと順番に表示させる事が出来ません。
もしそれが(モーダルダイアログを途中で表示させる以外の)別の方法で実現出来れば、ユーザーの返事を入力するダイアログはモーダレスでも構わないので、場所の問題が解決するのですが

分かりにくい質問になってしまいすいません。
もしよければご教授の方よろしくお願いします


KING・王  2006-06-21 17:18:27  No: 62256

あまり詳しくないのですが・・・

1.については、モーダルで表示されるダイアログのOnInitDialog()の中で、MoveWindow()を使用して、表示位置を変更できませんか?

2.については、少し意味をつかみかねるのですが。。。

(A)> モーダレスにすれば簡単に場所やスタイルの変更が出来る(分かる)のですが、

=>ということは、モーダレスでは問題ないが、モーダルでは問題があるということですか?

(B)> エディットボックスには様々なメッセージの組み合わせをその都度、制御して組み合わせ、一行ずつ順番に表示させる「会話風」の実装としているのですが、

=>これは初心者服部さんが実装したい仕様になるとおもうのですが、1行ずつ表示される内容が追加されているのですか?それとも、どんどん次のメッセージで上書きされているのですか?

(C)> モーダルダイアログのようにアプリケーションの制御を完全に保持する関数を途中で呼び出さないと、エディットボックスに一行ずつ順番に表示させたい文字列が一気に表示され(というより、最後の文字列のみ見える状態で、それ以外は見えない状態になり機能しなくなる)、エディットボックスにゆっくりと順番に表示させる事が出来ません。

=>これは、モーダルなら表示できるが、モーダレスの場合表示できないって意味ですか???
それだと(A)の部分と(C)の部分で矛盾があるように感じるのですが・・・
モーダル、モードレスのどちらの場合が問題なんですか?

単に再描画される前に、次のメッセージでエディットボックスの内容を上書きして、
最終的に、最後のメッセージが上書きされた後に再描画が実行され、最後のメッセージが表示されているだけ???

もう少し箇条書きにする等、分かりやすくしていただいたほうが、回答が得られやすいとおもいますよ。
また、初心者服部さんが記述されたソースコードを提示したりすると、より的確な回答が得られやすいと思います。


PATIO  2006-06-21 23:43:17  No: 62257

1.については既にKING・王さんが書かれているので良いとして
2.ですが、
単にDoModalだと一回一回制御が止まるのでうまくいっているだけなのでは?
自分で文字列を一行ずつ表示する為の制御をしているというよりも
プログラムの流れ上、結果的にそうなっているだけと言う気がします。
モードレスの場合、Createでは制御が止まりませんから
モードレスダイアログ側で入力があった事を受けて表示を行う処理が
別に必要になるはずです。
(つまりモーダルダイアログのときのままでは駄目と言うこと)
モードレスダイアログにするのであれば、いっその事、そのあたりの制御は
すべてモードレスダイアログ側に持たせた方が楽に制御できます。
どうしても呼び出し側のウインドウから制御したいのであれば、
ユーザー定義のウインドウメッセージを使ってモードレス側で入力があった事を
呼び出し側に伝えてメッセージをモードレス側に引き渡すような手段を考える
必要があります。
この辺は、仕組み次第なのでご自分で考えてください。


PATIO  2006-06-21 23:46:23  No: 62258

ちょっとわかりにくかったので補足。

ユーザー定義のウインドウメッセージを使ってモードレス側で入力があった事を
呼び出し側に伝えて、
受けた呼び出し側で必要なメッセージ内容をモードレス側に引き渡すような仕組みを考える必要があります。


初心者服部  2006-06-24 08:50:31  No: 62259

レスありがとうございます

返信が遅くなりすいません。いろいろ試したりしてしてました。
あと、こちらのスレの質問が自分の聞きたかったこととかなり重複してたので
質問の内容に驚きつつ参考にさせていただきました

【参考】
ループ中にEDITBOXの内容を逐一変更するためには
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200606/06060044.txt

自分の質問の下手さを痛感しました。やりたかった事はこういう事だったわけです。

1の件についてはKさんの言う通りOnInitialDialog()でちゃんといけました
ありがとうございます。初歩的ですいません

2の件についてなんですが、文章が分かりにくくて申し訳ありませんでした
もともとやりたい事は
・エディットボックスコントロールに一行ずつゆっくりとテキストを表示させたい
という事だったのです

参考までに具体的なコード(というか、クラスの関係)を抜粋して書いみます。

エディットボックスを持ってるのは今回はダイアログバーで
クラスを仮にCHukidashiDialogBar とします

そのクラスのメンバにエディットボックスに
CStringを入れるだけのメンバ関数

BOOL CHukidashiDialogBar::SetHukidashi(CString comment)
{
GetDlgItem(IDC_EDIT_HUKIDASHI)->SetWindowsText(comment)
}

を置いていますこの関数の中身は基本的にこの一行
だけです
(今この関数の中に、DoModal()を置くと、一行ずつ表示させる事はうまくいくのですが  いちいち、ダイアログがアプリケーションのモーダルになってしまうので、
  やはり気持ち悪さがかなり残ってしまいます)、

このダイアログバークラスにはいろいろなところからアクセスさせるものとしてます。

そしてその(アクセスする側の)一つに、完全に別のインスタンスの
クラスのある関数の中で

        {
        //
        m_pHukidashiDialogBar->SetComment("それでは開始します。よろしいですか?);
        
        //〜〜ここからコードA
        //実時間のかかり、ユーザー入力待ちなどもある処理コード

        m_pHukidashiDialogBar->SetComment("●●終了しました。○○も行いますか?");

        //ここからコードB
        //実時間のかかり、ユーザー入力待ちなどもある処理コード
        //

        m_pHukidashiDialogBar->SetComment("全て終了しました。他にも行いますか?");
        }

のように、一つの関数の中にいろいろ内容を変えて、SetComment(comment)を呼び出して
も、実際に動かしてみると一番最後の「全て終了しました。他にも行いますか」がずっと表示された
状態のまま(に見えるの)です。

この件については、前述の別スレの方の質問を参考に「UpdateWindow()を呼ぶ」ことで、
(一瞬で全て流れてしまいますが)、表示自体は出来るようになりました

そこであとは、これを読みやすいタイミングに制御することのみが問題となりました。

もともと、「エディットボックスに表示させるメッセージを一定時間おきにゆっくり
表示させる」という仕様として考えていろいろ思いつく方法を試したのですが
Sleep()のような簡単な方法では問題があり分かりませんでした。

ただ、いざ雰囲気を実現させてみると、勝手に「ゆっくり」と実時間待機させるよりは
ダイアログをモーダルにして、キーボードを連打すれば、
「とばしたい時はガンガンメッセージを進む」ことが出来る仕様の方が
何かと使い安いということが分かったので
前述のモーダルダイアログの方法でいきたいと思います

エディットボックスを流れるメッセージの実時間的タイミングを制御する方法については
研究課題として宿題にしたいと思います

KING・王 さん  PATIOさん
分かりにくい質問に貴重なレスを本当にありがとうございました
とても参考になり勉強になりました。精進したいと思います


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加