窗体的焦点问题,我搞不懂了

kingyo 2011-01-18 11:51:47
我有一个控件,里面包含一个动态下拉的CListbox(派生类类名CInplacePopup),在点击按钮时,就会弹出这个CInplacePopup,当在这个CInplacePopup中选择后,CInplacePopup就会自动隐藏。(这个非常类似CComboBox的效果,点击下拉三角后,就会拉出下拉列表,然后在下拉列表中选择,选好后下拉列表就会自动隐藏。)

这个CInplacePopup的父窗体是桌面,而不是控件本身。

其他功能我都实现了,现在有一个问题:

当下拉的CInplacePopup显示后,我希望这个CInplacePopup获得焦点。可是我不管怎么样,都不能把焦点设置到这个CInplacePopup上来。

方法1:
m_InplacePopup.SetFocus();
//_ASSERTE(::GetFocus() == m_InplacePopup.m_hWnd); //断言不成立
这样子不行,m_InplacePopup没有获得焦点(一般有焦点的ListBox,当前条目上会有虚线框框起来的,这个显示出来的时侯,连虚线框都没有)

方法2:
GetFocus()->SendMessage(WM_KILLFOCUS, 0, 0);
m_InplacePopup.SendMessage(WM_SETFOCUS, ::GetFocus(), 0);
//_ASSERTE(::GetFocus() == m_InplacePopup.m_hWnd); //断言不成立
这样子还是不行,m_InplacePopup貌似获得焦点(因为当前条目上会有虚线框框起来的).可是,他居然不能获得键盘消息,而且断言不成立!!!!

请大家帮忙看看,是什么地方出了问题?
...全文
223 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
yqf_123 2011-01-19
  • 打赏
  • 举报
回复
同意jacky_qiu的说法!
kingyo 2011-01-19
  • 打赏
  • 举报
回复
非常感谢,按照jacky_qiu的方法,确实解决问题了。看来是对窗口的关系没有弄清楚导致的。还要继续努力啊。
kingyo 2011-01-19
  • 打赏
  • 举报
回复
OK,谢谢jacky_qiu,马上测试。
jacky_qiu 2011-01-19
  • 打赏
  • 举报
回复
哈哈!不客气,能够帮上忙也会很高兴的!阿弥陀佛!

[Quote=引用 14 楼 kingyo 的回复:]

非常感谢,按照jacky_qiu的方法,确实解决问题了。看来是对窗口的关系没有弄清楚导致的。还要继续努力啊。
[/Quote]
jacky_qiu 2011-01-18
  • 打赏
  • 举报
回复
1.父窗口,子窗口,还有窗口拥有者的关系要清楚
2.情况一:
(1)创建窗口时CreateWindow 指定了WS_CHILD 并且指定了父窗口句柄,这样的子窗口是不能跳出父窗口的范围。
(2)创建窗口时CreateWindow 指定了WS_POPUP 并且指定了父窗口句柄,这类窗口的特点是他的父窗口其实是桌面(用GetParent得到NULL),而这类窗口的拥有者是刚才指定的父窗口句柄。他们两者应该确定为拥有关系,而不是父子关系。这类窗口可以超出“父窗口”的窗口界限。非模式对话框就是这种关系了。

第一点:我印象中CListBox应该指定父窗口句柄的,也就是说他只能是子窗口,不能是一个弹出窗口(指定风格WS_POPUP)。

第二点:SetFocus 只能用于 设置子窗口获得焦点。你自己的那个类实际上不是子窗口来的(真正意义上的子窗口是不可能跑到父窗口外面的),所以你应该用SetForegroundWindow。

第三点:我用Win32api创建了一个ListBox,是可以获得焦点的,你试一下:
HWND StaticWnd=CreateWindowEx(WS_EX_TOPMOST,TEXT("LISTBOX"),"this is a static" ,
WS_POPUP|WS_VISIBLE|WS_BORDER ,
100,100,200,200,m_hWnd,NULL,NULL,NULL);

最后介绍一篇关于窗口的文章,相当好,你应该看完它,知道窗口间的关系。
http://blog.csdn.net/guogangj/archive/2008/12/06/3460267.aspx
否则以后也会经常遇到一些无法解决的问题。
愿顺利,阿弥陀佛!
kingyo 2011-01-18
  • 打赏
  • 举报
回复
今天晚上,杭州又下大雪了。飘飘洋洋一大片。
kingyo 2011-01-18
  • 打赏
  • 举报
回复
在应用程序中创建一个子窗体,其父窗体是桌面,这种子窗体的SetFocus有什么不一样吗?大家遇到过吗?
oldmtn 2011-01-18
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 kingyo 的回复:]
想把图片贴上来,不知道怎么贴图片。
[/Quote]
1,把图片上传到CSDN的微薄
2,在你CSDN微薄相册里面的 已上传的照片,单击属性就找到图片的链接了,然后这里就可以贴图片了。。
kingyo 2011-01-18
  • 打赏
  • 举报
回复
这里有个地方要注意:如果该CInplacePopup的父窗体是控件的话,就没有这个问题,SetFocus能正常工作,但是只要CInplacePopup的父窗体是桌面,就不行。大家可以从这个区别上看看有没有什么地方我遗漏了?

可惜,如果该CInplacePopup的父窗体是控件的话,CInplacePopup会被控件裁剪掉。
kingyo 2011-01-18
  • 打赏
  • 举报
回复
想把图片贴上来,不知道怎么贴图片。
kingyo 2011-01-18
  • 打赏
  • 举报
回复
我试过了,其实ListBox没有获得焦点,而是焦点还在原来的地方。可是为什么还在原来的地方?为什么SetFocus没有把焦点换过来?
  • 打赏
  • 举报
回复
KillFocus消息是系统在执行SetFocus过程中自动发送的,因为有窗体获得焦点就必有窗体失去焦点。
由程序发送这个消息没有作用的,也没有意义。

要确认列表框控件是否获得了键盘焦点,可以用方向键加空格键操作试试看。
也许是列表框本身有bug,没画出来虚线框。
ghostjeky 2011-01-18
  • 打赏
  • 举报
回复
要setfocus的窗体首先要是激活状态的,LZ可以尝试下先调用SetActiveWindow 然后再调用setfocus
kingyo 2011-01-18
  • 打赏
  • 举报
回复
自己顶,请求帮助!

15,979

社区成员

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

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