Forcing window on top of everything

BlitzPlus Forums/BlitzPlus Programming/Forcing window on top of everything

steve.jr(Posted 2003) [#1]
I was experimenting with a program which would remind you about events (tv program on/collect kids from cubs/shopping etc). Ive had a look but I cant find how to force the window to be on top of anything. If your playing a game of UT2003 there must be a way to have the reminder program pop up and remind you with whatever you set the message to be. ICQ does this for example.

Anyone know how to do this in blitz?


soja(Posted 2003) [#2]
Sure, sorry I can't give you more details at this moment, but I remember seeing some functions to do this with in the User32.dll. BringWindowToTop? GetForegroundWindow? Etc... it would be pretty simple to make userlibs. Let me know if you need more info/help and I can look into more when I get back.


steve.jr(Posted 2003) [#3]
Hi

Ive written the code below but I still cant get the same effect as Task Manager or ICQ where it can stay on top of ANY window. The code below works for windows apps but not while games are running :(

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

win=CreateWindow("blah",280,30,250,190,Desktop(),17) 
hwnd=QueryObject(win,1 ) ;returns windows HWND 
api_SetWindowPos(hwnd,HWND_TOPMOST,280, 30, 250, 190, 0)
api_SetForegroundWindow (hwnd)


Repeat 
	wx=GadgetX(win) : wy=GadgetY(win) 
	ww=GadgetWidth(win) : wh=GadgetHeight(win) 
	;api_SetWindowPos(win_hwnd, HWND_TOPMOST, 280, 30, 250, 190, 0)
	;api_SetWindowPos(win_hwnd, HWND_NOTOPMOST,280, 30, 250, 190, 0)
	;api_SetWindowPos(hwnd,HWND_TOPMOST,wx, wy, ww, wh, 0)
	;api_SetWindowPos(hwnd,HWND_TOPMOST,wx, wy, ww, wh, 0)
Until WaitEvent()=$803 

End



GfK(Posted 2003) [#4]
I haven't got any games installed, so I can't test, but, wouldn't a Notify command do the trick?


steve.jr(Posted 2003) [#5]
Id rather have control over the window, I planned to have the window to include date/time and some other information. Much like sticky notes.


Oldefoxx(Posted 2003) [#6]
I think you will find that there is no absolute always-at-the-top layer capability in Windows. True, you can flag always-on-top, but if another windows is also trying to be always-on-top... well you can see the resulting problem.

Games presume that you want them to be at their best when you play them. They try to dominate your machine, and by taking control of the foreground, they ensure that they get the most timeslots as generally allocated to make a good showing.


steve.jr(Posted 2003) [#7]
I wonder how ICQ and other apps do it then?


poopla(Posted 2003) [#8]
Does B+ not use massive ammounts of processor cycles like B3d? If it does then this sounds nutz.


Shagwana(Posted 2003) [#9]

Does B+ not use massive ammounts of processor cycles like B3d? If it does then this sounds nutz.



Nope, blitz+ can be coded not to use masses of processor cycles. Its a much more windows freindly way of coding then blitz3d.


EOF(Posted 2003) [#10]
@steve.jr

See if this does the trick:

; Always On top - example
; Syntax Error

; userlibs
; ***********************************
; .lib "user32.dll
; SetWindowPos%(hWnd%,hWndAfter%,x%,y%,w%,h%,flags%):"SetWindowPos"
; ***********************************

Global title$="Always On Top"
AppTitle title$
win = CreateWindow(title$,200,100,200,100,Desktop(),3)
checkbox=CreateButton("Keep me on top of other windows",10,20,200,28,win,2)
SetButtonState checkbox,True

AlwaysOnTop win

; --------------------------

Repeat
	ev=WaitEvent()
	If ev=$401
		AlwaysOnTop win , ButtonState(checkbox)
	EndIf
Until ev=$803
End

; --------------------------

; set/clear the 'AlwaysOnTop' state of a BlitzPlus window
Function AlwaysOnTop(bpwin,flag=True)
	SetWindowPos QueryObject(bpwin,1) , -2+flag ,0,0,0,0 , 83
End Function



steve.jr(Posted 2003) [#11]
Nice idea and it works for applications but if someone is playing a game the reminder program does not come to the foreground and stay there. I think other applications which can do this must find all current running programs in memory and force them to the background?


AKJ(Posted 2003) [#12]
Below is a procedure extracted from a PureBasic program I wrote a few months ago. It is based on a routine I received from James L Boyd and it works very reliably.

The parameter 'ontop' should be True to force the window to remain on top, and False to subsequently cancel the effect.

It should be quite easy to translate to Blitz Plus code. The names of API constants start with # and the names of API routines end in _ .

Procedure.b WindowOnTop(ontop)
; ontop = True (1) for window to be on top, else False (0)
Hwin = WindowID() ; Window handle
If ontop
ontop = 1
zorder = #HWND_TOPMOST
BringWindowToTop_(Hwin)
Else
zorder = #HWND_NOTOPMOST
EndIf
; Make the on top request persistent
begindeferstruct = BeginDeferWindowPos_(1)
If begindeferstruct

deferstruct = DeferWindowPos_(begindeferstruct, Hwin, zorder, 0, 0, 0, 0, #SWP_NOMOVE+#SWP_NOSIZE+#SWP_SHOWWINDOW*ontop)

If deferstruct
res.b = EndDeferWindowPos_(deferstruct)
ProcedureReturn res
EndIf
EndIf
EndProcedure

Anthony Jordan


steve.jr(Posted 2003) [#13]
Cheers for the code, but this will only work with windowed applications and not fullscreen applications. I noticed messenger is able to stay on top of fullscreen games so it looks like another undocumented Microsoft API call :(