I applied the code exactly as above. It seems to have the limitation that it only brings the form to the "front" at the moment the SetWindowPos command is called.
I tried applying the code to the Form_LostFocus sub which didn't work. I then threw it in a timer, which does seem to have the desired effect, but I would prefer to not have a short duration Timer spam-proc'ing 100% of the time when my program is running.
Any idea how I might be able to event-capture when my form is not on top? Or maybe another method?
As I said in my original post:
"I just want to make it so my form will always be on top of any other programs (it doesn't have to have focus)."
What I meant to say in my last post was, after I call SetWindowPos, it is able to be "behind" other programs that do not have "always on top". Like notepad. The code was copied exactly as above into a blank project.
Last edited by deathfxu; May 8th, 2009 at 08:16 PM.
Reason: typo
I've actually run into similar problems with a couple apps I want AlwaysOnTop, like for instance a WinAmp-style mp3 player. My best guess is that the window may not stay on top if it isn't fully loaded when the SetWindowPos call is made. Doesn't make a ton of sense since you can send a hwnd, but whatever.
My workaround was to set up a short timer to set the form AlwaysOnTop on startup. The timer gets some short delay, like half second or so. It gets Enabled at the end of Form_Load, and when it fires it disables itself and then calls SetWindowPos. End result is that it runs only once, but the form is likely to be fully loaded before it gets called.
This isn't a 100% guaranteed solution. That WinAmp-style program I wrote will occasionally still fail to be always on top if the system is very busy when the program is first run. Despite that, it works correctly the vast majority of the time, so that's the solution I've stuck with.
If anyone has any better ideas, I'm definitely interested.
Create a new project with nothing but the AlwaysOnTop logic implemented and see if that works. If it doesn't, attach that small test project here and I'll take a look.
I have a huge free products range, of computer software in which you can download using any kind of 64-Bit Web Browser. Also there is coming a Social Networking section that I am making on my Website...
|Ambra Productions Inc. | The Black Sun Society | The Black Shield | Ambra College | Church of the Black Sun | Ambra Productions Inc's Homepage | Boomtick Venues: Ambar Nightclub, Jack Rabbit Slim's, Villa Nightclub and Lucy's Love Shack | Pasta Ambra | Fish Feast Company | Wallet Wizard | Ambrose Liquor | Ambar Tavern | Ambra University | Ambra Cheese |
Do you wish to do unpaid work for me??? If so, the PM me on this Forum, and then we can get to work, programming for the future of computers go by the name of ThEiMp. This is my ghost writers name. Also my nickname, means that I am: The Imperial of the Technology Industry, so then to make it really short, I just then wrote: The Imp, which is where I get the nickname from...
Yes, I was waiting until the command triggered. I have been programming in Visual Basic for 12 years. I frequently help people on this website, I just didn't know how to do this "always on top" thing.
ThEiMp, the Zorder command did nothing. Does that work for other people?
In the interest of trying anything, as opposed to just giving up, here is the helper function I've been using since last year:
Code:
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
' Set/unset a form as AlwaysOnTop
Public Sub SetAlwaysOnTop(ByVal hwnd As Long, Optional ByVal AlwaysOnTop As Boolean = True)
Const SWP_NOSIZE = &H1
Const SWP_NOMOVE = &H2
Const SWP_SHOWWINDOW = &H40
Const HWND_NOTOPMOST = -2
Const HWND_TOPMOST = -1
If AlwaysOnTop Then
SetWindowPos hwnd, HWND_TOPMOST, 0&, 0&, 0&, 0&, SWP_NOMOVE Or SWP_NOSIZE Or SWP_SHOWWINDOW
Else
SetWindowPos hwnd, HWND_NOTOPMOST, 0&, 0&, 0&, 0&, SWP_NOMOVE Or SWP_NOSIZE Or SWP_SHOWWINDOW
End If
End Sub
Edge, maybe post your library function too, just so he can try it?
Mods, I'm intentionally violating an explicit board rule here, and for that I apologize. I've attached a bare-bones project that works for me, including the compiled exe it makes. I've reported this post.
deathfxu, run the exe on your computer and see if it works. (The delay is 200ms.) If so, I guess that means your compiler isn't working right. (?!)
Edge, maybe post your library function too, just so he can try it?
K,
Code:
Option Explicit
'ModStayOnTop_No_Focus.bas
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 Const HWND_TOPMOST = -1
Private Const HWND_NOTOPMOST = -2
Private Const SWP_NOSIZE = 1
Private Const SWP_NOMOVE = 2
Private Const SWP_NOACTIVATE = &H10
Private Const FLAGS = SWP_NOMOVE Or SWP_NOSIZE Or SWP_NOACTIVATE
Public Sub StayOnTop(LHwnd As Long, OnTop As Boolean)
If OnTop = True Then
SetWindowPos LHwnd, HWND_TOPMOST, 0, 0, 0, 0, FLAGS
Else
SetWindowPos LHwnd, HWND_NOTOPMOST, 0, 0, 0, 0, FLAGS
End If
End Sub
For me, I have found that the standard "always on top" code doesnt work if you minimize your "on top" form. So my solution was to place the api call in the forms "Form_Resize" event. No timer needed.
Last edited by RobDog888; May 9th, 2009 at 09:09 PM.
VB/Office Guru™ (AKA: Gangsta Yoda™ ®)
I dont answer coding questions via PM. Please post a thread in the appropriate forum.
Well I didn't write this code to do this, that is why I cannot comment on this. But you can go and private message: Ellis Dee for the source code of the top most window.
I have a huge free products range, of computer software in which you can download using any kind of 64-Bit Web Browser. Also there is coming a Social Networking section that I am making on my Website...
|Ambra Productions Inc. | The Black Sun Society | The Black Shield | Ambra College | Church of the Black Sun | Ambra Productions Inc's Homepage | Boomtick Venues: Ambar Nightclub, Jack Rabbit Slim's, Villa Nightclub and Lucy's Love Shack | Pasta Ambra | Fish Feast Company | Wallet Wizard | Ambrose Liquor | Ambar Tavern | Ambra University | Ambra Cheese |
Do you wish to do unpaid work for me??? If so, the PM me on this Forum, and then we can get to work, programming for the future of computers go by the name of ThEiMp. This is my ghost writers name. Also my nickname, means that I am: The Imperial of the Technology Industry, so then to make it really short, I just then wrote: The Imp, which is where I get the nickname from...
How about reinstalling your version of VB6 that might probably work, even more so than the code we are giving you.
I have a huge free products range, of computer software in which you can download using any kind of 64-Bit Web Browser. Also there is coming a Social Networking section that I am making on my Website...
|Ambra Productions Inc. | The Black Sun Society | The Black Shield | Ambra College | Church of the Black Sun | Ambra Productions Inc's Homepage | Boomtick Venues: Ambar Nightclub, Jack Rabbit Slim's, Villa Nightclub and Lucy's Love Shack | Pasta Ambra | Fish Feast Company | Wallet Wizard | Ambrose Liquor | Ambar Tavern | Ambra University | Ambra Cheese |
Do you wish to do unpaid work for me??? If so, the PM me on this Forum, and then we can get to work, programming for the future of computers go by the name of ThEiMp. This is my ghost writers name. Also my nickname, means that I am: The Imperial of the Technology Industry, so then to make it really short, I just then wrote: The Imp, which is where I get the nickname from...
Ellis Dee, in the project you attached the timer was calling the command every 200ms, and did work just like the one I created the same way. When I made the Timer set it's Enabled to False after it proc'd once, it did not stay on top as desired.
But fascinating results here...
RobDog, I tried putting the code in the Form_Resize sub and it worked! But only after manually resizing the form.
So I also added the command to Form_Load again, and it still didn't work till I manually resized the form (I even tried manually calling Form_Resize in Form_Load, to no avail). It's as though the command only works "forever" if it triggers by me manually doing something while the program is running.
In all my years of programming i've never seen anything like this! This is crazy, lol.
Okay, this is pretty funny, but at the moment I have a timer on interval 100 that loops until the user does anything with the form, then whatever they do (click, dblclick, resize, etc) that sub calls the command and turns off the timer, lol.
Somehow it works perfect, lol. I wish I knew what is causing it to only work forever on manually triggered events though.
What I do in this kind of situation is have "Me.Show" then "Me.Refresh" (which could arguably be DoEvents) at the end of Form_Load, followed by the code that affects the form (in this case, the "always on top" code).
That way the visible aspect of the form will exist, and the hWnd should be valid.
Ellis Dee, in the project you attached the timer was calling the command every 200ms, and did work just like the one I created the same way. When I made the Timer set it's Enabled to False after it proc'd once, it did not stay on top as desired.
But fascinating results here...
RobDog, I tried putting the code in the Form_Resize sub and it worked! But only after manually resizing the form.
So I also added the command to Form_Load again, and it still didn't work till I manually resized the form (I even tried manually calling Form_Resize in Form_Load, to no avail). It's as though the command only works "forever" if it triggers by me manually doing something while the program is running.
In all my years of programming i've never seen anything like this! This is crazy, lol.
Sorry, forgot to say that to initialize it, place another call in the Form_Load event. Then it will work like expected and when minimized/restored it will continue to work.
VB/Office Guru™ (AKA: Gangsta Yoda™ ®)
I dont answer coding questions via PM. Please post a thread in the appropriate forum.
RobDog, the problem is that for whatever reason the command only brings the window to the front the instant that I call the command SetWindowPos, except if it's in a subroutine of an event that is manually triggered by the user. (Yes, odd as it sounds.) Which means I can't put it in Form_Load, in a Timer, or anything else that triggers automatically.
Maybe Im missing something but I whipped this up to show that if its automatically set or manually invoked it still works. Maybe you have a different scenerio?
Code:
Option Explicit
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 Const HWND_TOPMOST As Long = -1
Private Const HWND_NOTOPMOST As Long = -2
Private Const SWP_NOSIZE As Long = 1
Private Const SWP_NOMOVE As Long = 2
Private Const SWP_NOACTIVATE As Long = &H10
Private Const FLAGS As Long = SWP_NOMOVE Or SWP_NOSIZE Or SWP_NOACTIVATE
Private mlState As Long
Private Sub OnTop()
SetWindowPos Me.hwnd, mlState, 0, 0, 0, 0, FLAGS
End Sub
Private Sub Command1_Click()
If mlState = HWND_TOPMOST Then
mlState = HWND_NOTOPMOST
Else
mlState = HWND_TOPMOST
End If
OnTop
Me.Label1.Caption = "TopMost State: " & mlState
End Sub
Private Sub Form_Load()
mlState = HWND_TOPMOST
OnTop
Me.Label1.Caption = "TopMost State: " & mlState
End Sub
Private Sub Form_Resize()
OnTop
Me.Label1.Caption = "TopMost State: " & mlState
End Sub
VB/Office Guru™ (AKA: Gangsta Yoda™ ®)
I dont answer coding questions via PM. Please post a thread in the appropriate forum.
The Form_Load call is not making it stay on top. When I resize the form, it does stay on top permanently. When I click on the button the first time, it continues not being on top. But when I click on it again, it will stay on top until I click the button again, at which point it loses "on top" again.
=P
Last edited by deathfxu; May 10th, 2009 at 01:36 PM.
Reason: clarification
Ok I started up the app. Its automatically set to topmost. I resized the form and brought other windows into active and the form remained topmost. I minimized it, restored it, resized it and it still remained topmost
Button first click is HWND_NOTOPMOST
VB/Office Guru™ (AKA: Gangsta Yoda™ ®)
I dont answer coding questions via PM. Please post a thread in the appropriate forum.