animated splash screen with win api stuff

Blitz3D Forums/Blitz3D Programming/animated splash screen with win api stuff

I've been playing around with win api stuff and came up with this animated splash screen. Don't know how usefull this is for 'real' games. Unfortunately it crashes when run in full screen mode :(
Anyway, play around with it and com up with improvements, ideas

You have to compile this code before running the testing code below.

;*******************************************************************************************
; animated splash screen by nadia, Jan 2005
;
; to run this sample code you need to compile this 'animSplash.bb' to 'animSplash.exe
; and save it in the same folder as 'test animSplash.bb'
;
; make sure you add the following declarations to the user libs:
;
;		.lib "Gdi32.dll"
;		api_CreateRectRgn%(X1%, Y1%, X2%, Y2%): "CreateRectRgn"
;		api_CreateRoundRectRgn%(X1%, Y1%, X2%, Y2%, X3%, Y3%): "CreateRoundRectRgn"
;
;		.lib "user32.dll"
;		api_FindWindow_0% (lpClassName%, lpWindowName$) : "FindWindowA"
;		api_SendMessage% (hWnd%, wMsg%, wParam%, lParam%): "SendMessageA"
;		api_SetWindowRgn%(hWnd%, hRgn%, bRedraw): "SetWindowRgn"
;		api_SetWindowPos%(hWnd% ,hWndInsertAfter%, x%, y%, cx%, cy%, wFlags%): "SetWindowPos"
;
;;*******************************************************************************************


; API Constants
Const WM_CLOSE 	= $10
Const SWP_NOMOVE 	= 2
Const SWP_NOSIZE 	= 1
Const FLAGS = SWP_NOMOVE Or SWP_NOSIZE
Const HWND_TOPMOST 	= -1
Const HWND_NOTOPMOST = -2

; width and height of anim splash screen app
Const SCR_TITLEBAR_HEIGHT = 27	; height of window title bar
Const SCR_RADIUS = 20				; corner radius for rounded region 


Const SCR_WIDTH  = 250
Const SCR_HEIGHT = 200
Const APP_TITLE$ = "Animated Splash Screen"

AppTitle APP_TITLE$
Graphics SCR_WIDTH,SCR_HEIGHT,16,2

roundedRgn = False ; flag for splash screen with rounded corners

; get the command line input used for displayed message
msg$ = CommandLine()

; extract indicator if rounded corners are required
If Instr(msg$, "[roundRect]") Then
	roundedRgn = True
	msg$ = Replace(msg$, "[roundRect]", "")
End If

; if we didn't get a message via command line, set a default message
If msg$ = "" Then
	msg$ = "loading...!
End If




If Not roundedRgn Then 
	; create the region to restrict the visible part of the splash screen app
	hRgn = api_CreateRectRgn(0,SCR_TITLEBAR_HEIGHT,SCR_WIDTH + 5, SCR_HEIGHT + SCR_TITLEBAR_HEIGHT +5)
Else 
	; create a region with rounded corners
	hRgn = api_CreateRoundRectRgn(5,SCR_TITLEBAR_HEIGHT + 5 ,SCR_WIDTH, SCR_HEIGHT + SCR_TITLEBAR_HEIGHT - 5, SCR_RADIUS, SCR_RADIUS)
End If 

; get the win handle of this app
hWnd = FindWindow(APP_TITLE$)

; applay the win region 
If hRgn <> 0 And hWnd <> 0 Then
	api_SetWindowRgn(hWnd, hRgn, True)

	; set this app to stay as topmost window while open
	api_SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, FLAGS)
End If


; create and load a font
fnt = LoadFont("arial", 20, True)
SetFont fnt

; set uo some variables for the text animation
txtW = StringWidth(msg$)
txtH = StringHeight(msg$)
curX = 20 + (txtW/2)
curY = 20 + (txtH/2)
incX = 2
incY = 2

Repeat
	Cls 
	Delay 10

	; emergency exit !!!!
	If KeyHit(1) End	

	; draw some animated lines
	For i = 0 To 200
		Color Rand(50,255), Rand(80), 0; Rand(255)
		Line Rand(SCR_WIDTH), 0, Rand(SCR_WIDTH), SCR_HEIGHT
	Next

	; bounce the message around
	Color 250, 200, 0
	If (curX + incX - (txtW / 2) < 0 ) Or (curX + incX + (txtW / 2) > SCR_WIDTH) Then incX = incX * -1
	If (curY + incY - (txtH / 2) < 0 ) Or (curY + incY + (txtH / 2) > SCR_HEIGHT) Then incY = incY * -1
	curX = CurX + incX
	curY = CurY + incY
	Text curX, curY, msg$, True, True 
	Flip
Forever

;===============================
; uses semar's code from code library
; FindWindow without class name
; api_FindWindow_0% (lpClassName%, lpWindowName$) : "FindWindowA"
Function FindWindow(name$)
	hWnd% =  api_FindWindow_0% (0,name$)
	Return hWnd
End Function 


Here is the testing code

;*******************************************************************************************
; testing animated splash screen by nadia, Jan 2005
;
; to run this sample code you need to compile 'animSplash.bb' to 'animSplash.exe
; and save it in the same folder as this file.
; DON'T try this in FULL SCREEN MODE, it will crash!!!!!
;
; make sure you add the following declarations to the user libs:
;
;		.lib "Gdi32.dll"
;		api_CreateRectRgn%(X1%, Y1%, X2%, Y2%): "CreateRectRgn"
;		api_CreateRoundRectRgn%(X1%, Y1%, X2%, Y2%, X3%, Y3%): "CreateRoundRectRgn"
;
;		.lib "user32.dll"
;		api_FindWindow_0% (lpClassName%, lpWindowName$) : "FindWindowA"
;		api_SendMessage% (hWnd%, wMsg%, wParam%, lParam%): "SendMessageA"
;		api_SetWindowRgn%(hWnd%, hRgn%, bRedraw): "SetWindowRgn"
;		api_SetWindowPos%(hWnd% ,hWndInsertAfter%, x%, y%, cx%, cy%, wFlags%): "SetWindowPos"
;
;;*******************************************************************************************


; API Constants
Const WM_CLOSE 	= $10

; Splash screen data
Const SPL_APP_TITLE$ = "Animated Splash Screen"	; must be the same as AppTitle of animSplash.exe
Const SPL_EXE_NAME$ 	= "animSplash.exe"			; file name if animSplash app
																; make sure 'animSplash.exe' is in the
																; same folder as this app

Const USE_ROUND_RECT$ = "[roundRect]"				; draws regions with rounded corners
																; also send with command line

; text displayed in the animSplash.exe
; send to splash screen as command line
msg$ = "loading stuff..."	; <<---	change this to anything...
									
roundedRgn = True 			; <<---  set to true for splash screen with rounded corners!!!
; create command line
If roundedRgn Then
	cmdLine$ = msg$ + USE_ROUND_RECT$
Else
	cmdLine$ = msg$
End If 
; run the splash screen app
ExecFile(SPL_EXE_NAME$ + " " + cmdLine$)

; get the win handle of the splash screen app
; without loop the handle gets missed
hWnd = 0	
Repeat
	Delay 10
	hWnd = FindWindow(SPL_APP_TITLE$)
Until hWnd <> 0


; initialise the game engine
Graphics3D 640,480,16,2 ; <<<--- if you use full screen mode this will crash!!!
ClsColor 0, 0, 100


; \./\./ here you would load all the game related stuff \./\./\./\./\./\./\./\./\

; some loops to waste time
secs = 10
start# = MilliSecs()
wait# = start# + (1000 * secs)
Repeat
	elapsed# = (MilliSecs() - start#) / 1000
	Cls
	Color 255, 255, 255
	Text 10, 10, "Splash Screen Handle = " + hWnd
	Text 10, 30, "Rgn Handel = " + hRgn
	Color 255, 0, 0
	Text 10, 50, "Closing Splash Screen in " + (secs - Int(elapsed#))  + " secs"
	Flip
Until wait < MilliSecs()

Cls

; finished loading the game stuff
;==============================================================================

; unload the the splash screen app
If KillWindow(hWnd) Then
	msg$ = "Animated splash screen closed ok!"
Else
	msg$ = "Failed to close splash screen!"
End If
Color 255, 255, 255
Text 10, 10,  msg$
Text 10, 30, "Hit any key to close me"
Flip 

WaitKey 
End


Function KillWindow(hWND)
	If hWND = 0 Then Return
	
	ret = api_SendMessage(hWND, WM_CLOSE, 0, 0) 
	If ret = 0 Then 	; I think this always returns 0,
							; regardless if the function succeeds or not
		Return True
	Else
		Return False
	End If 

End Function 

;===============================
; uses semar's code from code library
; FindWindow without class name
; api_FindWindow_0% (lpClassName%, lpWindowName$) : "FindWindowA"
Function FindWindow(name$)
	hWnd% =  api_FindWindow_0% (0,name$)
	Return hWnd
End Function 


I got nutten!!

Could you post a screenshot? No offence, but I don't want to try compiling this if I don't know wether I'm interested or not :)

Nope, no screenies…
They wouldn’t help much anyway. You have to run this stuff to see what it does or forever wonder in agony, what marvelously ingenious code you might have missed out on ;-)

Ok, here is a bit of a description what it does:
The first bit is a simple little splash screen, which runs an animation. On loading it applies win regions to itself to cut off the window title bar and optionally rounds off the windows corners. It also sets itself as topmost to stay on top of every other open window.

The second code bit is for testing. It simulates the game app. First it attempts to load the above app (compiled into an exe). Then it goes through some routines, which in a real game would be contents loading stuff. Finally, ones finished with the ‘loading stuff’ it will kill the animated splash screen, which was running in the foreground…

Note:
This stuff only runs in window mode!
Make sure you declare all the API call declarations in the right user libs!

..let me know if you get it to run.

Both runs ok here,
although sometimes, the small window in front flickers to black color, and that doesn't look so good ...
So, if I understand it well, the second code loads the first compiled code and show it in front while the stuff is being
loaded in the back, isn't it? (oops, yes, that's what it does, I have just read your second post :)

Also, remember there's a blitz sys dll (or something) that let you create windows without frames and more ... just a thought...

Paolo.

I still wonder if it's possible to use a fake-fullscreen resolution that is using the entire screen for a window without frame. This way we could use multithreading things like this in Games that are looking like fullscreen (but actually are not). Thanks for sharing.

Jfk- nice idea, faking full screen with a frameless full screen window. One would have to use api calls to check out the current monitor settings and store them. Then one could fire the ChangeDisplaySettings function to reset the display res. Then before closing the app one can reset the screen res back to the initial setting (unless blitz crashes which would leave the user to reset the display manually).

If I've got a bit of time I'll try it out...