Obsolete test build - Tab3 control with autosizing, SetTimer improvements

Community news and information about new or upcoming versions of AutoHotkey
lexikos
Posts: 9553
Joined: 30 Sep 2013, 04:07
Contact:

Obsolete test build - Tab3 control with autosizing, SetTimer improvements

19 Sep 2015, 00:01

Test builds: Download Latest


v1.1.22.06-5+gc938422

Fixed +Disabled/Hidden losing effect on controls in a tab.
Fixed disabled tab controls to ignore Ctrl+Tab.
Fixed GuiControl to update controls when adding/deleting tabs. Specifically:
  • Selecting a new tab with || now works correctly.
  • Deleting all tabs now hides the controls of the former tab.
Added Tab3 control.
Most of these issues are caused by the Tab control being a "sibling" of the other controls. Tab3 solves this by putting controls inside a "tab dialog". This dialog is a sibling (not child) of the Tab3 control to allow the Tab3 control's tabs to accept focus. A few more tricks are used to get everything working and to adjust the backgrounds of controls to match the tab control.

Caveats:
  • Calling MoveWindow() on a control (via DllCall or WinMove, ahk_id %control_hwnd%, ...) will produce different results, since MoveWindow() expects coordinates relative to the control's parent, and the control's parent is the tab dialog. GuiControl Move and ControlMove are unaffected.
  • Custom controls which send notification messages to their parent window will work only if they use WM_COMMAND, WM_NOTIFY, WM_VSCROLL or WM_HSCROLL. These and any WM_CTLCOLOR' messages are forwarded to the main GUI, so can be intercepted by OnMessage. If the tab control is themed, WM_CTLCOLORSTATIC is fully handled by the tab dialog and not forwarded, unless the control has +BackgroundTrans.
  • The order in which the tab key cycles through controls may be different (and more sensible). Focus will move from the tabs, to the controls in the tab dialog, then out to the next control. Unlike Tab2, Tab3 does not put itself after the controls it contains.
  • Controls belonging to tabs can be placed outside the tab control only if they are added before the tab control exists (for simplicity).
  • Moving the Tab3 control will also move all of the controls which were placed inside it.
The test scripts demonstrate issues fixed by the control and how to utilize Tab3 without preventing the script from loading in older versions.
tab-tests.zip
(5.2 KiB) Downloaded 660 times
Old Tab control:
before.png
Old Tab control with theme:
before-themed.png
New Tab3 control (default options):
after.png
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: New test build - Tab3 control

21 Sep 2015, 01:35

outside-tabs.ahk
Missing the Edit Outside in Tab3

Image
(Windows 8.1 Enterprise N - x64 | AHK U64)
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: New test build - Tab3 control

21 Sep 2015, 02:38

The point is: to NOT allow controls to show up out of bounds?
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: New test build - Tab3 control

21 Sep 2015, 02:44

Image
Than there should not be empty space under Tab3 control
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: New test build - Tab3 control

21 Sep 2015, 02:52

Try this:

Code: Select all

/*
Tabs with controls out of bounds.
*/


TestGui("Tab")
TestGui("Tab2")
TestGui("Tab3")
return

TestGui(ctrl) {
    global
    Gui New, +LabelGui
    Gui Tab, 1
    Gui Add, Edit,, Before
    try
        Gui Add, %ctrl%, vTab h100 w200, One|Two
    catch {
        Gui Destroy
        return
    }
    Gui Add, Edit, xp+6 yp+25 r10, Inside
    Gui Add, Edit, xm y+10, Outside
    static count := 0
    Gui Show, % "x" (100+count*360), Testing %ctrl%
    count++
}

GuiClose:
GuiEscape:
ExitApp
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: New test build - Tab3 control

21 Sep 2015, 03:31

Controls belonging to tabs can be placed outside the tab control only if they are added before the tab control exists (for simplicity).
I dont think it's a good idea.

How can you add the Edit after the tab with y+10 if you dont know how big the Tab is on a non static Gui?
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
lexikos
Posts: 9553
Joined: 30 Sep 2013, 04:07
Contact:

Re: New test build - Tab3 control

21 Sep 2015, 04:33

The test scripts are there to demonstrate the behaviour; they are not expected to behave identically.
jNizM wrote:Than there should not be empty space under Tab3 control
You're right; it doesn't make much sense. It's probably best for controls in Tab3 controls to be ignored for the purposes of calculating the GUI height or the position of the next control not contained by a tab; the tab control itself should be considered instead.

Currently the control positioning is always relative to the previous control by default, even if it was in a tab, unless the new control is the first control in its tab.
jNizM wrote:I dont think it's a good idea.
It's not an idea; it's a fact.

Anyway, I think you're missing the point. Even if you place the control outside the display area of a Tab or Tab2 control, it still belongs to the tab control unless you've called Gui Tab to "disconnect" from the tab control. If you switch tabs, the control will disappear even though it sits outside the tab control. outside-tabs.ahk demonstrates this behaviour (but you have to switch tabs to see it).

I don't think it's a good idea to place controls that belong to a tab outside the tab control. I just mentioned it because of the possibility that users have used the tab control in very odd ways. For example, there is a script which gives the tab control zero dimensions and shows its own custom graphic buttons for switching tabs. That script could just continue using Tab/Tab2, or it could manually hide/show controls, but it's just one example. (Also, I intend there to be only one Tab control in v2, so simply using another type of Tab won't be an option.)
How can you add the Edit after the tab with y+10 if you dont know how big the Tab is on a non static Gui?
You can easily retrieve its size with GuiControlGet. Also, I think it's very uncommon to not specify the size of the tab control, since it isn't auto-sized like a GUI. Although it isn't a static size, it only depends on the font size and DPI (like the GUI margin), not the tab control's contents.

Also, it's actually very easy: just add the y+10 control after the tab control but before the tab's contents, as demonstrated by tab-order.ahk (#2 control). It messes up the tab order for Tab and Tab2, but Tab3 is okay.

Ideally the tab control could grow to fit its contents (auto-size like a GUI) and not need the size to be manually specified, but I hadn't seriously considered doing it due to complexity. Now that I think about it more, it would be very convenient and should be implemented before the stable release if it's going to be the default behaviour. There probably aren't any cases where the default size (as it's calculated now) is exactly right.


The clipping of controls in a Tab3 control can be useful; for example, when implementing scroll bars as illustrated by evilC in GUI in tab [Split from Tab3 announcement] (it was remiss of me to not mention this topic sooner).
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: New test build - Tab3 control

21 Sep 2015, 04:47

animatewindow.ahk (not about Tab3)
I saw with the old Tab the content is hiding after animatewindow.

There is a same issue with SS_SUNKEN & SS_ETCHEDVERT
Example:

Code: Select all

; GLOBAL SETTINGS ===============================================================================================================
 
#Warn
#NoEnv
#SingleInstance Force
SetBatchLines -1
 
global SS_BLACKRECT   := 0x4       ; displays a frame around the control and fills the control with a solid color that is the same color as the Window Frame (COLOR_WINDOWFRAME).
global SS_GRAYRECT    := 0x5       ; displays a frame around the control and fills the control with a solid color that is the same color as the Desktop (COLOR_BACKGROUND).
global SS_WHITERECT   := 0x6       ; displays a frame around the control and fills the control with a solid color that is the same color as the Window (COLOR_WINDOW).
global SS_BLACKFRAME  := 0x7       ; displays a frame around the control that is the same color as the Window Frame (COLOR_WINDOWFRAME).
global SS_GRAYFRAME   := 0x8       ; displays a frame around the control that is the same color as the Desktop, the screen background (COLOR_BACKGROUND).
global SS_WHITEFRAME  := 0x9       ; displays a frame around the control that is the same color as the Window (COLOR_WINDOW).
global SS_ETCHEDHORZ  := 0x10      ; Draws the top and bottom edges of the static control using the EDGE_ETCHED edge style.
global SS_ETCHEDVERT  := 0x11      ; Draws the left and right edges of the static control using the EDGE_ETCHED edge style.
global SS_ETCHEDFRAME := 0x12      ; Draws the frame of the static control using the EDGE_ETCHED edge style.
global SS_SUNKEN      := 0x1000    ; Draws a half-sunken border around a static control.
 
; GUI ===========================================================================================================================
 
Gui, Add, Text, x10  y10    w50                   , % "SS_BLACKRECT"
Gui, Add, Text, x10  y30    w50   h1    0x4       ; Horizontal Line (small)   >   SS_BLACKRECT
Gui, Add, Text, x10  y33    w50   h4    0x4       ; Horizontal Line (big)     >   SS_BLACKRECT
Gui, Add, Text, x10  y40    w1    h50   0x4       ; Vertical   Line (small)   >   SS_BLACKRECT
Gui, Add, Text, x13  y40    w4    h50   0x4       ; Vertical   Line (big)     >   SS_BLACKRECT
 
Gui, Add, Text, x150 y10    w50                   , % "SS_BLACKFRAME"
Gui, Add, Text, x150 y30    w50   h7    0x7       ; Horizontal Frame          >   SS_BLACKFRAME
Gui, Add, Text, x150 y40    w7    h50   0x7       ; Vertical   Frame          >   SS_BLACKFRAME
 
 
Gui, Add, Text, x10  y110   w50                   , % "SS_GRAYRECT"
Gui, Add, Text, x10  y130   w50   h1    0x5       ; Horizontal Line (small)   >   SS_GRAYRECT
Gui, Add, Text, x10  y133   w50   h4    0x5       ; Horizontal Line (big)     >   SS_GRAYRECT
Gui, Add, Text, x10  y140   w1    h50   0x5       ; Vertical   Line (small)   >   SS_GRAYRECT
Gui, Add, Text, x13  y140   w4    h50   0x5       ; Vertical   Line (big)     >   SS_GRAYRECT
 
Gui, Add, Text, x150 y110   w50                   , % "SS_GRAYFRAME"
Gui, Add, Text, x150 y130   w50   h7    0x8       ; Horizontal Frame          >   SS_GRAYFRAME
Gui, Add, Text, x150 y140   w7    h50   0x8       ; Vertical   Frame          >   SS_GRAYFRAME
 
 
Gui, Add, Text, x10  y210   w50                   , % "SS_WHITERECT"
Gui, Add, Text, x10  y230   w50   h1    0x6       ; Horizontal Line (small)   >   SS_WHITERECT
Gui, Add, Text, x10  y233   w50   h4    0x6       ; Horizontal Line (big)     >   SS_WHITERECT
Gui, Add, Text, x10  y240   w1    h50   0x6       ; Vertical   Line (small)   >   SS_WHITERECT
Gui, Add, Text, x13  y240   w4    h50   0x6       ; Vertical   Line (big)     >   SS_WHITERECT
 
Gui, Add, Text, x150 y210   w50                   , % "SS_WHITEFRAME"
Gui, Add, Text, x150 y230   w50   h7    0x9       ; Horizontal Frame          >   SS_WHITEFRAME
Gui, Add, Text, x150 y240   w7    h50   0x9       ; Vertical   Frame          >   SS_WHITEFRAME
 
 
Gui, Add, Text, x10  y310                         , % "SS_ETCHEDHORZ / -VERT / -FRAME"
Gui, Add, Text, x10  y330   w50   h1    0x10      ; Horizontal Line (small)   >   SS_ETCHEDHORZ
Gui, Add, Text, x10  y340   w1    h50   0x11      ; Vertical   Line (small)   >   SS_ETCHEDVERT
 
Gui, Add, Text, x150 y330   w50   h7    0x12      ; Horizontal Frame          >   SS_ETCHEDFRAME
Gui, Add, Text, x150 y340   w7    h50   0x12      ; Vertical   Frame          >   SS_ETCHEDFRAME
 
 
Gui, Add, Text, x10  y410                         , % "SS_SUNKEN"
Gui, Add, Text, x10  y430   w50   h1    0x1000    ; Horizontal Line (small)   >   SS_SUNKEN
Gui, Add, Text, x10  y440   w1    h50   0x1000    ; Vertical   Line (small)   >   SS_SUNKEN
 
Gui, Add, Text, x150 y430   w50   h7    0x1000    ; Horizontal Frame          >   SS_SUNKEN
Gui, Add, Text, x150 y440   w7    h50   0x1000    ; Vertical   Frame          >   SS_SUNKEN

Gui, Add, Button, x10 y+20 w75 h25, Hide && Show
Gui, Show, AutoSize
return


ButtonHideShow:
Gui, +LastFound
hWnd := WinExist()
DllCall("user32.dll\AnimateWindow", "UInt", hWnd, "UInt", 200, "UInt", 0x90000) ; AW_BLEND + AW_HIDE = 0x90000
Sleep, 500
DllCall("user32.dll\AnimateWindow", "UInt", hWnd, "UInt", 200, "UInt", 0x80000) ; AW_BLEND = 0x80000
Return

; EXIT ==========================================================================================================================

GuiClose:
GuiEscape:
ExitApp
Return

You can split it if you want, since it's not about Tab3.
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
lexikos
Posts: 9553
Joined: 30 Sep 2013, 04:07
Contact:

Re: New test build - Tab3 control

21 Sep 2015, 04:57

I'm not even remotely interested in debugging AnimateWindow. It is an antiquated API with two major by-design flaws: 1) It relies on the window and controls painting themselves correctly in response to WM_PRINT/WM_PRINTCLIENT messages. They don't, as you've noted. 2) It isn't compatible with the desktop window manager; i.e. the window frame reverts to the non-Aero Vista style while the window is animating (even on Windows 10).

For fading, WinSet Transparent on a timer works much better.
lexikos
Posts: 9553
Joined: 30 Sep 2013, 04:07
Contact:

Re: New test build - Tab3 control

27 Sep 2015, 07:00

v1.1.22.07-19+g6c206a4

Menu improvements:

Items can be identified by position with the Menu command. Use the same syntax as WinMenuSelectItem: 1&, 2&, etc.

Added Menu, MenuName, Insert [, ItemToInsertBefore, NewItemName, Label-or-Submenu, Options].
  • ItemToInsertBefore is the name or position& of an existing item, or n& where n is the current number of items plus 1 (and is the same as omitting the parameter).
  • Menu M, Insert, , ... is the same as Menu M, Add, ..., except that if an item with that name already exists, Add modifies it whereas Insert creates a new item.
Added options for the Add and Insert sub-commands. The parameter formerly known as Pn can contain a list of options, with the same syntax as Gui/GuiControl: space/tab delimited, optional + or - prefix.
  • Radio: If checked, a bullet point is used instead of a check mark.
  • Right: The item is right-justified within the menu bar (on a Gui).
  • Break: The item begins a new column in a popup menu.
  • BarBreak: As above, but with a dividing line between columns.
  • Pn: As before.
Added HMENU := MenuGetHandle(MenuName).
Fixed A_ThisMenuItemPos to support duplicate item names.
Optimized menu code to counteract the increase in executable size.

Pictures:

Improved Picture control to support BackgroundTrans with icons. (Omit AltSubmit for best results.)

The next two features are intended for any scripts or techniques which already deal with icon/bitmap handles (so you're expected to know what to do with the icon/bitmap). They can be used, for example, to set a window's icon with WM_SETICON or put a window's icon into a menu after retrieving it with WM_GETICON.

Added Handle := LoadPicture(Filename [, Options, ByRef ImageType]).
  • Options is a space/tab-delimited string of options.
    • wN and hN: Width and height. Omit both to use actual size.
      Examples: w80 h50, w48 h-1 or w48 (preserve aspect ratio), h0 w100 (actual height but override width).
    • IconN: N is the icon number. If non-zero, the file must contain an icon.
    • GDI+: Use GDI+ if available.
  • ImageType receives the type of image: 0 (IMAGE_BITMAP), 1 (IMAGE_ICON) or 2 (IMAGE_CURSOR). If omitted or not a variable, the return value is always a bitmap handle (icons/cursors are converted if necessary).
  • The return value is a bitmap, icon or cursor handle (see above).
Commands and functions which load a picture, such as Gui Add, Picture, Menu M, Icon, ImageSearch, SplashImage, etc. now support passing an icon or bitmap handle. The syntax is HICON:handle or HBITMAP:handle (not case sensitive) in place of a filename. By default, AutoHotkey treats the handle as though it loaded the image from file itself -- deleting it automatically at some point, or perhaps immediately if it needs to be resized. To avoid this, put an asterisk between the colon and handle (and remember to delete the icon/bitmap at some point). For example: hbitmap:*%handle% (or "hbitmap:*" handle in an expression).

For a download link, see the top post.

Suggestions for syntax or behavioural changes are welcome (but not required).
User avatar
jballi
Posts: 723
Joined: 29 Sep 2013, 17:34

Re: New test builds - Tab3 control, Menu improvements, LoadPicture/handles

27 Sep 2015, 20:10

Looks like some seriously cool improvements. 8-) I wish I had time to do some serious testing on them but I look forward to using them when they are formally released.
just me
Posts: 9423
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: New test builds - Tab3 control, Menu improvements, LoadPicture/handles

29 Sep 2015, 01:57

Has 1.1.22.07 already become an official release (as the Download button indicates)?
lexikos
Posts: 9553
Joined: 30 Sep 2013, 04:07
Contact:

Re: New test builds - Tab3 control, Menu improvements, LoadPicture/handles

29 Sep 2015, 02:36

v1.1.22.07 is just a minor bug-fix release and is unrelated to this thread. I uploaded it shortly before the test build, and forgot to announce it.

v1.1.22.07-19+g6c206a4 is a version string generated by git, which includes the most recent tag (v1.1.22.07), number of commits since that tag (19) and git commit (6c206a4). The stable release containing these new features will not be labelled v1.1.22.xx.
lexikos
Posts: 9553
Joined: 30 Sep 2013, 04:07
Contact:

Re: New test builds - Tab3 control, Menu improvements, LoadPicture/handles

30 Sep 2015, 17:04

v1.1.22.07-27+g615a1ce

Added variables:
A_CoordModeToolTip/Pixel/Mouse/Caret/Menu
A_DefaultGui
A_DefaultListView
A_DefaultTreeView
A_KeyDelayPlay
A_KeyDuration
A_KeyDurationPlay
A_MouseDelayPlay
A_SendLevel
A_SendMode
A_StoreCapslockMode

Optimized built-in variable lookup code, reducing code size and marginally increasing performance in some cases.

Added Ix Hotkey option to set the hotkey variant's input level to x.

See top post for download.
just me
Posts: 9423
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: New test builds - Tab3 control, Menu improvements, LoadPicture, new vars

01 Oct 2015, 01:16

Why does A_DefaultGui contain 1 even if no Gui exists?
lexikos
Posts: 9553
Joined: 30 Sep 2013, 04:07
Contact:

Re: New test builds - Tab3 control, Menu improvements, LoadPicture, new vars

01 Oct 2015, 03:11

Because it's the default GUI name. Gui xxx: Default ordinarily sets the default name used by the Gui commands, regardless of whether any window "xxx" exists. It does not cause the window to be created, and if you pass a name or the HWND of a GUI which has a name, the setting persists even if you destroy and recreate the window. If you set an anonymous GUI as default and then destroy it, the default name reverts to "1".

The purpose of the variable is to allow scripts to save and restore the default GUI:

Code: Select all

dgui := A_DefaultGui
Gui fancymsgbox: Default
;... do something with fancymsgbox ...
Gui %dgui%: Default
If you use +LastFoundExist and WinExist(), it will fail if the default GUI doesn't exist:

Code: Select all

Gui foo: Default
MsgBox % A_DefaultGui  ; foo
Gui +LastFoundExist
dgui := WinExist()  ; 0x0, because no window has been created.
Gui bar: Default
;...
try
    Gui %dgui%: Default
catch ex
    MsgBox % ex.Message " " ex.Extra  ; Error: Invalid Gui name. 0x0: Default
MsgBox % A_DefaultGui  ; bar
ExitApp
Using +hwndVarName will work, but it may create a window as a side-effect. This is wasteful and may affect the behaviour of the script.

Both +LastFoundExist and +hwndVarName would fail to work correctly if the window was destroyed in between retrieving the HWND and resetting the default, whereas using A_DefaultGui will properly restore the default Gui name.
just me
Posts: 9423
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: New test builds - Tab3 control, Menu improvements, LoadPicture, new vars

01 Oct 2015, 10:37

I see, thanks. But in this case it seems to be of limited benefit. In GUI threads it's equal to A_Gui, and it seems to contain always 1 in non-GUI threads.
lexikos
Posts: 9553
Joined: 30 Sep 2013, 04:07
Contact:

Re: New test builds - Tab3 control, Menu improvements, LoadPicture, new vars

01 Oct 2015, 16:19

No, as I demonstrated, it does not contain 1 if you change the default Gui. If you never change the default Gui, then obviously it is of no benefit to you, but it will be of benefit to others. (It also does not contain the same value as A_Gui if you have changed the default Gui.)
just me
Posts: 9423
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: New test builds - Tab3 control, Menu improvements, LoadPicture, new vars

02 Oct 2015, 03:00

Obviously I don't get the sense. :?

Code: Select all

#NoEnv
MsgBox, 0, AHK Version, %A_AhkVersion%
Gui, Main:New
Gui, +OwnDialogs
Gui, Add, Text, , Press F1 to display A_DefaultGui
Gui, Add, Button, wp gClicked, Display A_DefaultGui
Gui, Show, w400 h300
MsgBox, 0, Auto-Exec #1, A_DefaultGui: %A_DefaultGui% - A_Gui: %A_Gui%
Gui, Second:New
MsgBox, 0, Auto-Exec #2, A_DefaultGui: %A_DefaultGui% - A_Gui: %A_Gui%
SetTimer, MyTimer, -1
Return
MainGuiClose:
MainGuiEscape:
ExitApp
Clicked:
   MsgBox, 0, Gui thread %A_ThisLabel%, A_DefaultGui: %A_DefaultGui% - A_Gui: %A_Gui%
Return
F1::
   MsgBox, 0, Hotkey %A_ThisHotkey%, A_DefaultGui: %A_DefaultGui% - A_Gui: %A_Gui%
Return
MyTimer:
   MsgBox, 0, Timer %A_ThisLabel%, A_DefaultGui: %A_DefaultGui% - A_Gui: %A_Gui%
Return
---------------------------
AHK Version
---------------------------
1.1.22.07-27+g615a1ce
---------------------------
OK
---------------------------

---------------------------
Auto-Exec #1
---------------------------
A_DefaultGui: Main - A_Gui:
---------------------------
OK
---------------------------

---------------------------
Auto-Exec #2
---------------------------
A_DefaultGui: Second - A_Gui:
---------------------------
OK
---------------------------

---------------------------
Timer MyTimer
---------------------------
A_DefaultGui: 1 - A_Gui:
---------------------------
OK
---------------------------

---------------------------
Gui thread Clicked
---------------------------
A_DefaultGui: Main - A_Gui: Main
---------------------------
OK
---------------------------

---------------------------
Hotkey F1
---------------------------
A_DefaultGui: 1 - A_Gui:
---------------------------
OK
---------------------------
lexikos
Posts: 9553
Joined: 30 Sep 2013, 04:07
Contact:

Re: New test builds - Tab3 control, Menu improvements, LoadPicture, new vars

02 Oct 2015, 03:48

If you don't understand what the variable is for, you should review this post from last year and try to remember why you spent some of your time writing your own A_DefaultGui() function. :roll:

The purpose of these new variables is the same as for all of the previously existing thread settings: A_TitleMatchMode, A_KeyDelay, etc. If one is writing a function (or any self-contained portion of code) which requires changing a thread setting, one often wants to revert the setting afterward so as to not affect whatever code called the function. It's not necessary to use these variables directly in code which runs as its own thread (such as your timer and GUI threads), since any changes in that thread won't affect other threads.

Return to “Announcements”

Who is online

Users browsing this forum: No registered users and 43 guests