none
Dialogで得た変数を ChildViewの変数に渡す RRS feed

  • 質問

  • WindowsXpVC6.0 C++ MFC 利用
    以下のような コードがあります 必要な情報がないかもしれません。ご指摘くだされば おくります
    そので m_SwellMode ( = 3)の数値がおくりわたされないのです


    CParameterDlg.h
    class CParameterDlg : public CDialog
    {
    // Attributes
    public:
     
    // 2009/10/09 ColorDialogInEnglish 保持している色
    void SetColor(COLORREF color)
    {
    m_Color = color;
    if(::IsWindow(m_hWnd)) RedrawWindow();
    }
    COLORREF GetColor() const { return m_Color; }
    // 2009/10/09 ColorEnglish 

    // nagata カラ値を送りわたしのため
    void SetColorG(COLORREF color)
    {
    m_GroundColor = color;  // nagata 受けわたしのため
    m_SwellMode = 3;
    }

    そして
    CParameterDlg.cc で
    //2009/10/9  
    void CParameterDlg::OnBtn1Gcolor() 
    {
    // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
    //MessageBox(_T("ParameterDialog で GroundColorが押されました"));

    //+{ 以後英語化で 追加
    COLORREF crSelected; // 選択された色
    COLORREF crFirst; // 初期色

    crFirst = m_Color; // 初期選択色の設定
    // カスタムカラー配列を最初から独自指定する場合
    static DWORD dwCustomColor[16];
    static int first = 1;
    // 初期カスタムカラーの設定(最初の1回だけ実行)
    if(first == 1){
    for(int i=0; i < 16 ; i++){
    // 全部白から始める場合
    dwCustomColor[i] = RGB(255,255,255);
    // 肌色系の階のカスタムカラー配列にする場合
    //dwCustomColor[i] = RGB(255, 150+ i*5, 100 + i* 5);
    }
    first =2;
    }
    // カスタムカラー配列を独自指定して呼び出し
    if( ColorDlg( this->m_hWnd, &crSelected, crFirst ,TRUE, dwCustomColor ) ){
    // 選択された色をcrSelectedから受け取ります。
    SetColorG(crSelected); //m_GroundColor = crSelected;
    }
    //}+
    }

    としています。 結果
    SetColorG(crSelected);
    での色値の送り渡しはChildView.ccで 正常に行くのですが
    m_SwellMode = 3; は
    ChildViewに送られません。
    元々は m_SwellMode 数値は同じDialogで 入力m_SwellMode  アイテムとして定義されています。
    そこで 3を入力すると 希望の状態になるのですが
    これをColorDialogの読み出しと連動させて 優先的にこの場合は=3としたいのです。
    どんな風にすれば良いでしょうか?

    なお、
    void CParameterDlg::DoDataExchange(CDataExchange* pDX)
    {
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CParameterDlg)
    // メモ - ClassWizard はこの位置にマッピング用のマクロを追加または削除します。
    DDX_Text(pDX, IDC_KOMASIZE, m_KomaSize);
    DDX_Text(pDX, IDC_SWELLMODE, m_SwellMode);
    //}}AFX_DATA_MAP
    }

    2009年10月13日 12:49

回答

  • SetColorG(crSelected);
    での色値の送り渡しはChildView.ccで 正常に行くのですが
    m_SwellMode = 3; 
    はChildViewに送られません。
    「正常に行く」側は、なぜうまくいくのか調べてください。
    そして、「送られない」側との差を比較してください。

    コードでの差を見つけて、なぜ、動きが違うようになっているのかを考えましょう。


    最近のご質問から、MFC プログラミングへの理解が足りないことを伺わせます。
    1つ1つ聞くのは結構ですが、答えを得るだけで満足せず、なぜそうなるのか、どうやって調べたら分かるのか等、今後に活きる聞き方をしてください。
    そうでないと、ずっと聞き続けるハメになりますし、他人にプログラムを作ってもらっているのとあまり差がありません。(自分一人で作ったとは言えない)


    解決した場合は、参考になった返信に「回答としてマーク」のボタンを利用して、回答に設定しましょう(複数に設定できます)。
    2009年10月13日 14:11
    モデレータ
  • えーと。
    既に何度も書いているので、そろそろ耳にタコが出来ていると思うのですが。
    ベテランとか何とかと言うよりもC++言語の知識がほぼ無いのと同じなのではないかと
    思うのですが、当たっていますか?

    今回の質問が出てくると言う事は、C++言語の中のクラスに関する概念が
    理解できていないことを意味します。
    で、VisualStdioでVC++で開発する為には、C++言語の知識が「必須」です。
    これが無いとコーディングできないのです。

    なので、クラスと言うものについてしっかり勉強し直してください。
    そうしないとこれから先も同じことの繰り返しになります。

    解決した時は、参考になったレスポンスの所にある[回答としてマーク]ボタンをクリックしてスレッドを締めましょう。
    2009年10月14日 5:00
  • SetColorG(crSelected);
    での色値の送り渡しはChildView.ccで 正常に行くのですが
    m_SwellMode = 3; は
    ChildViewに送られません。
    元々は m_SwellMode 数値は同じDialogで 入力m_SwellMode  アイテムとして定義されています。
    そこで 3を入力すると 希望の状態になるのですが
    これをColorDialogの読み出しと連動させて 優先的にこの場合は=3としたいのです。
    どんな風にすれば良いでしょうか?
    「ChildViewに送られません。」というあたりがよくわからないのですが、
    m_SwellModeに値を入れても、UpdateData(FALSE); を呼び出さなければ、
    エディットコントロールに値が反映されないのでは?

    void SetColorG(COLORREF color)
    {
      UpdateData();   // コントロールの値を変数に反映
      m_GroundColor = color;  // nagata 受けわたしのため
      m_SwellMode = 3;
      UpdateData(FALSE);  // m_SwellModeの値をコントロールに反映
    }
    

    2009年10月15日 0:56
  • 私が書いたのは、CParameterDlg::SetColorG()でUpdateData()を呼び出せば
    CParameterDlg::m_SwellModeの値をコントロールに反映できるのでは? ということであって、
    CColorPickerButtonでの話ではありません。

    なんだか、だんだんひどい状況になってきているような気がします。

    以下のテクニカルノートを見て、まずはDDXについて理解してください。
    テクニカル ノート 26: DDX ルーチンおよび DDV ルーチン (MFC)
     
    理解するとわかると思いますが、
    CButton派生クラスのUpdateData() を呼び出したところで何も起きません。
    2009年10月15日 8:18
  • 類推の推察がまちがっていました。 で 改めて 現状でのChildViewにColorDialogを読み出して 戻り値を得たという 数値を送る方法をおしえてください

    これは予想ですが、たぶん。

    CColorPickerButtonはON_CONTROL_REFLECT()を使って、CColorPickerButton自身がBN_CLICKEDを受け取っている。
    そのため、CParameterDlgのBN_CLICKEDのハンドラが呼び出されない。
    CColorPickerButtonは自分自身で色を変更するから、見た目には変更されたように見えるが、
    CParameterDlgには反映されていないということなのでは?

    試しにCParameterDlgのBN_CLICKEDのハンドラにブレイクポイントを仕掛けてみて、来るかどうか見てみては?

    CParameterDlgにもBN_CLICKEDを送ってほしいということであれば、
    CColorPickerButtonのON_CONTROL_REFLECT()をON_CONTROL_REFLECT_EX()に変更して、
    void CColorPickerButton::OnClicked() を
    BOOL CColorPickerButton::OnClicked(UINT nID) に変える。(ヘッダの宣言も)
    その上で、return FALSE; として FALSE を返すといいです。
    2009年10月15日 9:38
  • えーと、提示されているソースを見るとかなりぐちゃぐちゃな状態になっているような気がします。

    CColorPickerButtonの中でUpdateDataと言うのも変な話ですし。
    ボタンクラスであってダイアログではないのですよね?
    ボタンクラスが他のコントロールを持っているのでしょうか?
    一般的なつくりならボタンクラスを派生させてその中でダイアログを呼ぶと言うようなことは
    しないと思いますし、その事が反って状況を混乱させているような気がします。

    コントロールの値を受け取るように設定された変数はUpdateDataが呼ばれると
    TRUEで取り込み、FALSEで表示に行きますから、そういうつもりでないなら
    コントロールに関連付けた変数ではなくて単なる変数を追加した方が良いと思います。
    その数値を画面からも入力するのであれば良いのですけれど、
    それならば、受け取った値を画面にも反映しておかないと話がおかしくなります。

    もはや全体像が見えない状態になっていて色んな所のバグが関連しあって
    うまく行かない状態になっていそうです。
    最下層からひとつずつ片付けていかないと辻褄が合わないかもしれません。

    解決した時は、参考になったレスポンスの所にある[回答としてマーク]ボタンをクリックしてスレッドを締めましょう。
    2009年10月15日 9:39

すべての返信

  • SetColorG(crSelected);
    での色値の送り渡しはChildView.ccで 正常に行くのですが
    m_SwellMode = 3; 
    はChildViewに送られません。
    「正常に行く」側は、なぜうまくいくのか調べてください。
    そして、「送られない」側との差を比較してください。

    コードでの差を見つけて、なぜ、動きが違うようになっているのかを考えましょう。


    最近のご質問から、MFC プログラミングへの理解が足りないことを伺わせます。
    1つ1つ聞くのは結構ですが、答えを得るだけで満足せず、なぜそうなるのか、どうやって調べたら分かるのか等、今後に活きる聞き方をしてください。
    そうでないと、ずっと聞き続けるハメになりますし、他人にプログラムを作ってもらっているのとあまり差がありません。(自分一人で作ったとは言えない)


    解決した場合は、参考になった返信に「回答としてマーク」のボタンを利用して、回答に設定しましょう(複数に設定できます)。
    2009年10月13日 14:11
    モデレータ
  • ベテランの方には ”なぜ”が すぐわかるかと おもいますが、
    その差 目の付け所がわからないのです。
    老眼のしょぼ目をさらにして そうとう 見て いろいろ比較しているのですが
    思いあまっての 質問です。
    どうか ご指導を やや 具体的に深めて いただけるように伏してお願いします

    2009年10月13日 21:43
  • えーと。
    既に何度も書いているので、そろそろ耳にタコが出来ていると思うのですが。
    ベテランとか何とかと言うよりもC++言語の知識がほぼ無いのと同じなのではないかと
    思うのですが、当たっていますか?

    今回の質問が出てくると言う事は、C++言語の中のクラスに関する概念が
    理解できていないことを意味します。
    で、VisualStdioでVC++で開発する為には、C++言語の知識が「必須」です。
    これが無いとコーディングできないのです。

    なので、クラスと言うものについてしっかり勉強し直してください。
    そうしないとこれから先も同じことの繰り返しになります。

    解決した時は、参考になったレスポンスの所にある[回答としてマーク]ボタンをクリックしてスレッドを締めましょう。
    2009年10月14日 5:00
  • SetColorG(crSelected);
    での色値の送り渡しはChildView.ccで 正常に行くのですが
    m_SwellMode = 3; は
    ChildViewに送られません。
    元々は m_SwellMode 数値は同じDialogで 入力m_SwellMode  アイテムとして定義されています。
    そこで 3を入力すると 希望の状態になるのですが
    これをColorDialogの読み出しと連動させて 優先的にこの場合は=3としたいのです。
    どんな風にすれば良いでしょうか?
    「ChildViewに送られません。」というあたりがよくわからないのですが、
    m_SwellModeに値を入れても、UpdateData(FALSE); を呼び出さなければ、
    エディットコントロールに値が反映されないのでは?

    void SetColorG(COLORREF color)
    {
      UpdateData();   // コントロールの値を変数に反映
      m_GroundColor = color;  // nagata 受けわたしのため
      m_SwellMode = 3;
      UpdateData(FALSE);  // m_SwellModeの値をコントロールに反映
    }
    

    2009年10月15日 0:56
  • 具体的なコードまで頂きありがとうございます。
    まず 色値やModeIndex値をChildViewに送るといいますのは
    CChildView で

    m_grdColor = RGB(150, 100, 0);
     if( m_swell == 3 ) { 
    m_grdColor = m_paramDlg.m_BtnGColor.GetColor(); //色値を受け取る

    CMemDC memDC;
    memDC.FillSolidRect(0, 0, m_imageSiH, m_imageSiV, m_grdColor); //ground color

    ということです。このようなことをここではなんというでしょうか?

    それで先の説明は現状のプログラムの前の状態であって
    今は Paramerter Dialog で色つきボタン(m_BtnGColor)押すことでColorDialogを呼び出して
    その色値は上のような コードでChildveiwで送り渡しをしています。
    それに 新たに ボタンの領域にその戻り色値の色が着色されます。

    で void SetColorG(COLORREF color){}が無くなっています。
    代わりには

    ParameterDlg.h に
    // Attributes
    public:
     
    CColorPickerButton m_colorPiButton;   // transfer DATA from ParameterDialog

    // ダイアログ データ //{{AFX_DATA(CParameterDlg) enum { IDD = IDD_ParameterDIALOG };

    // 2009/10/14 色つきボタンにする
    CColorPickerButton m_BtnGColor; //changed from、 CButton m_BtnGColor;
    int m_SwellMode;

    -----------------------------
    ParameterDlg.cc
    では
    //m_BtnGColord に なにもしていません。
    void CParameterDlg::OnChangeEdit1() // for write the changed variable
    {
    // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
    UpdateData(TRUE);
    //以下 本Dialog内で計算結果を直に表示する
    m_KomaSize = m_ImageSizWidth/m_KomaX_N;
    m_M_Max = 1850/m_KomaX_N; // max50x37 as m_koM[]
    //.Format("%4d", 1850/m_KomaX_N); //'.Format' : 左側がクラス、構造体、共用体ではありません。
    m_SwellMode = m_colorPiButton.m_SwellManual; // これを追加した 。 m_swell =0 day color, =1 for Swelling paper for braille, =2 night color 
    UpdateData(FALSE); // set the final action
    }

    ーーーーーーーーーーーーー
    ColorPickerButton.h
    class CColorPickerButton : public CButton { public: int m_SwellManual; //色モード index

    m_SwellManual = 0; //初期値はここでよいか?
    void SetColor(COLORREF color)
    {
    UpdateData();   // コントロールの値を変数に反映
    m_Color = color;
    m_SwellManual = 3;
    UpdateData(FALSE);  // m_SwellModeの値をコントロールに反映
    if(::IsWindow(m_hWnd)) RedrawWindow();
    }
    がありますので ここで 助言のように変数を入れましたがなにもかわりません。

    ーーーーーーーーーーーーーーーーーーーーーーー
    ColorPickerButton.cpp で

    void CColorPickerButton::OnClicked() 
    {

    COLORREF crSelected; // 選択された色

    // カスタムカラー配列を独自指定して呼び出し
    if( ColorDlg( this->m_hWnd, &crSelected, crFirst ,TRUE, dwCustomColor ) ){
    // 選択された色をcrSelectedから受け取ります。
    SetColor(crSelected);
    }

    となっています。

    情報が不足していましたら おくりますので 言ってください。
    以上な状態ですが
    2009年10月15日 7:52
  • 以上な状態ですが よろしく ご指導ください

    2009年10月15日 7:53
  • 私が書いたのは、CParameterDlg::SetColorG()でUpdateData()を呼び出せば
    CParameterDlg::m_SwellModeの値をコントロールに反映できるのでは? ということであって、
    CColorPickerButtonでの話ではありません。

    なんだか、だんだんひどい状況になってきているような気がします。

    以下のテクニカルノートを見て、まずはDDXについて理解してください。
    テクニカル ノート 26: DDX ルーチンおよび DDV ルーチン (MFC)
     
    理解するとわかると思いますが、
    CButton派生クラスのUpdateData() を呼び出したところで何も起きません。
    2009年10月15日 8:18
  • 私が書いたのは、CParameterDlg::SetColorG()でUpdateData()を呼び出せば
    CParameterDlg::m_SwellModeの値をコントロールに反映できるのでは? ということであって、
    CColorPickerButtonでの話ではありません。
    それは承知していますが おなじようにするかと推察して 同様にしたものです。 まちがった推察でした。



    なんだか、だんだんひどい状況になってきているような気がします。
    いえ、いえ、小生としては すごく機能がまし 便利になり よろこんでいます
    以下のテクニカルノートを見て、まずはDDXについて理解してください。
    テクニカル ノート 26: DDX ルーチンおよび DDV ルーチン (MFC)
     
    理解するとわかると思いますが、

    CButton派生クラスのUpdateData() を呼び出したところで何も起きません。
    類推の推察がまちがっていました。 で 改めて 現状でのChildViewにColorDialogを読み出して 戻り値を得たという 数値を
    送る方法をおしえてください

    2009年10月15日 8:34
  • 類推の推察がまちがっていました。 で 改めて 現状でのChildViewにColorDialogを読み出して 戻り値を得たという 数値を送る方法をおしえてください

    これは予想ですが、たぶん。

    CColorPickerButtonはON_CONTROL_REFLECT()を使って、CColorPickerButton自身がBN_CLICKEDを受け取っている。
    そのため、CParameterDlgのBN_CLICKEDのハンドラが呼び出されない。
    CColorPickerButtonは自分自身で色を変更するから、見た目には変更されたように見えるが、
    CParameterDlgには反映されていないということなのでは?

    試しにCParameterDlgのBN_CLICKEDのハンドラにブレイクポイントを仕掛けてみて、来るかどうか見てみては?

    CParameterDlgにもBN_CLICKEDを送ってほしいということであれば、
    CColorPickerButtonのON_CONTROL_REFLECT()をON_CONTROL_REFLECT_EX()に変更して、
    void CColorPickerButton::OnClicked() を
    BOOL CColorPickerButton::OnClicked(UINT nID) に変える。(ヘッダの宣言も)
    その上で、return FALSE; として FALSE を返すといいです。
    2009年10月15日 9:38
  • えーと、提示されているソースを見るとかなりぐちゃぐちゃな状態になっているような気がします。

    CColorPickerButtonの中でUpdateDataと言うのも変な話ですし。
    ボタンクラスであってダイアログではないのですよね?
    ボタンクラスが他のコントロールを持っているのでしょうか?
    一般的なつくりならボタンクラスを派生させてその中でダイアログを呼ぶと言うようなことは
    しないと思いますし、その事が反って状況を混乱させているような気がします。

    コントロールの値を受け取るように設定された変数はUpdateDataが呼ばれると
    TRUEで取り込み、FALSEで表示に行きますから、そういうつもりでないなら
    コントロールに関連付けた変数ではなくて単なる変数を追加した方が良いと思います。
    その数値を画面からも入力するのであれば良いのですけれど、
    それならば、受け取った値を画面にも反映しておかないと話がおかしくなります。

    もはや全体像が見えない状態になっていて色んな所のバグが関連しあって
    うまく行かない状態になっていそうです。
    最下層からひとつずつ片付けていかないと辻褄が合わないかもしれません。

    解決した時は、参考になったレスポンスの所にある[回答としてマーク]ボタンをクリックしてスレッドを締めましょう。
    2009年10月15日 9:39
  • 小生が希望したのは CParameterDlg::SetColorG() で m_swellMode=3
    を設定することでした。
    しかし 見直すと そのSetColorG() は CColorPickerButtonを 組み込んだときに 無効になっていました。
    それで 助言頂いたコードでは 効かなかったのです。
    まず コンボボックスでm_SwellMode 数値獲得を実現し、それで 既に実現していたCChildViewへ送り渡しができました。

    そこで その後 CColorPickerButtonが働いたときに  コンボボックスでの数値を強制的に変える(_SwellMode=3)
    とすることに やり方を変えて
    そのCColorPickerButton において

    void CColorPickerButton::OnClicked()
     { 
    CParameterDlg* pParentDlg = (CParameterDlg*)GetParent();
    pParentDlg->UpdateData(TRUE);
    pParentDlg->m_SwellMode = 3;
    pParentDlg->UpdateData(FALSE);
    と教えて頂き これで コンボボックスの表示と 同時に CChildViewへの引渡しも解決しました。

    本当に ありがとうございました。

    2009年10月23日 10:29
  • こんにちは、フォーラムオペレーターの高橋春樹です。

    Azuleanさん、PATIOさん、Atsushi777さん、いつもお世話になっております。
    沢山のアドバイスありがとうございました。

    Shonan Hannyaさん、こんにちは。
    MSDNフォーラムのご利用ありがとうございます。

    問題が解決したようなので、大丈夫と思いますが、
    皆様からのアドバイスに、回答マークを付けさせてもらいました。

    問題が解決した場合、有用と思われた皆様からの投稿に、
    お礼も兼ねて、回答マークを付けて頂きたいと思います。
    ご理解、ご協力の程、よろしくお願いします。


    マイクロソフト株式会社 フォーラム オペレーター 高橋春樹
    2009年12月17日 9:23