应该是一个很简单的问题:如何让自定义CWnd的派生类无法接收WM_SETFOCUS消息?就象对话框一样

atEleven 2003-10-23 11:35:30
新建SDI工程,在CMyView::OnCreate中用Create方式创建一个CEdit控件.编译.
运行,让焦点落在Edit控件上,切换到别的窗口再切换回来,这时焦点是在CMyView上的.如何让焦点直接落在Edit上?

其实我在写一个用作容器的ActiveX控件,这是它的简单模拟.
因为在它上面有很多控件,而且情况也比较复杂,所以不想通过响应WM_SETFOCUS消息对子控件进行SetFocus,希望各位能给点帮助.

感谢任何有内容的提示:)
...全文
458 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
atEleven 2003-10-27
  • 打赏
  • 举报
回复
感谢各位帮助.问题终于解决
最终问题还是落在activex控件上面

先重写IOleInPlaceActivateObject::OnFrameWindowActivate()方法,发现只有VB做客户端(即Container)时不能正确响应.GOOGLE搜索也是这个结果.

后来是通过子类化VB窗口用MFC事件来解决的.

和和,跟我提的问题不相关啊~~~~~~~问题模拟的不好.

结贴.大家都有分
sxslyy 2003-10-24
  • 打赏
  • 举报
回复
将丢失焦点的那个子控件的句柄保存在一个全局变量中,还原时用它设焦点。
fengqinggao 2003-10-24
  • 打赏
  • 举报
回复
思路,未经过测试:
在框架类的
afx_msg void OnActivate( UINT nState, CWnd* pWndOther, BOOL bMinimized );
消息函数中,当窗口DeActive时,用GetFocus()函数获取当前控件的句柄,保存;

然后还是在该函数中,当窗口Active时,用SetFocus()函数将原来保存指针所指的控件设置光标

我想应该是可行的,估计在View类中这样判断也可,甚至更好。
popyyb 2003-10-24
  • 打赏
  • 举报
回复
up
atEleven 2003-10-24
  • 打赏
  • 举报
回复
说一下我的实际情况吧

例子: 实际情况:
CView派生类 COleControl派生类,在VB环境下运行的ActiveX控件.
一个Edit子控件 多个控件(控件还有嵌套,同时还有子的ActiveX控件)

WM_ACTIVATE,就需要处理AcitveX控件的容器的WM_ACTIVATE消息,这个我目前还没想到好方法
WM_SETFOCUS,需要记录并还原切换窗口之前丢失焦点的那个子控件,这个又怎么处理?
vcforever 2003-10-24
  • 打赏
  • 举报
回复
我的建议和wuxfBrave相同。在TransLateMessage()之前,也就是在PretranslateMessage()函数中处理
WM_SETFOCUS和WM_ACTIVE消息!通常情况下我都是这么做的!
arvid_gs 2003-10-24
  • 打赏
  • 举报
回复
PretranslateMessage中处理WM_SETFOCUS
如果是edit则接受,负责继续传递知edit接受为止
atEleven 2003-10-24
  • 打赏
  • 举报
回复
MilitaryMiniatures(++) : 非常感谢你的试验,赞同你的观点:)
通用的做法是这样. fengqinggao(风清高) , wuxfBrave(升星了,休息休息) 的建议也类似.


其他人还有更好的提议吗?
wuxfBrave 2003-10-24
  • 打赏
  • 举报
回复
在PretranslateMessage中处理WM_SETFOCUS和WM_ACTIVATE消息
lqs10 2003-10-24
  • 打赏
  • 举报
回复
这个问题我也碰到过,当时我这样做的:
在控件的EN_KILLFOCUS事件里

void CLoginDlg::OnKillfocusUser()
{
GetDlgItem( IDC_PASSWD)->SetFocus() ;
return;
}

对于你来说,只要在WM_ACTIVATE消息来的时候,GetDlgItem( IDC_PASSWD)->SetFocus() ;就好了,至于你的需求“切换到别的窗口再切换回来,”,必须在窗口的在TransLateMessage()之前,也就是在PretranslateMessage()里,让你的窗口重新激活。


请给分哦
MilitaryMiniatures 2003-10-24
  • 打赏
  • 举报
回复
说说我的实验的结果(一个晚上就在做这个试验了,sigh,老了)
1,我的试验说明,对话框在对焦点输入方面,做了处理了。就是说,对话框在响应消息WM_SETFOCUS时,将焦点转向了其中的子控件(应该是通过SetFocus实现的)。
试验的方法如下:创建一个对话框,只包含一个按钮,那么这个按钮自然就拥有了focus(这个时候,没有对对话框作任何处理)。然后在该对话框中加入定时器(为方便观察,将定时器设置为2秒),在定时器中,唯一作的事情就是调用对话框自身的SetFocus()),这个时候,如果你没有修改对话框的其余部分,那么focus将一直停留在这个按钮上。然而,如果重载对话框的WM_SETFOCUS消息响应,其中什么也不做(目的是为了防止它调用对话框的处理过程),这个时候,你将看到,按钮将失去输入焦点!这说明,对话框在响应消息WM_SETFOCUS时,将输入焦点传输给了其中的子控件;
2,对话框在WM_ACTIVATE的消息处理中,将Focus传输给了其中的子控件。
(1),你如果没有对对话框作任何处理,使用spy++观察这个对话框,你发现它没有得到WM_SETFOCUS消息,因此并没有得到focus;即使你Activate多次,也是这样。
(2),用1中的方法,屏蔽对话框的WM_ACTIVATE以及WM_SETFOCUS消息处理过程,那么你将发现,你切换窗口返回到对话框的时候,那个按钮不再有输入焦点!屏蔽WM_SETFOCUS是为了防止它把focus传递给子控件。这说明,WM_ACTIVATE处理中,将focus传递给了子控件。

这两个实验表明,你要达到你这个目的,一般来说,也要进行两个方面的处理(也许一个就可以了)。
对于WM_ACTIVATE消息,它只是发送给top-level窗口的,而view是个子窗口,不可能有该消息,此时,你可以重载CView::OnActivateView来达到同样的效果,你大概需要在其中设置输入焦点(如果Activate)或者保存输入焦点的控件(如果Deactivate);
对于WM_SETFOCUS消息,你大概需要在其中通过SetFocus进而将焦点传递给其中的子控件;你可以参考CFormView中关于这几个消息的处理过程;

也就是说,楼主提出的,不通过WM_SETFOCUS处理而达到相同的效果,恐怕很难实现。(你在CDialog这个类里面看不到WM_SETFOCUS等的处理函数,是因为这些处理都在Default里面处理,由Windows实现,而不是MFC,题外话)

好累啊:)
MilitaryMiniatures 2003-10-24
  • 打赏
  • 举报
回复
WM_ACTIVATE只是发送给top-level窗口的,子窗口,包括view,是响应不到这个消息的,view的话,只能重载OnActivateView
atEleven 2003-10-23
  • 打赏
  • 举报
回复
我是希望窗口能象对话框一样,当Activate的时候就把焦点转换到子控件中去.

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧