在VC6中根据向导新建一个对话框程序,把向导生成的OK、Cancel和文本都删除,然后拖三个编辑框控件和一个按钮到界面上。为按钮添加响应函数:
void CNetxeditDlg::OnBtn1()
{
// TODO: Add your control notification handler code here
MessageBox("Button1");
}
然后再添加一个OnOK函数:
void CNetxeditDlg::OnOK()
{
GetNextDlgTabItem(GetFocus())->SetFocus();
}
运行该程序,于是出现一个奇怪的现象:一运行,焦点停在第一个编辑框中,按回车,焦点会到第二个编辑框,再按回车,焦点到第三个编辑框,再按回车,焦点到了按钮上,再按回车,焦点又到了第一个编辑框中,而不是触发按钮的响应函数。改用按Tab键,焦点也是从第一个编辑框一直到第三个编辑框再到按钮上,此时按回车,按钮的响应函数才执行。请问这是怎么回事啊?两种情况下都是在按钮上有焦点的情况下按回车,可反应却不同?
void CNetxeditDlg::OnBtn1()
{
// TODO: Add your control notification handler code here
MessageBox("Button1");
}
然后再添加一个OnOK函数:
void CNetxeditDlg::OnOK()
{
GetNextDlgTabItem(GetFocus())->SetFocus();
}
运行该程序,于是出现一个奇怪的现象:一运行,焦点停在第一个编辑框中,按回车,焦点会到第二个编辑框,再按回车,焦点到第三个编辑框,再按回车,焦点到了按钮上,再按回车,焦点又到了第一个编辑框中,而不是触发按钮的响应函数。改用按Tab键,焦点也是从第一个编辑框一直到第三个编辑框再到按钮上,此时按回车,按钮的响应函数才执行。请问这是怎么回事啊?两种情况下都是在按钮上有焦点的情况下按回车,可反应却不同?
解决方案 »
- VC网络传输中BYTE*,在接受时如何解析成字符?
- 为何针对IMarkupServices的QueryInterface总是返回E_NOINTERFACE?
- 大家放心,MFC的路还很长很长很长的
- 取出list控件中一行,与数据库记录进行查询,后取出库里一记录存入Str出错
- 我使用DirectShow来控制从 DVD->硬盘 导入数据,如何检测磁盘满了
- 版主:木有人回我贴我该怎样结贴啊???
- 哪位好心人能不能提供一个YUV2RGB的汇编代码
- WebBrowser控件如何响应HTML事件
- 为什么要用CreateProcess创建进程
- vc6创建子对话框失败
- win7 注册表 HKEY_CLASSES_ROOT 文件关联 VC6.0
- 我该如何多个图片在listCtrl中一起拖拽呢
你把你新加的按钮属性设上“default button”,或者edit控件有“multiline”和“want return”属性时就不会默认回车OnOK了。
{
CButton* pBtn = (CButton*)GetFocus();
pBtn->SetButtonStyle(BS_DEFPUSHBUTTON, TRUE);
}
仔细看一下就会发现,执行LZ的OnOK的处理将焦点移至按钮上时,只出现了虚线框。
(如果没用鼠标点过按钮,甚至虚线框也不会出现。)
而使用Tab键将焦点移至按钮上时,不仅出现了虚线框,还出现了粗边框(不同主题下效果不同)。
猜测此时按钮被赋予了临时的“缺省”属性,此时回车键只会识别这个按钮。你可以看看 COccManager::IsDialogMessage() 的实现
(...\Program Files\Microsoft Visual Studio 9.0\VC\atlmfc\src\mfc\occdlg.cpp)
看我在5楼的答复,粗线就是因为有BS_DEFPUSHBUTTON属性。
有黑边框就是因为按钮有default button属性,有该属性时回车才能执行该按钮的动作。
按tab切换焦点时,windows不单setfocus,对按钮还SetButtonStyle(BS_DEFPUSHBUTTON, TRUE);了,而你的代码中没有调用该代码。按5楼说的加上这段设置按钮属性的代码就行了。
2. 如果返回值是DLGC_DEFPUSHBUTTON,就给这个有黑边框的按钮发送BM_SETSTYLE消息,用BS_PUSHBUTTON当wParam,这样就能去掉黑边框。
3. 发送BM_SETSTYLE消息给当前获得焦点的push button,用BS_DEFPUSHBUTTON当作wParam参数,使其拥有黑边框。例程:case WM_KEYDOWN: // Check for keys that need this processing such as the
// TAB and arrow keys.
if ( (wParam == VK_TAB) ||
(wParam == VK_DOWN) || (wParam == VK_UP) ||
(wParam == VK_RIGHT) || (wParam == VK_LEFT) )
{
// Set the focus to the first control, Button #1
// in this case.
hwndBtn1 = GetDlgItem(hParentDlg,IDBUTTON1);
SetFocus(hwndBtn1); // Loop through all the controls and remove the
// dark border that the previous default push
// button has.
hwndCtrls = GetWindow(hParentDlg, GW_CHILD);
while (hwndCtrls)
{
wRet = (WORD)(DWORD)SendMessage(hwndCtrls,
WM_GETDLGCODE, 0, 0L); if (wRet & DLGC_DEFPUSHBUTTON)
SendMessage(hwndCtrls, BM_SETSTYLE,
(WPARAM)BS_PUSHBUTTON, TRUE); hwndCtrls = GetWindow(hwndCtrls, GW_HWNDNEXT);
} // Give the hwndBtn1 button the default push button
// border.
SendMessage(hwndBtn1, BM_SETSTYLE,
(WPARAM)BS_DEFPUSHBUTTON, TRUE); return(0L);
} break;
老兄,你别太固执了哈,建议你在Windows Xp的默认主题或经典主题下试试,
任何按钮在真正获得焦点(Tab键走位或鼠标点击)后,都是带黑边框的。
所以我就想能不能把那个黑边框去掉,所以专门研究过按钮状态问题。CButton::GetState()
MSDN对这个函数的说明中,给出了按钮的3个状态值:0x0003(check)、
0x0004(hilight) 和 0x0008(focus)。但是经实验发现,按钮在
获得焦点后的状态值为 0x0208,也就是说出现了一个值为0x0200的
未知状态(黑边框状态)。PS:CButton这个类适用于Button、Radio和CheckBox。
首先明确一下,回车键执行OnOK是对话框的缺省处理,与有无IDOK按钮无关。
但当存在带DEFPUSHBUTTON的按钮时,对话框PreTranslateMessage处理回车键
时会取这个按钮(如果有多个则取Tab走位顺序最靠前的)。LZ在9L的问题,目前查不到任何资料,看来只能去问微软了。
SetFocus方法对按钮不适用,一定要编码更改按钮焦点的话,只能是调一下
IsDialogMessage,例:MSG msg = {0};
msg.hwnd = ::GetFocus();
msg.message = WM_KEYDOWN;
msg.wParam = VK_TAB;
IsDialogMessage(&msg);※注:这段代码如果要在ON_BN_CLICKED消息响应中用,不能直接用,
要触发一个定时器,在OnTimer中使用这段代码。
我晕,我的回复你确认看了吗?我怎么感觉是在对空气说话呢?!MSDN中的示例代码都贴上了,都被你无视了。
提供两个关键字,BS_DEFPUSHBUTTON、DLGC_DEFPUSHBUTTON,别的不多说了,这个主题我也不会再回复了。