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

MiSheps
MiSheps used Ask the Experts™
on
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?


Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
3_S

Commented:
did you try
me.hide

Author

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.

Commented:
See SetWindowPos()
Ensure you’re charging the right price for your IT

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Author

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.

Author

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:

Const HWND_BOTTOM = 1

Author

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! :-)

Commented:
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

Author

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

Author

Commented:
ooops... I spoke to soon....

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

But....

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?

SetWindowPos Me.hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE Or SWP_NOMOVE Or SWP_NOACTIVATE

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()
   'SetWindowPos Me.hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE Or SWP_NOMOVE Or SWP_NOACTIVATE
   FormAlwaysAtBottom
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

Author

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.

buggy.JPG

Author

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
SetParentDesktop.jpg

Author

Commented:
By God Bat-Man! You've done it Danaseaman !!! FANTASTIC HELP! Thank you!

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial