I've added an adjustment for transparent areas at the edges, as shadows are considered as part of the window size.
Perhaps I need to calculate the client area and add the width and height of the window borders, depending on the window style.
Download yandex, upload.ee
Code: Select all
;- TOP
;- @AZJIO v1.0 (03.07.2025)
Define UserIntLang, *Lang
If OpenLibrary(0, "kernel32.dll")
*Lang = GetFunction(0, "GetUserDefaultUILanguage")
If *Lang
UserIntLang = CallFunctionFast(*Lang)
EndIf
CloseLibrary(0)
EndIf
#CountStrLang = 9
Global Dim Lng.s(#CountStrLang)
Lng(1) = "Select a window"
Lng(2) = "Refresh list"
Lng(3) = "Left"
Lng(4) = "Top"
Lng(5) = "Right"
Lng(6) = "Bottom"
Lng(7) = "Visible windows ("
Lng(8) = "Delta"
Lng(9) = "Client region"
If UserIntLang = 1049 ; ru
Lng(1) = "Выберите окно"
Lng(2) = "Обновить список"
Lng(3) = "Слева"
Lng(4) = "Сверху"
Lng(5) = "Справа"
Lng(6) = "Снизу"
Lng(7) = "Видимые окна ("
Lng(8) = "Поправка"
Lng(9) = "Клиентскую часть"
EndIf
;- # Constants
#Window = 0
;- ● Enumeration
Enumeration
#Btn
#LIG
#txtL
#txtT
#txtR
#txtB
#txtD
#FieldL
#FieldT
#FieldR
#FieldB
#FieldD
#ch
EndEnumeration
;- ● Global
Global hIconProg.l
Global hIconFolder.l
Global WinRect.RECT
Procedure Limit(*Value.integer, Min, Max)
If *Value\i < Min
*Value\i = Min
ElseIf *Value\i > Max
*Value\i = Max
EndIf
EndProcedure
Procedure EnumChildProc(hwnd.l, *hwnd)
Protected Title${256}
Protected class${256}
Protected hIcon.l
If IsWindowVisible_(hwnd)
GetWindowText_(hwnd, @Title$, 256)
If Asc(Title$)
If Title$ = "Program Manager"
ProcedureReturn 1
EndIf
hIcon = GetClassLongPtr_(hwnd, #GCL_HICON)
If hIcon
AddGadgetItem(#LIG, n, Title$, hIcon)
Else
GetClassName_(hwnd, @class$, 256)
If class$ = "CabinetWClass"
AddGadgetItem(#LIG, n, Title$, hIconFolder)
Else
AddGadgetItem(#LIG, n, Title$, hIconProg)
EndIf
EndIf
SetGadgetItemData(#LIG, n, hwnd)
n+1
EndIf
EndIf
ProcedureReturn 1
EndProcedure
; Fred
; https://www.purebasic.fr/english/viewtopic.php?t=7424
Procedure SetForegroundWindow(hWnd)
Protected foregroundThreadID, ourThreadID
If GetWindowLong_(hWnd, #GWL_STYLE) & #WS_MINIMIZE
; ShowWindow_(hWnd, #SW_MAXIMIZE)
ShowWindow_(hWnd, #SW_SHOWNOACTIVATE)
UpdateWindow_(hWnd)
EndIf
foregroundThreadID = GetWindowThreadProcessId_(GetForegroundWindow_(), 0)
ourThreadID = GetCurrentThreadId_()
If (foregroundThreadID <> ourThreadID)
AttachThreadInput_(foregroundThreadID, ourThreadID, #True);
EndIf
SetForegroundWindow_(hWnd)
If (foregroundThreadID <> ourThreadID)
AttachThreadInput_(foregroundThreadID, ourThreadID, #False)
EndIf
InvalidateRect_(hWnd, #Null, #True)
EndProcedure
Procedure SizeWindowHandler()
w = WindowWidth(#Window)
h = WindowHeight(#Window)
ResizeGadget(#LIG, #PB_Ignore, #PB_Ignore, w - 174, h - 20)
#PosX = 154
ResizeGadget(#Btn, w - #PosX, #PB_Ignore, #PB_Ignore, #PB_Ignore)
ResizeGadget(#txtL, w - #PosX, #PB_Ignore, #PB_Ignore, #PB_Ignore)
ResizeGadget(#txtT, w - #PosX, #PB_Ignore, #PB_Ignore, #PB_Ignore)
ResizeGadget(#txtR, w - #PosX, #PB_Ignore, #PB_Ignore, #PB_Ignore)
ResizeGadget(#txtB, w - #PosX, #PB_Ignore, #PB_Ignore, #PB_Ignore)
ResizeGadget(#ch, w - #PosX, #PB_Ignore, #PB_Ignore, #PB_Ignore)
#PosX2 = 94
ResizeGadget(#FieldL, w - #PosX2, #PB_Ignore, #PB_Ignore, #PB_Ignore)
ResizeGadget(#FieldT, w - #PosX2, #PB_Ignore, #PB_Ignore, #PB_Ignore)
ResizeGadget(#FieldR, w - #PosX2, #PB_Ignore, #PB_Ignore, #PB_Ignore)
ResizeGadget(#FieldB, w - #PosX2, #PB_Ignore, #PB_Ignore, #PB_Ignore)
EndProcedure
Define hwnd.l, res$, n, w, h, delta
Define left, right, top, bottom
ExtractIconEx_("Shell32.dll", 3, 0, @hIconFolder, 1)
ExtractIconEx_("Shell32.dll", 2, 0, @hIconProg, 1)
;-┌──GUI──┐
If OpenWindow(#Window, 0, 0, 724, 560, Lng(1),
#PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget)
ButtonGadget(#Btn, 570, 10, 144, 30, Lng(2))
TextGadget(#txtL, 570 , 50, 60, 25, Lng(3))
TextGadget(#txtT, 570 , 80, 60, 25, Lng(4))
TextGadget(#txtR, 570 , 110, 60, 25, Lng(5))
TextGadget(#txtB, 570 , 140, 60, 25, Lng(6))
TextGadget(#txtD, 570 , 170, 70, 25, Lng(8))
StringGadget(#FieldL, 630 , 50, 70, 25, "")
StringGadget(#FieldT, 630 , 80, 70, 25, "")
StringGadget(#FieldR, 630 , 110, 70, 25, "")
StringGadget(#FieldB, 630 , 140, 70, 25, "")
StringGadget(#FieldD, 640 , 170, 70, 25, "8")
CheckBoxGadget(#ch, 570 , 210, 140, 25, Lng(9))
ListIconGadget(#LIG, 10, 10, 550, 540, "", 500)
EnumWindows_(@EnumChildProc(), @hwnd)
SetGadgetItemAttribute(#LIG, 2, #PB_ListIcon_ColumnWidth , #LVSCW_AUTOSIZE, 0)
SetGadgetItemText(#LIG, -1, Lng(7) + Str(CountGadgetItems(#LIG)) + ")")
BindEvent(#PB_Event_SizeWindow, @SizeWindowHandler())
;-┌──Loop──┐
Repeat
Select WaitWindowEvent()
Case #PB_Event_Gadget
Select EventGadget()
Case #Btn
ClearGadgetItems(#LIG)
n = 0
hwnd = 0
EnumWindows_(@EnumChildProc(), @hwnd)
SetGadgetItemAttribute(#LIG, 2, #PB_ListIcon_ColumnWidth , #LVSCW_AUTOSIZE, 0)
SetGadgetItemText(#LIG, -1, Lng(7) + Str(CountGadgetItems(#LIG)) + ")")
Case #LIG
If EventType() = #PB_EventType_LeftClick
n = GetGadgetState(#LIG)
If n > -1
delta = 0
hwnd = GetGadgetItemData(#LIG, n)
If IsIconic_(hwnd)
SetForegroundWindow(hwnd)
EndIf
ExamineDesktops()
w = DesktopWidth(0)
h = DesktopHeight(0)
If GetGadgetState(#ch) & #PB_Checkbox_Checked
GetClientRect_(hwnd, @WinRect)
ClientToScreen_(hwnd, @WinRect)
With WinRect
\right + \left
\bottom + \top
EndWith
Else
GetWindowRect_(hwnd, @WinRect)
delta = Val(GetGadgetText(#FieldD))
EndIf
With WinRect
left = \left + delta
right = w - \right + delta
top = \top
bottom = h - \bottom + delta
Limit(@left, 0, w)
Limit(@right, 0, w)
Limit(@top, 0, h)
Limit(@bottom, 0, h)
SetGadgetText(#FieldL, Str(left))
SetGadgetText(#FieldT, Str(top))
SetGadgetText(#FieldR, Str(right))
SetGadgetText(#FieldB, Str(bottom))
EndWith
EndIf
EndIf
EndSelect
Case #PB_Event_CloseWindow
CloseWindow(#Window)
DestroyIcon_(hIconProg)
DestroyIcon_(hIconFolder)
End
EndSelect
ForEver
EndIf