先看一下MSDN对于Show方法的文档,其中Style参数决定了窗体的显示方式:
---
object.Show style, ownerform
Show 方法的语法包含下列部分:
部分 描述
object 可选的。一个对象表达式,其值为“应用于”列表中的一个对象。如果省略 object,则与活动窗体模块关联的窗体缺省为 object。
Style 可选的。一个整数,它用以决定窗体是模式还是无模式 。如果 style 为 0,则窗体是无模式的;如果 style 为 1,则窗体是模式的。
ownerform 可选的。字符串表达式,指出部件所属的窗体被显示。对于标准的Visual Basic 窗体,使用关键字 Me。
---
如果想判断窗体是否为模态显示,有一种方法是大家都知道的,
就是通过Tag或者其他方式在Show的时候记录其是否为模态,在需要判断的时候可以判断此属性或者变量.
但这种方式的缺点在于如果窗口比较多,每次都记录的话改起来比较麻烦,而且也不好维护.
现在有一个问题:
请问有没有什么办法可以直接获取窗体是否为模态显示的,而不用自己写语句去记录状态?(即有没有内置的属性或者api函数可以判断窗体是否为模态显示?)
26 个解决方案
#1
其实模态并不是窗口的状态。
模态窗口是这样一组操作的集合:
1 设置调用窗口为主窗口的子窗口
2 将主窗口的Enable设置为False
3 显示调用窗口
你可以用这个思路,获得当前窗口的父窗口,判断它是否Enable。
模态窗口是这样一组操作的集合:
1 设置调用窗口为主窗口的子窗口
2 将主窗口的Enable设置为False
3 显示调用窗口
你可以用这个思路,获得当前窗口的父窗口,判断它是否Enable。
#2
可是如果没有父窗口怎么办呢?或者不知道父窗口?
另外,我觉得模态显示和Enabled设置为False还是有一些区别的:
比如说,
1 在显示模态窗口的时候,点击父窗口会导致被显示的模态窗口标题闪动;
2 在显示模态窗体的时候,其父窗体(如果有的话)的消息循环是阻塞的,并且不会执行Show之后的语句,直到模态窗体被关闭.
另外,我觉得模态显示和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
你显示子窗口,你看看是不是照样更新。
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 某窗口为模式窗口
其实真正的模式窗口并非只父窗口被禁用,而是线程内的所有窗口都被禁用
一般情况下,判断某个窗口是否为模式窗口可以这样测试
if iswindowenabled( Getwindow(hwnd,gw_owner)) =0 then 某窗口为模式窗口
#9
支持。
#10
顶
#11
同意,这就是我在1楼说的办法。
#12
帮你顶
#13
记得很早以前我写过一个小工具,叫 Window Resizer,可以设置窗口的状态。
下载:http://www.onlinedown.net/soft/27125.htm
你可以做一个验证。打开记事本,打开查找/替换对话框,打开帮助-关于对话框。
然后用我的程序启用主窗口。这时候,查找/替换对话框也被激活了,而关于对话框成了非模态子窗口
我推测:
其实真正的模式窗口并非只父窗口被禁用,而是线程内的所有窗口都被禁用
这个是更低级的窗口函数自动实现的。
所以简单地说,模态窗口就是这样一组操作的集合:
1 设置调用窗口为主窗口的子窗口
2 将主窗口的Enable设置为False
3 显示调用窗口
下载:http://www.onlinedown.net/soft/27125.htm
你可以做一个验证。打开记事本,打开查找/替换对话框,打开帮助-关于对话框。
然后用我的程序启用主窗口。这时候,查找/替换对话框也被激活了,而关于对话框成了非模态子窗口
我推测:
其实真正的模式窗口并非只父窗口被禁用,而是线程内的所有窗口都被禁用
这个是更低级的窗口函数自动实现的。
所以简单地说,模态窗口就是这样一组操作的集合:
1 设置调用窗口为主窗口的子窗口
2 将主窗口的Enable设置为False
3 显示调用窗口
#14
呵呵,不是父子关系,是属主关系。
#15
form1:
form2.show ,me
form2:
form1.enabled = not form1.enabled
这两句就能实现 form2 的模式与非模切换了
创建模式窗口其实在ms看来那是一个宏, msdn 上都一直这么叫...
而且是模版窗口操作函数
#16
从表面上来看,似乎是这么回事。
但事实证明不象这简单:
' 标准模块中的代码
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 Explicit
Private 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 Long
Private Const GW_OWNER As Long = 4
Private Const GW_HWNDNEXT As Long = 2
Private 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
#17
VB的模态显示确实可以用属主窗口的Enabled属性判断出来.
谢谢各位:)
谢谢各位:)
#18
发现一个有趣的现象:
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.
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.
#19
MessageBox和VB模态实现机制不同。
你显示MessageBox后点主窗口,窗口标题栏不闪吧 :)
#20
其实还是有区别的:
VB中的模态窗体不会在任务栏上显示,即使选中了ShowInTaskbar属性
#21
呵呵,确实是这样:)
#22
lz的分是不是可以考虑多给我一点合适?
#23
帮顶哇
#24
要判断msgbox类的模式窗口简单很多,它们都有WS_POPUP风格。
#25
反驳一下楼主的新发现(其实这东西,我N久前就做过测试)
msgbox并不能阻止timer事件,不管你带哪个参数,请不要在IDE里测试(你的程序不会只在IDE里使用吧?),请编译以下程序到EXE文件,然后运行并观查结果。、
Private Sub Form_Paint()
MsgBox "?", vbSystemModal
End Sub
Private Sub Timer1_Timer()
Text1 = Time
End Sub
#26
是啊,呵呵
谢谢你帮了大忙了
#1
其实模态并不是窗口的状态。
模态窗口是这样一组操作的集合:
1 设置调用窗口为主窗口的子窗口
2 将主窗口的Enable设置为False
3 显示调用窗口
你可以用这个思路,获得当前窗口的父窗口,判断它是否Enable。
模态窗口是这样一组操作的集合:
1 设置调用窗口为主窗口的子窗口
2 将主窗口的Enable设置为False
3 显示调用窗口
你可以用这个思路,获得当前窗口的父窗口,判断它是否Enable。
#2
可是如果没有父窗口怎么办呢?或者不知道父窗口?
另外,我觉得模态显示和Enabled设置为False还是有一些区别的:
比如说,
1 在显示模态窗口的时候,点击父窗口会导致被显示的模态窗口标题闪动;
2 在显示模态窗体的时候,其父窗体(如果有的话)的消息循环是阻塞的,并且不会执行Show之后的语句,直到模态窗体被关闭.
另外,我觉得模态显示和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
你显示子窗口,你看看是不是照样更新。
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 某窗口为模式窗口
其实真正的模式窗口并非只父窗口被禁用,而是线程内的所有窗口都被禁用
一般情况下,判断某个窗口是否为模式窗口可以这样测试
if iswindowenabled( Getwindow(hwnd,gw_owner)) =0 then 某窗口为模式窗口
#9
支持。
#10
顶
#11
同意,这就是我在1楼说的办法。
#12
帮你顶
#13
记得很早以前我写过一个小工具,叫 Window Resizer,可以设置窗口的状态。
下载:http://www.onlinedown.net/soft/27125.htm
你可以做一个验证。打开记事本,打开查找/替换对话框,打开帮助-关于对话框。
然后用我的程序启用主窗口。这时候,查找/替换对话框也被激活了,而关于对话框成了非模态子窗口
我推测:
其实真正的模式窗口并非只父窗口被禁用,而是线程内的所有窗口都被禁用
这个是更低级的窗口函数自动实现的。
所以简单地说,模态窗口就是这样一组操作的集合:
1 设置调用窗口为主窗口的子窗口
2 将主窗口的Enable设置为False
3 显示调用窗口
下载:http://www.onlinedown.net/soft/27125.htm
你可以做一个验证。打开记事本,打开查找/替换对话框,打开帮助-关于对话框。
然后用我的程序启用主窗口。这时候,查找/替换对话框也被激活了,而关于对话框成了非模态子窗口
我推测:
其实真正的模式窗口并非只父窗口被禁用,而是线程内的所有窗口都被禁用
这个是更低级的窗口函数自动实现的。
所以简单地说,模态窗口就是这样一组操作的集合:
1 设置调用窗口为主窗口的子窗口
2 将主窗口的Enable设置为False
3 显示调用窗口
#14
呵呵,不是父子关系,是属主关系。
#15
form1:
form2.show ,me
form2:
form1.enabled = not form1.enabled
这两句就能实现 form2 的模式与非模切换了
创建模式窗口其实在ms看来那是一个宏, msdn 上都一直这么叫...
而且是模版窗口操作函数
#16
从表面上来看,似乎是这么回事。
但事实证明不象这简单:
' 标准模块中的代码
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 Explicit
Private 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 Long
Private Const GW_OWNER As Long = 4
Private Const GW_HWNDNEXT As Long = 2
Private 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
#17
VB的模态显示确实可以用属主窗口的Enabled属性判断出来.
谢谢各位:)
谢谢各位:)
#18
发现一个有趣的现象:
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.
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.
#19
MessageBox和VB模态实现机制不同。
你显示MessageBox后点主窗口,窗口标题栏不闪吧 :)
#20
其实还是有区别的:
VB中的模态窗体不会在任务栏上显示,即使选中了ShowInTaskbar属性
#21
呵呵,确实是这样:)
#22
lz的分是不是可以考虑多给我一点合适?
#23
帮顶哇
#24
要判断msgbox类的模式窗口简单很多,它们都有WS_POPUP风格。
#25
反驳一下楼主的新发现(其实这东西,我N久前就做过测试)
msgbox并不能阻止timer事件,不管你带哪个参数,请不要在IDE里测试(你的程序不会只在IDE里使用吧?),请编译以下程序到EXE文件,然后运行并观查结果。、
Private Sub Form_Paint()
MsgBox "?", vbSystemModal
End Sub
Private Sub Timer1_Timer()
Text1 = Time
End Sub
#26
是啊,呵呵
谢谢你帮了大忙了