#Include Once "windows.bi"

Declare Sub ProgNext(d As Any Ptr) 'run in thread

Type UnknownWaitDlg
	As HWND hUWin 'created dlg's handle
	As String Title, ConstText, ProgText
	As Integer WinWide, WinHigh 'width and height of display area
	As Integer WinHorz, WinVert 'location on screen
	As Integer TextWide, TextHigh 'width and height of text area
	'threading
	As Any Ptr mtx
	As BOOL RunLikeTheWind 'flag to keep going
	As BOOL Exited 'flag that thread has stopped
	'functions and subs
	Declare Constructor()
	'Declare Destructor()
	Declare Function StartIt(DlgTitle As String,CText As String,PText As String) As Integer
	Declare Sub KillIt 'Kills and waits for tread to complete
	Private:
	As BOOL Active 'only one instance allowed
	As HWND MainW 'caller handle
End Type

Constructor UnknownWaitDlg()
MainW = GetForegroundWindow() 'use this as param 9 in first CreateWindow?
Active = FALSE
End Constructor

Sub UnknownWaitDlg.KillIt
	'kill and wait for thread to complete
	RunLikeTheWind = FALSE
	Do
		Sleep 10
	Loop Until Exited
	ThreadWait(mtx)
	'kill window
	DestroyWindow(hUWin)
	'allow another call
	Active = FALSE
End Sub

Sub ProgNext(d As Any Ptr)
	Dim As String B,CT,PT
	Dim As Integer NumC,L
	Dim As Integer SpaceWide, ConstWide, CurrWide
	Dim As UnknownWaitDlg Ptr DData = d
	Dim as HANDLE hDC
	'
	DData->Exited = FALSE
	CT = DData->ConstText
	PT = DData->ProgText
	'
	hDC=GetDC(DData->hUWin)
	Dim As Integer PW(Len(PT)-1)
	For L = 0 To Len(PT)-1
		GetCharWidth32(hdc, PT[L], PT[L], @PW(L))
	Next
	If Len(CT) Then
		For NumC = 0 To Len(CT)-1
			GetCharWidth32(hdc, CT[NumC], CT[NumC], @L)
			ConstWide += L
		Next
	EndIf
	GetCharWidth32(hdc, 32, 32, @SpaceWide) 'width of space
	NumC = 0
	While DData->RunLikeTheWind
		B = CT
		CurrWide = ConstWide
		If NumC Then
			B += Left(PT,NumC)
			For L = 0 To NumC-1
				CurrWide += PW(L)
			Next
		EndIf
		While CurrWide < DData->TextWide
			B += " "
			CurrWide += SpaceWide
		Wend
		'Print B;"*"
		TextOut hDC,5,1,B,Len(B)
		InvalidateRgn(DData->hUWin,NULL,TRUE)
		NumC += 1
		If NumC > Len(PT) Then NumC = 0
		Sleep 1000
	Wend
	ReleaseDC(DData->hUWin, hDC)
	DData->Exited = TRUE
End Sub

Function UnknownWaitDlg.StartIt(DlgTitle As String,CText As String,PText As String) As Integer
	If Active = FALSE Then
		Title = DlgTitle
		ConstText = CText 'may be null
		ProgText = PText
		'
		Dim As RECT MainWLoc
		Dim As TEXTMETRIC tm
		Dim as HANDLE hDC
		Dim As Integer nCharWidth,x
		'main window may have been moved or resized
		GetWindowRect(MainW,@MainWLoc)
		'width and height of window
		WinHigh = TextHigh + 39
		WinWide = TextWide + 8
		'set starting location of window
		With MainWLoc
			WinHorz = 16 + .left 'just inside
			WinVert = (.bottom - .top)/2 + .top - WinHigh/2 'half way down
		End With
		' Create Window
		hUWin = CreateWindowEx( 0, "#32770", Title, WS_EX_DLGMODALFRAME Or WS_VISIBLE, WinHorz, WinVert, WinWide, WinHigh, 0, 0, 0, 0 )
		'
		If hUWin = 0 Then
			'window not created (return 0)
			RunLikeTheWind = FALSE
		Else
			'recalc width and height of window based on the font
			hdc = GetDC(hUWin)
			GetTextMetrics(hDC, @tm) 'just need for height
			TextHigh = tm.tmHeight 'font height
			TextWide = 0
			For x = 0 To Len(ProgText)-1
				GetCharWidth32(hdc, ProgText[x], ProgText[x], @nCharWidth)
				TextWide += nCharWidth
			Next
			If Len(ConstText) Then
				For x = 0 To Len(ConstText)-1
					GetCharWidth32(hdc, ConstText[x], ConstText[x], @nCharWidth)
					TextWide += nCharWidth
				Next
			EndIf
			ReleaseDC(hUWin, hDC)
			'
			WinHigh = TextHigh + 32
			WinWide = TextWide + 4
			SetWindowPos(hUWin,HWND_TOP, WinHorz, WinVert, WinWide, WinHigh,SWP_NOMOVE	Or SWP_DRAWFRAME)
			/'
			SWP_DRAWFRAME	Draws a frame (defined in the window's class description) around the window.
			SWP_FRAMECHANGED	Sends a WM_NCCALCSIZE message to the window, even if the window's size is not being changed. If this flag is not specified, WM_NCCALCSIZE is sent only when the window's size is being changed.
			SWP_HIDEWINDOW	Hides the window.
			SWP_NOACTIVATE	Does not activate the window. If this flag is not set, the window is activated and moved to the top of either the topmost or non-topmost group (depending on the setting of the hwndInsertAfter parameter).
			SWP_NOCOPYBITS	Discards the entire contents of the client area. If this flag is not specified, the valid contents of the client area are saved and copied back into the client area after the window is sized or repositioned.
			SWP_NOMOVE	Retains the current position (ignores the x and y parameters).
			SWP_NOSIZE	Retains the current size (ignores the cx and cy parameters).
			SWP_NOREDRAW	Does not redraw changes. If this flag is set, no repainting of any kind occurs. This applies to the client area, the nonclient area (including the title bar and scroll bars), and any part of the parent window uncovered as a result of the window being moved. When this flag is set, the application must explicitly invalidate or redraw any parts of the window and parent window that need redrawing.
			SWP_NOZORDER	Retains the current Z order (ignores the hwndInsertAfter parameter).
			SWP_SHOWWINDOW	Displays the window.
			'/
			'
			RunLikeTheWind = TRUE
			'Start Thread
			mtx = ThreadCreate(@ProgNext,@This)
			Active = TRUE
			Return 1
		EndIf
	EndIf
	Return 0
End Function

Dim Shared As UnknownWaitDlg UnknownWait
