请问如何判断已经显示的窗体是否是模态的?

sonic_andy 2010-05-18 09:00:43
请问如何判断已经显示的窗体是否是模态显示的?

先看一下MSDN对于Show方法的文档,其中Style参数决定了窗体的显示方式:
---
object.Show style, ownerform

Show 方法的语法包含下列部分:

部分 描述
object 可选的。一个对象表达式,其值为“应用于”列表中的一个对象。如果省略 object,则与活动窗体模块关联的窗体缺省为 object。
Style 可选的。一个整数,它用以决定窗体是模式还是无模式 。如果 style 为 0,则窗体是无模式的;如果 style 为 1,则窗体是模式的。
ownerform 可选的。字符串表达式,指出部件所属的窗体被显示。对于标准的Visual Basic 窗体,使用关键字 Me。

---

如果想判断窗体是否为模态显示,有一种方法是大家都知道的,
就是通过Tag或者其他方式在Show的时候记录其是否为模态,在需要判断的时候可以判断此属性或者变量.
但这种方式的缺点在于如果窗口比较多,每次都记录的话改起来比较麻烦,而且也不好维护.

现在有一个问题:
请问有没有什么办法可以直接获取窗体是否为模态显示的,而不用自己写语句去记录状态?(即有没有内置的属性或者api函数可以判断窗体是否为模态显示?)
...全文
1000 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
liguicd 2010-05-20
  • 打赏
  • 举报
回复
帮顶哇
sonic_andy 2010-05-20
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 pctgl 的回复:]
lz的分是不是可以考虑多给我一点合适?
[/Quote]
是啊,呵呵
谢谢你帮了大忙了
chinaboyzyq 2010-05-20
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 sonic_andy 的回复:]

发现一个有趣的现象:
Form2.Show vbModal
不能阻止当前窗口上的Timer事件
但是MsgBox却可以阻止Timer事件,即使不加下边的参数:-)

msgbox 貌似有2个模态相关的参数:
vbApplicationModal 0 Application modal; the user must respond to the message box before c……
[/Quote]
反驳一下楼主的新发现(其实这东西,我N久前就做过测试)
msgbox并不能阻止timer事件,不管你带哪个参数,请不要在IDE里测试(你的程序不会只在IDE里使用吧?),请编译以下程序到EXE文件,然后运行并观查结果。

Private Sub Form_Paint()
MsgBox "?", vbSystemModal
End Sub

Private Sub Timer1_Timer()
Text1 = Time
End Sub



lsftest 2010-05-20
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 sonic_andy 的回复:]
发现一个有趣的现象:
Form2.Show vbModal
不能阻止当前窗口上的Timer事件
但是MsgBox却可以阻止Timer事件,即使不加下边的参数:-)

msgbox 貌似有2个模态相关的参数:
vbApplicationModal 0 Application modal; the user must respond to the message box before co……
[/Quote]
要判断msgbox类的模式窗口简单很多,它们都有WS_POPUP风格。
PctGL 2010-05-19
  • 打赏
  • 举报
回复

form1:
form2.show ,me


form2:
form1.enabled = not form1.enabled


这两句就能实现 form2 的模式与非模切换了


创建模式窗口其实在ms看来那是一个宏, msdn 上都一直这么叫...
而且是模版窗口操作函数
lyserver 2010-05-19
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 caozhy 的回复:]
1 设置调用窗口为主窗口的子窗口
[/Quote]
呵呵,不是父子关系,是属主关系。
PctGL 2010-05-19
  • 打赏
  • 举报
回复
lz的分是不是可以考虑多给我一点合适?
threenewbee 2010-05-19
  • 打赏
  • 举报
回复
记得很早以前我写过一个小工具,叫 Window Resizer,可以设置窗口的状态。
下载:http://www.onlinedown.net/soft/27125.htm

你可以做一个验证。打开记事本,打开查找/替换对话框,打开帮助-关于对话框。
然后用我的程序启用主窗口。这时候,查找/替换对话框也被激活了,而关于对话框成了非模态子窗口

我推测:
其实真正的模式窗口并非只父窗口被禁用,而是线程内的所有窗口都被禁用
这个是更低级的窗口函数自动实现的。

所以简单地说,模态窗口就是这样一组操作的集合:
1 设置调用窗口为主窗口的子窗口
2 将主窗口的Enable设置为False
3 显示调用窗口
chinaboyzyq 2010-05-19
  • 打赏
  • 举报
回复
帮你顶
threenewbee 2010-05-19
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 pctgl 的回复:]
没有父窗口的模式窗口和非模式窗口还是有区别的

其实真正的模式窗口并非只父窗口被禁用,而是线程内的所有窗口都被禁用

一般情况下,判断某个窗口是否为模式窗口可以这样测试

if iswindowenabled( Getwindow(hwnd,gw_owner)) =0 then 某窗口为模式窗口
[/Quote]
同意,这就是我在1楼说的办法。
sonic_andy 2010-05-19
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 caozhy 的回复:]
引用 18 楼 sonic_andy 的回复:
发现一个有趣的现象:
Form2.Show vbModal
不能阻止当前窗口上的Timer事件
但是MsgBox却可以阻止Timer事件,即使不加下边的参数:-)

msgbox 貌似有2个模态相关的参数:
vbApplicationModal 0 Application modal; the user must respond to ……
[/Quote]

呵呵,确实是这样:)
sonic_andy 2010-05-19
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 caozhy 的回复:]
没有父窗口调用Modal其实和非模态没有区别。
[/Quote]

其实还是有区别的:
VB中的模态窗体不会在任务栏上显示,即使选中了ShowInTaskbar属性
threenewbee 2010-05-19
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 sonic_andy 的回复:]
发现一个有趣的现象:
Form2.Show vbModal
不能阻止当前窗口上的Timer事件
但是MsgBox却可以阻止Timer事件,即使不加下边的参数:-)

msgbox 貌似有2个模态相关的参数:
vbApplicationModal 0 Application modal; the user must respond to the message box before co……
[/Quote]
MessageBox和VB模态实现机制不同。
你显示MessageBox后点主窗口,窗口标题栏不闪吧 :)
sonic_andy 2010-05-19
  • 打赏
  • 举报
回复
发现一个有趣的现象:
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.

sonic_andy 2010-05-19
  • 打赏
  • 举报
回复
VB的模态显示确实可以用属主窗口的Enabled属性判断出来.
谢谢各位:)
东方之珠 2010-05-19
  • 打赏
  • 举报
回复
lyserver 2010-05-19
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 pctgl 的回复:]
没有父窗口的模式窗口和非模式窗口还是有区别的

其实真正的模式窗口并非只父窗口被禁用,而是线程内的所有窗口都被禁用

一般情况下,判断某个窗口是否为模式窗口可以这样测试

if iswindowenabled( Getwindow(hwnd,gw_owner)) =0 then 某窗口为模式窗口
[/Quote]
支持。
舉杯邀明月 2010-05-19
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 caozhy 的回复:]
记得很早以前我写过一个小工具,叫 Window Resizer,可以设置窗口的状态。
下载:http://www.onlinedown.net/soft/27125.htm

你可以做一个验证。打开记事本,打开查找/替换对话框,打开帮助-关于对话框。
然后用我的程序启用主窗口。这时候,查找/替换对话框也被激活了,而关于对话框成了非模态子窗口

我推测:
其实真正的模式窗口并非只父窗口……
[/Quote]
从表面上来看,似乎是这么回事。

但事实证明不象这简单:
' 标准模块中的代码
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
PctGL 2010-05-19
  • 打赏
  • 举报
回复
没有父窗口的模式窗口和非模式窗口还是有区别的

其实真正的模式窗口并非只父窗口被禁用,而是线程内的所有窗口都被禁用

一般情况下,判断某个窗口是否为模式窗口可以这样测试

if iswindowenabled( Getwindow(hwnd,gw_owner)) =0 then 某窗口为模式窗口
threenewbee 2010-05-18
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 asftrhgjhkjlkttttttt 的回复:]
模式窗口可以蔽屏主窗口的一切的消息发送,除非模式窗口close
你可以发送一个消息给主窗口如果不响应,则这是个模式窗口,若响应则是非模式的
[/Quote]
你有没有用SPY++看过。

主窗口消息仍然可以获得。
加载更多回复(6)

7,763

社区成员

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

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