使用 CTabCtrl 和子 CFormView 的 Tab 键顺序
在我的应用程序中,我有一个带有 CTabCtrl
的 CFormView
,我还有 4 个 CFormView,它们是主 CFormView 的子级,当用户更改所选选项卡时显示/隐藏。
但是,我找不到使 Tab 键顺序正常工作的方法。如果 CTabCtrl 具有焦点,则按 Tab 键没有任何效果,并且如果子 CFormView 之一具有焦点,则 Tab 键将仅在 CFormView 内的控件周围移动焦点。
我尝试使用 SetWindowPos
将可见子 CFormView 的 z 顺序更改为位于 CTabCtrl 之后,将子 CFormViews 样式更改为 WS_EX_CONTROLPARENT
但似乎没有任何效果。
In my application I have a CFormView
with a CTabCtrl
, I also have 4 CFormViews that are children of the main CFormView and that are shown/hidden when the user changes the selected tab.
However, I can't find a way to make the Tab Order to work properly. If the CTabCtrl has the focus, pressing the Tab key has no effect and if one of the child CFormView has the focus the Tab key will move the focus only around the controls inside the CFormView.
I tried changing the z-order of the visible child CFormView to be right after the CTabCtrl with SetWindowPos
, changed the child CFormViews styles to WS_EX_CONTROLPARENT
but nothing seems to work.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您从错误的实现开始:您不应该使用
CTabCtrl
创建一个CFormView
,然后将更多的CFormView
填充到其中。这不会正常工作。相反,您应该使用CPropertySheet
和CPropertyPage
,其中焦点处理已经完成。您仍然可以通过调用GetTabControl()
来访问CPropertySheet
拥有的CTabCtrl
,但 MFC 会解决您遇到的问题遇到过。简而言之:为每个要显示的对话框窗口(例如,CConfigPage1、CConfigPage2)从
CPropertySheet
派生类。在资源编辑器中为每个对话框创建一个对话框资源,并执行所有其他标准CDialog
设置。接下来,从
CPropertySheet
派生一个类(例如CProps),并(可选)处理WM_SIZE 和TCN_SELCHANGE。最后,从 CView 后代派生一个类,例如
CScrollView
(例如,CViewMyAwesomeStuff)。然后为CPropertySheet
和CPropertyPage
添加成员变量,并处理 WM_CREATE,其中将每个页面 Add() 到属性表,然后Create(this,WS_CHILD| WS_VISIBLE)
属性表。奖励:您可以通过循环调用
GetPage()
将CView::OnUpdate
转发给每个子CPropertyPage
并调用每个函数的函数,或者您可以向每个函数发送消息(使用用户定义的消息,例如WM_APP+1
)。他们可以通过调用GetParent()->GetParent()->GetDocument()
来发现其父级的CDocument
。You've started out from the wrong implementation: you shouldn't make a
CFormView
with aCTabCtrl
and then stuff moreCFormView
s into it. This isn't going to work right. Instead, you should work withCPropertySheet
andCPropertyPage
, where focus handling has already been taken care of. You will still be able to access theCTabCtrl
owned by theCPropertySheet
by callingGetTabControl()
, but MFC will take care of the problems you've encountered.Briefly: derive classes from
CPropertySheet
for each of the dialog windows you want to show (e.g., CConfigPage1, CConfigPage2). Create a Dialog resource in the Resource Editor for each of them, and do all of the other standardCDialog
setup.Next, derive a class from
CPropertySheet
(e.g., CProps), and (optionally) handle WM_SIZE and TCN_SELCHANGE.Finally, derive a class from a CView descendent, like
CScrollView
(e.g., CViewMyAwesomeStuff). Then add member variables for theCPropertySheet
andCPropertyPage
s, and handle WM_CREATE where you Add() each page to the property sheet and thenCreate(this,WS_CHILD|WS_VISIBLE)
the property sheet.Bonus: You can forward the
CView::OnUpdate
to each childCPropertyPage
by callingGetPage()
in a loop and calling a function on each of them, or you can send a message to each of them (use a user-defined message, likeWM_APP+1
). They can discover their parent'sCDocument
by callingGetParent()->GetParent()->GetDocument()
.