Post by Walt Decker on Jun 27, 2023 11:24:59 GMT -5
With a little API magic and some imagination one can lock a form in place or make it follow another form. The below code creates two forms. The form with the LOCK button follows the first form around. Click the "LOCK" button to unlock following. Click it again to lock it.
The governing code is in function FN.KeepLocked().
'
NOMAINWIN
OPEN "User32.dll" FOR DLL AS #USER
OPEN "Kernel32.dll" FOR DLL AS #KERN
STRUCT tPos, _
Pulx AS LONG, _
Puly AS LONG, _
Lszx AS LONG, _
Lszy AS LONG
GLOBAL Dmo.Done, _
Win.Lock
LockHndl = 0
PrntHndl = 0
Ux = 0
Uy = 0
Szx = 0
Szy = 0
Win.Lock = 1
LockHndl = FN.CreateLockedWindow()
PrntHndl = FN.CreateParentWindow()
RetVal = FN.GetWinRect(PrntHndl, Ux, Uy, 0, 0)
tPos.Pulx.struct = Ux
tPos.Puly.struct = Uy
RetVal = FN.GetWinRect(LockHndl, Ux, Uy, Szx, Szy)
tPos.Lszx.struct = Szx - Ux
tPos.Lszy.struct = Szy - Uy
Ux = tPos.Pulx.struct
Uy = tPos.Puly.struct
Szx = tPos.Lszx.struct
Szy = tPos.Lszy.struct
RetVal = FN.MoveWin(LockHndl, Ux - Szx, Uy, Szx, Szy)
RetVal = FN.KeepLocked(75, LockHndl, PrntHndl)
WAIT
'---------------------------
'---------------------------
SUB CLOSE.ALL PHndl$
Dmo.Done = 1
CLOSE #USER
CLOSE #KERN
CLOSE #LOC
CLOSE #PHndl$
END
END SUB
'---------------------------
'---------------------------
SUB LOCKED.WIN BtnHndl$
IF Win.Lock THEN
Win.Lock = 0
#BtnHndl$, "UNLOCKED"
ELSE
Win.Lock = 1
#BtnHndl$, "LOCKED"
END IF
END SUB
'---------------------------
'---------------------------
FUNCTION FN.KeepLocked(Ms, LocHndl, PntHndl)
RetVal = 0
CurPosx = 0
CorPosy = 0
Szx = 0
Szy = 0
WHILE Dmo.Done = 0
IF Win.Lock THEN
RetVal = FN.GetWinRect(PntHndl, CurPosx, CurPosy, 0, 0)
IF (CurPosx <> tPos.Pulx.struct) OR (CurPosy <> tPos.Puly.struct) THEN
tPos.Pulx.struct = CurPosx
tPos.Puly.struct = CurPosy
Szx = tPos.Lszx.struct
Szy = tPos.Lszy.struct
RetVal = FN.MoveWin(LocHndl, CurPosx - Szx, CurPosy, Szx, Szy)
END IF
END IF
CALLDLL #KERN, "Sleep", Ms AS LONG, RetVal AS VOID
SCAN
WEND
END FUNCTION
'---------------------------
'---------------------------
FUNCTION FN.CreateLockedWindow()
WS.THICKFRAME = HEXDEC("&H00040000")
WinHndl = 0
RetVal = 0
Cx = 0
Cy = 0
Wx = 200
Wy = 70
RetVal = FN.ScreenCenter(Cx, Cy)
RetVal = FN.SetWinPos(INT(Cx - Wx / 2), INT(Cy - Wy / 2))
RetVal = FN.SetWinSize(Wx, Wy)
BUTTON #LOC.BTNLOC, "LOCKED", LOCKED.WIN, UL, 5, 5, 60, 20
RetVal = FN.ScreenCenter(Cx, Cy)
RetVal = FN.SetWinPos(INT(Cx - Wx / 2), INT(Cy - Wy / 2))
RetVal = FN.SetWinSize(Wx, Wy)
STYLEBITS #LOC, 0, WS.THICKFRAME, 0, 0
OPEN "LOCKED WIN" FOR WINDOW AS #LOC
WinHndl = HWND(#LOC)
FN.CreateLockedWindow = WinHndl
END FUNCTION
'---------------------------
'---------------------------
FUNCTION FN.CreateParentWindow()
WinHndl = 0
RetVal = 0
Wx = 250
Wy = 175
RetVal = FN.SetWinSize(Wx, Wy)
OPEN "PARENT WIN" FOR WINDOW AS #PRNT
WinHndl = HWND(#PRNT)
#PRNT, "TRAPCLOSE CLOSE.ALL"
FN.CreateParentWindow = WinHndl
END FUNCTION
'---------------------------
'---------------------------
FUNCTION FN.ClientSize(WinHndl, BYREF Xw, BYREF Yh)
STRUCT tRect, _
X AS LONG, _
Y AS LONG, _
X1 AS LONG, _
Y1 AS LONG
RetVal = 0
CALLDLL #USER, "GetClientRect", WinHndl AS ULONG, tRect AS STRUCT, RetVal AS LONG
Xw = tRect.X1.struct
Yh = tRect.Y1.struct
FN.GetClient = RetVal
END FUNCTION
'---------------------------
'---------------------------
FUNCTION FN.MoveWin(WinHndl, Ux, Uy, Xwide, Yhigh)
RetVal = 0
CALLDLL #USER, "MoveWindow", WinHndl AS ULONG, Ux AS LONG, Uy AS LONG, Xwide AS LONG, _
Yhigh AS LONG, 1 AS LONG, RetVal AS VOID
END FUNCTION
'---------------------------
'---------------------------
FUNCTION FN.GetWinRect(WinHndl, BYREF Ux, BYREF Uy, BYREF Bx, BYREF By)
STRUCT tRect, _
X AS LONG, _
Y AS LONG, _
X1 AS LONG, _
Y1 AS LONG
RetVal = 0
CALLDLL #USER, "GetWindowRect", WinHndl AS ULONG, tRect AS STRUCT, RetVal AS LONG
Ux = tRect.X.struct
Uy = tRect.Y.struct
Bx = tRect.X1.struct
By = tRect.Y1.struct
FN.GetWinRect = RetVal
END FUNCTION
'---------------------------
'---------------------------
FUNCTION FN.ScreenCenter(BYREF Cx, BYREF Cy)
Cx = INT(DisplayWidth * 0.5)
Cy = INT(DisplayHeight * 0.5)
FN.ScreenCenter = Cx * Cy
END FUNCTION
'--------------------------
'--------------------------
FUNCTION FN.SetWinPos(PosX, PosY)
UpperLeftX = PosX
UpperLeftY = PosY
FN.SetWinPos = PosX * PosY
END FUNCTION
'--------------------------
'--------------------------
FUNCTION FN.SetWinSize(Szx, Szy)
WindowWidth = Szx
WindowHeight = Szy
FN.SetWinSize = Szx * Szy
END FUNCTION
'----------------------------------------------------------
'----------------------------------------------------------
'