当子窗口控件的状态发生改变时,控件通过向其父窗口发送WM_COMMAND消息进行通信,在该消息的wParam中含有通知消息和控件的ID,在lParam中则包含了控件的句柄。例如,当用户在按钮上单击鼠标时,按钮控件会向父窗口发送BN_CLICKED消息。
利用ClassWizard可以很容易地为控件通知消息加入消息映射和消息处理函数。例如,某按钮的BN_CLICKED消息的消息映射及其处理函数的声明如下所示:
ON_BN_CLICKED(IDC_ADD,OnAdd)
afx_msg void OnAdd();
有时,为了方便处理,需要把多个ID连续的控件发出的相同消息映射到同一个处理函数中。这就要用到ON_CONTROL_RANGE宏。ON_CONTROL_RANGE消息映射宏的第一个参数是控件消息码,第二个和第三个参数分别用来指明一组连续的控件ID中的第一个和最后一个ID,最后一个参数是消息处理函数名。例如,要处理一组单选按钮发出的BN_CLICKED消息,响应的消息映射如下所示:
ON_CONTROL_RANGE(BN_CLICKED,IDC_FIRST,IDC_LAST,OnRadioClicked)
函数OnRadioClicked的声明如下,该函数比上面的函数OnAdd多了一个参数nID用以说明发送通知消息的控件ID。
afx_msg void OnRadioClicked(UINT nID);
ClassWizard不支持ON_CONTROL_RANGE宏,所以需要手工建立消息映射和消息处理函数。
事实上,在使用ClassWizard时只要运用一个小小的技巧,就可以把不同控件的通知消息映射到同一个处理函数上,也可以把一个控件的不同通知消息映射到同一个处理函数上,这个技巧就是在用ClassWizard创建消息处理函数时,指定相同的函数名即可。此方法的优点在于控件的ID不必是连续的,缺点是处理函数没有nID参数,因而不能确定是哪一个控件发送的消息,所以这个方法用于复选或单选框不错,因为通过GetDlgItem->GetCheck()可以判断各控件选中状态,对于按钮可就不容易了。
下面结合我的实例演示讲一下:
我的上位机软件有一组特殊功能按钮,控制我的单片机系统的休眠,复位等等,为了能够使用ON_CONTROL_RANGE宏,通过ctrl+D,将其ID按顺序编号,这里先用两个IDC_BUTTON_EXTEND9,IDC_BUTTON_EXTEND10,然后在CLEDDlg.cpp中的消息映射中加入ON_CONTROL_RANGE(BN_CLICKED,IDC_BUTTON_EXTEND9,IDC_BUTTON_EXTEND10,OnButtonClicked)消息映射,然后在CLEDDlg. h中添加OnButtonClicked的函数声明,再在CLEDDlg.cpp中创建OnButtonClicked(nID)函数:
CLEDDlg.h
protected:
HICON m_hIcon;
// Generated message map functions
//{{AFX_MSG(CLEDDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg LONG OnComm(WPARAM ch,LPARAM port); //串口字符接收消息的响应函数声明
afx_msg void OnButtonOpenPort();
afx_msg void OnButtonExitPort();
afx_msg void OnButtonDebugSend();
afx_msg void OnButtonGroupOK();
afx_msg void OnButtonClear();
afx_msg void OnButtonSave();
afx_msg void OnCheckRecycle();
afx_msg void OnTimer(UINT nIDEvent);
afx_msg void OnButtonClicked(UINT nID); ////*****头文件中函数声明*******///
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
CLEDDlg.cpp
BEGIN_MESSAGE_MAP(CLEDDlg, CDialog)
//{{AFX_MSG_MAP(CLEDDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_MESSAGE(WM_COMM_RXCHAR,OnComm)
ON_BN_CLICKED(IDC_BUTTON_OPENPORT, OnButtonOpenPort)
ON_BN_CLICKED(IDC_BUTTON_EXITPORT, OnButtonExitPort)
ON_BN_CLICKED(IDC_BUTTON_DEBUGSEND, OnButtonDebugSend)
ON_BN_CLICKED(IDC_BUTTON_GROUPOK, OnButtonGroupOK)
ON_BN_CLICKED(IDC_BUTTON_CLEAR, OnButtonClear)
ON_BN_CLICKED(IDC_BUTTON_SAVE, OnButtonSave)
ON_BN_CLICKED(IDC_CHECK_RECYCLE, OnCheckRecycle)
ON_CONTROL_RANGE(BN_CLICKED,IDC_BUTTON_EXTEND9,IDC_BUTTON_EXTEND10,OnButtonClicked)//////**消息映射*****///
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CLEDDlg message handlers
void CLEDDlg::OnButtonClicked(UINT nID) ////处理函数/////
{
switch(nID)
{
case IDC_BUTTON_EXTEND9:
m_SerialPort.WriteToPort(ColorGroup[0],21);
break;
case IDC_BUTTON_EXTEND10:
m_SerialPort.WriteToPort(DataFrame);
break;
}
}
文章评论(0条评论)
登录后参与讨论