先日はお世話になりました。
Super 初心者です。
また、分からないことが発生しました。
モードレスダイアログを表示するDLLを作成しています。
押されたボタンによって関数の戻り値を変えたいのですが、
どのようにすれば良いのか、全く分かりません。
VC++6.0で、MFCで作っています。
Dialog::Createで表示しています。
「なんの関数」の戻り値でしょう?
以下のようにしたいのです。
呼び出し元exe
(呼ぶ)↓ ↑(戻り値返す)
ダイアログを表示するDLLの関数
(表示)↓ ↑(ボタン押される)
モードレスダイアログ
分かりますでしょうか?
モードレスダイアログを表示するDLL関数の戻り値を
押されたボタンによって変えたいわけです。
モーダルなら簡単なんですが。
よろしくおねがいします。
モーダレスでしょ?
ダイアログを表示するDLLの関数
↑(ボタン押される)
モードレスダイアログ
はないのでは?
ダイアログを表示するDLLの関数
(表示)↓ ↑(表示しただけ)
モードレスダイアログ → exeに知らせたい
(ボタン押される)
では?
メッセージとかコールバック関数を使うか
押されたボタンをDLL側で記憶しておき
exeから時々問い合わすか・・・
ぐらいしか思いつきませんが (^_^;)
関数の戻り値を変えるのは無理だと思います。
何とか戻り値として、返すことはできないでしょうか?
やはり、難しいことなのでしょうか?
モードレスダイアログを同じ感覚でモードレスダイアログを捉えてはいけません。
モーダルダイアログを表示するCDialog::DoModal()と、モードレスダイアログを作る
CDialog::Create()の戻り値は全く意味合いが異なるのです。いや、意味合いだけでな
く、戻り値が戻ってくる(?)タイミングが全然違うのです。CDialog::Create()ではダイア
ログを作った時点で戻ってきてしまうのです。ユーザーがボタンを押すなどという時間的
余裕はありません。
ならばどうするか。それが?さんのアドバイスです。
いえ、CDialog::Create()の戻り値ではなく、
CDialog::Create()を使ってモードレスダイアログを表示するDLLの関数が、
ボタンに応じた戻り値を返したいわけです。
やっぱり、無理なんですかね・・・。
もういちどよく?さんのアドバイスを読んでください。
>押されたボタンをDLL側で記憶しておき
とあるではないですか。これをヒントにすればいい、というところに考えは至りません
か? どうもあなたのレスをみていると与えられたアドバイスをろくに咀嚼もせず安直に
「やはりムリなんですか?」と聞き返しているように見えます。なぜ「この1文の意味が分
からないのですが」程度の言い方ができないのでしょう?
>CDialog::Create()を使ってモードレスダイアログを表示するDLLの関数が、
>ボタンに応じた戻り値を返したいわけです。
こういう関数の存在は今初めて出てきたので、もう少し詳しく説明してください。この関
数はどういうタイミングでreturnするのですか?
申し訳ありません。
>これをヒントにすればいい、というところに
色々と事情がありまして、戻り値で返す方法が知りたいんです。
>こういう関数の存在は今初めて出てきたので、もう少し詳しく説明してください。この関
>数はどういうタイミングでreturnするのですか?
はじめから言ってるつもりなんですが、読み返してみると確かに
誤解を招く書き方だったと思います。申し訳ありません。
つまり私はモードレスダイアログを表示するDLLを作成しています。
そのDLLの関数を仮にButtonDlg()とします。
ButtonDlg()の中ではモードレスダイアログを表示します。
そしてそのモードレスダイアログ内の、あるボタンを押されたときに、
画面はそのまま表示しておいて、ButtonDlg()の戻り値として値を
返したいんです。
そもそも、こういうことが出来るのかどうかも私の知識では分かりません。
戻り値を返すという方法が出来ないことなのであれば、
一応、それで解決になります。(色々事情がありまして・・・)
始めに言っておかなかったのが良くなかったと思います。
申し訳ございません。
>色々と事情がありまして、戻り値で返す方法が知りたいんです。
ですから、?さんのアドバイスを基にすれば可能だ、というかそれが答えだ、といってる
んです。
>ButtonDlg()の中ではモードレスダイアログを表示します。
>そしてそのモードレスダイアログ内の、あるボタンを押されたときに、
>画面はそのまま表示しておいて、ButtonDlg()の戻り値として値を
>返したいんです。
いままでのあなたの説明から、そのDLLを使う側はこんなコーディング例になると考えます。
CSomething::DoSomething()
{
... // 何らかの前処理
nCheck = pDll->ButtonDlg(); // モードレスダイアログを開く
switch( nCheck ) // ButtonDlg()のリターン値により処理を分岐
...
}
ここでわからなくなるのは、
>あるボタンを押されたときに、画面はそのまま表示しておいて、
>ButtonDlg()の戻り値として値を返したいんです。
という部分です。「あるボタンが押されたときに画面を閉じないでおく」ということは、
「どれかのボタンがまた押される可能性がある」ということです。別のボタン(同じボタ
ンでもいいんでしょうが)が押されたタイミングで上の「リターン値により処理を分岐」
が何度でも実行される、というイメージで質問されているのでしょうか。だとしたら無理
な話です。「1回呼ばれたら1回だけリターン値を返す」、それが関数だからです。
# 最初に押されたボタンだけ解ればいいというのであれば、
# そのタイミングでButtonDlg()をリターンさせればいいだけです。
で、?さんのアドバイスに立ち返ります。
>メッセージとかコールバック関数を使うか
上記の関数はモードレスダイアログを開いたところまでで終わる様にし、その後の処理を
別関数にしておいて、DLLからのメッセージで動くようにする。もしくは「あるボタンが
押されたタイミング」で呼んでほしい関数へのポインタをDLLに渡しておいて、DLLはその
関数を呼ぶようにする。という解決法が考えられます。
>押されたボタンをDLL側で記憶しておき
>exeから時々問い合わすか・・・
ButtonDlg()はモードレスダイアログを開いた時点でリターンする、別に「最後に押され
たボタンは何か」を返す関数を用意して、exeからいつでも呼べるようにしておく。この
関数のリターン値が前回と違う値だったら何かのボタンが押されたのだ、と判断する。と
いう解決法が考えられます。
なぜリターン値にこだわるのか、どんな事情がおありになるのかは解りませんが、もし既
存のシステムの中の一部しか公開されていない状況で対処しなければならない、というこ
とであれば「DLLの改造だけで済む話とは思えない」というのが結論といえるでしょう。
呼び側にも仕様変更が必要になってくる話です。