本帖最后由 bcrun 于 2013-08-15 12:51:45 编辑

解决方案 »

  1.   

    代码加一句,先显示窗体,就True了。
    Private Sub Form_Load()
        Me.Show
        Debug.Print Text1.Visible   'VB6 bug:输出false
    End Sub
      

  2.   

    说白了就是一个事件先后的问题.
    先有Initialize事件,再有Load事件,再加载显示控件,再Show 再有Resize事件
    问题是.有Hwnd的没有Show,那就表示不可见.
      

  3.   

    1楼的算是另一种绕弯的办法,不过这样可能会引起显示刷新的“动画”过程变长。唉,BUG就是BUG啊,估计也没太好的办法,也就用这几种方式绕一下算了。
      

  4.   

    类似的,你在vb.net中写类似的代码测试,在load事件里也是visible.这下就知道哪种更合理了吧。
    Sub MainFormLoad(sender As Object, e As EventArgs)
    trace("Form_load Text1.Visible: " & textBox1.Visible.ToString())
    End Sub

    Private Sub trace(ByVal Value As String)
        'Debug.Print value
         listBox1.Items.Add(Value)
    End Sub

    Sub MainFormActivated(sender As Object, e As EventArgs)
    trace("Form_Activated Text1.Visible: " & textBox1.Visible.ToString())
    End Sub
      

  5.   

    这不是 Bug,而是基本概念。
    刚加载没显示的时候就是 Visible = False,这是定性的。
    去检测属性值纯属脱裤子放屁——多此一举。
      

  6.   

    Me.Visible = True
    Debug.Print Text1.Visible
      

  7.   

    这个也算BUG吗?如果你非要在窗体的Load事件中检查控件的Visible属性,基本等同于还没怀孕就检查是男是女一样!!
    至于类似Lable1控件,这些控件没有hwnd属性,它们可以理解为父窗口的一块区域而已。
      

  8.   

    本帖最后由 bcrun 于 2013-08-16 10:41:36 编辑
      

  9.   

    一个 TextBox 控件可以看成一个窗口句柄和一个类的的组成。
    VB6 和 VB.Net 的控件设计方式是不一样的:
    VB6 中句柄和类是强关联的,取 Visible 就是取 hWnd 的对应属性的当前值。
    VB.Net 中句柄和类是弱关联的,取 Visible 属性取的是变量值,并不反映当前的真是状态。
    '以下为 System.Windows.Forms.Control 的 reflector 代码'
    Public Property Visible As Boolean
        Get
            Return Me.GetVisibleCore
        End Get
        Set(ByVal value As Boolean)
            Me.SetVisibleCore(value)
        End Set
    End PropertyFriend Overridable Function GetVisibleCore() As Boolean
        If Not Me.GetState(2) Then '这个标志位存放的是应该是 Visible 属性'
            Return False
        End If
        '就算递归检查容器也与 hWnd 无关'
        Return ((Me.ParentInternal Is Nothing) OrElse Me.ParentInternal.GetVisibleCore)
    End FunctionFriend Function GetState(ByVal flag As Integer) As Boolean
        Return ((Me.state And flag) <> 0)
    End FunctionPrivate state As Integer
    所以两者没有可比性,设计就是这样的,不存在“缺陷”的说法。
      

  10.   


    不是 Bug,是一种设计约定。比如我在某一个控件(比如 ListBox 或 ComBoBox)的 Click 事件中对另一个控件进行操作。如果我在 Form_Load 事件中将对该 ListBox 或 ComBoBox 或 AddItem 并设置了当前 Index,则 Click 事件就被触发。但此时另一个控件还不能进行某些操作,比如 SetFocus(因为还没有完成初始化)。所以,我可以在前一个控件的 Click 事件中这样写:If txtCLS.Visible Then txtCLS.SetFocus这样,由于 FormLoad 中的语句引起的事件触发就不会发生错误,而后续运行中的事件触发就得到正确处理。当然了,如果当初设计时没有对 Visible 这样处理,也还可以再添加一个新的属性,比如较 Initialized 来处理这种情况,也是可以的。但目前的约定更简单一些。不要预先假设微软的设计者比我们更 2。
      

  11.   

    窗口未显示出来之前,其子控件是不可以见的,如果非得在那里面判断,则先使用
    show 显示窗口
      

  12.   

    简单地说,我觉得楼主说的这个,应该还算不上BUG。当然,也不是说“微软出品”就是没BUG 。
    至少,我目前发现了两个在界面处理方面的BUG:
    一个是 Windows XP系统的;一个是 VB6的下拉列表控件的。
      

  13.   

    这个基本上人尽皆知的事情真的不能算BUG
    就好像在load事件中不能xxx.setfocus一样
      

  14.   

     先Load后Initialize好吧?
    一般我们要设置某个控件启动后获得焦点都在Initialize事件中处理。
      

  15.   

    Re:"先Load后Initialize好吧?"
    错,你自己在每个事件开关放个Debug.print就看得出来了