VC/MFC子窗体向父窗体传递参数的几种方法

VC/MFC子窗体向父窗体传递参数的几种方法

http://my.oschina.net/ypimgt/blog/89621

典型问题举例

    窗体和子窗体均有一个Edit控件和一个按钮,点击父窗体按钮显示子窗体;点击子窗体按钮后,子窗体中Edit控件的值显示在在父窗体中的Edit控件中。

在MFC中实现子窗体向父窗体传递参数的几种方法简述

    1、在父窗体定义静态变量
    2、传窗体的指针给子窗体
    3、子窗体调用GetParent
    4、向父窗体sendMessage

    方法1,使用静态变量,如果有多个子对象和父对象存在时,处理比较麻烦。
    方法2, 传指针给子窗体,子窗体需要另外保存这个指针,此方法可由方法3替代。
    方法3, 比方法2优,但与方法2都与父窗体耦合较深。
    方法4,推荐采用方法;采用这种方法,子窗体可以放到任何父窗体上,只要父窗体响应此消息即可。

示例源码

通过子窗体调用GetParent向父窗体传递参数的示例

GetParent()->SetDlgItemText(IDC_EDIT1,TCHAR *)

通过向父窗体发送消息(sendMessage)来传递参数示例

    SendMessage的基本结构如下

SendMessage( 
  HWND hWnd, //消息传递的目标窗口或线程的句柄。 
  UINT Msg, //消息类别(这里可以是一些系统消息,也可以是自己定义,下文具体介绍,) 
  WPARAM wParam, //参数1 (WPARAM 其实是与UINT是同种类型的, 
                 //在vc编译器中右键有个“转到WPARAM的定义”的选项可以查看。   
  LPARAM lParam); //参数2

    其中一些参数的说明如下:

    //typedef unsigned int UINT;
    //typedef UINT WPARAM;
    //typedef LONG LPARAM;
    //typedef LONG LRESULT;

    可以用以下语句发送消息:

::SendMessage(this->m_hWnd, WM_MY_DOSOME, (WPARAM) 0, (LPARAM) 0);

    这里我发送的消息是本窗体接收的,所以句柄用:this->m_hWnd。

    这里的消息类别WM_MY_DOSOME是用户自定义的,在接收消息的窗体或线程所在的头文件里:

#define WM_MY_DOSOME WM_USER+1 // do something 
当然你还可以定义更多如: 
#define WM_DOOTHER WM_USER+2   // do other表示要做一些事情。

    我们发了一个消息出去,那么接收方要能识别这个消息是干什么,就是通过消息类别来区分,并且根据消息类别去调用消息处理函数。接收方需要做以下几步:

1、在接收方编写一个消息处理函数

    我们在接收窗体里定义一个消息处理函数,以处理接收到该消息后应该做什么事情。

afx_msg LRESULT DoSomeThing(WPARAM iParam1,LPARAM iParam2) 

    MessageBox("收到消息了,我要开始做一些事情了。","收到",MB_OK); 
    //可以运用iParam1,iParam2 来做一些事情。 
    return 0; 
}

    编写消息处理函数有3点需要格外注意:

    1)使用了afx_msg,并且要将afx_msg LRESULT DoSomeThing(WPARAM iParam1,LPARAM iParam2) 改写到头文件的 {{AFX_MSG ... AFX_MSG}}包含的灰色部分,如下:

//{{AFX_MSG   
//。。。改写到这里,颜色会变成灰的。这一点非常重要。 
//}}AFX_MSG

    2)参数有2个,WPARAM iParam1,LPARAM iParam2,哪怕没有东西传进来也要写,不然会吃苦头的,vc里不会提醒你少写了一个,但如果不写可能会产生莫名奇妙的错误。

    3)类型用 LRESULT,完了要return 0; 

2、在接收方定义各种消息类型与消息处理函数的映射关系,即让接收方知道每个消息要调用哪个处理函数

    映射关系书写示例如下

//{{AFX_MSG_MAP 
//。。。这里写上 
ON_MESSAGE(WM_MY_DOSOME,DoSomeThing) 
//如果还有其他消息就再写一个 
ON_MESSAGE(WM_DOOTHER,DoOther) 
//}}AFX_MSG_MAP

    到这里,当发送方用SendMessage,发出一个WM_MY_DOSOME类型的消息过来的时候,接收方就会去做DoSomeThing(WPARAM iParam1,LPARAM iParam2);
发送方发出一个WM_DOOTHER类型的消息过来的时候,接收方就会去做DoOther(WPARAM iParam1,LPARAM iParam2)。

.h头文件中要定义的内容

#define WM_MYMSG WM_USER+5 //自定义一个消息 
afx_msg void OnMyMessage(WPARAM wParam, LPARAM lParam); //自定义消息的处理函数声明

.cpp文件要实现的内容

ON_MESSAGE(WM_MYMSG, OnMyMessage)
//利用ON_MESSAGE()宏在自定义消息与其处理函数间建立映射关系

void CModelessDlg::OnMyMessage(WPARAM wParam, LPARAM lParam)
//从lParam中取出CString对象的指针,并将字符串内容在IDC_MSGEDIT中显示出来
{
  CString *str;
  str=(CString *)lParam;

  SetDlgItemText(IDC_EDIT,*str);
}

按下按钮发送消息

void CModelessDlg::OnMsgBTN()   

    CString str= "自定义消息被触发了!"; 
    SendMessage(WM_MYMSG, 0, (LPARAM) &str); //给ModelessDlg自己发一个自定义的消息 
}

你可能感兴趣的:(VC/MFC子窗体向父窗体传递参数的几种方法)