Board index » Visual Studio » Who's on top?

Who's on top?

Visual Studio271
In a non-MDI VB6 application, if frm1 is the owner of frm2, frm3, & frm4

respectively... how can I determine which of the "owned" forms is on top?

I've tried various API calls, spent hours in Google groups, the API book,

MSDN... but somehow this is escaping me.



I just want to know who is on top, NOT set the topmost window.



Any help would be greatly appreciated.



MIke C.


-
 

Re:Who's on top?

"Mike C." <noname@nonet.net>wrote

Quote
In a non-MDI VB6 application, if frm1 is the owner of frm2, frm3, & frm4

respectively... how can I determine which of the "owned" forms is on top?

I've tried various API calls, spent hours in Google groups, the API book,

MSDN... but somehow this is escaping me.



I just want to know who is on top, NOT set the topmost window.



Any help would be greatly appreciated.





I didn't try it, but will Screen.ActiveForm do that task for you?



LFS







-

Re:Who's on top?

I don't think that will work as there is the possibility that frm1 could be

active (Infocus) with several "owned" forms on top of him. Actually, that

particular situation has been my nemesis.



Mike C.





"Larry Serflaten" <serflaten@usinternet.com>wrote in message

Quote
"Mike C." <noname@nonet.net>wrote

>In a non-MDI VB6 application, if frm1 is the owner of frm2, frm3, & frm4

>respectively... how can I determine which of the "owned" forms is on

top?

>I've tried various API calls, spent hours in Google groups, the API

book,

>MSDN... but somehow this is escaping me.

>

>I just want to know who is on top, NOT set the topmost window.

>

>Any help would be greatly appreciated.





I didn't try it, but will Screen.ActiveForm do that task for you?



LFS











-

Re:Who's on top?

On Fri, 14 Nov 2003 07:27:32 -0500, "Mike C." <noname@nonet.net>

wrote:



Quote
In a non-MDI VB6 application, if frm1 is the owner of frm2, frm3, & frm4

respectively... how can I determine which of the "owned" forms is on top?

I've tried various API calls, spent hours in Google groups, the API book,

MSDN... but somehow this is escaping me.



I just want to know who is on top, NOT set the topmost window.



Any help would be greatly appreciated.



Can't recall using it for exactly that purpose, but it looks like the

GetWindow Api function (with GW_FIRST, GW_NEXT) should do it. It's not

app or thread specific, so you'd need to filter out those windows

who's process or thread IDs (GetWindowThreadProcessId) don't belong to

your app.





-Tom

MVP - Visual Basic

(please post replies to the newsgroup)

-

Re:Who's on top?



Quote
-----Original Message-----

In a non-MDI VB6 application, if frm1 is the owner of

frm2, frm3, & frm4

respectively... how can I determine which of the "owned"

forms is on top?

I've tried various API calls, spent hours in Google

groups, the API book,

MSDN... but somehow this is escaping me.



I just want to know who is on top, NOT set the topmost

window.



Any help would be greatly appreciated.



MIke C.





.



-

Re:Who's on top?

Uhhh, ok... but not sure where to go next with the ProcessID, once I have

that in hand. The GetWindow function requires a Hwnd. And another thought

occured to me... since I'm running in the IDE, could that possibly be why

I'm not picking up correct Hwnd's from the GetWindow function? I was trying

to pass frm1's Hwnd to that function and there's no windows in the Forms

collection that correlates to the return value.



I'm just about ready to implement a window list collection, on my own, to

keep the heirarchy.



Thanks,



Mike C.





"Tom Esh" <tjeshGibberish@earthlink.net>wrote in message

Quote
On Fri, 14 Nov 2003 07:27:32 -0500, "Mike C." <noname@nonet.net>

wrote:



>In a non-MDI VB6 application, if frm1 is the owner of frm2, frm3, & frm4

>respectively... how can I determine which of the "owned" forms is on top?

>I've tried various API calls, spent hours in Google groups, the API book,

>MSDN... but somehow this is escaping me.

>

>I just want to know who is on top, NOT set the topmost window.

>

>Any help would be greatly appreciated.



Can't recall using it for exactly that purpose, but it looks like the

GetWindow Api function (with GW_FIRST, GW_NEXT) should do it. It's not

app or thread specific, so you'd need to filter out those windows

who's process or thread IDs (GetWindowThreadProcessId) don't belong to

your app.





-Tom

MVP - Visual Basic

(please post replies to the newsgroup)





-

Re:Who's on top?

Quote
Can't recall using it for exactly that purpose, but it looks like the

GetWindow Api function (with GW_FIRST, GW_NEXT) should do it. It's not

app or thread specific, so you'd need to filter out those windows

who's process or thread IDs (GetWindowThreadProcessId) don't belong to

your app.



What about EnumThreadWindows()?



Juergen.





-

Re:Who's on top?

On Fri, 14 Nov 2003 11:34:07 -0500, "Mike C." <noname@nonet.net>

wrote:



Quote
Uhhh, ok... but not sure where to go next with the ProcessID, once I have

that in hand. The GetWindow function requires a Hwnd. And another thought

occured to me... since I'm running in the IDE, could that possibly be why

I'm not picking up correct Hwnd's from the GetWindow function? I was trying

to pass frm1's Hwnd to that function and there's no windows in the Forms

collection that correlates to the return value.

GetCurrentProcessID will get you the PID for your app. Or you could

match the thread ID (App.ThreadID) instead. GetWindowThreadProcessID

will fetch both given a hwnd. However on second thought, you really

wouldn't need to match the PID or TID since you would need to iterate

the Forms collection to match up a hwnd with the appropriate form (if

any) for each found hwnd anyway.



Quote
I'm just about ready to implement a window list collection, on my own, to

keep the heirarchy.

That might be a PITA to keep sync'ed. OTOH if you're only interested

in tracking the one on top, a simple way would be stuff a ref to the

form currently on top in a var. You could set it in the forms Activate

events.

Ex:

'in a bas module or the main form...

Public oCurrentTopForm As Form



'in each "owned" form...

Private Sub Form_Activate()

Set oCurrentTopForm = Me

End Sub





-Tom

MVP - Visual Basic

(please post replies to the newsgroup)

-

Re:Who's on top?

On Fri, 14 Nov 2003 19:28:37 +0100, "Juergen Thuemmler"

<thue@gmxremovethis.de>wrote:



Quote
>Can't recall using it for exactly that purpose, but it looks like the

>GetWindow Api function (with GW_FIRST, GW_NEXT) should do it. It's not

>app or thread specific, so you'd need to filter out those windows

>who's process or thread IDs (GetWindowThreadProcessId) don't belong to

>your app.



What about EnumThreadWindows()?



Yeah that'll work, but the problem with the Enum_ funcs (or a

FindWindowEx loop) is that even though they do follow zorder, it's

undocumented behavior. Granted it hasn't changed since Win95, but...

<g>





-Tom

MVP - Visual Basic

(please post replies to the newsgroup)

-

Re:Who's on top?



Quote


>I'm just about ready to implement a window list collection, on my own, to

>keep the heirarchy.

That might be a PITA to keep sync'ed.



Yes, agreed. In what little experimentation that I've done, it has shown to

be a real PITA.



Quote
OTOH if you're only interested

in tracking the one on top, a simple way would be stuff a ref to the

form currently on top in a var. You could set it in the forms Activate

events.



That's a good idea, but when that Top form unloads, sometimes the owner form

gets the focus, and when that happens I don't have a clue who's on top.

That's why I was hoping an API call would be of some benefit.



Thanks Tom... I'll keep plugging away.



Mike





-

Re:Who's on top?

On Sat, 15 Nov 2003 09:54:44 -0500, "Mike C." <noname@nonet.net>

wrote:



Quote
That's a good idea, but when that Top form unloads, sometimes the owner form

gets the focus, and when that happens I don't have a clue who's on top.

That's why I was hoping an API call would be of some benefit.



Thanks Tom... I'll keep plugging away.



If it helps, here's what I was thinking of with GetWindow. The

App.ThreadID test isn't strictly necessary, but it does eliminate

iterating the forms collection for windows that don't belong to the

app.



'declares...

Public Const GW_HWNDFIRST = 0

Public Const GW_HWNDNEXT = 2

Public Declare Function GetWindow Lib "user32" _

(ByVal hwnd As Long, ByVal wCmd As Long) As Long

Public Declare Function GetWindowThreadProcessId Lib "user32" _

(ByVal hwnd As Long, lpdwProcessId As Any) As Long



'implementation...

Public Function GetLastActiveOwnedForm(Owner As Form) As Form

Dim hwndTop As Long

Dim F As Form



hwndTop = GetWindow(Owner.hwnd, GW_HWNDFIRST)

Do While (hwndTop <>0) And (hwndTop <>Owner.hwnd)

If App.ThreadID = GetWindowThreadProcessId(hwndTop, _

ByVal 0&) Then

For Each F In Forms

If F.hwnd = hwndTop Then

Set GetLastActiveOwnedForm = F

Exit Function '======>>>

End If

Next

End If

hwndTop = GetWindow(hwndTop, GW_HWNDNEXT)

Loop

End Function



'ex usage...

Dim F As Form



Set F = GetLastActiveOwnedForm(Me)

If Not (F Is Nothing) Then

Debug.Print F.Name

End If





-Tom

MVP - Visual Basic

(please post replies to the newsgroup)

-

Re:Who's on top?

Tom,



I can't express my gratitude enough, for your help. Your sample works like a

champ and does exactly what I need. Although, I will admit a bit of

apprehension and breath holding as I was looping through all the forms and

finally said the heck with it as I turned off the break point and let it

rip. Once again, thanks so much for your help. I will dance at your wedding,

or ummm, better yet, I'll buy your lunch if you ever find your way into

central North Carolina.



Regards and best wishes,



Mike C.





"Tom Esh" <tjeshGibberish@earthlink.net>wrote in message

Quote
On Sat, 15 Nov 2003 09:54:44 -0500, "Mike C." <noname@nonet.net>

wrote:



>That's a good idea, but when that Top form unloads, sometimes the owner

form

>gets the focus, and when that happens I don't have a clue who's on top.

>That's why I was hoping an API call would be of some benefit.

>

>Thanks Tom... I'll keep plugging away.



If it helps, here's what I was thinking of with GetWindow. The

App.ThreadID test isn't strictly necessary, but it does eliminate

iterating the forms collection for windows that don't belong to the

app.



'declares...

Public Const GW_HWNDFIRST = 0

Public Const GW_HWNDNEXT = 2

Public Declare Function GetWindow Lib "user32" _

(ByVal hwnd As Long, ByVal wCmd As Long) As Long

Public Declare Function GetWindowThreadProcessId Lib "user32" _

(ByVal hwnd As Long, lpdwProcessId As Any) As Long



'implementation...

Public Function GetLastActiveOwnedForm(Owner As Form) As Form

Dim hwndTop As Long

Dim F As Form



hwndTop = GetWindow(Owner.hwnd, GW_HWNDFIRST)

Do While (hwndTop <>0) And (hwndTop <>Owner.hwnd)

If App.ThreadID = GetWindowThreadProcessId(hwndTop, _

ByVal 0&) Then

For Each F In Forms

If F.hwnd = hwndTop Then

Set GetLastActiveOwnedForm = F

Exit Function '======>>>

End If

Next

End If

hwndTop = GetWindow(hwndTop, GW_HWNDNEXT)

Loop

End Function



'ex usage...

Dim F As Form



Set F = GetLastActiveOwnedForm(Me)

If Not (F Is Nothing) Then

Debug.Print F.Name

End If





-Tom

MVP - Visual Basic

(please post replies to the newsgroup)





-