 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
silkcom Guest
|
Posted: Mon Aug 20, 2007 5:38 pm Post subject: current |
|
|
Ok, I've spent sometime making the keys changeable, and it seems to be working without any problems (not the cleanest implementation, but it works).
I've also added a minimize, but it doesn't work very well. I'm wondering if someone can help me to get it working properly.
Ideally when u minimize it hooks to the window that was minimized. So the next commands should work on that window. I have it so that if you minimize it usually restores, but not always.
Here's the key layout:
fill left half (win+alt+z), fill right half (win+alt+x) -- win+ctrl = alternate
1/4 screen top left = q, top right = w, bottom left = a, bottom right = s
top half = e, bottom half = d, center screen = c.
Maximize = up arrow
Minimize = down arrow
also, fill left half works with left arrow, and fill right works with right arrow.
Heres my code: (Ignore the comments from the original version)
| Code: | ; WindowPad:
;
; Move and resize windows with Win+Numpad.
; Win+Numpad1 = Fill bottom-left quarter of screen
; Win+Numpad2 = Fill bottom half of screen
; etc.
;
; Move windows across monitors. For example:
; Win+Numpad4 places the window on the left half of the screen.
; Win+Numpad4 again moves it to the monitor to the right.
;
; Quick monitor switch:
; Win+Numpad5 places the window in the center of the screen.
; Win+Numpad5 again moves the window to the next monitor.
; (This works by monitor number, not necessarily left to right.)
;
; QUICKER Monitor Switch:
; Win+NumpadDot switches to the next monitor (1->2->3->1 etc.)
; Win+NumpadDiv moves ALL windows to monitor 2.
; Win+NumpadMult moves ALL windows to monitor 1.
;
; Other shortcuts:
; Win+Numpad0 toggles maximize.
; Insert (or some other key) can be used in place of "Win".
;
; Credits:
; Concept based on HiRes Screen Splitter by JOnGliko.
; Written from scratch by Lexikos to support multiple monitors.
; NumpadDot key functionality suggested by bobbo.
;
; Built with AutoHotkey v1.0.47.02
;
; HISTORY
;
; Version 1.1:
; - "Gather windows" hotkeys (NumpadDiv and NumpadMult)
; - NumpadDot to move window to next monitor
; - Added more EasyKey combos (for symmetry)
; - Original functionality of EasyKey is retained (on key-release)
; - SetWinDelay, -1 to reduce lag when making multiple moves (quickly)
;
; Version 1:
; - intial release
WindowPadInit:
Prefix_Active = #! ; Alt+Win+Char = Move active window
Prefix_Other = #^ ; Ctrl+Win+Numpad = Move previously active window
; Note: Shift (+) should not be used, as +Numpad is hooked by the OS
; to do left/right/up/down/etc. (reverse Numlock) -- at least on Vista.
EasyKey = Insert ; Insert is near Numpad on my keyboard...
; Note: Prefix_Other must not be a sub-string of Prefix_Active.
; (If you want it to be, first edit the line "if (InStr(A_ThisHotkey, Prefix_Other))")
Hotkey, IfWinActive ; in case this is included in another script...
;;Edit all the hotkeys here:
; Left and Right
Leftt = z
Rightt = x
; Grid of four
TopLeft = q
TopRight = w
BottomLeft = a
BottomRight = s
; Top and Bottom
Top = e
Bottom = d
; Center
Center = c
Hotkey1a = %Prefix_Active%%BottomLeft%
Hotkey1o = %Prefix_Other%%BottomLeft%
Hotkey2a = %Prefix_Active%%Bottom%
Hotkey2o = %Prefix_Other%%Bottom%
Hotkey3a = %Prefix_Active%%BottomRight%
Hotkey3o = %Prefix_Other%%BottomRight%
Hotkey4a = %Prefix_Active%%Leftt%
Hotkey4o = %Prefix_Other%%Leftt%
Hotkey4a2 = %Prefix_Active%Left
Hotkey4o2 = %Prefix_Other%Left
Hotkey5a = %Prefix_Active%%Center%
Hotkey5o = %Prefix_Other%%Center%
Hotkey6a = %Prefix_Active%%Rightt%
Hotkey6o = %Prefix_Other%%Rightt%
Hotkey6a2 = %Prefix_Active%Right
Hotkey6o2 = %Prefix_Other%Right
Hotkey7a = %Prefix_Active%%TopLeft%
Hotkey7o = %Prefix_Other%%TopLeft%
Hotkey8a = %Prefix_Active%%Top%
Hotkey8o = %Prefix_Other%%Top%
Hotkey9a = %Prefix_Active%%TopRight%
Hotkey9o = %Prefix_Other%%TopRight%
Hotkey, %Hotkey1a%, DoMoveWindowInDirection
Hotkey, %Hotkey1o%, DoMoveWindowInDirection
Hotkey, %Hotkey2a%, DoMoveWindowInDirection
Hotkey, %Hotkey2o%, DoMoveWindowInDirection
Hotkey, %Hotkey3a%, DoMoveWindowInDirection
Hotkey, %Hotkey3o%, DoMoveWindowInDirection
Hotkey, %Hotkey4a%, DoMoveWindowInDirection
Hotkey, %Hotkey4o%, DoMoveWindowInDirection
Hotkey, %Hotkey4a2%, DoMoveWindowInDirection
Hotkey, %Hotkey4o2%, DoMoveWindowInDirection
Hotkey, %Hotkey5a%, DoMoveWindowInDirection
Hotkey, %Hotkey5o%, DoMoveWindowInDirection
Hotkey, %Hotkey6a%, DoMoveWindowInDirection
Hotkey, %Hotkey6o%, DoMoveWindowInDirection
Hotkey, %Hotkey6a2%, DoMoveWindowInDirection
Hotkey, %Hotkey6o2%, DoMoveWindowInDirection
Hotkey, %Hotkey7a%, DoMoveWindowInDirection
Hotkey, %Hotkey7o%, DoMoveWindowInDirection
Hotkey, %Hotkey8a%, DoMoveWindowInDirection
Hotkey, %Hotkey8o%, DoMoveWindowInDirection
Hotkey, %Hotkey9a%, DoMoveWindowInDirection
Hotkey, %Hotkey9o%, DoMoveWindowInDirection
; Setup Hotkeys
;Loop, 9
;{ ; Register hotkeys.
; Hotkey, %Prefix_Active%Numpad%A_Index%, DoMoveWindowInDirection
; Hotkey, %Prefix_Other%Numpad%A_Index%, DoMoveWindowInDirection
;
; ; OPTIONAL
; if EasyKey
; Hotkey, %EasyKey% & Numpad%A_Index%, DoMoveWindowInDirection
;}
Hotkey, %Prefix_Active%Up, DoMaximizeToggle
Hotkey, %Prefix_Other%Up, DoMaximizeToggle
Hotkey, %Prefix_Active%Down, DoMinimizeToggle
Hotkey, %Prefix_Other%Down, DoMinimizeToggle
Hotkey, %Prefix_Active%NumpadDot, MoveWindowToNextScreen
Hotkey, %Prefix_Other%NumpadDot, MoveWindowToNextScreen
Hotkey, %Prefix_Active%NumpadDiv, GatherWindowsLeft
Hotkey, %Prefix_Active%NumpadMult, GatherWindowsRight
;if (EasyKey) {
; Hotkey, %EasyKey% & Numpad0, DoMaximizeToggle
; Hotkey, %EasyKey% & NumpadDot, MoveWindowToNextScreen
; Hotkey, %EasyKey% & NumpadDiv, GatherWindowsLeft
; Hotkey, %EasyKey% & NumpadMult, GatherWindowsRight
; Hotkey, %EasyKey%, SendEasyKey ; let EasyKey's original function work (on release)
;}
return
SendEasyKey:
Send {%EasyKey%}
return
; This is actually based on monitor number, so if your secondary is on the
; right, you may want to switch these around.
GatherWindowsLeft:
GatherWindows(1)
return
GatherWindowsRight:
GatherWindows(2)
return
; Hotkey handler.
DoMoveWindowInDirection:
; Define constants.
if (!Directions1) {
dir = -1:+1,0:+1,+1:+1,-1:0,0:0,+1:0,-1:-1,0:-1,+1:-1
StringSplit, Directions, dir, `,
}
gosub WP_SetLastFoundWindowByHotkey
; Determine which direction we want to go.
;if (!RegExMatch(A_ThisHotkey, "\d+", dir) or !Directions%dir%)
;{
; MsgBox Error: "%A_ThisHotkey%" was registered and I can't figure out which number it is!
; return
;}
if (A_ThisHotKey = Hotkey1a) or (A_ThisHotKey = Hotkey1o)
{
dir := Directions1
}
else if (A_ThisHotKey = Hotkey2a) or (A_ThisHotKey = Hotkey2o)
{
dir := Directions2
}
else if (A_ThisHotKey = Hotkey3a) or (A_ThisHotKey = Hotkey3o)
{
dir := Directions3
}
else if (A_ThisHotKey = Hotkey4a) or (A_ThisHotKey = Hotkey4o) or (A_ThisHotKey = Hotkey4a2) or (A_ThisHotKey = Hotkey4o2)
{
dir := Directions4
}
else if (A_ThisHotKey = Hotkey5a) or (A_ThisHotKey = Hotkey5o)
{
dir := Directions5
}
else if (A_ThisHotKey = Hotkey6a) or (A_ThisHotKey = Hotkey6o) or (A_ThisHotKey = Hotkey6a2) or (A_ThisHotKey = Hotkey6o2)
{
dir := Directions6
}
else if (A_ThisHotKey = Hotkey7a) or (A_ThisHotKey = Hotkey7o)
{
dir := Directions7
}
else if (A_ThisHotKey = Hotkey8a) or (A_ThisHotKey = Hotkey8o)
{
dir := Directions8
}
else if (A_ThisHotKey = Hotkey9a) or (A_ThisHotKey = Hotkey9o)
{
dir := Directions9
}
;dir := Directions%dir%
StringSplit, dir, dir, :
; Determine width/height factors.
if (dir1 or dir2) { ; to a side
widthFactor := dir1 ? 0.5 : 1.0
heightFactor := dir2 ? 0.5 : 1.0
} else { ; to center
widthFactor := 0.5
heightFactor := 0.5
}
; Move the window!
MoveWindowInDirection(dir1, dir2, widthFactor, heightFactor)
return
WP_SetLastFoundWindowByHotkey:
; Set Last Found Window.
if (InStr(A_ThisHotkey, Prefix_Other))
WinPreviouslyActive()
else
WinExist("A")
return
; "Maximize"
DoMaximizeToggle:
gosub WP_SetLastFoundWindowByHotkey
WinGet, state, MinMax
if minimizedId
{
WinRestore, ahk_id %minimizedId%
minimizedId = 0
}
else
{
if state
WinRestore
else
WinMaximize
}
return
; "Minimize"
DoMinimizeToggle:
gosub WP_SetLastFoundWindowByHotkey
WinGet, state, MinMax
WinGet, active_id, ID, A
if minimizedId
{
; Msgbox minimizedId = %minimizedId%
WinPreviouslyActive()
if state
{
WinRestore, ahk_id %minimizedId%
}
minimizedId = 0
}
else
{
; Msgbox minimizedId = %minimizedId%
if state >= 0
{
minimizedId = %active_id%
WinMinimize, ahk_id %minimizedId%
}
}
return
; Does the grunt work of the script.
MoveWindowInDirection(sideX, sideY, widthFactor, heightFactor, screenMoveOnly=false)
{
WinGetPos, x, y, w, h
; Determine which monitor contains the center of the window.
m := GetMonitorAt(x+w/2, y+h/2)
; Get work area of active monitor.
gosub CalcMonitorStats
; Calculate possible new position for window.
gosub CalcNewPosition
; If the window is already there,
if (newx "," newy "," neww "," newh) = (x "," y "," w "," h)
{ ; ..move to the next monitor along instead.
if (sideX or sideY)
{ ; Move in the direction of sideX or sideY.
SysGet, monB, Monitor, %m% ; get bounds of entire monitor (vs. work area)
x := (sideX>0 ? monBRight : monBLeft) + sideX
y := (sideY>0 ? monBBottom : monBTop) + sideY
newm := GetMonitorAt(x, y, m)
}
else
{ ; Move to center (Numpad5)
newm := m+1
SysGet, mon, MonitorCount
if (newm > mon)
newm := 1
}
if (newm != m)
{ m := newm
; Move to opposite side of monitor (left of a monitor is another monitor's right edge)
sideX *= -1
sideY *= -1
; Get new monitor's work area.
gosub CalcMonitorStats
}
; Calculate new position for window.
gosub CalcNewPosition
}
; Restore before resizing...
WinGet, state, MinMax
if state
WinRestore
; Finally, move the window!
SetWinDelay, -1
WinMove,,, newx, newy, neww, newh
return
CalcNewPosition:
; Calculate new size.
if (IsResizable()) {
neww := Round(monWidth * widthFactor)
newh := Round(monHeight * heightFactor)
} else {
neww := w
newh := h
}
; Calculate new position.
newx := Round(monLeft + (sideX+1) * (monWidth - neww)/2)
newy := Round(monTop + (sideY+1) * (monHeight - newh)/2)
return
CalcMonitorStats:
; Get work area (excludes taskbar-reserved space.)
SysGet, mon, MonitorWorkArea, %m%
monWidth := monRight - monLeft
monHeight := monBottom - monTop
return
}
; Get the index of the monitor containing the specified x and y co-ordinates.
GetMonitorAt(x, y, default=1)
{
y := 100
SysGet, m, MonitorCount
; Iterate through all monitors.
Loop, %m%
{ ; Check if the window is on this monitor.
SysGet, Mon, Monitor, %A_Index%
if (x >= MonLeft && x <= MonRight && y >= MonTop && y <= MonBottom)
return A_Index
}
return default
}
IsResizable()
{
WinGet, Style, Style
return (Style & 0x40000) ; WS_SIZEBOX
}
; Note: This may not work properly with always-on-top windows. (Needs testing)
WinPreviouslyActive()
{
active := WinActive("A")
WinGet, win, List
; Find the active window.
; (Might not be win1 if there are always-on-top windows?)
Loop, %win%
if (win%A_Index% = active)
{
if (A_Index < win)
N := A_Index+1
; hack for PSPad: +1 seems to get the document (child!) window, so do +2
ifWinActive, ahk_class TfPSPad
N += 1
break
}
; Use WinExist to set Last Found Window (for consistency with WinActive())
return WinExist("ahk_id " . win%N%)
}
;
; Switch without moving/resizing (relative to screen)
;
MoveWindowToNextScreen:
gosub WP_SetLastFoundWindowByHotkey
MoveWindowToNextScreen()
return
MoveWindowToNextScreen()
{
WinGetPos, x, y, w, h
; Determine which monitor contains the center of the window.
ms := GetMonitorAt(x+w/2, y+h/2)
; Determine which monitor to move to.
md := ms+1
SysGet, mon, MonitorCount
if (md > mon)
md := 1
; This may happen if someone tries it with only one screen. :P
if (md = ms)
return
; Get source and destination work areas (excludes taskbar-reserved space.)
SysGet, ms, MonitorWorkArea, %ms%
SysGet, md, MonitorWorkArea, %md%
msw := msRight - msLeft, msh := msBottom - msTop
mdw := mdRight - mdLeft, mdh := mdBottom - mdTop
; Calculate new size.
if (IsResizable()) {
w *= (mdw/msw)
h *= (mdh/msh)
}
SetWinDelay, -1
; Move window, using resolution difference to scale co-ordinates.
WinMove,,, mdLeft + (x-msLeft)*(mdw/msw), mdTop + (y-msTop)*(mdh/msh), w, h
}
;
; "Gather" windows on a specific screen.
;
GatherWindows(md=1)
{
SetWinDelay, -1 ; Makes a BIG difference to perceived performance.
; List all visible windows.
WinGet, win, List
; Copy bounds of all monitors to an array.
SysGet, mc, MonitorCount
Loop, %mc%
SysGet, mon%A_Index%, MonitorWorkArea, %A_Index%
; Destination monitor
mdx := mon%md%Left
mdy := mon%md%Top
mdw := mon%md%Right - mdx
mdh := mon%md%Bottom - mdy
Loop, %win%
{
; Set Last Found Window.
if (!WinExist("ahk_id " . win%A_Index%))
continue
WinGetPos, x, y, w, h
; Determine which monitor this window is on.
xc := x+w/2, yc := y+h/2
ms := 1
Loop, %mc%
if (xc >= mon%A_Index%Left && xc <= mon%A_Index%Right
&& yc >= mon%A_Index%Top && yc <= mon%A_Index%Bottom)
{
ms := A_Index
break
}
; If already on destination monitor, skip this window.
if (ms = md)
continue
; Source monitor
msx := mon%ms%Left
msy := mon%ms%Top
msw := mon%ms%Right - msx
msh := mon%ms%Bottom - msy
; If the window is resizable, scale it by the monitors' resolution difference.
if (IsResizable()) {
w *= (mdw/msw)
h *= (mdh/msh)
}
; Move window, using resolution difference to scale co-ordinates.
WinMove,,, mdx + (x-msx)*(mdw/msw), mdy + (y-msy)*(mdh/msh), w, h
}
} |
|
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2494 Location: Australia, Qld
|
Posted: Mon Aug 20, 2007 10:06 pm Post subject: |
|
|
Nice work. I believe the minimize problem is this: | Code: | WinGet, state, MinMax
...
if state
{
WinRestore, ahk_id %minimizedId%
} | "state" would be the state of the Last Found Window, which I imagine should be of no consequence. |
|
| Back to top |
|
 |
silkcom Guest
|
Posted: Mon Aug 20, 2007 10:21 pm Post subject: reply |
|
|
The reason I grab the state of the last active window, is because when you minimize a window it becomes inactive. Is it possible to check the state of the window that was minimized?
I also need to add in a clear minimizedID if I click on a different window. Basically until I'm working on a different app, I want the key strokes to affect the one I was working on. |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2494 Location: Australia, Qld
|
Posted: Tue Aug 21, 2007 7:23 am Post subject: Re: reply |
|
|
| silkcom wrote: | | Is it possible to check the state of the window that was minimized? | Yes, similar to the way you restore the window that was minimized: | Code: | | WinGet, state, MinMax, ahk_id %minimizedId% |
|
|
| Back to top |
|
 |
triff Guest
|
Posted: Wed Aug 22, 2007 8:50 am Post subject: Win+NumpadDot won't move maximize window to a smaller screen |
|
|
Hi,
Thanks for this great script.
On my computer, MoveWindowToNextScreen won't move a maximized window to a smaller screen. It seems like the calculus of a new size don't work on maximized window.
A quick hack that work for me is to restore the window, then move it and then maximize it again on the new screen :
| Code: | ;
; Switch without moving/resizing (relative to screen)
;
MoveWindowToNextScreen:
gosub WP_SetLastFoundWindowByHotkey
;;; Act differently if the window is maximized :
;;; restore, then move and then maximize again on the new screen
WinGet, state, MinMax
if state {
WinRestore
MoveWindowToNextScreen()
WinMaximize
}
else
;;; End of modification
MoveWindowToNextScreen()
return
|
|
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2494 Location: Australia, Qld
|
Posted: Wed Aug 22, 2007 9:58 am Post subject: Re: Win+NumpadDot won't move maximize window to a smaller sc |
|
|
| triff wrote: | | On my computer, MoveWindowToNextScreen won't move a maximized window to a smaller screen. It seems like the calculus of a new size don't work on maximized window. | That's strange - my secondary monitor is smaller than my primary. Windows are scaled precisely by the difference in working area, so maximized windows always end up perfect on mine. The only "problem" I have is: | lexikos wrote: | | maximized windows go back to their original screen when you restore them. | The "quick hack" you mentioned fixes this, but I still prefer not to have it. Perhaps I'll add it in the next edit, since it seems to work better for some people. |
|
| Back to top |
|
 |
bobbo
Joined: 19 Mar 2007 Posts: 14
|
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2494 Location: Australia, Qld
|
Posted: Tue Aug 28, 2007 3:50 pm Post subject: |
|
|
And will probably take up around 10% as much disk space.  |
|
| Back to top |
|
 |
JOnGliko
Joined: 30 Aug 2006 Posts: 7
|
Posted: Tue Aug 28, 2007 7:08 pm Post subject: Happy |
|
|
Hi,
Happy to see that the idea as grown, thx lexikos. I think I'll use your script now .
When I made the first script I wanted to implement an other feature, but I never found the time to do it.
The idea is when you hit quickly the same number, the first window move to a side and the window just under move to the opposite.
For example you hit two time '4' quickly, the first window resize and go the the left, and the next window resize and go to the right.
I think it could be a good way to move two windows quickly. When I use the '4' or the '6' I usually move the window under to the opposit to have 2 windows split on the screen.
Keep on the good job.
JOnGliko |
|
| Back to top |
|
 |
ezuk
Joined: 04 Jun 2005 Posts: 122
|
Posted: Mon Sep 03, 2007 6:49 am Post subject: Awesome! |
|
|
Lexikos, you rock!
I just bought a new 22" flat-screen monitor, and now I have that as my second screen in a dual-monitor setup with my laptop. This script lets me utilize my new screen real-estate to the max!
Thanks for making it -- works very well. |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2494 Location: Australia, Qld
|
Posted: Mon Sep 03, 2007 6:55 am Post subject: Re: Awesome! |
|
|
| ezuk wrote: | | I just bought a new 22" flat-screen monitor, and now I have that as my second screen in a dual-monitor setup with my laptop. This script lets me utilize my new screen real-estate to the max! | The only reason I wrote this script was my new 22" widescreen and old 19" (side by side) made my desktop too wide for the mouse to be effective.
I think wiiiiidescreen is a more accurate term... |
|
| Back to top |
|
 |
ezuk
Joined: 04 Jun 2005 Posts: 122
|
Posted: Mon Sep 03, 2007 7:39 am Post subject: Re: Awesome! |
|
|
| lexikos wrote: |
I think wiiiiidescreen is a more accurate term... |
Completely agreed!
I just thought of a new feature-suggestion and wanted to share:
Let's say I have my screen with Excel to the left, and FireFox to the right. Currently, they take 50%-50% (using WindowPad, of course).
Now, let's say I want to make FF wider and Excel narrower -- kind of like when I split panes on Total Commander, you know, and have one pane take 70% and one pane 30%.
It would be great if I could hit Ctrl+Win+Numpad4 to have the current window "expand" to the left while "shrinking" the window which is already there. You know what I mean? Have it grow at 5% increments. And this feature can work well even if I have two windows on the bottom (like, bottom-right quarter and bottom-left quarter) or on the top.
What do you think? Is it hard to make? |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2494 Location: Australia, Qld
|
Posted: Mon Sep 03, 2007 8:05 am Post subject: |
|
|
Excellent idea. I'll see what I can do. Ideally, it'd "push" other windows (possibly squashing them against the side), rather than just squashing "the window that's in that quadrant."
Actually, I think I'll postpone it 'til I've finished the custom hotkey system. |
|
| Back to top |
|
 |
ezuk
Joined: 04 Jun 2005 Posts: 122
|
Posted: Mon Sep 03, 2007 8:18 am Post subject: |
|
|
| lexikos wrote: | Excellent idea. I'll see what I can do. Ideally, it'd "push" other windows (possibly squashing them against the side), rather than just squashing "the window that's in that quadrant."
Actually, I think I'll postpone it 'til I've finished the custom hotkey system. |
Cool -- thanks for considering it  |
|
| Back to top |
|
 |
Dave Campbell
Joined: 09 Jun 2005 Posts: 25 Location: Clearwater, Florida
|
Posted: Sat Sep 08, 2007 9:31 pm Post subject: Window Pad |
|
|
| lexikos wrote: | Updated to v1.1:
- Added "Gather windows" hotkeys (NumpadDiv and NumpadMult)
- Added Win+NumpadDot to move window to next monitor
- Added more EasyKey combos (for symmetry)
- Original functionality of EasyKey is now retained (on key-release)
- Added SetWinDelay, -1 to reduce lag when making multiple moves (quickly)
 |
Where can I find the current version with the full screen throw capability? |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|