Using VB6 - How to force my application to sit behind all other applications.

Greetings Experts,

I have an application which I developed called "ACM".

In short, it is an application which handles our run-time environment for applications that load in our controlled environment. It sits in the Windows Startup, and is designed to handle the following tasks:

1) Load necessary applications upon startup, in a specific order
2) Sit in the background and wait for files to process (in the background, without taking focus)
3) constantly check for the status of a specific application, Lets Call that app "Main APP" for reference to see if the process (application) is running or not.
4) Once it senses that it isn't running, it handles some other functions, and eventually shuts the computer off.

Everything works great as I have it right now... other then one very important thing. Sometimes, for some reason, my application pops in front of the other application. This creates a problem, because The types of units that this is running on are PDA type units (where there is no easy keyboard ot Alt+Tab, etc.) So to get back to the main application is difficult or impossible.

In short, I have to always ensure that my application sits behind all other applications, with no acception.

Attributes of my main form are:
   * Running in full screen mode
   * visible
   * No title bars
   * no X, Min, etc.

I know how to use top most.. but can't find anything for bottom most, etc.

Any suggestions?

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.

did you try
MiShepsAuthor Commented:
I can't use me.hide, because I need my window to be visible in the background.

Basically what it is, is an application Control manager, which launches apps, waits for the apps to close, and then handles a shutdown.

I have built it full screen so that the user can not see the desktop icons, start menu, etc at any time. So... when they close the main app that we have running for them, (which would normally bring you to the windows desktop) instead it shows my ACM which is set to full screen and not closable.

My program then has a password keypad that can be used to avoid shutdown, but if not entered in time, it then shuts the obu down.

So... what I need is:

For my app, to run in full screen, on the first layer above the desktop.

Then all of the other applications that I run would run on top of my app.

Then, when they close, all that is left is my app, which then handles the shutdown.

so, unfortunately me.hide won't work, because that would then show the desktop/icons/start menu, etc.

I specifically need a method to send my application to the back of all others. Basically exactly the opposite of TOPMOST.
See SetWindowPos()
Maximize Customer Retention with Superior Service

The IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy for valuable how-to assets including sample agreements, checklists, flowcharts, and more to help build customer satisfaction and retention.

MiShepsAuthor Commented:
Just searched for SetWindowsPos(), and I have found a million examples on how to use it to set your app to Top-Most, but none on how to set it to back-most....

Any suggestions would be great!

Thank you.
MiShepsAuthor Commented:
I just tried the following, using SetWindowsPos()

Private Const HWND_TOPMOST = -1
Private Const HWND_NOTOPMOST = -2
Private Const SWP_NOMOVE = &H2
Private Const SWP_NOSIZE = &H1
Private Const SWP_NOACTIVATE = &H10
Private Const SWP_SHOWWINDOW = &H40
Private Const Flags = SWP_NOMOVE Or SWP_NOSIZE

Private 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

Private Sub Form_Load()
   Call SetWindowPos(Me.hwnd, HWND_TOPMOST, 0, 0, 0, 0, Flags)
End Sub

Works great to set the window to Topmost... and changing HWND_TOPMOST to HWND_NOTOPMOST works great to remove the topmost functionality....

But what I need is something that will move my window behind all other apps. (not just allow other apps to open over top of it)
Try this Const with SetWindowPos:


MiShepsAuthor Commented:
Wew hew!!!! You ROCK DanaSeaman! :) That 1 answer alone was worth the $200 I just shelled out to join Experts-X !

You may have saved my job! :-)
Sorry, I meant to add 'use HWND_BOTTOM'.

I've got this working, but it required me to subclass the form - the Activate event doesn't work as well as trapping the WM_ACTIVATE message.

Basically, the code is this - well - this works [there are probably better ways!]
    If msg = WM_ACTIVATE Then
        If LowWord(wParam) <> 0 Then ' If it's 1 or 2 the window's being activated.        
            ' Set the next window in the master window list to be active.
            Call SetForegroundWindow(GetWindow(hwnd, GW_HWNDNEXT))
            ' Set this window bottom most again, and set NOACTIVATE.
            Call SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE Or SWP_NOACTIVATE)
            ' Signal we've handled this message.
            NewWindowProc = 0
            Exit Function

Open in new window

MiShepsAuthor Commented:
This is my first post, So I'm not sure if I closed it correctly or not, but thanks to Peetm, and Dana, I've got it working!

Thanks peeps
MiShepsAuthor Commented:
ooops... I spoke to soon....

The suggestions do drop my window back to the back of the window stacks...


As soon as the next line processes in my app, it sends it back to the front....

How do I keep it in the back, behind all other windows, no matter what?
Have you tried SetWindowPos with various flags?


Here is another method:

Don't know if this will work on a PDA but Sub FormAlwaysAtBottom works on Desktop here.
When you click on Form it doesn't budge and stays behind other windows.

Option Explicit
Private Declare Function SetWindowPos Lib "user32.dll" (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
Private Declare Function FindWindowA Lib "user32.dll" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function FindWindowExA Lib "user32.dll" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Private Declare Function SetParent Lib "user32.dll" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long
Private Const HWND_BOTTOM = 1
Private Const SWP_NOMOVE = &H2
Private Const SWP_NOSIZE = &H1
Private Const SWP_NOACTIVATE = &H10
Private Sub Form_Load()
End Sub
Public Sub FormAlwaysAtBottom()
    Dim ProgMan&, shellDllDefView&, sysListView&
    ProgMan = FindWindowA("progman", vbNullString)
    shellDllDefView = FindWindowExA(ProgMan&, 0&, "shelldll_defview", vbNullString)
    sysListView = FindWindowExA(shellDllDefView&, 0&, "syslistview32", vbNullString)
    SetParent Me.hwnd, sysListView
End Sub

Open in new window

MiShepsAuthor Commented:
That looks like it might work... but when I ran it on my desktop, it did something funny....

You can't see the form, and it seems to paint over the icons.  

I don't really have a way of describing this, so I've attached a screen clip.

MiShepsAuthor Commented:
yes... just ran through some tests, and if I can get the above code to not do what it is doing in the attached image, then it should do exactly what I want it to....

And... on a side note... I'm going to keep that snippet of code just for the cool affect that it produces! :) graphically it sits above the icons, but only where there are icons. even when you move the window around, it slides behind the icons and repaints the window on them... neat affect... but not exactly what i'm looking for here! lol... close though...

Get that window to paint fully, above the iconds, but behind all other windows, and I think we will have a winner! :)

I appreciate all the help, VERY MUCH! thank you experts :)
Here is another:

Here is another method which works on Desktop here:

Private Declare Function SetParent Lib "user32.dll" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long
Private Declare Function GetWindow Lib "user32.dll" (ByVal hwnd As Long, ByVal wCmd As Long) As Long

Private Const GW_HWNDLAST As Long = 1

Private Sub Form_Load()
   SetParent Me.hwnd, GetWindow(Me.hwnd, GW_HWNDLAST)
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
MiShepsAuthor Commented:
By God Bat-Man! You've done it Danaseaman !!! FANTASTIC HELP! Thank you!
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.