Disable shutdown for a while... (Windows)

Share your advanced PureBasic knowledge/code with the community.
User avatar
Michael Vogel
Addict
Addict
Posts: 2666
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Disable shutdown for a while... (Windows)

Post by Michael Vogel »

Sometimes I want my computer to work a little bit longer than I do - and I want to prevent that the notebook also start sleeping as soon I go to bed...
So I wrote a program which can be configured to prevent a shutdown or even the screen saver to be started for a defined period of time. My first version used quite a lot of icons and bitmaps but now I made a vector version which is much smaller and allows smoother graphics.

You can use start parameters to define the mode and you are able to use shortcuts or the popup menu to do some changes while the program is running.

Some parameters:
'A' (or 'D') toggles the 'active display' mode (deactives the screen saver)
'B' shows/hides a black screen
'S' changes the symbol size
'1-9' changes the active time (before the program will be closed)
'0' no timer (endless mode)
'Esc' quits program

Code: Select all

; Define

	; Programmed by Michael Vogel

	EnableExplicit

	#WindowsName="z²Z"

	#Startsize=	80;
	#PulseDelay=15;
	#StarsDelay=50;

	#IconSize=	#Startsize<<1+16
	#Shrinker=	4
	#Center=	#IconSize>>1
	#FullyVisible=8
	
	#Endless=	6000
	#EndText=	"×"
	#KillerKey=	$FF

	#Q=		#DOUBLEQUOTE$
	#BACKSPACE=$8

	Global WinID
	Global zRingSize=#Startsize
	Global zCounter=#Endless
	Global zRunning
	Global zScreenOn
	Global zActive
	Global zColor
	Global zAnimate
	Global zMorph
	Global zText.s
	Global zTextSize
	Global zVisible
	Global zToggle
	Global zBlack

	Global Dim InfoSize(15)

	CompilerIf Defined(SetThreadExecutionState_,#PB_OSFunction) = #False
		Import "Kernel32.lib"
			CompilerIf #PB_Processor_x86
				SetThreadExecutionState_(esFlags.l) As "_SetThreadExecutionState@4"
			CompilerElse
				SetThreadExecutionState_(esFlags.l) As "SetThreadExecutionState"
			CompilerEndIf
		EndImport
	CompilerEndIf

	Global SX,SY

	SX=GetSystemMetrics_(#SM_CXSCREEN)
	SY=GetSystemMetrics_(#SM_CYSCREEN);	SY=GetSystemMetrics_(#SM_CYFULLSCREEN) wegen Taskleiste zu klein

	CreatePopupMenu(#Null)
	MenuItem(1, "Active display"+#TAB$+"A")
	MenuItem(2, "Black background"+#TAB$+"B")
	MenuItem(3, "Small screen icon"+#TAB$+"S")
	MenuBar()
	MenuItem(11, "Quit in &10 minutes"+#TAB$+"1")
	MenuItem(12, "Quit in &20 minutes"+#TAB$+"2")
	MenuItem(13, "Quit in &30 minutes"+#TAB$+"3")
	MenuItem(20, "Quit &never"+#TAB$+"Space")
	MenuBar()
	MenuItem(10, "Quit now..."+#TAB$+"Esc")

	RegisterHotKey_(WinID,6666,#MOD_WIN|#MOD_CONTROL,#VK_B)
	RegisterHotKey_(WinID,6699,#MOD_WIN|#MOD_CONTROL,#VK_RETURN)

	Global _time

	Macro WaitStart()
		_time=ElapsedMilliseconds()
	EndMacro
	Procedure WaitStop(delay)

		_time-ElapsedMilliseconds()+delay
		If _time>0
			Delay(_time)
		EndIf

	EndProcedure

; EndDefine

Macro Blender(a)
	(((a*zVisible)>>3)<<24)
EndMacro
Procedure Choose(first,alternative)

	If first
		ProcedureReturn first
	Else
		ProcedureReturn alternative
	EndIf

EndProcedure
Procedure UpdateWindow()

	Protected ImageID
	Protected Image_HDC
	Protected Image_Bitmap.BITMAP,Image_BitmapInfo.BITMAPINFO
	Protected ContextOffset.POINT,Blend.BLENDFUNCTION
	Protected Image_Ancienne
	; Protected Color
	; Protected x,y,w,h,Alpha

	SetWindowLong_(WinID,#GWL_EXSTYLE,GetWindowLong_(WinID,#GWL_EXSTYLE)|#WS_EX_LAYERED)

	ImageID=ImageID(#Null)
	Image_HDC=CreateCompatibleDC_(#Null)
	Image_Ancienne=SelectObject_(Image_HDC,ImageID)

	GetObject_(ImageID,SizeOf(BITMAP),@Image_Bitmap)
	Image_BitmapInfo\bmiHeader\biSize=SizeOf(BITMAPINFOHEADER)
	Image_BitmapInfo\bmiHeader\biWidth=Image_Bitmap\bmWidth
	Image_BitmapInfo\bmiHeader\biHeight=Image_Bitmap\bmHeight
	Image_BitmapInfo\bmiHeader\biPlanes=1
	Image_BitmapInfo\bmiHeader\biBitCount=32

	Blend\SourceConstantAlpha=255
	Blend\AlphaFormat=1
	Blend\BlendOp=0
	Blend\BlendFlags=0
	UpdateLayeredWindow_(WinID,0,0,@Image_BitmapInfo+4,Image_HDC,@ContextOffset,0,@Blend,2)

	SelectObject_(Image_HDC,Image_Ancienne)
	DeleteDC_(Image_HDC)

EndProcedure
Procedure DrawZ(x.d,y.d,size.d)

	MovePathCursor(x,y)
	AddPathLine(74*size,0,#PB_Path_Relative)
	AddPathLine(0,-17*size,#PB_Path_Relative)
	AddPathLine(-48*size,0,#PB_Path_Relative)
	AddPathLine(48*size,-63*size,#PB_Path_Relative)
	AddPathLine(0,-13*size,#PB_Path_Relative)
	AddPathLine(-72*size,0,#PB_Path_Relative)
	AddPathLine(0,17*size,#PB_Path_Relative)
	AddPathLine(45*size,0,#PB_Path_Relative)
	AddPathLine(-47*size,63*size,#PB_Path_Relative)
	ClosePath()

EndProcedure
Procedure DrawSymbol()

	Protected n,o,t
	Protected z.d,v.d
	Protected color

	color=zRunning*#White

	CreateImage(0,#IconSize,#IconSize,32,#PB_Image_Transparent)
	StartVectorDrawing(ImageVectorOutput(0))

	o=#Center-((#Startsize-zRingSize)*5)>>3
	DrawZ(#Center-zRingSize*0.05,o+zRingSize*0.09,zRingSize/115)
	DrawZ(#Center-zRingSize*0.62,o+zRingSize*0.4,zRingSize/128)
	DrawZ(#Center+zRingSize*0.05,o+zRingSize*0.7,zRingSize/180)

	For n=1 To 5
		Select n
		Case 1 To 3
			VectorSourceColor($15000000)
			StrokePath(zRingSize/(13+3*n),#PB_Path_Preserve)
		Case 4
			VectorSourceColor($FF000000|zColor)
			FillPath(#PB_Path_Preserve)
		Case 5
			VectorSourceColor($50000000)
			StrokePath(zRingSize/30.0)
		EndSelect

	Next n

	AddPathCircle(#Center,o,zRingSize,0,360)
	If zMorph
		z=zRingSize/8.5
		v=zRingSize*zMorph/14;*0.7071
		AddPathCircle(#Center,o,zRingSize*0.8,51,219)
		AddPathLine(#Center-z,o)
		AddPathLine(#Center-z-v,o+v)
		AddPathLine(#Center-v,o+v+z)
		AddPathLine(#Center,o+z)
		ClosePath()
		AddPathCircle(#Center,o,zRingSize*0.8,231,39)
		AddPathLine(#Center+z,o)
		AddPathLine(#Center+z+v,o-v)
		AddPathLine(#Center+v,o-v-z)
		AddPathLine(#Center,o-z)
		ClosePath()

	ElseIf zScreenOn
		z=zRingSize/8.5
		AddPathCircle(#Center,o,zRingSize*0.8,51,129)
		AddPathLine(#Center,o+z)
		ClosePath()
		AddPathCircle(#Center,o,zRingSize*0.8,141,219)
		AddPathLine(#Center-z,o)
		ClosePath()
		AddPathCircle(#Center,o,zRingSize*0.8,231,309)
		AddPathLine(#Center,o-z)
		ClosePath()
		AddPathCircle(#Center,o,zRingSize*0.8,321,39)
		AddPathLine(#Center+z,o)
		ClosePath()

	Else
		AddPathCircle(#Center,o,zRingSize*0.8,51,219)
		ClosePath()
		AddPathCircle(#Center,o,zRingSize*0.8,231,39)
		ClosePath()
	EndIf

	For n=1 To 6
		Select n
		Case 1 To 4
			VectorSourceColor($0D000000)
			StrokePath(zRingSize/(3+3*n),#PB_Path_Preserve)
		Case 5
			VectorSourceColor($FF0000FF)
			FillPath(#PB_Path_Preserve)
		Case 6
			VectorSourceColor($A0000000)
			StrokePath(zRingSize/60+1)
		EndSelect
	Next n

	#Font="Geometr212 BkCn BT"
	If zVisible

		t=InfoSize(zRingSize>>3)+zTextSize

		If t>0
			VectorFont(LoadFont(0,#Font,8,#PB_Font_Bold),t*1.2)

			n=#Center+zRingSize-t
			o+zRingSize-t
			AddPathCircle(n,o,t)

			VectorSourceColor(Blender($0A))
			v=zRingSize/160+1.5
			For t=3 To 6
				StrokePath(v*t,#PB_Path_Preserve)
			Next t
			VectorSourceColor(Blender($FF)|color)
			FillPath(#PB_Path_Preserve)
			color!#White
			VectorSourceColor(Blender($80)|color)
			StrokePath(zRingSize/64+1.25,#PB_Path_Preserve)
			StrokePath(zRingSize/100+1,#PB_Path_Preserve)
			StrokePath(zRingSize/300+0.75)

			MovePathCursor(n-VectorTextWidth(zText)/2,o-VectorTextHeight(zText)/2)
			VectorSourceColor(Blender($E0)|color)
			AddPathText(zText)
			FillPath()
		EndIf

	EndIf

	StopVectorDrawing()
	UpdateWindow()

EndProcedure
Procedure Info()

	MessageRequester("z²Z","©2018 by Michael Vogel",#PB_MessageRequester_Ok|#MB_ICONINFORMATION)

EndProcedure

Procedure Pulsate(mode)

	Protected i,time

	zAnimate=mode

	For i=1 To 10
		Select zAnimate
		Case 0
			zTextSize=10-i
		Case 1
			zTextSize=i
		EndSelect
		WaitStart()
		DrawSymbol()
		WaitStop(#PulseDelay)
	Next i

EndProcedure
Procedure Update(ForceUpdate)

	Protected s.s

	If zAnimate=#Null

		If zRunning
			If zCounter=#Endless
				s=#EndText
			ElseIf zCounter<60
				s=Str(zCounter)+#Q
			Else
				s=Str((zCounter+59)/60)+"'"
			EndIf
			If zAnimate=0 And zCounter%60=0
				Pulsate(1)
			EndIf
		Else
			s="II"
		EndIf

		If ForceUpdate Or s<>zText
			zText=s
			If zAnimate=#Null
				DrawSymbol()
			EndIf
		EndIf

		If zAnimate
			Pulsate(0)
		EndIf

	EndIf

EndProcedure

Procedure SetScreenOn()

	SetThreadExecutionState_(#ES_AWAYMODE_REQUIRED|#ES_SYSTEM_REQUIRED|#ES_CONTINUOUS | (zScreenOn * #ES_DISPLAY_REQUIRED))

EndProcedure
Procedure SetMenu()

	SetMenuItemState(0,1,zScreenOn)
	SetMenuItemState(0,2,zBlack)
	SetMenuItemState(0,3,Bool(zRingSize<#Startsize))

EndProcedure
Procedure SetCounter(n)

	zCounter=n
	zRunning=1

	If zCounter=#Endless
		While zVisible>#Null
			zVisible-1
			zTextSize-1
			DrawSymbol()
			Delay(2)
		Wend
	Else
		zTextSize-(#FullyVisible+zVisible)
		While zVisible<#FullyVisible
			zVisible+1
			DrawSymbol()
			Delay(2)
			zTextSize+1
		Wend
	EndIf

	Update(#False)

EndProcedure

Procedure ToggleSize()

	Protected i,n

	n=8-Bool(zRingSize=#Startsize)<<4

	For i=1 To #Shrinker
		zRingSize+n
		If zAnimate=#Null
			DrawSymbol()
		EndIf
	Next i

	SetMenuItemState(0,3,Bool(zRingSize<#Startsize))

EndProcedure
Procedure ToggleColor(mode)

	Protected i,n

	If mode<>zActive
		zActive=mode
		n=$100000-Bool(zActive)<<21
		For i=1 To 10
			zColor+n
			If zAnimate=#Null
				DrawSymbol()
			EndIf
			Delay(20)
		Next i
	EndIf

EndProcedure
Procedure TogglePause()

	Protected m,n

	If zCounter=#Endless
		zRunning=1
		SetCounter(99*60)
	Else
		zRunning!1

		If zRunning
			m=1
			n=0
		Else
			m=-1
			n=6
		EndIf

		Update(#True)
		While zTextSize*m<n
			zTextSize+m
			If zAnimate=#Null
				DrawSymbol()
			EndIf
		Wend
	EndIf

EndProcedure
Procedure ToggleScreenOn()

	Protected m,n,z

	zScreenOn!1
	SetScreenOn()

	For z=1 To 8
		If zScreenOn
			zMorph=z&7
		Else
			zMorph=8-z
		EndIf
		If zAnimate=#Null
			DrawSymbol()
		EndIf
	Next z

	SetMenuItemState(0,1,zScreenOn)
	Update(#True)

EndProcedure
Procedure ToggleBlackScreen()

	StickyWindow(1,1)
	StickyWindow(0,1)
	HideWindow(1,zBlack,#PB_Window_NoActivate)
	zBlack!1
	SetMenuItemState(0,2,zBlack)

EndProcedure

Procedure Quit()

	UnregisterHotKey_(WinID,6666)
	UnregisterHotKey_(WinID,6699)

	While zRingSize>10
		WaitStart()
		zRingSize-4
		DrawSymbol()
		WaitStop(#PulseDelay)
	Wend

	End

EndProcedure

Procedure Main()

	Protected z
	Protected s.s

	s.s=LCase(ProgramParameter())
	If FindString(s,"?")
		Info()
		Quit()
	EndIf

	zCounter=#Endless
	zScreenOn=Bool(FindString(s,"d"))
	zRingSize=#Startsize-(#Shrinker<<3)*Bool(FindString(s,"s"))
	zBlack=Bool(FindString(s,"b"))
	zToggle=Bool(FindString(s,"t"))

	For z='1' To '9'
		If FindString(s,Chr(z))
			zCounter=600*(z-'0')
			zVisible=#FullyVisible
		EndIf
	Next z

	If FindString(s,"p")
		zVisible=#FullyVisible
		zRunning=0
	Else
		zRunning=1
	EndIf

	z=FindWindow_(0,#WindowsName)
	If z
		Debug "z²Z window found..."
		PostMessage_(z,#WM_CHAR,#KillerKey,0)

	Else
		For z=0 To 15
			InfoSize(z)=z*2+10
		Next z
		zColor=#White

		WinID=OpenWindow(0,SX-#IconSize,0,#IconSize,#IconSize,#WindowsName,#PB_Window_BorderLess|#PB_Window_Invisible)
		SetWindowLong_(WinID,#GWL_EXSTYLE,GetWindowLong_(WinID,#GWL_EXSTYLE)|#WS_EX_LAYERED)
		SetWindowLong_(WinID,#GWL_EXSTYLE,GetWindowLong_(WinID,#GWL_EXSTYLE)|#WS_EX_TOOLWINDOW)

		Update(#True)
		SetScreenOn()

		AddWindowTimer(0,0,1000)
		StickyWindow(0,1)
		HideWindow(0,0)

		OpenWindow(1,0,0,SX,SY,"Darkness",#PB_Window_BorderLess|#PB_Window_Invisible)
		SetWindowColor(1,#Black)
		HideWindow(1,1!zBlack)
		
		Repeat

			Select WaitWindowEvent()

			Case #PB_Event_Gadget

			Case #WM_LBUTTONDOWN
				SendMessage_(GetForegroundWindow_(),#WM_NCLBUTTONDOWN,#HTCAPTION,0)

			Case #WM_RBUTTONDOWN
				DisplayPopupMenu(0,WinID)

			Case #PB_Event_ActivateWindow
				ToggleColor(#True)
			Case #PB_Event_DeactivateWindow
				ToggleColor(#False)

			Case #PB_Event_Timer
				If zRunning
					If zCounter
						If zCounter<#Endless
							zCounter-1
							Update(#False)
						EndIf
					Else
						Quit()
					EndIf
				EndIf

			Case #WM_HOTKEY
				Select EventwParam()
				Case 6666
					ToggleBlackScreen()
				Case 6699
					SendMessage_(#HWND_BROADCAST,#WM_SYSCOMMAND,#SC_HOTKEY,WinID)
				EndSelect

			Case #WM_CHAR
				Select EventwParam()
				Case #ESC
					Quit()
				Case ' ','p','P'
					TogglePause()
				Case 'd','a','D','A'
					ToggleScreenOn()
				Case 's','S'
					ToggleSize()
				Case 'b','B'
					ToggleBlackScreen()
				Case 'm','M'
					DisplayPopupMenu(0,WinID)
				Case '?'
					ToggleColor(#False)
					Info()

				Case '0' To '9'
					z=EventwParam()
					If z='0'
						SetCounter(#Endless)
					Else
						SetCounter(600*(z-'0'))
					EndIf

				Case #KillerKey
					If zToggle
						Quit()
					Else
						SendMessage_(#HWND_BROADCAST,#WM_SYSCOMMAND,#SC_HOTKEY,WinID)
					EndIf
				EndSelect

			Case #PB_Event_Menu
				Select EventMenu()
				Case 1
					ToggleScreenOn()
				Case 2
					ToggleBlackScreen()
				Case 3
					ToggleSize()
				Case 10
					Quit()
				Case 11 To 16
					SetCounter((EventMenu()-10)*600)
				Case 20
					SetCounter(#Endless)
				EndSelect

			Case #PB_Event_CloseWindow
				Quit()

			EndSelect

		ForEver
	EndIf

EndProcedure
Main()
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Disable shutdown for a while... (Windows)

Post by Kwai chang caine »

I love it !!!!!!! :D
A very very nice software !!!!
Mine is often of the same style :wink:
Thanks a lot for this nice little jewel 8)
ImageThe happiness is a road...
Not a destination
fryquez
Enthusiast
Enthusiast
Posts: 362
Joined: Mon Dec 21, 2015 8:12 pm

Re: Disable shutdown for a while... (Windows)

Post by fryquez »

Indeed, it's very nice.

Just one thing: CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
Justin
Addict
Addict
Posts: 829
Joined: Sat Apr 26, 2003 2:49 pm

Re: Disable shutdown for a while... (Windows)

Post by Justin »

I get POLINK error unresolved external symbol SetThreadExecutionState.

Win7 64
User avatar
Michael Vogel
Addict
Addict
Posts: 2666
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: Disable shutdown for a while... (Windows)

Post by Michael Vogel »

Sorry...
Justin wrote:I get POLINK error unresolved external symbol SetThreadExecutionState. 64 Bit
...and thanks.
fryquez wrote:CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
Post Reply