VB6使用SetParent函数出现的问题

时间:2021-07-10 02:02:07
我用SetParent函数把A窗体设为父窗体,B窗体为子窗体,B窗体比A窗体小,程序运行后,如果我的程序被别的程序覆盖了,点击A窗体(也就是父窗体)则可以把我的程序置前,可是点击B窗体则不能把我的程序置前,而我要的效果是当我的程序被别的程序覆盖后,点击子窗体也可以把我的程序置前,请教高手们怎么解决这个问题?(100分!最高了)

37 个解决方案

#1


A 窗口,你的代码是
FrmB.Show
修改成 FrmB.Show , FrmA

#2


1楼的高手,按你说的改了代码,还是没解决问题。

#3


SetParent frmB.hwnd, frmA.hwnd   '用API函数设frmLvheye为frmRcgl的父窗体
frmB.Show , frmA

改成这样了也是不行。

#4


SetParent frmB.hwnd, frmA.hwnd 这个不用了。

在显示frmb的时候调用我的代码

#5


不要SetParent frmB.hwnd, frmA.hwnd 这句代码的后果是B窗体跑到A窗体的外面去了,而我要的是B窗体必须在A窗体里面。

#6


不理解。。。
既然B在A的里面,怎么会出现点了B,A不能获得焦点呢?
再说,B在A里面,完全可以把A设置为MDI父窗体,B设为子窗体。

#7


我说的情况类似记事本的查找/替换对话框,之于主窗口的情况。

#8


我没设MDI窗体,窗体的父子关系是用SetParent设定的。

#9


试一试:
(1)Form1.SetFocus;或者
(2)用SetwindowPos将Form2置顶

#10


...楼主想要的效果是点击窗体的时候,不是show的时候

#11


引用 6 楼 caozhy 的回复:
不理解。。。
既然B在A的里面,怎么会出现点了B,A不能获得焦点呢?
再说,B在A里面,完全可以把A设置为MDI父窗体,B设为子窗体。

我也不太明白lz的意思,貌似不可能......

#12


9楼的你的第一种方法我试过了的,没用。第二种不理想,我不想把我的程序总是置顶。

#13


SetParent() 之后真有问题。
但不 SetParent() 则完全正常。


友情Up.........

#14


郁闷了,还有谁能帮帮我?

#16


那在子窗体的activeWindow事件里调用一下SetForegroundWindow(主窗体句柄)呗~~~

#17


是Form_Activate事件,果然记错了,哇哈哈。。。

#18


用SetParent的话,A窗体被档住了,B窗体怎么能看见?你如何点B啊!

#19


所以,只须将A窗体用SetWindowLong置为*窗口就行了。

#20


应该不是全挡住,挡一半吧。

#21


B窗体在A窗体里面,即A窗体为B窗体的容器,有时候会有别的程序挡了一部分我的程序,比如QQ聊天窗口,这时我要点击B窗体时我的程序置前。可是这种情况下点B窗体区域是不会置前的,要点A窗体显示出来的区域才能置前。

#22


我是初学VB的菜鸟,如果高手们能把实现的代码贴出来加上注释那最好不过了。

#23


'FORM1中。
Option Explicit

Private Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long

Private Sub Form_Load()
    Load Form2
    SetParent Form2.hwnd, Me.hwnd
    Form2.Show
End Sub

'FORM2中。
Option Explicit

Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long

Private Sub Form_Activate()
    SetForegroundWindow Form1.hwnd
End Sub

是这样吧。

#24


既然“B窗体在A窗体里面”,那么直接将B做成UserControl放在A里面就可以了,B就不应该是窗体。

#25


既然都是自己的程序,何不直接用MDI窗体呢?

#26


引用 25 楼 wallescai 的回复:
既然都是自己的程序,何不直接用MDI窗体呢?
我想做个特别点的程序,MDI窗体达不到我想要的效果。

#27


问题解决了,23楼的myjian做的效果正是我要的。非常感谢!

#28


问题又出来了,按23楼说的做,B窗体变成不能编辑了。

#29


引用 28 楼 lvheye 的回复:
问题又出来了,按23楼说的做,B窗体变成不能编辑了。

.......setforegroundWindow,再让自己得到焦点不就行了.....

加个开关量判断一下就行了嘛.

#30


引用 29 楼 myjian 的回复:
引用 28 楼 lvheye 的回复:
问题又出来了,按23楼说的做,B窗体变成不能编辑了。


.......setforegroundWindow,再让自己得到焦点不就行了.....

加个开关量判断一下就行了嘛.
说具体点,怎么加?谢谢了。

#31


Option Explicit

Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetForegroundWindow Lib "user32.dll" () As Long
Dim bShow As Boolean

Private Sub Form_Activate()
    If bShow Then Exit Sub
    bShow = True
    SetForegroundWindow Form1.hwnd
    Me.SetFocus
    Timer1.Enabled = True
End Sub

Private Sub Timer1_Timer()
    Dim lWnd As Long
    
    lWnd = GetForegroundWindow
    If lWnd <> Me.hwnd Then
        Timer1.Enabled = False
        bShow = False
        Form1.SetFocus
        SetForegroundWindow lWnd
    End If
End Sub

定时器时间设置为100就可以了.

发现从FORM2直接切换到外部别的窗体再切换回来的话,FORM2的Activate事件并不会再次触发,所以只有先切换焦点到本进程的其它窗体,再切换到别的外部窗体了.

#32


问题终于解决了,真是太谢谢myjian了。

#33


不过还是有些不理想的地方,就是有一个闪动的过程.

要完美解决,可能要用子类化从消息里处理.......

#34


myjian 不知你还看不看这个贴子,用你后面那种方法后虽然是解决了主要问题,但是我的程序有一个隐藏功能,当点击隐藏后程序就常常出错.

#35


出现什么错?

这几天没上网呢,HOHO.

代码很简单,你跟踪一下吧.

#36


哈哈........终于完美解决了出错和闪的问题....

#37


嘿嘿,那就好呀.

如果方便的话,建议把最终的代码发上来,这样对别人也有帮助的:)

另,新年快乐.

#1


A 窗口,你的代码是
FrmB.Show
修改成 FrmB.Show , FrmA

#2


1楼的高手,按你说的改了代码,还是没解决问题。

#3


SetParent frmB.hwnd, frmA.hwnd   '用API函数设frmLvheye为frmRcgl的父窗体
frmB.Show , frmA

改成这样了也是不行。

#4


SetParent frmB.hwnd, frmA.hwnd 这个不用了。

在显示frmb的时候调用我的代码

#5


不要SetParent frmB.hwnd, frmA.hwnd 这句代码的后果是B窗体跑到A窗体的外面去了,而我要的是B窗体必须在A窗体里面。

#6


不理解。。。
既然B在A的里面,怎么会出现点了B,A不能获得焦点呢?
再说,B在A里面,完全可以把A设置为MDI父窗体,B设为子窗体。

#7


我说的情况类似记事本的查找/替换对话框,之于主窗口的情况。

#8


我没设MDI窗体,窗体的父子关系是用SetParent设定的。

#9


试一试:
(1)Form1.SetFocus;或者
(2)用SetwindowPos将Form2置顶

#10


...楼主想要的效果是点击窗体的时候,不是show的时候

#11


引用 6 楼 caozhy 的回复:
不理解。。。
既然B在A的里面,怎么会出现点了B,A不能获得焦点呢?
再说,B在A里面,完全可以把A设置为MDI父窗体,B设为子窗体。

我也不太明白lz的意思,貌似不可能......

#12


9楼的你的第一种方法我试过了的,没用。第二种不理想,我不想把我的程序总是置顶。

#13


SetParent() 之后真有问题。
但不 SetParent() 则完全正常。


友情Up.........

#14


郁闷了,还有谁能帮帮我?

#15


#16


那在子窗体的activeWindow事件里调用一下SetForegroundWindow(主窗体句柄)呗~~~

#17


是Form_Activate事件,果然记错了,哇哈哈。。。

#18


用SetParent的话,A窗体被档住了,B窗体怎么能看见?你如何点B啊!

#19


所以,只须将A窗体用SetWindowLong置为*窗口就行了。

#20


应该不是全挡住,挡一半吧。

#21


B窗体在A窗体里面,即A窗体为B窗体的容器,有时候会有别的程序挡了一部分我的程序,比如QQ聊天窗口,这时我要点击B窗体时我的程序置前。可是这种情况下点B窗体区域是不会置前的,要点A窗体显示出来的区域才能置前。

#22


我是初学VB的菜鸟,如果高手们能把实现的代码贴出来加上注释那最好不过了。

#23


'FORM1中。
Option Explicit

Private Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long

Private Sub Form_Load()
    Load Form2
    SetParent Form2.hwnd, Me.hwnd
    Form2.Show
End Sub

'FORM2中。
Option Explicit

Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long

Private Sub Form_Activate()
    SetForegroundWindow Form1.hwnd
End Sub

是这样吧。

#24


既然“B窗体在A窗体里面”,那么直接将B做成UserControl放在A里面就可以了,B就不应该是窗体。

#25


既然都是自己的程序,何不直接用MDI窗体呢?

#26


引用 25 楼 wallescai 的回复:
既然都是自己的程序,何不直接用MDI窗体呢?
我想做个特别点的程序,MDI窗体达不到我想要的效果。

#27


问题解决了,23楼的myjian做的效果正是我要的。非常感谢!

#28


问题又出来了,按23楼说的做,B窗体变成不能编辑了。

#29


引用 28 楼 lvheye 的回复:
问题又出来了,按23楼说的做,B窗体变成不能编辑了。

.......setforegroundWindow,再让自己得到焦点不就行了.....

加个开关量判断一下就行了嘛.

#30


引用 29 楼 myjian 的回复:
引用 28 楼 lvheye 的回复:
问题又出来了,按23楼说的做,B窗体变成不能编辑了。


.......setforegroundWindow,再让自己得到焦点不就行了.....

加个开关量判断一下就行了嘛.
说具体点,怎么加?谢谢了。

#31


Option Explicit

Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetForegroundWindow Lib "user32.dll" () As Long
Dim bShow As Boolean

Private Sub Form_Activate()
    If bShow Then Exit Sub
    bShow = True
    SetForegroundWindow Form1.hwnd
    Me.SetFocus
    Timer1.Enabled = True
End Sub

Private Sub Timer1_Timer()
    Dim lWnd As Long
    
    lWnd = GetForegroundWindow
    If lWnd <> Me.hwnd Then
        Timer1.Enabled = False
        bShow = False
        Form1.SetFocus
        SetForegroundWindow lWnd
    End If
End Sub

定时器时间设置为100就可以了.

发现从FORM2直接切换到外部别的窗体再切换回来的话,FORM2的Activate事件并不会再次触发,所以只有先切换焦点到本进程的其它窗体,再切换到别的外部窗体了.

#32


问题终于解决了,真是太谢谢myjian了。

#33


不过还是有些不理想的地方,就是有一个闪动的过程.

要完美解决,可能要用子类化从消息里处理.......

#34


myjian 不知你还看不看这个贴子,用你后面那种方法后虽然是解决了主要问题,但是我的程序有一个隐藏功能,当点击隐藏后程序就常常出错.

#35


出现什么错?

这几天没上网呢,HOHO.

代码很简单,你跟踪一下吧.

#36


哈哈........终于完美解决了出错和闪的问题....

#37


嘿嘿,那就好呀.

如果方便的话,建议把最终的代码发上来,这样对别人也有帮助的:)

另,新年快乐.