从Dlg1到Dlg2的访问变量 [英] Access variable from Dlg1 to Dlg2

查看:72
本文介绍了从Dlg1到Dlg2的访问变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在dlg1(9个文件)上有9个浏览按钮,我必须传递给dlg2点击按钮事件。



 < span class =code-comment> //   MyTabControl.cpp  

MyTabCtrl :: MyTabCtrl()
{
m_DialogID [ 0 ] = IDD_DIALOG1;
m_DialogID [ 1 ] = IDD_DIALOG2;

m_Dialog [ 0 ] = new MyDlg1();
m_Dialog [ 1 ] = new MyDlg2();

m_nPageCount = 2 ;

}

MyTabCtrl :: ~MyTabCtrl()
{
}

void MyTabCtrl :: InitDialogs()
{
m_Dialog [ 0 ] - >创建(m_DialogID [ 0 ],的getParent());
m_Dialog [ 1 ] - >创建(m_DialogID [ 1 ],GetParent()) ;

}





  //   MyDlg.cpp  

MyDlg1 :: MyDlg1(CWnd * pParent / * = NULL * /
:CDialog(MyDlg1 :: IDD,pParent)
{
// {{AFX_DATA_INIT(MyDlg1)
// 注意:ClassWizard将在此处添加成员初始化
// }} AFX_DATA_INIT
// m_NumberOfEvents = 0;
m_SetUp = 0 ;
m_EdpCode = _T( );
}


void MyDlg1 :: DoDataExchange(CDataExchange * pDX)
{
CDialog的:的DoDataExchange(PDX);
DDX_CBString(pDX,IDC_EDP_CODE,m_EdpCode);
DDV_MaxChars(pDX,m_EdpCode, 40 );
DDX_Control(pDX,IDC_LIST1,m_Events);
DDX_Control(pDX,IDC_RADIO1,m_Radio1);

DDX_Control(pDX,IDC_RUN,m_Combo1);
DDX_Control(pDX,IDC_EDIT2,m_Edit2);
DDX_Control(pDX,IDC_EDIT1,m_Edit1);

DDX_Control(pDX,IDC_BROWSE7,m_Browse1);

}

BEGIN_MESSAGE_MAP(MyDlg1,CDialog)
// {{AFX_MSG_MAP(MyDlg1)
// }} AFX_MSG_MAP
ON_BN_CLICKED(IDOK,& MyDlg1 :: OnBnClickedOk)
ON_CBN_SELCHANGE(IDC_COMBO2,& MyDlg1 :: OnCbnSelchangeCombo2)
ON_CBN_SELCHANGE(IDC_COMBO1,& MyDlg1 :: OnCbnSelchangeCombo1)

ON_BN_CLICKED(IDC_RADIO9,& MyDlg1 :: OnBnClickedRadio9)

ON_BN_CLICKED(IDC_BUTTON1,& MyDlg1 :: OnBnClickedButton1)
ON_BN_CLICKED(IDC_BUTTON10,& MyDlg1 :: OnBnClickedButton10)
END_MESSAGE_MAP()


// MyDlg1消息处理程序

void MyDlg1 :: OnOK()
{
// TODO:在此处添加额外验证
MessageBox( Tab 1);

}

void MyDlg1 :: OnBnClickedButton6() // 浏览文件
{
// TODO:在此处添加您的控制通知处理程序代码

char strFilter [] = { BCR文件(* .bcr)| * .bcr |所有文件(*。*)| *。* ||};

CFileDialog FileDlg(TRUE, 。bcr,NULL, 0 ,strFilter);

if (FileDlg.DoModal()== IDOK)
{
CString m_PathName1 = FileDlg.GetPathName() ;
m_Edit4.SetWindowText(m_PathName1);

}
}





  //   MyDlg2.cpp  

MyDlg2 :: MyDlg2(CWnd * pParent / * = NULL * /
:CDialog(MyDlg2 :: IDD,pParent)
{
// {{AFX_DATA_INIT(MyDlg2)
// 注意:ClassWizard将在此处添加成员初始化
// }} AFX_DATA_INIT
}


void MyDlg2 :: DoDataExchange(CDataExchange * pDX)
{
CDialog :: DoDataExchange(pDX);
// {{AFX_DATA_MAP(MyDlg2)
// 注意:ClassWizard将在此处添加DDX和DDV调用
/ / }} AFX_DATA_MAP

DDX_Control(pDX,IDC_LIST2,m_List2);
DDX_Control(pDX,IDC_BUTTON3,m_SaveDlg1);
// DDX_Control(pDX,IDC_BUTTON1,m_Calculate1);
}


BEGIN_MESSAGE_MAP(MyDlg2,CDialog)
// {{AFX_MSG_MAP( MyDlg2)
// }} AFX_MSG_MAP
ON_CBN_SELCHANGE(IDC_CHOPPING ,& MyDlg2 :: OnCbnSelchangeChopping)
ON_WM_DRAWITEM()


ON_BN_CLICKED(IDC_BUTTON3,& MyDlg2 :: OnBnClickedButton3)
ON_BN_CLICKED(IDC_BUTTON4,& MyDlg2: :OnBnClickedButton4)
ON_BN_CLICKED(IDC_BUTTON5,& MyDlg2 :: OnBnClickedButton5)
ON_NOTIFY(LVN_KEYDOWN,IDC_LIST2,& MyDlg2 :: OnKeydown)
ON_BN_CLICKED(IDC_BUTTON2,& MyDlg2 :: OnBnClickedButton2)
ON_NOTIFY(LVN_ITEMCHANGED,IDC_LIST2,& MyDlg2 :: OnItemchangedList2)
ON_BN_CLICKED(IDC_BUTTON1,& MyDlg2 :: OnBnClickedButton1)
END_MESSAGE_MAP()


// MyDlg2消息处理程序

void MyDlg2 :: OnOK()
{
// TODO:添加额外验证这里
MessageBox( Tab 2);

}

void MyDlg2 :: OnBnClickedButton2()
{
// TODO:在此处添加控制通知处理程序代码

ShellExecute(NULL,(< span class =code-string> open),( C:\\ABC.exe),这里我要从dlg1传递路径,NULL,SW_SHOWNORMAL);


}

解决方案

2个对话框之间有什么关系?



你是否从Dlg1创建Dlg2?



例如,一种方式(如果Dlg2是从内部创建的) Dlg1)



 // ... 
void CDlg2 :: SetFileName(const CString& filename)
{
m_FileName = filename;
}

// ... ...
CString CDlg1 :: GetFileName()
{
return m_FileName;
}

// ... ...
void CDlg1 :: CreateDlg2()
{
CDlg2 dlg2;
dlg2.SetFileName(GetFileName());
dlg2.DoModal();
}

//...


在''from''对话框中提供GetFilename()访问器并从到对话框中调用它:



  //  获取文件名 
CString CDlg1 :: GetFileName()
{
return m_FileName;
}





...或者如果您想以另一种方式执行此操作,请添加一个SetFilename()访问器''到''对话框并从''from''对话框中调用它。在访问器中,执行ShellExecute()调用。这也意味着你必须得到2个对话框,以便能够彼此识别自己(实际上只在一个方向上,方向取决于你选择的解决方案)......


< blockquote>当我正确理解你的问题时,你的两个对话框彼此不知道,但都是制表符控件的页面。所以,你的问题实际上是:如何在Dlg2的成员函数中获得指向Dlg1的指针?



有几种方法可以做到这一点,一些比其他人更优雅:



1.您可以在全局指针变量中存放指向Dlg1的指针,并从Dlg2访问该指针。例如:

  //  在Dlg1.cpp中:  
Dlg1 * ptrToDlg1 = 0 ;

Dlg1 :: Dlg1(...)
{
ptrToDlg1 = this ;
}

// 在Dlg2.cpp中
#include Dlg1.h

extern Dlg1 * ptrToDlg1;

...

Dlg2 :: OnOk()
{
CString fileName = ptrToDlg1-> GetFileName();
...
}





通常情况下,我们尽量避免使用全局指针。所以这里有一个更优雅的方式:



b)在某个地方你创建了两个对话框;可能在您的选项卡控件的某些代码中。这是告诉Dlg2 Dlg1在哪里的写作地点:

 ... 
Dlg1 * ptrDlg1 = Dlg1(...);
Dlg2 * ptrDlg2 = new Dlg2(...);

// 告诉Dlg2关于Dlg1
ptrDlg2-> SetPtrToDlg1(ptrDlg1);



现在Dlg2有一个指向Dlg1的指针,可以在适当的时候询问它的文件名。 ...



这是Maximilien在解决方案1中发布的相当详尽的版本。我只是想,这可能是缺失的链接并帮助您你的方式。



[在OP修改他的源代码后编辑]

这里是你需要做的更改的非常详细的描述。



在你的Dlg2类中,添加一个函数Dlg2 :: SetDlg1ptr(Dlg1 * pDlg1),代码为:

  void  Dlg2 :: SetDlg1Ptr(Dlg1 * pDlg1)
{
m_ptrToDlg1 = pDlg1;
}



并添加Dlg2的头文件:

  //    

class Dlg1; // 提前声明

class Dlg2
{
public
...
void SetDlg1Ptr(Dlg1 * pDlg1);

受保护
Dlg1 * m_ptrToDlg1;
...
};



你在MyTabCtrl的构造函数中调用这个函数:

 m_Dialog [ 0 ] =  new  MyDlg1(); 
m_Dialog [ 1 ] = new MyDlg2();
m_Dialog [ 1 ] - > SetDlg1Ptr(m_Dialog [ 0 ]);



从这一刻开始,Dlg2可以通过这个指针调用Dlg1的成员函数。



接下来,在Dlg1中更改OnBnClickedButton6函数:

  void  MyDlg1 :: OnBnClickedButton6() //  浏览文件 
{
if (FileDlg.DoModal()== IDOK)
{
m_pathName = FileDlg.GetPathName();
// 请勿将m_pathName声明为本地字符串!
m_Edit4.SetWindowText (m_pathName);
}
}



并在Dlg2.h中添加成员变量m_pathName。

  Dlg1 
{
public
PCTSTR GetPathName( ) const ;
...
protected
CString m_pathName;
...
};



然后为m_pathName添加一个访问器函数

 PCTSTR Dlg1 :: GetPathName() const  
{
return m_pathName;
}



最后,你可以访问OnBnClickedButton2中的路径名:

 ShellExecute( NULL,....,m_ptrDlg1-> GetPathName(),...); 


I Have 9 browse buttons on dlg1 (9 files) which i have to pass to dlg2 click button event.

// MyTabControl.cpp

MyTabCtrl::MyTabCtrl()
{
	m_DialogID[0] =IDD_DIALOG1;
	m_DialogID[1] =IDD_DIALOG2;

	m_Dialog[0] = new MyDlg1();
	m_Dialog[1] = new MyDlg2();

    m_nPageCount = 2;

}

MyTabCtrl::~MyTabCtrl()
{
}

void MyTabCtrl::InitDialogs()
{
	m_Dialog[0]->Create(m_DialogID[0],GetParent());
	m_Dialog[1]->Create(m_DialogID[1],GetParent());

}



// MyDlg.cpp

MyDlg1::MyDlg1(CWnd* pParent /*=NULL*/)
	: CDialog(MyDlg1::IDD, pParent)
{
	//{{AFX_DATA_INIT(MyDlg1)
	// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	//  m_NumberOfEvents = 0;
	m_SetUp = 0;
	m_EdpCode = _T("");
}


void MyDlg1::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_CBString(pDX, IDC_EDP_CODE, m_EdpCode);
	DDV_MaxChars(pDX, m_EdpCode, 40);
	DDX_Control(pDX, IDC_LIST1, m_Events);
	DDX_Control(pDX, IDC_RADIO1, m_Radio1);

        DDX_Control(pDX, IDC_RUN, m_Combo1);
	DDX_Control(pDX, IDC_EDIT2, m_Edit2);
	DDX_Control(pDX, IDC_EDIT1, m_Edit1);

	DDX_Control(pDX, IDC_BROWSE7, m_Browse1);

}
	
BEGIN_MESSAGE_MAP(MyDlg1, CDialog)
	//{{AFX_MSG_MAP(MyDlg1)
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDOK, &MyDlg1::OnBnClickedOk)
	ON_CBN_SELCHANGE(IDC_COMBO2, &MyDlg1::OnCbnSelchangeCombo2)
	ON_CBN_SELCHANGE(IDC_COMBO1, &MyDlg1::OnCbnSelchangeCombo1)
	
	ON_BN_CLICKED(IDC_RADIO9, &MyDlg1::OnBnClickedRadio9)

	ON_BN_CLICKED(IDC_BUTTON1, &MyDlg1::OnBnClickedButton1)
	ON_BN_CLICKED(IDC_BUTTON10, &MyDlg1::OnBnClickedButton10)
END_MESSAGE_MAP()


// MyDlg1 message handlers

void MyDlg1::OnOK() 
{
	// TODO: Add extra validation here
	MessageBox("Tab 1");
	
}

void MyDlg1::OnBnClickedButton6() // browse for file 
{
	// TODO: Add your control notification handler code here

    char strFilter[] = { "BCR Files (*.bcr)|*.bcr|All Files (*.*)|*.*||" };

    CFileDialog FileDlg(TRUE, ".bcr", NULL, 0, strFilter);
     
	if(FileDlg.DoModal() == IDOK)
    {
		 CString  m_PathName1 = FileDlg.GetPathName();
		 m_Edit4.SetWindowText( m_PathName1);
		
	}
}



// MyDlg2.cpp

MyDlg2::MyDlg2(CWnd* pParent /*=NULL*/)
	: CDialog(MyDlg2::IDD, pParent)
{
	//{{AFX_DATA_INIT(MyDlg2)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
}


void MyDlg2::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(MyDlg2)
	// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP

	DDX_Control(pDX, IDC_LIST2, m_List2);
	DDX_Control(pDX, IDC_BUTTON3, m_SaveDlg1);
	//  DDX_Control(pDX, IDC_BUTTON1, m_Calculate1);
}


BEGIN_MESSAGE_MAP(MyDlg2, CDialog)
	//{{AFX_MSG_MAP(MyDlg2)
	//}}AFX_MSG_MAP
	ON_CBN_SELCHANGE(IDC_CHOPPING, &MyDlg2::OnCbnSelchangeChopping)
	ON_WM_DRAWITEM()


	ON_BN_CLICKED(IDC_BUTTON3, &MyDlg2::OnBnClickedButton3)
	ON_BN_CLICKED(IDC_BUTTON4, &MyDlg2::OnBnClickedButton4)
	ON_BN_CLICKED(IDC_BUTTON5, &MyDlg2::OnBnClickedButton5)
	ON_NOTIFY(LVN_KEYDOWN, IDC_LIST2, &MyDlg2::OnKeydown)
	ON_BN_CLICKED(IDC_BUTTON2, &MyDlg2::OnBnClickedButton2)
	ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST2, &MyDlg2::OnItemchangedList2)
	ON_BN_CLICKED(IDC_BUTTON1, &MyDlg2::OnBnClickedButton1)
END_MESSAGE_MAP()


// MyDlg2 message handlers

void MyDlg2::OnOK() 
{
	// TODO: Add extra validation here
	MessageBox("Tab 2");
	
}

void MyDlg2::OnBnClickedButton2()
{
	// TODO: Add your control notification handler code here
   
ShellExecute(NULL, ("open"), ("C:\\ABC.exe"),here I have to Pass path from dlg1 ,NULL,SW_SHOWNORMAL);


}

解决方案

What is the relation between the 2 dialogs ?

Do you create Dlg2 from Dlg1 ?

for example, one way of doing it (if Dlg2 is created from within Dlg1)

//...
void CDlg2::SetFileName( const CString& filename )
{
  m_FileName = filename;
}

//...
CString CDlg1::GetFileName( )
{
  return m_FileName;
}

//...
void CDlg1::CreateDlg2 ()
{
   CDlg2 dlg2;
   dlg2.SetFileName( GetFileName() );
   dlg2.DoModal();
}

//...


Provide a GetFilename() accessor in the ''from'' dialog and call it from the ''to'' dialog:

// Get Filename
CString CDlg1::GetFileName( )
{
    return m_FileName;
}



... or if you want to do it the other way, add a SetFilename() accessor in the ''to'' dialog and call it from the ''from'' dialog. In the accessor, do the ShellExecute() call. This also means that you will have to get the 2 dialogs to be able to identify themselves to each other (well actually in one direction only, the direction depending on which solution you choose)...


When I understand your question correctly, your two dialogs do not know of each other, but are both pages of tab control. So, your question would actually be: How can I get a pointer to Dlg1 while being in a member function of Dlg2?

There are several ways to do that, some more elegant than others:

1. You can deposite a pointer to Dlg1 in a global pointer variable and access that from Dlg2. For example:

// In Dlg1.cpp:
Dlg1* ptrToDlg1 = 0;

Dlg1::Dlg1 (...)
{
   ptrToDlg1 = this;
}

//in Dlg2.cpp
#include "Dlg1.h"

extern Dlg1* ptrToDlg1;

...

Dlg2::OnOk ()
{
    CString fileName = ptrToDlg1->GetFileName();
    ...
}



Normally we try to avoid global pointers whenever possible. So here''s a more elegant way:

b) At some place you create your two dialogs; probably in some code of your tab control. That is the write place to tell Dlg2 about where Dlg1 is:

...
Dlg1* ptrDlg1 = new Dlg1 (...);
Dlg2* ptrDlg2 = new Dlg2 (...);

// tell Dlg2 about Dlg1
ptrDlg2->SetPtrToDlg1 (ptrDlg1);


Now Dlg2 has a pointer to Dlg1 and can ask it at the right moment for the filename. ...

This is pretty much a long and detailed version of what Maximilien posted in Solution 1. I just thought, this might be the missing link and help you on your way.

[EDIT after OP amended his source code]
Here is a very detailed description of the changes you need to make.

In your Dlg2 class, add a function Dlg2::SetDlg1ptr (Dlg1* pDlg1) with code:

void Dlg2::SetDlg1Ptr (Dlg1* pDlg1)
{
    m_ptrToDlg1 = pDlg1;
}


and add in the header file of Dlg2:

// in Dlg2.h

class Dlg1; // advance declaration

class Dlg2
{
public:
    ...
    void SetDlg1Ptr (Dlg1* pDlg1);

protected:
    Dlg1* m_ptrToDlg1;
    ...
};


You call this function in the constructor of MyTabCtrl:

m_Dialog[0] = new MyDlg1();
m_Dialog[1] = new MyDlg2();
m_Dialog[1]->SetDlg1Ptr (m_Dialog[0]);


From this moment on Dlg2 can call member functions of Dlg1 via this pointer.

Next, change your OnBnClickedButton6 function in Dlg1:

void MyDlg1::OnBnClickedButton6() // browse for file 
{
    if (FileDlg.DoModal() == IDOK)
    {
	m_pathName = FileDlg.GetPathName();
            // DO NOT DECLARE m_pathName as a local string!
	m_Edit4.SetWindowText (m_pathName);
    }
}


and add the member variable m_pathName in Dlg2.h.

class Dlg1
{
public:
    PCTSTR GetPathName () const;
    ...
protected:
    CString m_pathName;
    ...
};


Then add an accessor function to m_pathName

PCTSTR Dlg1::GetPathName () const
{
    return m_pathName;
}


And finally, you can access the path name in OnBnClickedButton2:

ShellExecute (NULL, ....  , m_ptrDlg1->GetPathName(), ...);


这篇关于从Dlg1到Dlg2的访问变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆