本帖最后由 sonic_andy 于 2010-05-18 21:01:47 编辑

解决方案 »

  1.   

    其实模态并不是窗口的状态。模态窗口是这样一组操作的集合:
    1 设置调用窗口为主窗口的子窗口
    2 将主窗口的Enable设置为False
    3 显示调用窗口
    你可以用这个思路,获得当前窗口的父窗口,判断它是否Enable。
      

  2.   

    可是如果没有父窗口怎么办呢?或者不知道父窗口?另外,我觉得模态显示和Enabled设置为False还是有一些区别的:
    比如说,
    1 在显示模态窗口的时候,点击父窗口会导致被显示的模态窗口标题闪动;
    2 在显示模态窗体的时候,其父窗体(如果有的话)的消息循环是阻塞的,并且不会执行Show之后的语句,直到模态窗体被关闭.
      

  3.   

    (1)
    Private Sub Command1_Click()
    Form2.Show 0, Me
    Me.Enabled = False
    End Sub这样照样闪烁(2)
    你在Form1里面放一个Timer,添加一个Label
    Private Sub Timer1_Timer()
        Label1.Caption = Now
    End Sub你显示子窗口,你看看是不是照样更新。
      

  4.   

    没有父窗口调用Modal其实和非模态没有区别。
      

  5.   

    UPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUP
      

  6.   

    模式窗口可以蔽屏主窗口的一切的消息发送,除非模式窗口close   
    你可以发送一个消息给主窗口如果不响应,则这是个模式窗口,若响应则是非模式的
      

  7.   

    你有没有用SPY++看过。主窗口消息仍然可以获得。
      

  8.   

    没有父窗口的模式窗口和非模式窗口还是有区别的其实真正的模式窗口并非只父窗口被禁用,而是线程内的所有窗口都被禁用一般情况下,判断某个窗口是否为模式窗口可以这样测试if iswindowenabled( Getwindow(hwnd,gw_owner)) =0 then 某窗口为模式窗口
      

  9.   

    记得很早以前我写过一个小工具,叫 Window Resizer,可以设置窗口的状态。
    下载:http://www.onlinedown.net/soft/27125.htm你可以做一个验证。打开记事本,打开查找/替换对话框,打开帮助-关于对话框。
    然后用我的程序启用主窗口。这时候,查找/替换对话框也被激活了,而关于对话框成了非模态子窗口我推测:
    其实真正的模式窗口并非只父窗口被禁用,而是线程内的所有窗口都被禁用
    这个是更低级的窗口函数自动实现的。所以简单地说,模态窗口就是这样一组操作的集合:
    1 设置调用窗口为主窗口的子窗口
    2 将主窗口的Enable设置为False
    3 显示调用窗口
      

  10.   


    form1:
    form2.show ,me
    form2:
    form1.enabled = not form1.enabled
    这两句就能实现 form2 的模式与非模切换了
    创建模式窗口其实在ms看来那是一个宏, msdn 上都一直这么叫...
    而且是模版窗口操作函数
      

  11.   

    从表面上来看,似乎是这么回事。但事实证明不象这简单:
    ' 标准模块中的代码
    Option Explicit
    ' 把工程设置成从 Sub Main 启动
    Sub Main()
        Load Form1: Form1.Caption = "‘模态’窗口!"
        Form1.Show 1
        Load Form1: Form1.Caption = "‘非模态’窗口!"
        Form1.Show 0
    '   即使直接 form1.Show 1、form1.show 0 ,结果也是一样
    End Sub
    ' Form1 中的代码
    Option ExplicitPrivate Declare Function GetWindow Lib "user32" (ByVal hWnd As Long, ByVal wCmd As Long) As Long
    Private Declare Function IsWindowEnabled Lib "user32" (ByVal hWnd As Long) As LongPrivate Const GW_OWNER      As Long = 4
    Private Const GW_HWNDNEXT   As Long = 2Private Sub Command1_Click()
    ' 单击 Command1 后, 始终输出“非模态”
        Print GetWindow(hWnd, GW_OWNER)     '输出非0
        Print GetWindow(GetWindow(hWnd, GW_OWNER), GW_HWNDNEXT)
        If (IsWindowEnabled(GetWindow(hWnd, GW_OWNER)) = 0) Then
            Print "模态!"
        Else
            Print "非模态!"
        End If
    End Sub
      

  12.   

    VB的模态显示确实可以用属主窗口的Enabled属性判断出来.
    谢谢各位:)
      

  13.   

    发现一个有趣的现象:
    Form2.Show vbModal
    不能阻止当前窗口上的Timer事件
    但是MsgBox却可以阻止Timer事件,即使不加下边的参数:-)msgbox 貌似有2个模态相关的参数:
    vbApplicationModal 0 Application modal; the user must respond to the message box before continuing work in the current application. 
    vbSystemModal 4096 System modal; all applications are suspended until the user responds to the message box. 
      

  14.   

    MessageBox和VB模态实现机制不同。
    你显示MessageBox后点主窗口,窗口标题栏不闪吧 :)
      

  15.   


    其实还是有区别的:
    VB中的模态窗体不会在任务栏上显示,即使选中了ShowInTaskbar属性
      

  16.   

    要判断msgbox类的模式窗口简单很多,它们都有WS_POPUP风格。
      

  17.   

    反驳一下楼主的新发现(其实这东西,我N久前就做过测试)
    msgbox并不能阻止timer事件,不管你带哪个参数,请不要在IDE里测试(你的程序不会只在IDE里使用吧?),请编译以下程序到EXE文件,然后运行并观查结果。、Private Sub Form_Paint()
        MsgBox "?", vbSystemModal
    End SubPrivate Sub Timer1_Timer()
        Text1 = Time    
    End Sub