++++ 转移焦点的问题 ++++

waiwaijing 2005-10-21 05:33:56
SendKey "{Tab}" 会使焦点在窗口中所有控件中转移焦点,如何能让焦点仅在一组控件中转移焦点呢?

就像CommandButton或OptionButton一样,如果把这些控件用容器(如PictureBox、Frame)分组,当按下方向键时焦点只在同组的控件内转移。这是如何实现的呢?

如能解决,此贴可加到200分,决不食言!

...全文
413 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
waiwaijing 2005-10-31
  • 打赏
  • 举报
回复
看来没有人能帮助我了,散分算了。
再次感谢各位帮助我的朋友:
超级绿豆,尽管你的代码没有帮助我解决问题,但也非常感谢你。
songyaowu,尽管你没有给出任何代码,但我看得出您是非常明确我的意图的,而且你的帮助使我避免使用了错误的代码,我将特别感谢您。
其他兄弟分低些,也就略表心意吧。

waiwaijing 2005-10-29
  • 打赏
  • 举报
回复
感谢各位对我的帮助!
to: songyaowu,您说的有道理,我试了,的确,看来绿豆的代码也不能解决问题。

我最近发现随想命令按钮可以完全实现我的问题,但不知他的作者是不是从不来CSDN、或者说他没看到这个贴子。难道他是个技术保守的人?不愿告诉我?!但好象他不是这种人啊,各位兄弟姐妹们,以位高手,快来帮我吧,要不然又要看老板脸色了。
shawls 2005-10-28
  • 打赏
  • 举报
回复
Private Sub Form_Click()
SendKeys "{tab}"
End Sub

我修改一下

Private Sub Form_Load()
Dim ctl As Control
For Each ctl In Me.Controls
If Not TypeOf ctl.parent.name Is TextBox Then ctl.TabStop = 0
Next
End Sub
Summer006 2005-10-28
  • 打赏
  • 举报
回复
自己写代码来解决把。
捕捉键盘方向键,从当前焦点处向所按方向扫描最近的控件。
就非常麻烦了。
韧恒 2005-10-28
  • 打赏
  • 举报
回复
虽然我还不知道这个问题应如何解决,但可以肯定的是,绿豆先生的办法表面上看可以解决问题,但不能真正解决你的问题。

因为绿豆先生也说了,“窗口根据创建的先后都会有自己特有的ZOrder位置”,而这个与控件的TabIndex并不一致,由于你做的是用户自定义控件,所以你无法保证控件的使用者在开发过程中不去更改控件的TabIndex属性,因此这段代码与想要的结果就不一致了。

看来还得继续!
jxgzay 2005-10-27
  • 打赏
  • 举报
回复
用TabStop属性,如
Command1.TabStop = False
那么Command1将不具有焦点(按下TAB不会落到此处)。

如果你要在一组控件中转移焦点,只要将其它控件的.TabStop设置为False即可。

.TabIndex是顺序号,你可以分成若干组,比如0~3一组,4~7一组。
当.TabIndex在0~3时,用代码将.TabIndex在4~7的.TabStop设置为False,再sendkeys"{TAB}"
supergreenbean 2005-10-27
  • 打赏
  • 举报
回复
老实说,实在看不出这贴进去的控件和自己加的控件有些什么区别。在找到为什么前,恐怕你得一个个拉上去先了,呵呵
waiwaijing 2005-10-27
  • 打赏
  • 举报
回复
超级绿豆,我说你应该叫“超级高手”才对!

你的方案基本已解决问题,但我在测试过程中偶然发现了一个BUG,不知是你这个方案的问题,还是VB的问题,或者是windows本身的问题。情况如下:

对于VB中的标准控件没有任何问题,但对于自定义控件(这正是我要做的),如果控件不设为控件数组,则没有任何问题,但是:如果控件设为控件数组,且有两个以上的控件元素存在,此时,若再向同一容器内粘贴其他控件,如按钮等等,

**** 注意,是“粘贴”控件,那么问题来了(结果令我百思不得其解,经多次测试也有找到问题的真正原因)。此时按方向键时,有些控件将被忽略。若向后移动焦点,则焦点只在最后粘贴的控件和自定义控件中最后的控件中移动,其他控件全被忽略;若向前移动焦点,则自定义控件数组中最后那个控件被忽略。

难道是VB、甚至是getwindow的BUG?

请明示!
supergreenbean 2005-10-26
  • 打赏
  • 举报
回复
这个功能似乎是系统已经做好的。
我们知道窗口根据创建的先后都会有自己特有的ZOrder位置,因此按下箭头键沿着在Z轴前后搜寻窗体大概就是你这个问题的解决方法了。

这里的一个代码片段,完整的示例代码可以从
http://60.191.21.235/supergreenbean/walk2next.rar
下载

Option Explicit
Private Declare Function GetWindow Lib "user32" (ByVal hWnd As Long, ByVal wCmd As Long) As Long
Private Declare Function SetWindowFocus Lib "user32" Alias "SetFocus" (ByVal hWnd As Long) As Long

Private Const GW_HWNDFIRST = 0
Private Const GW_HWNDLAST = 1
Private Const GW_HWNDNEXT = 2
Private Const GW_HWNDPREV = 3

Public Sub Walk2Next(ByVal hWndMe As Long, ByVal KeyCode As Integer)
Dim hWndFirst As Long, hWndLast As Long, hWndPrev As Long, hWndNext As Long
Dim hWndTarget As Long

'获得最顶层窗口句柄
hWndFirst = GetWindow(hWndMe, GW_HWNDFIRST)
'获得最底层窗口句柄
hWndLast = GetWindow(hWndMe, GW_HWNDLAST)
'获得前1个窗口句柄
hWndPrev = GetWindow(hWndMe, GW_HWNDPREV)
'获得后1个窗口句柄
hWndNext = GetWindow(hWndMe, GW_HWNDNEXT)

Select Case KeyCode
'按了向上或向左的箭头键
Case vbKeyUp, vbKeyLeft
hWndTarget = IIf(hWndNext, hWndNext, hWndFirst)
'按了向下或向右的箭头键
Case vbKeyDown, vbKeyRight
hWndTarget = IIf(hWndPrev, hWndPrev, hWndLast)
End Select

'将下个应该获得焦点的窗口设置焦点
SetWindowFocus hWndTarget
End Sub

知道了原理后,就可以为任意的控件(包括自定义控件和TextBox、ComboBox这些原先不支持此功能的控件)添加这个功能了
dong127 2005-10-26
  • 打赏
  • 举报
回复
那你有没有先是一下让windows自己去判断呢?说不定windows自身就能判断
northwolves 2005-10-26
  • 打赏
  • 举报
回复
同样道理,下面代码使焦点只在textbox1所在容器里转移:

Private Sub Form_Click()
SendKeys "{tab}"
End Sub

Private Sub Form_Load()
Dim ctl As Control
For Each ctl In Controls
If Not TypeOf ctl Is Frame Then
If Not ctl.Container.Name = Text1.Container.Name Then
ctl.TabStop = False
Else
ctl.TabStop = True
End If
End If
Next
End Sub
northwolves 2005-10-26
  • 打赏
  • 举报
回复
不需要很高的手吧,以下代码使焦点只在FRAME1中转移:

Private Sub Form_Click()
SendKeys "{tab}"
End Sub

Private Sub Form_Load()
Dim ctl As Control
For Each ctl In Controls
If Not TypeOf ctl Is Frame Then
If Not ctl.Container.Name = "Frame1" Then
ctl.TabStop = False
Else
ctl.TabStop = True
End If
End If
Next
End Sub
waiwaijing 2005-10-26
  • 打赏
  • 举报
回复
楼上的兄弟, 你的方法在提问前我就试过了, 但是不行。达不到效果!

盼高手早日出现!
Tiger_Zhao 2005-10-25
  • 打赏
  • 举报
回复

SendKey "{Right}"

SendKey "{Down}"
waiwaijing 2005-10-25
  • 打赏
  • 举报
回复
楼上的兄弟,我不会食言的,但你还是没有解决我的问题。我说了,我要做一个自定义控件,因此,我并不知到与自己在同一容器内的其他控件是什么,也不知道自己的容器是什么,也许是窗体,也许是frame,或许是picturebox,所以你的代码是无法解决我的问题的。
如果大家对我的问题还不太清楚,那么请建一窗体,在窗体上放一个Picturebox或frame,在这个容器里放两个按钮、两个option、两个checkbox,再在窗体上放两个按钮、两个option、两个checkbox,这时请按方向键,可以看到与按Tab是不同的,它不会在所有控件中转移焦点。但却可以在同一容器内的所有控件中转移焦点。
我就是想知道,当控件接收到方向键时,是不是向容器发送什么消息才由容器处理的?还是控件自己处理的?或者是系统处理的呢?我的控件想要实现此功能该怎么做呢?
知道这里有好多高手、更多很多MVP,敬请赐教!
yourredsun 2005-10-24
  • 打赏
  • 举报
回复
把所有你要分组的控件自己设置TabIndex值,
当按下方向键时,下一个控件是哪个你应该知道吧,
判断这个控件的TabIndex值超没超过你的设置,
超过了让焦点回到分组的第一个上去

因为SendKey "{Tab}"这句是按照控件的TabIndex值,
顺序转移焦点的
fishmans 2005-10-24
  • 打赏
  • 举报
回复
楼主没看清楚northwolves(狼行天下)的意思

他的意思就是设置tabstop这个属性,让不是你要用Tab键的控件都不能用tab键转移焦点(设其tabstop属性为0)

他给出的示例是让非textbox控件的其他控件都不能用tab键转移,你可以根据你的要求把条件换一下应该也可以的~~
waiwaijing 2005-10-24
  • 打赏
  • 举报
回复
首先感谢楼上两位的帮助。但这并解决不了我的问题。

northwolves(狼行天下)说的只是在同类控件中转移,并不是在同组控件中转移,比如窗口中10个按钮,被frame或picturebox分成两组,你的代码会在所有10个按钮中转移焦点。这并不是我想要的。
caozhy(cfx) 的办法更是不行,因为我可能并不知道同一个容器内到底有多少控件。或者它们的名字是什么,所以无法使用这个方法。

可能是我没说清楚,再具体点:我要做一个自定义控件,要按方向键时转移焦点,但并不是发送{Tab}键,因为它会使焦点在窗体中所有控件间转移。而非在同一容器中的控件中转移焦点。我要达到的是象命令按钮或选项按钮那样,按方向键时只在同一容器中的控件中转移焦点。

此贴由原来的50分加到200分,希望我的诚意能打动各路高手来帮我!
zou19820704 2005-10-24
  • 打赏
  • 举报
回复
楼主,兑现你的承诺吧“如能解决,此贴可加到200分,决不食言”
此对于控件数组我没有试过。对于非数组检验通过。
Private Sub Form_Load()
Dim ComButton As Control
For Each ComButton In Controls
If TypeOf ComButton Is CommandButton Then
str = ComButton.Container
If InStr(1, str, Frame1.Name) = 0 Then ComButton.TabStop = False

End If

Next
End Sub
其他的控件类似,你自己推敲吧

threenewbee 2005-10-21
  • 打赏
  • 举报
回复
SetFocus()
加载更多回复(1)

7,762

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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