MFC对话框编程四:输入焦点的传递

一、OK按钮时对话框的默认按钮(默认按钮消息响应函数),当我们按下回车键时会选择默认按钮的消息响应函数进行执行。因此,为了屏蔽按下回车键就关闭对话框的功能,应该重写OK键的消息响应函数,使得按下回车键时输入焦点按照自己设定的方式进行传递。最简单的方式就是注释掉对基类函数 CDialog::OnOK()的调用

二、为了实现按下回车键进行输入焦点的传递,下一个编辑输入控件应该捕捉键盘的输入字符消息,然后在该消息响应函数中传递输入焦点。如何捕捉这个消息?

1、为这个编辑控件关联一个类,通过这个类来捕获这个消息。

2、修改编辑控件的窗口过程函数,替换掉MFC提供的默认的编辑控件的窗口过程函数。我们知道窗口过程函数式在设计窗口类的时候设定的,但是当窗口建立之后如何去重新制定窗口过程函数。

LONG SetWindowLong(  HWND hWnd,       // handle to window
  int nIndex,      // offset of value to set  LONG dwNewLong   // new value);

该函数的作用是改变窗口的属性。如果为为制定窗口设计一个新的窗口过程,则该函数会返回为该窗口设计的窗口过程函数的地址。现在的问题是,该修改编辑控件的窗口过程函数应该放在哪个地方?WM_CREATE的消息响应函数中吗?不可以的,因为此时窗口的子控件还没有创建完毕,只有在该消息处理完毕之后才创建完。当然无法获得对应编辑控件的句柄。实际上,在对话框窗口的子控件创建完毕有一个 WM_INITDIALOG消息

3、先写一个为编辑框控件设计的窗口过程函数和WM_INITDIALOG的消息响应函数如下

//定义一个窗口过程函数
WNDPROC prevProc;
LRESULT CALLBACK WinSunProc(
  HWND hwnd,      // handle to window
  UINT uMsg,      // message identifier
  WPARAM wParam,  // first message parameter
  LPARAM lParam   // second message parameter
)
{
	if(uMsg==WM_CHAR && wParam==0x0d)
	{
		//::SetFocus(::GetNextWindow(hwnd,GW_HWNDNEXT));//getnextwindow获取窗口句柄的方法
                       
                //SetFocus(::GetWindow(hwnd,GW_HWNDNEXT));//
		SetFocus(::GetNextDlgTabItem(::GetParent(hwnd),hwnd,FALSE));//返回指定对话框的指定控件前面或者后面一个具有WS_TABSTOP风格的控件
		return 1;
	}
	else
	{
		return prevProc(hwnd,uMsg,wParam,lParam);
	}
}
BOOL CTestDlg::OnInitDialog() 
{
    CDialog::OnInitDialog();
    
    // TODO: Add extra initialization here
    prevProc=(WNDPROC)SetWindowLong(GetDlgItem(IDC_EDIT1)->m_hWnd,GWL_WNDPROC,
        (LONG)WinSunProc);
    return TRUE;  // return TRUE unless you set the focus to a control
                  // EXCEPTION: OCX Property Pages should return FALSE
}


4、修改编辑控件的属性,使其支持MultiLine,从而该控件窗口才会响应ENTER的消息响应函数

三、以上方法要实现输入焦点的依次传递,需要修改每个编辑框控件的窗口过程函数,很麻烦有木有,下面介绍一种相对简单的方法。当对话框中,按下回车键,会调用对话框默认按钮的消息响应函数,这个时候,我们可以在这个默认按钮的消息响应函数中讲输入焦点进行传递。

1、代码如下

void CTestDlg::OnOK() 
{
	// TODO: Add extra validation here
	//GetDlgItem(IDC_EDIT1)->GetNextWindow()->SetFocus();
	//GetFocus()->GetNextWindow()->SetFocus();
	//GetFocus()->GetWindow(GW_HWNDNEXT)->SetFocus();
	GetNextDlgTabItem(GetFocus())->SetFocus();
//	CDialog::OnOK();
}

2、修改具有tab stop 属性控件的顺序
打开对话资源视图->layout->tab order



原文地址:https://www.cnblogs.com/javawebsoa/p/3073317.html