• ベストアンサー

変数の代入について

ダイアログベースで、ダイアログ1からダイアログ2を開きダイアログ1のエディットボックスのデータをダイアログ2に表示する下記コードを教わりました。 変更後のようにしても問題ないと思いましたが、'dlg' は定義されていない識別子です。とエラーが出ます。 どうしてなのかお教えていただきたいのですが、 よろしくお願いします。 <変更前> CSubDlg dlg2; dlg2.m_strText = strText; dlg2.DoModal(); <変更後> void CSubDlg::OnPaint() { m_strText = dlg.strText; ちなみにdlgはウィザードが作ったコードで、 CMainDlg dlg; m_pMainWnd = &dlg; int nResponse = dlg.DoModal(); ダイアログ1のことだと思うのですが。。。。 ************************** メインダイアログとしてCMainDlgを例にしますが、かなり割愛します。 このダイアログには、Editが貼り付けられているとします。Editコントロールに割り当てたIDをIDC_EDIT_INPUTだと仮定します。 DDXとかのデータ変換を使う方法もありますが、ここでは単にデータを取得します。 // // OKボタンが押された時の処理 // void CMainDlg::OnOK() { // データの取得 CString strText; GetDlgItemText(IDC_EDIT_INPUT, strText); CSubDlg dlg2; dlg2.m_strText = strText; dlg2.DoModal(); } class CSubDlg : pbulic CDialog { public: CString m_strText; // 親から渡される文字列を格納する変数 ・ ・ ・ ・ ・ }; あとは、CSubDlgのOnPaintでテキストを描画します。 void CSubDlg::OnPaint() { // テキストをクライアント領域の中央に描画 CRect rect; GetClientRect(rect); CPaintDC dc(this); dc.TextOut(m_strText, rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); }

質問者が選んだベストアンサー

  • ベストアンサー
  • darksky
  • ベストアンサー率66% (38/57)
回答No.3

私が回答した質問なので、コメントしておきます。 以下のコードをよくチェックするとわかると思いますが、 ・CSubDlgクラスには、publicな変数であるm_strTextがある。 ・CMainDlgクラスのOnOK関数は、CSubDlgクラスのインスタンスを生成し、m_strText変数に文字列をセットしている。 ・CSubDlgクラスのインスタンスであるdlg2をモーダルダイアログとして実行している。 void CMainDlg::OnOK() { // データの取得 CString strText; GetDlgItemText(IDC_EDIT_INPUT, strText); CSubDlg dlg2; dlg2.m_strText = strText; dlg2.DoModal(); } CSubDlgのコードを以下のように変更されたようですね。 >このコードを >void CSubDlg::OnPaint() >{ >m_strText = dlg.strText; ここで問題なのは、CSubDlgクラスのインスタンスであるdlg2は、dlgの存在をしらないということです。 また、m_strTextは、CSubDlgクラスのメンバ変数ですが、dlg.strTextのstrTextはCMainDlg::OnOK関数の自動変数(Auto変数)です。 いろいろと確認をされているのだと思いますが、CSubDlgクラスは、m_strTextにセットされた文字列を処理するのであって、セットするのが誰かを意識しないプログラムにした方がいいと思います。

VitaminBB
質問者

お礼

回答ありがとうございます。 後は自分でじっくり考えてみます。

その他の回答 (2)

  • gimmick
  • ベストアンサー率49% (134/270)
回答No.2

おそらくdlgはアプリケーションクラスのInitInstance()で定義されているローカルオブジェクトだと思います。ローカルオブジェクトですから、外部から見えないのは当然です。dlgをグローバルオブジェクトにすれば > void CSubDlg::OnPaint() > { > m_strText = dlg.strText; のような方法も可能です。もっとも、こんな修正をするより、変更前の方法の方が良いと思います。

VitaminBB
質問者

お礼

回答ありがとうございます。 >ローカルオブジェクトですから、外部から見えないのは当然です。 言われていることは分かりますが、心情的にdlgさんはdlg2さんをしっているのに、どうして逆は成立しないのって思ってしまいます。

  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.1

><変更後> >void CSubDlg::OnPaint() >{ >m_strText = dlg.strText; m_strText = this->strText; もしくは、 m_strText = strText; ですね。 クラスとインスタンスの関係は理解していますか?

VitaminBB
質問者

お礼

回答ありがとうございます。 >m_strText = this->strText; >もしくは、 >m_strText = strText; どちらも、'strText' が定義されていない識別子です。とエラーが出ました。

関連するQ&A

  • 変数アクセス(MFC)

    クラス別の変数間のアクセスについてよくわかりません。 【CADlg.cpp】 void CADlg::OnOK() { CB bdlg; CString str; m_ed.GetwindowText(str); Astr=&str; cdlg.DoModal(); CDialog::OnOK(); } 【CADlg.h】 public: CString *Astr; 【CB.cpp】 void CB::OnOK() { CStr CADlg dlg; dlg.Astr=&bstr;; MessageBox(bstr); CDialog::OnOK(); } 【CB.h】 CString bstr; 中身見てもちゃんと移ってないようです。 どうすればちゃんとできますでしょうか?

  • ダイアログと変数

    はじめまして。VC++ Ver.6を使ってダイアログベースのアプリを作成しようと思っています。 ダイアログ上に [IDC_BOX1] [IDC_BOX2] [IDC_BOX3] と3つ入力ボックスを作ったのですが、 上から 「m_box[0]」「m_box[1]」「m_box[2]」という具合に 変数名をつけたいのですが、どうやればいいのかよくわかりません。 結果として hogehoge.h のダイアログデータの宣言部分に 「CString m_box[3]」と表示させるようにしたいのですが、 ClassWizardなどで、どういう指定をすればこのようになるのでしょうか?? よろしくお願いします。

  • メインダイアログのデータをウィンドウに反映させたい

    メインダイアログからウィンドウを生成しています ダイアログの値を GetDlgItemText()関数で取るまではいいのですが それから、値をウィンドウに反映できません。 メンバ値を遣うと思うのですが、どうすればいいのでしょうか? プログラムを添付します ///////////////////////////////////////////////////////// // dlg.rc #include "resource.h" #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// // // Dialog // MYDLG DIALOG DISCARDABLE 0, 0, 134, 80 STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "ダイアログからウィンドウ" FONT 9, "MS Pゴシック" BEGIN DEFPUSHBUTTON "OK",IDOK,15,55,50,14 PUSHBUTTON "キャンセル",IDCANCEL,65,55,50,14 EDITTEXT IDC_EDIT1,15,10,100,35,ES_AUTOHSCROLL END ////////////////////////////////////////////////// // resource.h #define IDC_EDIT1 1000 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 101 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1000 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif //////////////////////////////////////////////////////// // dlg.h //アプリケーション class CMyApp : public CWinApp { public: virtual BOOL InitInstance(); }; //ウィンドウ class CMyWindow : public CFrameWnd { private: CString MyMainStr; protected: afx_msg void OnPaint(); DECLARE_MESSAGE_MAP() }; //メインダイアログ class CMyDlg : public CDialog { public: CString m_MyStr; CMyDlg(CWnd *pParentWnd=NULL); CMyWindow* m_pMyWnd; protected: virtual void OnOK(); virtual void OnCancel(); }; ///////////////////////////////////////////// // DlgWnd.cpp #include <afxwin.h> #include <afxdlgs.h> #include <string.h> #include "dlg.h" #include "resource.h" CMyApp myApp; BOOL CMyApp::InitInstance(){ m_pMainWnd = new CMyDlg; m_pMainWnd ->ShowWindow(m_nCmdShow); m_pMainWnd ->UpdateWindow(); return TRUE; } CMyDlg::CMyDlg(CWnd* pParent /*=NULL*/):m_pMyWnd(NULL) //イニシャライザでポインタをNULLに初期化 { Create("MYDLG"); } BEGIN_MESSAGE_MAP(CMyWindow, CFrameWnd) ON_WM_PAINT() END_MESSAGE_MAP() void CMyDlg::OnOK() { GetDlgItemText(IDC_EDIT1, m_MyStr); const RECT rc = {10, 10, 320, 240}; m_pMyWnd = new CMyWindow(); m_pMyWnd->Create( NULL, "ダイアログから起動", WS_OVERLAPPEDWINDOW, rc, this,NULL); m_pMyWnd->ShowWindow(SW_SHOW); } void CMyDlg::OnCancel() { DestroyWindow(); } void CMyWindow::OnPaint() { CPaintDC dc(this); CMyDlg dlg; MyMainStr = dlg.m_MyStr; dc.TextOut(0, 0, MyMainStr); } よろしく御願いします

  • 親ウィンドウの変数の変更

    以下のようにクライアント領域をダブルクリックして、モーダルダイアログを表示し ダイアログからCPPPViewのメンバ変数flgを変更しましたが、 CPPPView内では変更結果が反映させていません。 どうしてなのでしょうか? またどうすれば変更されるようになりますか? void CPPPView::OnLButtonDblClk(UINT nFlags, CPoint point) {    CHenkouDlg dlg;    dlg.DoModal();           //  ここではflgが99になっていない    CView::OnLButtonDblClk(nFlags, point); } void CHenkouDlg::OnOK() {    CPPPView* my = (CPPPView*)GetParent();    my->flg=99;    CDialog::OnOK(); }

  • VC++ スレッドからDoModalへ

    いまさらですがVC++6.0でつまづいています MFCです AdlgクラスのダイアログのOnButtonA() からXXXスレッドを起動し そのXXXスレッドではcountを+1しつづけます。 そして別のダイアログ DDD10をDoModalで起動しそのDDD10 内のTextBoxの値にcount値を反映させて表示しようとしました 下記ソース内のAfxMessageBox(tmp);ではcount値は 更新されますが DDD10ダイアログ内のテキストボックス の値が変更されません m_gui_xfr_totalはDDD10のテキストボックスにつけた メンバー名です どなたかアドバイスをお願いします void ADlg::OnButtonA() { DDD10 dlg10 ; CWinThread *pThread = AfxBeginThread(XXX_thread_entry,(LPVOID *)this); dlg10.DoModal() ; } void XXX_Thread(){ CString tmp; unsigned int count=0; DDD10 dlg10; while(1){ count++; tmp.Format("%d",count); dlg10.m_gui_xfr_total.Format(tmp); AfxMessageBox(tmp); Sleep(1000); } }

  • ダイアログの領域全てをエデイトボックスが占めるプログラム

    お世話になります。 現在ダイアログにエディトボックス(IDC_EDIT1)を1つおいて、このエディトボックスがダイアログの全体を占める様なプログラムを作成しています。 以下のようなプログラムでは、サイズ変更をした時に初めてダイアログ内にエディトボックスが動的に占めるのですが、これをプログラムを起動したときから既にエディトボックスがダイアログの全体を占めている状態にしたいのですが、どのようにすればよいでしょうか? 開発環境はVC++ 6.0 MFC WindXPです。 ご教示よろしくお願いします。 プログラム: void CxxxDlg::OnSize(UINT nType, int cx, int cy) { CDialog::OnSize(nType, cx, cy); // TODO: この位置にメッセージ ハンドラ用のコードを追加してください CRect rect; CWnd* pEdit = GetDlgItem( IDC_EDIT1 ); GetClientRect(&rect); if( pEdit != NULL ) { rect=CRect(0,0,cx,cy); pEdit->MoveWindow( &rect, TRUE ); } }

  • アドレス

    利用環境はMFCのVC++6.0です。 void CTestDlg::OnDblclkList(NMHDR* pNMHDR, LRESULT* pResult) { CString str; int num=m_list.GetSelectionMark(); str=m_list.GetItemText(num,0); if(Tstr!=NULL){ *Tstr=str; } CTest2 dlg2; dlg2.DoModal(); ・ ・ ・ } ヘッダ:CString *Tstr; とすると*Tstr=str;がおかしいらしく、アドレスがきちんと渡っていないようです。Tstr!=NULLの所ではアドレスは0xcccccc"???"となっていて if文は意味をなしません。 値を受け取るダイアログでは CTest Tdlg; CString aa; Tdlg.Tstr=&aa; MessageBox(aa); としています。 TestDlgのリストビューの内容をうけとりそれを新しくダイアログを作って そちらに移すプログラムです。

  • beginthread 引数

    #include <windows.h> #include <process.h> class CPti4Dlg::public CDialog { public: void test(void*); } void CPti4Dlg::test(void *) {    long ret;    float data[4]; ret = PtMultiInputEx(m_Id, 4, data); if(ret != 0) { ErrorHandling("PtMultiInputEx", ret); if(ret != 20102){ return; } } m_Edit_Ch0 = data[0]; m_Edit_Ch1 = data[1]; m_Edit_Ch2 = data[2]; m_Edit_Ch3 = data[3]; UpdateData(FALSE); } void CPti4Dlg::OnButtonInput() { _beginthread(&CPti4Dlg::test,0,NULL); m_Edit_Ret.SetWindowText("入力処理:正常終了"); } error C2664: '_beginthread' : 1 番目の引数を 'void (__thiscall CPti4Dlg::* )(void *)' から 'void (__cdecl *)(void *)' に変換できません。(新しい機能 ; ヘルプを参照) ------------------------------------------------------------------------------ これ問題全然ないです。 void CPti4Dlg::OnButtonInput() {    long ret;    float data[4]; ret = PtMultiInputEx(m_Id, 4, data); if(ret != 0) { ErrorHandling("PtMultiInputEx", ret); if(ret != 20102){ return; } } m_Edit_Ch0 = data[0]; m_Edit_Ch1 = data[1]; m_Edit_Ch2 = data[2]; m_Edit_Ch3 = data[3]; UpdateData(FALSE); m_Edit_Ret.SetWindowText("入力処理:正常終了"); }

  • 閉じてしまったダイアログのエディットボックスへの書き込み禁止方法

    VC++ 6.0 MFC ダイアログベースです。 メインダイアログ画面で、ボタンを押下した時に、別ダイアログ(子ダイアログ)が呼び出されて、 その子ダイアログ内では、ワーカースレッドを使用して処理を行い、 処理結果をエディットボックスに表示させています。 子ダイアログを閉じる時に、WaitForSingleObject を使って、スレッドを完全に終了させてからダイアログを閉じるように しているのですが、スレッドの処理が、エディットボックスに書き込む時に閉じてしまうと、 スレッドがそこで止まってしまいスレッドが終了しません。 このような場合どうしたら良いのでしょうか? ・閉じるボタンが押されたら、エディットボックスに書き込まないようにすれば良いと思い、 (フラグを立てて試したのですが、フラグチェック後に閉じるが押されることがあり失敗) // スレッドの開始 m_Thread = AfxBeginThread(ThreadFunc, this);    // この時、子ダイアログを閉じてしまうと // INFINITEなので、ずっと止まってしまいます。 CString data = "処理結果"; case 0: m_M0edit.SetWindowText(data); break; case 1: m_M1edit.SetWindowText(data); break; case 2: m_M2edit.SetWindowText(data); break; ・ ・ ・ ・ // 子ダイアログを閉じる時に呼び出されます。 // スレッドでの処理が完全に終わるのを待ちます。 afx_msg void CSelecting_Dlg::OnClose() {   DWORD dwRet   dwRet = WaitForSingleObject(m_Thread->m_hThread, INFINITE);   EndDialog(0); } /***************/ 失敗談 /***************/ // スレッドの開始 m_Thread = AfxBeginThread(ThreadFunc, this);    // この時、子ダイアログを閉じてしまうと // INFINITEなので、ずっと止まってしまいます。 CString data = "処理結果"; if (m_openFlag == 1){ //フラグを見て書き込みするかチェックする。   switch (t){      case 0: m_M0edit.SetWindowText(data); break;      case 1: m_M1edit.SetWindowText(data); break;      case 2: m_M2edit.SetWindowText(data); break; ・ ・ ・ ・   } } // 子ダイアログを閉じる時に呼び出されます。 // スレッドでの処理が完全に終わるのを待ちます。 afx_msg void CSelecting_Dlg::OnClose() {   DWORD dwRet   m_openFlag = false; //閉じるボタンが押されたら フラグを降ろす。   dwRet = WaitForSingleObject(m_Thread->m_hThread, INFINITE);   EndDialog(0); }

  • 連続してダイアログを表示したい?

    VC++6.0を使用しています。 以下のようなコードでダイアログを連続して表示しようと思っています。1番目のダイアログを表示してOKボタンを押下後(このときこのダイアログは消えて)、2番目のダイアログを表示したいと思っているのですが2番目が表示できません。(1番目のところをコメントにすれば2番目は表示できます。)どうして2番目のダイアログが表示できないのでしょうか? // 1番目のダイアログ   CTest1Dlg dlg;   m_pMainWnd = &dlg;   int nResponse1 =dlg.DoModal(); // 2番目のダイアログ   CTest2Dlg dlg;   m_pMainWnd = &dlg;   int nResponse2 =dlg.DoModal(); //   if (nResponse1 == IDOK) {   :以下省略 これだけの情報でアドバイスができますでしょうか? すみません。よろしくお願い致します。

専門家に質問してみよう