How to? Place a form on top of all other windows BUT behind the taskbar

Hi All,

I'm trying to write a Messenger style popup, All's well the form stays on top of all other windows with HWND_TOPMOST, but this forces it to appear on top of the taskbar as well.  I'd like it to be on top of all windows but behind the taskbar?

Any ideas?

Regards,

Richard Adams.
r_s_adamsAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

codeconquerorCommented:
Try this:

Add this to the declarations section of a module or your form:

<CODE SNIPPET>
Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As Any, ByVal lpWindowName As Any) As Long
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
Const SWP_NOMOVE = &H2
Const SWP_NOSIZE = &H1
Const HWND_TOPMOST = -1
Const HWND_NOTOPMOST = -2
</CODE SNIPPET>

Then use it like this:

<CODE SNIPPET>
SetWindowPos Me.hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE + SWP_NOSIZE '**** Make your window the top most window
lHandle = FindWindow("Shell_TrayWnd", vbNullString) '**** Get the handle of the taskbar
SetWindowPos lHandle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE + SWP_NOSIZE '**** Set the taskbar as the new top most window
</CODE SNIPPET>
nffvrxqgrcfqvvcCommented:
hmmm.. Why not just position your form so its alignment is right above the taskbar rather then below it...This will ensure that the form can be ontop at all times and there would be no need to detect if the form is over the taskbar or not...its pretty simple to get the height of the taskbar..all you need to do is use some API and get the WorkArea which is the size of the screen without counting the taskbar and you subtract that from the screen height and you get the size of the taskbar. However this code assumes the taskbar will be present at the bottom of the screen.

Try this below....


 Option Explicit
Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type
 Const AW_HOR_POSITIVE = &O1
 Const AW_HOR_NEGATIVE = &H2
 Const AW_VER_POSITIVE = &H4
 Const AW_VER_NEGATIVE = &H8
 Const AW_CENTER = &H10
 Const AW_HIDE = &H10000
 Const AW_ACTIVATE = &H20000
 Const AW_SLIDE = &H40000
Const AW_BLEND = &H80000
Const HWND_TOPMOST = -1
Const HWND_NOTOPMOST = -2
Const SWP_NOSIZE = &H1
Const SWP_NOMOVE = &H2
Const SWP_NOACTIVATE = &H10
Const SWP_SHOWWINDOW = &H40
Private Declare Sub 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)

Private Declare Function SystemParametersInfo Lib "User32" _
    Alias "SystemParametersInfoA" (ByVal uAction As Long, _
    ByVal uParam As Long, ByRef lpvParam As RECT, ByVal _
    fuWinIni As Long) As Long
    Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Private Const SPI_GETWORKAREA = 48
Private Declare Function AnimateWindow Lib "User32" _
    (ByVal hWnd As Long, _
    ByVal dwTime As Long, _
    ByVal dwFlags As Long) As Long

Private Sub Form_Activate()
SetWindowPos Me.hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE Or SWP_SHOWWINDOW Or SWP_NOMOVE Or SWP_NOSIZE
End Sub

Private Sub Form_Load()
Dim I As Integer
Dim wa_info As RECT
Dim wa_hgt As Single
Dim wa_wgt As Single
Dim screen_hgt As Single
Dim SizeOfTaskbar As Single

'***************************************
'Form stuff....
'If you want no border you must use _
'borderstyle 1 and set control box false _
'and clipcontrols false + no caption of _
'form
Form1.ClipControls = False
Form1.BorderStyle = 1
Form1.Caption = vbNullString
Form1.Height = 1500
Form1.Width = 2500
'***************************************
    If SystemParametersInfo(SPI_GETWORKAREA, 0, wa_info, 0) <> 0 Then
        screen_hgt = Screen.Height
         wa_hgt = ScaleY(wa_info.Bottom, vbPixels, vbTwips)
         wa_wgt = ScaleY(wa_info.Right, vbPixels, vbTwips)
         SizeOfTaskbar = screen_hgt - wa_hgt
            Debug.Print SizeOfTaskbar
            Form1.Move Screen.Width - Form1.Width, Screen.Height - Form1.Height - SizeOfTaskbar, Form1.Width, Form1.Height
            'Slide form up...
            AnimateWindow Me.hWnd, 1000, AW_SLIDE Or AW_VER_NEGATIVE
            'Set your form color
            Form1.BackColor = vbBlue
            'Set it as topmost window
            SetWindowPos Me.hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE Or SWP_SHOWWINDOW Or SWP_NOMOVE Or SWP_NOSIZE
             End If
            'wait 5 - 10 seconds ...then hide form .
            'Form1.Hide
           
End Sub

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
r_s_adamsAuthor Commented:
Thankyou, U've been away for a week or so so it's nice to come back to some assistance.

Richard.
r_s_adamsAuthor Commented:
Sorry That's I've been away.... that pesky 'U' key sticks (and it's right next to the I)

Richard
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic Classic

From novice to tech pro — start learning today.