MFC中的几个消息

      最近在使用MFC的过程中发现了几个有用的消息,可能有些在类视图的左边找不到,需要自己手动添加,但是感觉这些宏非常有用,在这里记录一下:


ON_UPDATE_COMMAND_UI_RANGE

       这个消息的作用是批量修改菜单资源的状态,有时需要禁止一大堆菜单项时使用这个消息非常方便。

       这个消息的用法如下:

      在对话框的头文件中添加响应函数:

afx_msg void OnMenuItemUI(CCmdUI *pCmdUI);//点击卫片导入后更新菜单项状态
      然后在对话框的消息映射之间添加上下面的代码:

ON_UPDATE_COMMAND_UI_RANGE(ID_BEGIN,ID_END,&OnMenuItemUI)
      这个消息映射的第一个参数是一个起始的ID号,第二个参数是一个结束的ID号,第三个参数是消息响应函数。

void CMainFrame::OnMenuItemUI(CCmdUI *pCmdUI)
{
	//如果某种条件满足时,更新指定ID的控件的状态
	//注意下面的ID_ONE和ID_TWO要介于在消息映射中添加的ID_BEGIN 和ID_END之间。
	//然后可以使用switch语句对需要处理的ID进行处理
	if (flag)
	{
		switch (pCmdUI->m_nID)
		{
		case   ID_ONE:
			pCmdUI->Enable(false);
			break;

		case   ID_TWO:
			pCmdUI->Enable(false);
			break;
		default :
			break;
		}
	}

}


ON_EN_KILLFOCUS

      这个消息的用法如下:

      在对话框的头文件中添加响应函数:

afx_msg void OnKillFocusEditBox();
      然后在对话框的消息映射之间添加上下面的代码:
ON_EN_KILLFOCUS(IDC_ONE, &COutputParameterPage::OnKillFocusEditBox)
ON_EN_KILLFOCUS(IDC_TWO, &COutputParameterPage::OnKillFocusEditBox)

      这个函数的作用主要是用来校验对话框中文本框(CEdit)的数据,当对话框中的文本框失去焦点(注意是对话框中的文本框,不是对话框)后这个函数就会被调用,上面的消息映射中对两个ID添加了这个函数,那么会在这两个ID表示的控件失去焦点后调用OnKillFocusEditBox这个函数。同时为了校验后更改文本框的内容,需要对该文本框添加一个成员变量(下面用m_data表示与ID_ONE关联的成员变量,并校验这个数据,用0.0表示出错的情况,将它修正成1.0)
void COutputParameterPage::OnKillFocusEditBox(){

//首先使用true将数据从控件传入成员变量中
UpdateData(true);
	
	//校验成员变量m_data中的数据是否符合要求,如果不符合,修改后将它显示在控件中
	if (m_data=0.0)
	{
		m_data=1.0
		UpdateData(false);	
	}
}

      

      发现上面这个消息有个问题,就是这个消息会触发两次。不知道是怎么回事,断点调试时发现一个文本框失去焦点时这个函数会触发,并且也会触发另外一个文本框失去焦点二进入这个事件。弄了好久,又是尝试自定义消息和自定义文本框(结果任然进去了两次),又是在PreTranslateMessage中截取EN_KILLFOCUS消息(这个消息的

LOWORD(wParam)一直为0,不为文本框的ID),这两中方法都没有逃离EN_KILLFOCUS这个消息的范畴,我都是想在EN_KILLFOCUS这个消息上做文章,但是怎么都成功不了。


      如果不需要弹出对话框的话这个消息进去两次就两次,无所谓,但是要弹出对话框的话就肯定不能让他进去两次了。后来发现了一个方法,就是不要理会EN_KILLFOCUS这个消息,转而处理WM_LBUTTONDOWN消息,因为文本框的内容改变后肯定还会有一次鼠标左键单击事件,但是这个消息却不能在窗口类中直接添加消息映射,因为这个映射只会在鼠标点击对话框中的空白区时才会触发,如果你点击的是对话框中的文本框或者按钮这种控件是不会执行WM_LBUTTONDOWN这个消息的响应函数的。但是这显然与这里的要求不符合,我想做的是点击对话框的任何区域都要做一次验证。这就需要在PreTranslateMessage中截获WM_LBUTTONDOWN消息,然后处理就行了,这样无论点击对话框中的什么地方都会响应这个函数了。代码如下:OnKillFocusEditBox函数就是上面的校验函数,注意这时可以将OnKillFocusEditBox函数变成普通函数(声明前不需要afx_msg了)

BOOL COutputParameterPageMore::PreTranslateMessage(MSG* pMsg)
{
	// TODO: 在此添加专用代码和/或调用基类
	if (pMsg->message==WM_LBUTTONDOWN)
	{	
		OnKillFocusEditBox();
	}

	return CPropertyPage::PreTranslateMessage(pMsg);
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值