Form Always On Top
Form Always On Top
Form Always On Top
Form Always On Top
Form Always On Top
Form Always On Top Form Always On Top Form Always On Top Form Always On Top Form Always On Top Form Always On Top Form Always On Top Form Always On Top
Form Always On Top Form Always On Top
Form Always On Top
Go Back  Xtreme Visual Basic Talk > > > Form Always On Top


Reply
 
Thread Tools Display Modes
  #1  
Old 12-08-2016, 08:28 PM
mms mms is offline
Ultimate Contributor
 
Join Date: Jul 2002
Location: Hamilton, Ontario
Posts: 1,855
Default Form Always On Top


I need to have a form always on top in my app, but only over MY app forms.

I do this:

ret = SetWindowPos(Form3.hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE Or SWP_NOMOVE)

and it works.

Problem is, if user opens up Notepad, or Calculator, or Explorer for example, these would be under my topmost form.

How can I correct this, so that my always on top form, is ONLY top most for MY app?

Last edited by mms; 12-08-2016 at 08:42 PM.
Reply With Quote
  #2  
Old 12-09-2016, 02:17 AM
Goggy's Avatar
Goggy Goggy is offline
Contributor
 
Join Date: Sep 2005
Location: Enschede,The Netherlands
Posts: 647
Default

Sounds to me like you want to create an MDI application.
Where in you have one Main form and all the other forms are childeren of this and lay on top of it.
If so, maybe this is a good start for you.

Correct Link
__________________
As finishing touch, god created the Dutch!

utterly useless, but always trying to help

Last edited by Goggy; 12-09-2016 at 02:44 AM. Reason: Changed linked from .Net example to vb6 example
Reply With Quote
  #3  
Old 12-09-2016, 08:00 AM
mms mms is offline
Ultimate Contributor
 
Join Date: Jul 2002
Location: Hamilton, Ontario
Posts: 1,855
Default

Thanks for that, but I don't want to create an MDI application.

Thanks again.
Reply With Quote
  #4  
Old 12-09-2016, 11:28 AM
Cerian Knight's Avatar
Cerian KnightForm Always On Top Cerian Knight is offline
Polymath (in disciplina)

Super Moderator
* Expert *
 
Join Date: May 2004
Location: Michigan
Posts: 4,184
Default

I've done this years ago, but all I can do now is post (what I think are) the relevant code sections.
Module Code:
Code:
Public Sub Hook(ByVal gHW As Long, HKflg As Boolean)
Static IsHooked As Boolean
If HKflg Xor IsHooked Then
    If HKflg Then
        lpPrevWndProc = SetWindowLong(gHW, GWL_WNDPROC, AddressOf WindowProc)
    Else
        SetWindowLong gHW, GWL_WNDPROC, lpPrevWndProc
    End If
    IsHooked = HKflg
End If
End Sub

Public Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Dim PGF As Long
    If uMsg = WM_ACTIVATEAPP Then
        PGF = -wParam
        If frmParent.ShowChild.Checked Then frmChild.OnTop PGF 'this line should be reworked for better error prevention/handling
    End If
    WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, wParam, lParam)
End Function
Parent Form Code:
Code:
Private Sub Form_Load()
Hook Me.hwnd, True
End Sub

Private Sub Form_Unload(Cancel As Integer)
Hook Me.hwnd, False
End Sub
Child Form Code:
Code:
Private Sub Form_Load()
'child form position code goes here
'
OnTop True
End Sub

Public Sub OnTop(Fot As Long)
If Fot Then Me.Show vbModeless, frmParent
End Sub
__________________
I got all the answers wrong on the GLAT, apparently even #9 (where I put a period in the middle of the box and labeled it 'singularity ripe for rapid inflation').

Last edited by Cerian Knight; 12-09-2016 at 03:22 PM. Reason: Replaced a magic number with WM_ACTIVATEAPP
Reply With Quote
  #5  
Old 12-09-2016, 03:13 PM
mms mms is offline
Ultimate Contributor
 
Join Date: Jul 2002
Location: Hamilton, Ontario
Posts: 1,855
Default

Thanks Cerian Knight,

I tried to run your code, but it would not work unless I commented out this line:

If frmParent.ShowChild.Checked Then frmChild.OnTop PGF 'this line should be reworked for better error prevention/handling

Is your code for an MDI app?
Reply With Quote
  #6  
Old 12-09-2016, 03:17 PM
Cerian Knight's Avatar
Cerian KnightForm Always On Top Cerian Knight is offline
Polymath (in disciplina)

Super Moderator
* Expert *
 
Join Date: May 2004
Location: Michigan
Posts: 4,184
Default

Not MDI, because I needed to dock the child forms outside the parent (or even on other monitors).

I don't recall why I was subclassing to receive the WM_ACTIVATEAPP (&H1C) message. You may not need any of the module code...
__________________
I got all the answers wrong on the GLAT, apparently even #9 (where I put a period in the middle of the box and labeled it 'singularity ripe for rapid inflation').
Reply With Quote
  #7  
Old 12-09-2016, 03:35 PM
mms mms is offline
Ultimate Contributor
 
Join Date: Jul 2002
Location: Hamilton, Ontario
Posts: 1,855
Default

It works exactly as I want in this test project (without the subclassing).
On the weekend, I will use in my main project (it uses multiple monitors) and see if it works there.

This seems so trivial, compared to what I was doing.

Thanks!
Reply With Quote
  #8  
Old 12-10-2016, 07:58 AM
mms mms is offline
Ultimate Contributor
 
Join Date: Jul 2002
Location: Hamilton, Ontario
Posts: 1,855
Default

How incredibly simple.

Your code boils down to:

Form1 code (parent form)
Code:
Option Explicit

Private Sub Form_Load()
    Form2.Show
End Sub
Form2 code (child form)
Code:
Option Explicit

Private Sub Form_Load()
    Form2.Show vbModeless, Form1
End Sub
Can this be done without the intrinsic VB methods?
Reply With Quote
  #9  
Old 12-10-2016, 10:55 AM
Cerian Knight's Avatar
Cerian KnightForm Always On Top Cerian Knight is offline
Polymath (in disciplina)

Super Moderator
* Expert *
 
Join Date: May 2004
Location: Michigan
Posts: 4,184
Default

Quote:
Originally Posted by mms View Post
Your code boils down to:
Or perhaps, only:
Code:
'Form1 Code (no Form2 Code)
Private Sub Form_Load()
Form2.Show vbModeless, Me
End Sub
Quote:
Can this be done without the intrinsic VB methods?
Have you tried your original code, but replace 'HWND_TOPMOST' with 'Form1.hWnd' (the parent hWnd)?
__________________
I got all the answers wrong on the GLAT, apparently even #9 (where I put a period in the middle of the box and labeled it 'singularity ripe for rapid inflation').
Reply With Quote
  #10  
Old 12-11-2016, 12:11 AM
mms mms is offline
Ultimate Contributor
 
Join Date: Jul 2002
Location: Hamilton, Ontario
Posts: 1,855
Default

This is the best I can do to mimic the VB method.

I can't put my finger on the difference, but the VB method seems to initially draws the two forms cleaner than the API method.

I will use the VB method.

Form1 code
Code:
Option Explicit

Dim isChildLoaded As Boolean

Private Sub Form_Activate()
    Dim ret As Long
    If isChildLoaded = False Then
        ret = SetWindowPos(Form2.hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE Or SWP_NOSIZE Or SWP_NOMOVE Or SWP_SHOWWINDOW)
        isChildLoaded = True
    End If
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Unload Form2
End Sub
Module1 code
Code:
Option Explicit

Public Const HWND_TOP = 0
Public Const HWND_BOTTOM = 1
Public Const HWND_TOPMOST = -1
Public Const HWND_NOTOPMOST = -2

Public Const SWP_NOSIZE As Long = &H1
Public Const SWP_NOMOVE As Long = &H2
Public Const SWP_NOZORDER As Long = &H4
Public Const SWP_NOREDRAW As Long = &H8
Public Const SWP_NOACTIVATE As Long = &H10
Public Const SWP_FRAMECHANGED As Long = &H20
Public Const SWP_SHOWWINDOW As Long = &H40
Public Const SWP_HIDEWINDOW As Long = &H80
Public Const SWP_NOCOPYBITS As Long = &H100
Public Const SWP_NOOWNERZORDER As Long = &H200
Public Const SWP_NOSENDCHANGING As Long = &H400
Public Const SWP_DEFERERASE As Long = &H2000
Public Const SWP_ASYNCWINDOWPOS As Long = &H4000

Public Declare Function SetWindowPos Lib "user32" _
    (ByVal hwnd As Long, _
     ByVal hWndInsertAfter As Long, _
     ByVal X As Long, _
     ByVal Y As Long, _
     ByVal cx As Long, _
     ByVal cy As Long, _
     ByVal wFlags As Long) As Long
Reply With Quote
  #11  
Old 12-12-2016, 06:16 AM
mms mms is offline
Ultimate Contributor
 
Join Date: Jul 2002
Location: Hamilton, Ontario
Posts: 1,855
Default

Now I remember why I used the SetWindowPos method and not the Form.Show method in the first place.

A message box (or any dialog) will show on the wrong monitor when using the VB.Show method. My SetWindowPos method is not working properly either.

When running the following code, and dragging Form2 to monitor two,
the message box from Command1_Click will be displayed on monitor TWO,
not on monitor ONE as I want.

Form1 code:
Code:
Option Explicit

Private Sub Form_Load()
    Form2.Show vbModeless, Form1
End Sub

Private Sub Command1_Click()
    MsgBox "Test where displayed"
End Sub
My app's user interface form displays on monitor one,
and has a second form which simply shows a PREVIEW of two 8-1/2"X11" pages, that are updated "live" as user does his thing from monitor one.
This preview form is displayed on monitor two.

Any message boxes, dialogs, etc. should show on monitor one, but don't.

So I am looking for help in achieving these results:
- proper dialog placement
- my forms to not steal topmost positions from other apps opened after mine

I've hit a road block (I always struggle with what seems like trivial things).
Reply With Quote
  #12  
Old 12-15-2016, 09:15 AM
Cerian Knight's Avatar
Cerian KnightForm Always On Top Cerian Knight is offline
Polymath (in disciplina)

Super Moderator
* Expert *
 
Join Date: May 2004
Location: Michigan
Posts: 4,184
Default

I'm not sure if this will help, but I think you are bumping into one of the reasons the code I originally shared used subclassing.

Here was the the general idea (as I recall it):
1. Make sure the child form was on top when launched and actively worked with.
2. Remove the on top status of the child form when the WM_ACTIVATEAPP message is received from the parent (as Activate event only works with MDI, as I recall).
3. Conditionally reapply/revoke the child on top status when appropriate.

My child forms could be docked on or outside the parent and the parent had to respond to various events at the same time, so I had to do a lot of trial and error before it worked as intended.
__________________
I got all the answers wrong on the GLAT, apparently even #9 (where I put a period in the middle of the box and labeled it 'singularity ripe for rapid inflation').
Reply With Quote
  #13  
Old 12-15-2016, 02:11 PM
mms mms is offline
Ultimate Contributor
 
Join Date: Jul 2002
Location: Hamilton, Ontario
Posts: 1,855
Default

Thanks Cerian Knight.

I've been trying with the HWND_TOP and HWND_NOTOPMOST value (rather than HWND_TOPMOST) for the hWndInsertAfter parameter
and using the SWP_NOZORDER and SWP_NOOWNERZORDER flags
to get this to work, but to no avail.

I will give your subclassing suggestion a go.
Reply With Quote
Reply

Tags
app, calculator, form, notepad, top


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
Form Always On Top
Form Always On Top
Form Always On Top Form Always On Top
Form Always On Top
Form Always On Top
Form Always On Top Form Always On Top Form Always On Top Form Always On Top Form Always On Top Form Always On Top Form Always On Top
Form Always On Top
Form Always On Top
 
Form Always On Top
Form Always On Top
 
-->