AutoHotkey Community

It is currently May 26th, 2012, 6:47 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 41 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
 Post subject:
PostPosted: March 9th, 2008, 8:35 pm 
As per SKAN suggestion I am posting my working iteration of this. I have the computations (I think) down... however, even though the data is clean as you can see by the results, the GUI is locked frozen and does not re-compute based on XX.. anyone see why and can fix or make this work? :D I am not sure I understand the advanced hooks or stuff (like WM_WINDOWPOSCHANGING), but maybe someone can see a path to success from this.

here it is,

Code:

INPUT_WIDTH=425
INPUT_HEIGHT=496
FixedMinProportion=300

Gosub, Calculate

MsgBox, This 425x496 Input Would Scale Properly To %FixedMinProportion%x%OutPutHeightSize%

; CONTINUE TO GUI
;
;; :)

Gui +Resize +MinSize300x351 +MaxSize425x496
Gui, Show, w300 h351
Return

GuiSize:

INPUT_WIDTH=%A_GuiWidth%
INPUT_HEIGHT=%A_GuiHeight%

FixedMinProportion=300

Gosub, Calculate

ToolTip, INPUT: %INPUT_WIDTH% x %INPUT_HEIGHT% | OUTPUT: %FixedMinProportion% x %OutPutHeightSize%

Gui, Show,,RESIZER V1.0

Return

Calculate:

; CALCULATE PROPORTIONS

if (FixedMinProportion="") {
   if (OutPutHeightSize)
    FixedMinProportion:=ceil(OutPutHeightSize*INPUT_WIDTH/INPUT_HEIGHT)
   else FixedMinProportion:=INPUT_WIDTH
}

if (OutPutHeightSize="") {
   if (FixedMinProportion)
      OutPutHeightSize:=ceil(FixedMinProportion*INPUT_HEIGHT/INPUT_WIDTH)
   else OutPutHeightSize:=INPUT_HEIGHT
}

Return

GuiClose:
ExitApp


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: March 12th, 2008, 6:13 am 
(bump)

Could someone who is knowledgeable with these system calls please help me?


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: March 21st, 2008, 3:23 pm 
Can somebody try to take a crack at this? :)...:D :!: :!: :!: :!: :!:


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: April 2nd, 2008, 10:28 am 
Offline

Joined: December 1st, 2006, 9:27 am
Posts: 460
I went in a little bit of a different direction. This seems to work reasonably well. It will keep the original aspect ratio of the gui.
For this to work, the gui can't be sizable.
Code:
SetBatchLines, -1
SetWinDelay,10

fudgeFactor = 3   ;makes the border area larger for easier dragging, seems to be needed on the bottom border
GuiMinSize=300x351
GuiMaxSize=425x496

IDC_SIZEWE = 32644
IDC_SIZENS = 32645
SysGet, SM_CXFIXEDFRAME, 7
SysGet, SM_CYFIXEDFRAME, 8
leftBorder := SM_CXFIXEDFRAME + fudgeFactor
topBorder := SM_CYFIXEDFRAME + fudgeFactor
WM_MOUSEMOVE = 0x200
WM_LBUTTONDOWN = 0x201
 
Gui -Resize +MaximizeBox +LastFound
guiID := WinExist()
Gui, Show, w300 h351
WinGetPos,,,winW, winH
hProp := winH / winW   ;multiply the current width by hProp to get the new height
wProp := winW / winH   ;multiply the current height by wProp to get the new width
WEcursor := DllCall("LoadCursor", "Uint", 0, "Int", IDC_SIZEWE)    ;load west-east cursor
NScursor := DllCall("LoadCursor", "Uint", 0, "Int", IDC_SIZENS)    ;load north-south cursor
StringSplit, guiMin, GuiMinSize, x   ;guiMin1 is width   ;guiMin2 is height
StringSplit, guiMax, GuiMaxSize, x   ;guiMax1 is width   ;guiMax2 is height

OnMessage(WM_MOUSEMOVE, "CheckDrag")
OnMessage(WM_LBUTTONDOWN, "CheckDrag")

Return

;need to make left and top border work.
;for left, have to make x smaller while making w larger.

CheckDrag(wparam, lparam, msg, hwnd)
{
   global
   MouseGetPos, mX, mY
   WinGetPos, oX, oY, oW, oH, ahk_id %guiID%
   rightBorder := oW - SM_CXFIXEDFRAME - fudgeFactor
   bottomBorder := oH - SM_CYFIXEDFRAME - fudgeFactor
   
   If(mX < leftBorder)
   {   DllCall("SetCursor", "uint", WEcursor)   ;set west-east cursor
      direction = W
      SetTimer, sizer, 0
   }
   Else If(mX >= rightBorder)
   {   DllCall("SetCursor", "uint", WEcursor)   ;set west-east cursor
      direction = E
      SetTimer, sizer, 0
   }
   Else If(mX < topBorder)
   {   DllCall("SetCursor", "uint", NScursor)   ;set north-south cursor
      direction = N
      SetTimer, sizer, 0
   }
   Else If(mY > bottomBorder)
   {   DllCall("SetCursor", "uint", NScursor)   ;set north-south cursor
      direction = S
      SetTimer, sizer, 0
   }
}

sizer:
   Critical
   If GetKeyState("LButton","P")
   {   CoordMode, MOUSE, SCREEN
      MouseGetPos, moveX, moveY   
      If(direction = "W")   ;dragging left border   ******DOES NOT WORK*****
      {   DllCall("SetCursor", "uint", WEcursor)   ;set west-east cursor
         newW := oX - moveX
         newH := newW * hProp
      }
      Else If(direction = "E")   ;dragging right border
      {   DllCall("SetCursor", "uint", WEcursor)   ;set west-east cursor
         newW := moveX - oX
         newW := newW < guiMin1 ? guiMin1 : newW   ;make sure its not smaller than minimum
         newW := newW > guiMax1 ? guiMax1 : newW   ;make sure its not bigger than maximum
         newH := newW * hProp
         moveX := moveX > oX + guiMax1 ? oX + guiMax1 : moveX   ;keep mouse within max
         moveX := moveX < oX + guiMin1 ? oX + guiMin1 : moveX   ;keep mouse within min
      }
      Else If(direction = "N")   ;dragging top border   ******DOES NOT WORK*****
      {   DllCall("SetCursor", "uint", NScursor)   ;set north-south cursor
         newH := oY - moveY
         newH := newH < guiMin2 ? guiMin2 : newH   ;make sure its not smaller than minimum
         newH := newH > guiMax2 ? guiMax2 : newH   ;make sure its not bigger than maximum
         newW := newH * wProp
      }
      Else If(direction = "S")   ;dragging bottom border
      {   DllCall("SetCursor", "uint", NScursor)   ;set north-south cursor
         newH := moveY - oY
         newH := newH < guiMin2 ? guiMin2 : newH   ;make sure its not smaller than minimum
         newH := newH > guiMax2 ? guiMax2 : newH   ;make sure its not bigger than maximum
         newW := newH * wProp
         moveY := moveY > oY + guiMax2 ? oY + guiMax2 : moveY   ;keep mouse within max
         moveY := moveY < oY + guiMin2 ? oY + guiMin2 : moveY   ;keep mouse within min
      }
      MouseMove, moveX, moveY
      WinMove, ahk_id %guiID%,,,, %newW%, %newH%
   }
   Else
   {   SetTimer, sizer, Off
   }
Return

guiClose:
   ExitApp
Return
At this point, the left and top border drag don't work.

HTH

_________________
Image


Last edited by Micahs on April 2nd, 2008, 11:46 pm, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 2nd, 2008, 5:48 pm 
Hey - that is pretty neat. Just curious, I played with it a little and noticed it was a tiny bit choppy --- can that be made any smoother on-size, or is this a factor of Windows or maybe my pc machine? :D


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: April 2nd, 2008, 11:20 pm 
Offline

Joined: December 1st, 2006, 9:27 am
Posts: 460
I just added "SetWinDelay,10" and it works quite a bit smoother. I tried to add "Critical" to the "sizer" routine, but it didn't seem to make much difference. There might be some other optimizations also.

And now the mouse is constrained to the min and max gui sizes.

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 3rd, 2008, 4:02 pm 
Offline

Joined: April 17th, 2007, 1:37 pm
Posts: 761
Location: Florida
Here's my 2c:

Since you're defining a set aspect ratio, you don't need to have a height / width control (since there's really only one variable - size).

Because size is also constrained to a minimum and maximum, why not control it with a slide control in the GUI itself?

Edit:
Code:
ratio:=.66666
w:=300
h:=w * ratio

gui, add, Slider, gSlide vW Range300-600 AltSubmit,300
gui, show, w%w% h%h%
Return

GuiClose:
ExitApp
;Reload
Return

Slide:
;Tooltip, %W% ;For testing
h:=w * ratio
gui, show, w%w% h%h%
Return
Edit2: I started working on a version that allows sizing via the normal controls, but I have to go home and I have tomorrow off, so here's what I've got so far:
Code:
ratio:=1.1666666666666666666666666666667
w:=300
h:=w * ratio

gui, +resize +maxsize425x496
gui, add, Slider, gSlide vW Range300-425 AltSubmit,300
gui, show, w%w% h%h%
Return

GuiClose:
ExitApp
;Reload
Return

Slide:
;Tooltip, %W%
h:=w * ratio
gui, show, w%w% h%h%
Return

GuiSize:
If !(A_EventInfo)
{   If((A_GuiWidth / A_GuiHeight) > Ratio)
      

}
Return

_________________
[Join IRC!]
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 4th, 2008, 12:22 am 
Offline

Joined: December 1st, 2006, 9:27 am
Posts: 460
As for the slider control:
Plastic might be happy with that. But I don't think that was the original intent. I thought that he wanted the gui to be sized normally, but with a fixed aspect ratio. If Plastic is happy, so am I.

Rhys wrote:
you don't need to have a height / width control
I don't technically use a control to do the sizing.

Rhys wrote:
allows sizing via the normal controls
What do you mean? The standard window border drag for sizing? If so, you will run into some problems with dragging while resizing the gui manually (that's why I went the route I did.) Also, you have to keep track of which border they are dragging. For instance, the left border - you have to move the gui x position as well as the width. Each border has its own requirements. That's the reason I don't think:
Rhys wrote:
there's really only one variable - size
There's more to keep track of than just size.

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 5th, 2008, 7:29 am 
Offline

Joined: December 1st, 2006, 9:27 am
Posts: 460
This is what I have so far. It offers fixed ratio resizing and min/max. It works very well on my 950Mhz machine using only the "WM_SIZING" message. The only resize borders I have implemented are Right, Bottom, and Bottom-Right. There is a problem that I can't find right now and I am holding off adding the rest of the sides until I fix it.
When you resize (only the Right, Bottom, and Bottom-Right), the minimum constraint seems to work, but the max doesn't work right. If you drag it with the bottom border all the way to the maximum and then try to drag with the right border, it will resize a little more. The max is not consistent between the different sides. Does anyone see what I am missing? I'm tired, so its probably something stupid!

Code:
;Thread that I took the original code from: http://www.autohotkey.com/forum/viewtopic.php?t=2441
;Uses Anchor 4.60a by Titan

;~ _minSize = 300x200   ;if this is not specified, the min w,h will be the initial gui size
_maxSize = 500x400

SetBatchLines,150ms
SetWinDelay, 0
Gui +Resize +LastFound
guiID := WinExist()
Gui, Add, Edit, w300 h200 vg1Edit, Hello
Gui, Add, Button, vg1Ok, Ok
Gui, Add, Button, x+ yp vg1Exit, Exit
Gui, Add, Button, x+ yp vg1Close, Close

Gui, Show,, MinMax & AutoRatio
WinGetPos,,,guiW, guiH, ahk_id %guiID%   ;get gui w,h and calc the size ratio
_hProp := guiH / guiW   ;multiply the current width by _hProp to get the new height
_wProp := guiW / guiH   ;multiply the current height by _wProp to get the new width
If(_minSize)   ;only do this if minimum specified
{   StringSplit, _min, _minSize, x   ;_min1 is width      ;_min2 is height
}
Else   ;min not given - use gui w,h for minimum
{   _min1 := guiW   ;set the minimum width = initial gui width
   _min2 := guiH   ;set the minimum height = initial gui height
}
StringSplit, _max, _maxSize, x   ;_max1 is width   ;_max2 is height

OnMessage(0x214,"WM_SIZING")
Return

GuiClose:
   ExitApp
Return

GuiSize:
   anchor("g1Edit","wh")
   anchor("g1Ok","y")
   anchor("g1Exit","y")
   anchor("g1Close","y")
Return

WM_SIZING(wParam,lParam,msg)
{
    global guiID, _wProp, _hProp, _min1, _min2, _max1, _max2
    WM_SIZING_Edge:=wParam

    WinGetPos,CurrX,CurrY,CurrW,CurrH,ahk_id %guiID%   ;Get current W/H
   CoordMode, MOUSE, SCREEN
   MouseGetPos, mX, mY

   If WM_SIZING_Edge in 2,8   ;right and bottom-right border drag - keep within min and max, keep aspect ratio
   {   newWcoord := mX < CurrX + _min1 ? CurrX + _min1 : mX   ;make sure width isn't smaller than min
      newWcoord := newWcoord > CurrX + _max1 ? CurrX + _max1 : newWcoord   ;make sure width isn't larger than max
      InsertIntegerAtAddress(newWcoord,lParam,8,4)   ;set x coord of right side of gui
      
      newHcoord := CurrY + (CurrW * _hProp)   ;get the new height
      InsertIntegerAtAddress(newHcoord,lParam,12,4)   ;set y coord of bottom side of gui
   }

   If(WM_SIZING_Edge = 6)   ;bottom border drag - keep within min and max, keep aspect ratio
   {   newHcoord := mY < CurrY + _min2 ? CurrY + _min2 : mY   ;make sure height isn't smaller than min
      newHcoord := newHcoord > CurrY + _max2 ? CurrY + _max2 : newHcoord   ;make sure height isn't larger than max
      InsertIntegerAtAddress(newHcoord,lParam,12,4)   ;set y coord of bottom side of gui
      
      newWcoord := CurrX + (CurrH * _wProp)   ;get the new width
      InsertIntegerAtAddress(newWcoord,lParam,8,4)   ;set x coord of right side of gui
   }

   ;TODO - Top, Top-Right, Top-Left, Left, Left-Bottom   -   these will require modifing the x,y coords too.

    return true

   /*
   From MSDN (with edits):
   lParam - RECT Structure containing window coords
      typedef struct _RECT {
         LONG left;    (0) offset in structure
         LONG top;       (4)
         LONG right;    (8)
         LONG bottom;    (12)
      } RECT, *PRECT;
   
   wParam - Specifies which edge of the window is being sized. This
   parameter can be one of the following values.

      WMSZ_LEFT            (1)   Left edge
      WMSZ_RIGHT         (2)   Right edge
      WMSZ_TOP            (3)   Top edge
      WMSZ_TOPLEFT         (4)   Top-left corner
      WMSZ_TOPRIGHT      (5)   Top-right corner
      WMSZ_BOTTOM         (6)   Bottom edge
      WMSZ_BOTTOMLEFT   (7)   Bottom-left corner
      WMSZ_BOTTOMRIGHT   (8)   Bottom-right corner
   */
}



InsertIntegerAtAddress(pInteger, pAddress, pOffset = 0, pSize = 4)    ;update this to putnum
{
   mask := 0xFF  ; This serves to isolate each byte, one by one.
   Loop %pSize%  ; Copy each byte in the integer into the structure as raw binary data.
   {
      DllCall("RtlFillMemory", UInt, pAddress + pOffset + A_Index - 1, UInt, 1
       , UChar, (pInteger & mask) >> 8 * (A_Index - 1))
      mask := mask << 8  ; Set it up for isolation of the next byte.
   }
}

   

/*

   Function: Anchor
      Defines how controls should be automatically positioned relative to the new dimensions of a window when resized.
   
   Parameters:
      cl - a control HWND, associated variable name or ClassNN to operate on
      a - (optional) one or more of the anchors: 'x', 'y', 'w' (width) and 'h' (height),
         optionally followed by a relative factor, e.g. "x h0.5"
      r - (optional) true to redraw controls, recommended for GroupBox and Button types
   
   Examples:
> "xy" ; bounds a control to the bottom-left edge of the window
> "w0.5" ; any change in the width of the window will resize the width of the control on a 2:1 ratio
> "h" ; similar to above but directrly proportional to height
   
   Remarks:
      To assume the current window size for the new bounds of a control (i.e. resetting) simply omit the second and third parameters.
      However if the control had been created with DllCall() and has its own parent window,
         the container AutoHotkey created GUI must be made default with the +LastFound option prior to the call.
      For a complete example see anchor-example.ahk.
   
   License:
      - Version 4.60a by Titan <http://www.autohotkey.net/~Titan/#anchor>
      - GNU General Public License 3.0 or higher <http://www.gnu.org/licenses/gpl-3.0.txt>

*/

Anchor(i, a = "", r = false) {
   static c, cs = 12, cx = 255, cl = 0, g, gs = 8, gl = 0, gpi, gw, gh, z = 0, k = 0xffff
   If z = 0
      VarSetCapacity(g, gs * 99, 0), VarSetCapacity(c, cs * cx, 0), z := true
   If (!WinExist("ahk_id" . i)) {
      GuiControlGet, t, Hwnd, %i%
      If ErrorLevel = 0
         i := t
      Else ControlGet, i, Hwnd, , %i%
   }
   VarSetCapacity(gi, 68, 0), DllCall("GetWindowInfo", "UInt", gp := DllCall("GetParent", "UInt", i), "UInt", &gi)
      , giw := NumGet(gi, 28, "Int") - NumGet(gi, 20, "Int"), gih := NumGet(gi, 32, "Int") - NumGet(gi, 24, "Int")
   If (gp != gpi) {
      gpi := gp
      Loop, %gl%
         If (NumGet(g, cb := gs * (A_Index - 1)) == gp) {
            gw := NumGet(g, cb + 4, "Short"), gh := NumGet(g, cb + 6, "Short"), gf := 1
            Break
         }
      If (!gf)
         NumPut(gp, g, gl), NumPut(gw := giw, g, gl + 4, "Short"), NumPut(gh := gih, g, gl + 6, "Short"), gl += gs
   }
   ControlGetPos, dx, dy, dw, dh, , ahk_id %i%
   Loop, %cl%
      If (NumGet(c, cb := cs * (A_Index - 1)) == i) {
         If a =
         {
            cf = 1
            Break
         }
         giw -= gw, gih -= gh, as := 1, dx := NumGet(c, cb + 4, "Short"), dy := NumGet(c, cb + 6, "Short")
            , cw := dw, dw := NumGet(c, cb + 8, "Short"), ch := dh, dh := NumGet(c, cb + 10, "Short")
         Loop, Parse, a, xywh
            If A_Index > 1
               av := SubStr(a, as, 1), as += 1 + StrLen(A_LoopField)
                  , d%av% += (InStr("yh", av) ? gih : giw) * (A_LoopField + 0 ? A_LoopField : 1)
         DllCall("SetWindowPos", "UInt", i, "Int", 0, "Int", dx, "Int", dy
            , "Int", InStr(a, "w") ? dw : cw, "Int", InStr(a, "h") ? dh : ch, "Int", 4)
         If r != 0
            DllCall("RedrawWindow", "UInt", i, "UInt", 0, "UInt", 0, "UInt", 0x0101) ; RDW_UPDATENOW | RDW_INVALIDATE
         Return
      }
   If cf != 1
      cb := cl, cl += cs
   bx := NumGet(gi, 48), by := NumGet(gi, 16, "Int") - NumGet(gi, 8, "Int") - gih - NumGet(gi, 52)
   If cf = 1
      dw -= giw - gw, dh -= gih - gh
   NumPut(i, c, cb), NumPut(dx - bx, c, cb + 4, "Short"), NumPut(dy - by, c, cb + 6, "Short")
      , NumPut(dw, c, cb + 8, "Short"), NumPut(dh, c, cb + 10, "Short")
   Return, true
}   

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 5th, 2008, 8:51 am 
Offline

Joined: December 1st, 2006, 9:27 am
Posts: 460
All right, I got it! The fixed ratio and min/max all work correctly now.
Code:
;Thread that I got "InsertIntegerAtAddress" and "WM_SIZING" info from: http://www.autohotkey.com/forum/viewtopic.php?t=2441
;Uses Anchor 4.60a by Titan


_minWidth = 200   ;specify either minWidth, minHeight, or none.  If none, initial gui w,h is used.   - minWidth overrides minHeight
_minHeight =

_maxWidth = 500   ;specify either maxWidth, maxHeight, or none   - maxWidth overrides maxHeight
_maxHeight =


SetBatchLines,150ms
SetWinDelay, 0
SysGet, SM_CXMAXTRACK, 59   ;get largest window size
SysGet, SM_CYMAXTRACK, 60
Gui +Resize +LastFound
guiID := WinExist()
Gui, Add, Edit, w300 h200 vg1Edit, Hello
Gui, Add, Button, vg1Ok, Ok
Gui, Add, Button, x+ yp vg1Exit, Exit
Gui, Add, Button, x+ yp vg1Close, Close

Gui, Show,, MinMax & AutoRatio
WinGetPos,,,guiW, guiH, ahk_id %guiID%   ;get gui w,h and calc the size ratio
_hProp := guiH / guiW   ;multiply the current width by _hProp to get the new height
_wProp := guiW / guiH   ;multiply the current height by _wProp to get the new width

If(_minWidth)   ;this sets the vars for max w,h to keep aspect ratio
{   _min1 := _minWidth            ;this is the width
   _min2 := _minWidth * _hProp   ;this is the height
}
Else If(_minHeight)   ;_minHeight given
{   _min1 := _minHeight * _wProp   ;this is the width
   _min2 := _minHeight            ;this is the height
}
Else   ;no min given
{   _min1 := guiW   ;set min w,h = initial gui w,h
   _min2 := guiH
}

If(_maxWidth)   ;this sets the vars for max w,h to keep aspect ratio
{   _max1 := _maxWidth            ;this is the width
   _max2 := _maxWidth * _hProp   ;this is the height
}
Else If(_maxHeight)   ;_maxHeight given
{   _max1 := _maxHeight * _wProp   ;this is the width
   _max2 := _maxHeight            ;this is the height
}
Else   ;no max given
{   _max1 := SM_CXMAXTRACK   ;largest window possible in system
   _max2 := SM_CYMAXTRACK
}

OnMessage(0x214,"WM_SIZING")
Return

GuiClose:
   ExitApp
Return

GuiSize:
   anchor("g1Edit","wh")
   anchor("g1Ok","y")
   anchor("g1Exit","y")
   anchor("g1Close","y")
Return

WM_SIZING(wParam, lParam, msg)
{
    global guiID, _wProp, _hProp, _min1, _min2, _max1, _max2
    WM_SIZING_Edge := wParam

    WinGetPos, CurrX, CurrY, CurrW, CurrH, ahk_id %guiID%   ;Get current W/H
   CoordMode, MOUSE, SCREEN
   MouseGetPos, mX, mY

   If WM_SIZING_Edge in 2,8   ;right and bottom-right border drag - keep within min and max, keep aspect ratio
   {   newWcoord := mX < CurrX + _min1 ? CurrX + _min1 : mX   ;make sure width isn't smaller than min
      newWcoord := newWcoord > CurrX + _max1 ? CurrX + _max1 : newWcoord   ;make sure width isn't larger than max
      InsertIntegerAtAddress(newWcoord, lParam, 8, 4)   ;set x coord of right side of gui
      
      newHcoord := CurrY + (CurrW * _hProp)   ;get the new height
      InsertIntegerAtAddress(newHcoord, lParam, 12, 4)   ;set y coord of bottom side of gui
   }

   If(WM_SIZING_Edge = 6)   ;bottom border drag - keep within min and max, keep aspect ratio
   {   newHcoord := mY < CurrY + _min2 ? CurrY + _min2 : mY   ;make sure height isn't smaller than min
      newHcoord := newHcoord > CurrY + _max2 ? CurrY + _max2 : newHcoord   ;make sure height isn't larger than max
      InsertIntegerAtAddress(newHcoord, lParam, 12, 4)   ;set y coord of bottom side of gui
      
      newWcoord := CurrX + (CurrH * _wProp)   ;get the new width
      InsertIntegerAtAddress(newWcoord, lParam, 8, 4)   ;set x coord of right side of gui
   }

   ;TODO - Top, Top-Right, Top-Left, Left, Left-Bottom   -   these will require modifing the x,y coords too.

    return true

   /*
   From MSDN (with edits):
   lParam - RECT Structure containing window coords
      typedef struct _RECT {
         LONG left;    (0) offset in structure
         LONG top;       (4)
         LONG right;    (8)
         LONG bottom;    (12)
      } RECT, *PRECT;
   
   wParam - Specifies which edge of the window is being sized. This
   parameter can be one of the following values.

      WMSZ_LEFT            (1)   Left edge
      WMSZ_RIGHT         (2)   Right edge
      WMSZ_TOP            (3)   Top edge
      WMSZ_TOPLEFT         (4)   Top-left corner
      WMSZ_TOPRIGHT      (5)   Top-right corner
      WMSZ_BOTTOM         (6)   Bottom edge
      WMSZ_BOTTOMLEFT   (7)   Bottom-left corner
      WMSZ_BOTTOMRIGHT   (8)   Bottom-right corner
   */
}



InsertIntegerAtAddress(pInteger, pAddress, pOffset = 0, pSize = 4)    ;update this to putnum
{
   mask := 0xFF  ; This serves to isolate each byte, one by one.
   Loop %pSize%  ; Copy each byte in the integer into the structure as raw binary data.
   {
      DllCall("RtlFillMemory", UInt, pAddress + pOffset + A_Index - 1, UInt, 1
       , UChar, (pInteger & mask) >> 8 * (A_Index - 1))
      mask := mask << 8  ; Set it up for isolation of the next byte.
   }
}

   

/*

   Function: Anchor
      Defines how controls should be automatically positioned relative to the new dimensions of a window when resized.
   
   Parameters:
      cl - a control HWND, associated variable name or ClassNN to operate on
      a - (optional) one or more of the anchors: 'x', 'y', 'w' (width) and 'h' (height),
         optionally followed by a relative factor, e.g. "x h0.5"
      r - (optional) true to redraw controls, recommended for GroupBox and Button types
   
   Examples:
> "xy" ; bounds a control to the bottom-left edge of the window
> "w0.5" ; any change in the width of the window will resize the width of the control on a 2:1 ratio
> "h" ; similar to above but directrly proportional to height
   
   Remarks:
      To assume the current window size for the new bounds of a control (i.e. resetting) simply omit the second and third parameters.
      However if the control had been created with DllCall() and has its own parent window,
         the container AutoHotkey created GUI must be made default with the +LastFound option prior to the call.
      For a complete example see anchor-example.ahk.
   
   License:
      - Version 4.60a by Titan <http://www.autohotkey.net/~Titan/#anchor>
      - GNU General Public License 3.0 or higher <http://www.gnu.org/licenses/gpl-3.0.txt>

*/

Anchor(i, a = "", r = false) {
   static c, cs = 12, cx = 255, cl = 0, g, gs = 8, gl = 0, gpi, gw, gh, z = 0, k = 0xffff
   If z = 0
      VarSetCapacity(g, gs * 99, 0), VarSetCapacity(c, cs * cx, 0), z := true
   If (!WinExist("ahk_id" . i)) {
      GuiControlGet, t, Hwnd, %i%
      If ErrorLevel = 0
         i := t
      Else ControlGet, i, Hwnd, , %i%
   }
   VarSetCapacity(gi, 68, 0), DllCall("GetWindowInfo", "UInt", gp := DllCall("GetParent", "UInt", i), "UInt", &gi)
      , giw := NumGet(gi, 28, "Int") - NumGet(gi, 20, "Int"), gih := NumGet(gi, 32, "Int") - NumGet(gi, 24, "Int")
   If (gp != gpi) {
      gpi := gp
      Loop, %gl%
         If (NumGet(g, cb := gs * (A_Index - 1)) == gp) {
            gw := NumGet(g, cb + 4, "Short"), gh := NumGet(g, cb + 6, "Short"), gf := 1
            Break
         }
      If (!gf)
         NumPut(gp, g, gl), NumPut(gw := giw, g, gl + 4, "Short"), NumPut(gh := gih, g, gl + 6, "Short"), gl += gs
   }
   ControlGetPos, dx, dy, dw, dh, , ahk_id %i%
   Loop, %cl%
      If (NumGet(c, cb := cs * (A_Index - 1)) == i) {
         If a =
         {
            cf = 1
            Break
         }
         giw -= gw, gih -= gh, as := 1, dx := NumGet(c, cb + 4, "Short"), dy := NumGet(c, cb + 6, "Short")
            , cw := dw, dw := NumGet(c, cb + 8, "Short"), ch := dh, dh := NumGet(c, cb + 10, "Short")
         Loop, Parse, a, xywh
            If A_Index > 1
               av := SubStr(a, as, 1), as += 1 + StrLen(A_LoopField)
                  , d%av% += (InStr("yh", av) ? gih : giw) * (A_LoopField + 0 ? A_LoopField : 1)
         DllCall("SetWindowPos", "UInt", i, "Int", 0, "Int", dx, "Int", dy
            , "Int", InStr(a, "w") ? dw : cw, "Int", InStr(a, "h") ? dh : ch, "Int", 4)
         If r != 0
            DllCall("RedrawWindow", "UInt", i, "UInt", 0, "UInt", 0, "UInt", 0x0101) ; RDW_UPDATENOW | RDW_INVALIDATE
         Return
      }
   If cf != 1
      cb := cl, cl += cs
   bx := NumGet(gi, 48), by := NumGet(gi, 16, "Int") - NumGet(gi, 8, "Int") - gih - NumGet(gi, 52)
   If cf = 1
      dw -= giw - gw, dh -= gih - gh
   NumPut(i, c, cb), NumPut(dx - bx, c, cb + 4, "Short"), NumPut(dy - by, c, cb + 6, "Short")
      , NumPut(dw, c, cb + 8, "Short"), NumPut(dh, c, cb + 10, "Short")
   Return, true
}   

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 7th, 2008, 9:46 am 
Offline

Joined: December 1st, 2006, 9:27 am
Posts: 460
Now the sizing is contained in functions. To use, call
Code:
setGuiSize(gui1ID, "90%", "", "200%", "", True)
or
Code:
setGuiSize(gui2ID, "300", "", "550", "", False)

where the first param is the gui id or gui number, then minimum width, minimum height, maximum width, maximum height, and aspect ('True' or 'False'). The widths and heights can be given in pixels or percent of original. For the aspect, 'True' means to preserve the aspect ratio, and 'False' means to allow the width and height to change independently.

The main benefit of using the min/max settings without aspect ratio control is that you can specify the min or max values as a percent of the original instead of just pixels.

Code:
;Thread that I got "InsertIntegerAtAddress" and "WM_SIZING_Edge" from: http://www.autohotkey.com/forum/viewtopic.php?t=2441
;Uses Anchor 4.60a by Titan

Gui +Resize +LastFound
gui1ID := WinExist()
Gui, Add, Edit, w350 h250 vg1Edit, Hello
Gui, Add, Button, vg1Ok, Ok
Gui, Add, Button, x+ yp vg1Exit, Exit
Gui, Add, Button, x+ yp vg1Close, Close
Gui, Show,, MinMax & AutoRatio

Gui 2:+Resize +LastFound
gui2ID := WinExist()
Gui, 2:Add, Edit, w300 h200 vg2Edit, Hello
Gui, 2:Add, Button, vg2Ok, Ok
Gui, 2:Add, Button, x+ yp vg2Exit, Exit
Gui, 2:Add, Button, x+ yp vg2Close, Close
Gui, 2:Show,, Gui Number Two

Gui 3:+Resize +LastFound
gui3ID := WinExist()
Gui, 3:Add, Edit, w150 h100 vg3Edit, Hello
Gui, 3:Add, Button, vg3Ok, Ok
Gui, 3:Add, Button, x+ yp vg3Exit, Exit
Gui, 3:Add, Button, x+ yp vg3Close, Close
Gui, 3:Show,, NOT HANDLED

setGuiSize(gui1ID, "90%", "", "200%", "", True)
setGuiSize(gui2ID, "300", "", "550", "", False)

Return

GuiClose:
   ExitApp
Return

GuiSize:
   anchor("g1Edit","wh")
   anchor("g1Ok","y")
   anchor("g1Exit","y")
   anchor("g1Close","y")
Return

WM_SIZING(wParam, lParam, msg)
{
   Critical
   static guiID, debounce
   tmpBL := A_BatchLines
   SetBatchLines,-1
    WM_SIZING_Edge := wParam

   CoordMode, MOUSE, SCREEN
   If GetKeyState("LButton","P") and (!debounce)   ;get the gui id the first time only for this resizing
   {   debounce=1
      MouseGetPos, mX, mY, guiID
   }
   Else If(debounce)   ;not the first time through
   {   MouseGetPos, mX, mY
   }
   If !GetKeyState("LButton","P")   ;mouse released - reset
   {   debounce=0
   }

    WinGetPos, CurrX, CurrY, CurrW, CurrH, ahk_id %guiID%   ;Get current W/H
   getGuiSize(guiID, _ratio, _min1, _min2, _max1, _max2, _aspect)   ;get the ratio/min/max info for this gui
   IfEqual, _ratio, , Return False   ;if not a handled gui, exit func
   
   If WM_SIZING_Edge in 2,8   ;right and bottom-right border drag - keep within min and max, keep aspect ratio
   {   newWcoord := mX < CurrX + _min1 ? CurrX + _min1 : mX   ;make sure width isn't smaller than min
      newWcoord := newWcoord > CurrX + _max1 ? CurrX + _max1 : newWcoord   ;make sure width isn't larger than max
      InsertIntegerAtAddress(newWcoord, lParam, 8, 4)   ;set x coord of right side of gui
      
      If(_aspect)
      {   newHcoord := CurrY + Round(CurrW * (1/_Ratio))   ;get the new height
         InsertIntegerAtAddress(newHcoord, lParam, 12, 4)   ;set y coord of bottom side of gui
      }
   }

   If(WM_SIZING_Edge = 6)   ;bottom border drag - keep within min and max, keep aspect ratio
   {   newHcoord := mY < CurrY + _min2 ? CurrY + _min2 : mY   ;make sure height isn't smaller than min
      newHcoord := newHcoord > CurrY + _max2 ? CurrY + _max2 : newHcoord   ;make sure height isn't larger than max
      InsertIntegerAtAddress(newHcoord, lParam, 12, 4)   ;set y coord of bottom side of gui
      
      If(_aspect)
      {   newWcoord := CurrX + Round(CurrH * _Ratio)   ;get the new width
         InsertIntegerAtAddress(newWcoord, lParam, 8, 4)   ;set x coord of right side of gui
      }
   }

   If(WM_SIZING_Edge = 3)   ;top border drag - keep within min and max, keep aspect ratio
   {   newYcoord := mY < CurrY + _min2 ? CurrY + _min2 : mY   ;make sure height isn't smaller than min
      
      newYcoord := newHcoord > CurrY + _max2 ? CurrY + _max2 : newHcoord   ;make sure height isn't larger than max
      InsertIntegerAtAddress(newHcoord, lParam, 4, 4)   ;set y coord of bottom side of gui
      
      InsertIntegerAtAddress(newHcoord, lParam, 0, 4)   ;set y coord of top side of gui
      
      If(_aspect)
      {   newWcoord := CurrX + (CurrH * _Ratio)   ;get the new width
         InsertIntegerAtAddress(newWcoord, lParam, 8, 4)   ;set x coord of right side of gui
      }
   }
   
   ;TODO - Top, Top-Right, Top-Left, Left, Left-Bottom   -   these will require modifing the x,y coords too.

   SetBatchLines, %tmpBL%
    return True

   /*
   From MSDN (with edits):
   lParam - RECT Structure containing window coords
      typedef struct _RECT {
         LONG left;    (0) offset in structure
         LONG top;       (4)
         LONG right;    (8)
         LONG bottom;    (12)
      } RECT, *PRECT;
   
   wParam - Specifies which edge of the window is being sized. This
   parameter can be one of the following values.

      WMSZ_LEFT            (1)   Left edge
      WMSZ_RIGHT         (2)   Right edge
      WMSZ_TOP            (3)   Top edge
      WMSZ_TOPLEFT         (4)   Top-left corner
      WMSZ_TOPRIGHT      (5)   Top-right corner
      WMSZ_BOTTOM         (6)   Bottom edge
      WMSZ_BOTTOMLEFT   (7)   Bottom-left corner
      WMSZ_BOTTOMRIGHT   (8)   Bottom-right corner
   */
}


getGuiSize(_0, ByRef _1="", ByRef _2="", ByRef _3="", ByRef _4="", ByRef _5="", ByRef _6="", ByRef _7="", ByRef _8="", ByRef _9="", ByRef _10="", ByRef _11="", ByRef _12="", ByRef _13="", ByRef _14="")   ;get the info for the given gui - vars return blank if no match - allow up to 15 params (maybe the basis of another array handler?)
{
   global
   IfEqual, _0,, Return Please provide an ID or Gui Number
   If _0 Is Digit   ;must have passed gui number instead of ID
   {   Gui, %_0%:+LastFound
      _0 := WinExist()
   }
   StringSplit, _ggsStuff, %_0%_ggsArray, `,
   IfEqual, _ggsStuff0, 0, Return   ;if not a match, exit func
   Loop, %_ggsStuff0%
   {   tmp = _%A_Index%
      %tmp% := _ggsStuff%A_Index%
   }
}

/*
   defaults:
      _ID = gui1 id
      _minwidth = guiID.width
      _minheight = guiID.height
      _maxWidth = system window max width
      _maxHeight = system window max height
*/
setGuiSize(_ID=1, _minWidth="", _minHeight="", _maxWidth="", _maxHeight="", _aspect=True)   ;set the ratio/min/max info for the given gui
{   
   SysGet, SM_CXMAXTRACK, 59   ;get largest window size
   SysGet, SM_CYMAXTRACK, 60

   If _ID Is Digit   ;must have passed gui number instead of window ID
   {   Gui, %_ID%:+LastFound
      _ID := WinExist()
   }
   WinGetPos,,,guiW, guiH, ahk_id %_ID%   ;get gui w,h and calc the size ratio
   _Ratio := guiW / guiH   ;multiply the current width by _Ratio to get the new height, multiply the current height by (1/_Ratio) to get the new width
   
   ;this sets the vars for max w,h to keep aspect ratio
   If(_minWidth)   ;if minimum width is given
   {   IfInString, _minWidth, `%   ;if a percent is specified
      {   StringReplace, _minWidth, _minWidth, `%,,All
         _minWidth := _minWidth / 100   ;did it this way because _minWidth/100 produced '0' - an integer
         _min1 := Round(guiW * _minWidth)   ;this is the width
         _min2 := Round(_min1 * (1/_Ratio))      ;this is the height
      }
      Else   ;must be 'px'
      {   StringReplace, _minWidth, _minWidth, px,,All   ;just in case
         _min1 := _minWidth         ;this is the width
         _min2 := Round(_min1 * (1/_Ratio))   ;this is the height
      }
   }
   Else If(_minHeight)   ;_minHeight given
   {   IfInString, _minHeight, `%   ;if a percent is specified
      {   StringReplace, _minHeight, _minHeight, `%,,All
         _minHeight := _minHeight / 100   ;did it this way because _minHeight/100 produced '0' - an integer
         _min2 := guiH * _minHeight   ;this is the height
         _min1 := Round(_min2 * _Ratio)      ;this is the width
      }
      Else   ;must be 'px'
      {   StringReplace, _minHeight, _minHeight, px,,All   ;just in case
         _min2 := _minHeight         ;this is the height
         _min1 := Round(_min2 * _Ratio)   ;this is the width
      }
   }
   Else   ;no min given
   {   _min1 := guiW   ;set min w,h = initial gui w,h
      _min2 := guiH
   }

   If(_maxWidth)   ;if maximum width is given
   {   IfInString, _maxWidth, `%   ;if a percent is specified
      {   StringReplace, _maxWidth, _maxWidth, `%,,All
         _maxWidth /= 100
         _max1 := guiW * _maxWidth   ;this is the width
         _max2 := (_max1 * (1/_Ratio))      ;this is the height
      }
      Else   ;must be 'px'
      {   StringReplace, _maxWidth, _maxWidth, px,,All   ;just in case
         _max1 := _maxWidth         ;this is the width
         _max2 := Round(_max1 * (1/_Ratio))   ;this is the height
      }
   }
   Else If(_maxHeight)   ;_maxHeight given
   {   IfInString, _maxHeight, `%   ;if a percent is specified
      {   StringReplace, _maxHeight, _maxHeight, `%,,All
         _maxHeight /= 100
         _max2 := guiH * _maxHeight   ;this is the height
         _max1 := (_max2 * _Ratio)      ;this is the width
      }
      Else   ;must be 'px'
      {   StringReplace, _maxHeight, _maxHeight, px,,All   ;just in case
         _max2 := _maxHeight      ;this is the height
         _max1 := Round(_max2 * _Ratio)   ;this is the width
      }
   }
   Else   ;no max given
   {   _max1 := SM_CXMAXTRACK   ;largest window possible in system
      _max2 := SM_CYMAXTRACK
   }
   %_ID%_ggsArray := _ratio "," _min1 "," _min2 "," _max1 "," _max2 "," _aspect

   globalWrapper(_ID "_ggsArray", %_ID%_ggsArray)

   OnMessage(0x214,"WM_SIZING")   ;this will happen once for every window set, but that shouldn't cause any problems
}

globalWrapper(victim, content)   ;this turns a dynamic local variable into a global variable
{
   global
   %victim% := content
}


InsertIntegerAtAddress(pInteger, pAddress, pOffset = 0, pSize = 4)    ;update this to putnum
{
   mask := 0xFF  ; This serves to isolate each byte, one by one.
   Loop %pSize%  ; Copy each byte in the integer into the structure as raw binary data.
   {
      DllCall("RtlFillMemory", UInt, pAddress + pOffset + A_Index - 1, UInt, 1
       , UChar, (pInteger & mask) >> 8 * (A_Index - 1))
      mask := mask << 8  ; Set it up for isolation of the next byte.
   }
}

   

/*

   Function: Anchor
      Defines how controls should be automatically positioned relative to the new dimensions of a window when resized.
   
   Parameters:
      cl - a control HWND, associated variable name or ClassNN to operate on
      a - (optional) one or more of the anchors: 'x', 'y', 'w' (width) and 'h' (height),
         optionally followed by a relative factor, e.g. "x h0.5"
      r - (optional) true to redraw controls, recommended for GroupBox and Button types
   
   Examples:
> "xy" ; bounds a control to the bottom-left edge of the window
> "w0.5" ; any change in the width of the window will resize the width of the control on a 2:1 ratio
> "h" ; similar to above but directrly proportional to height
   
   Remarks:
      To assume the current window size for the new bounds of a control (i.e. resetting) simply omit the second and third parameters.
      However if the control had been created with DllCall() and has its own parent window,
         the container AutoHotkey created GUI must be made default with the +LastFound option prior to the call.
      For a complete example see anchor-example.ahk.
   
   License:
      - Version 4.60a by Titan <http://www.autohotkey.net/~Titan/#anchor>
      - GNU General Public License 3.0 or higher <http://www.gnu.org/licenses/gpl-3.0.txt>

*/

Anchor(i, a = "", r = false) {
   static c, cs = 12, cx = 255, cl = 0, g, gs = 8, gl = 0, gpi, gw, gh, z = 0, k = 0xffff
   If z = 0
      VarSetCapacity(g, gs * 99, 0), VarSetCapacity(c, cs * cx, 0), z := true
   If (!WinExist("ahk_id" . i)) {
      GuiControlGet, t, Hwnd, %i%
      If ErrorLevel = 0
         i := t
      Else ControlGet, i, Hwnd, , %i%
   }
   VarSetCapacity(gi, 68, 0), DllCall("GetWindowInfo", "UInt", gp := DllCall("GetParent", "UInt", i), "UInt", &gi)
      , giw := NumGet(gi, 28, "Int") - NumGet(gi, 20, "Int"), gih := NumGet(gi, 32, "Int") - NumGet(gi, 24, "Int")
   If (gp != gpi) {
      gpi := gp
      Loop, %gl%
         If (NumGet(g, cb := gs * (A_Index - 1)) == gp) {
            gw := NumGet(g, cb + 4, "Short"), gh := NumGet(g, cb + 6, "Short"), gf := 1
            Break
         }
      If (!gf)
         NumPut(gp, g, gl), NumPut(gw := giw, g, gl + 4, "Short"), NumPut(gh := gih, g, gl + 6, "Short"), gl += gs
   }
   ControlGetPos, dx, dy, dw, dh, , ahk_id %i%
   Loop, %cl%
      If (NumGet(c, cb := cs * (A_Index - 1)) == i) {
         If a =
         {
            cf = 1
            Break
         }
         giw -= gw, gih -= gh, as := 1, dx := NumGet(c, cb + 4, "Short"), dy := NumGet(c, cb + 6, "Short")
            , cw := dw, dw := NumGet(c, cb + 8, "Short"), ch := dh, dh := NumGet(c, cb + 10, "Short")
         Loop, Parse, a, xywh
            If A_Index > 1
               av := SubStr(a, as, 1), as += 1 + StrLen(A_LoopField)
                  , d%av% += (InStr("yh", av) ? gih : giw) * (A_LoopField + 0 ? A_LoopField : 1)
         DllCall("SetWindowPos", "UInt", i, "Int", 0, "Int", dx, "Int", dy
            , "Int", InStr(a, "w") ? dw : cw, "Int", InStr(a, "h") ? dh : ch, "Int", 4)
         If r != 0
            DllCall("RedrawWindow", "UInt", i, "UInt", 0, "UInt", 0, "UInt", 0x0101) ; RDW_UPDATENOW | RDW_INVALIDATE
         Return
      }
   If cf != 1
      cb := cl, cl += cs
   bx := NumGet(gi, 48), by := NumGet(gi, 16, "Int") - NumGet(gi, 8, "Int") - gih - NumGet(gi, 52)
   If cf = 1
      dw -= giw - gw, dh -= gih - gh
   NumPut(i, c, cb), NumPut(dx - bx, c, cb + 4, "Short"), NumPut(dy - by, c, cb + 6, "Short")
      , NumPut(dw, c, cb + 8, "Short"), NumPut(dh, c, cb + 10, "Short")
   Return, true
}   

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 14th, 2008, 4:51 am 
Micahs, .. big Applause!

I was going to post this on a separate thread, but maybe you can assist. I like the way this function works, but curious if you might know how to hook in a special sub-function which accomplishes this goal:

--Slow down the rate in which the GUI can be opened, in a smooth fashion.... so like, the way it is right now is like 1.0, ... and some setting like 0.5 would slow the rate at which one can grab and expand open the GUI.

It seems like you have the expertise to understand the dynamics of this and maybe can help me on a separate problem I have.... BTW, I love this design. Very cool ;)


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: April 15th, 2008, 6:04 pm 
Offline

Joined: December 1st, 2006, 9:27 am
Posts: 460
I had to move some things around. You'll have to find a happy balance between 'IncrementSize' and 'IncrementSpeed' to get the rate/smoothness you desire. What do you think?
Code:
;This one has resize speed control!
;Thread that I got "InsertIntegerAtAddress" and "WM_SIZING_Edge" from: http://www.autohotkey.com/forum/viewtopic.php?t=2441
;Uses Anchor 4.60a by Titan

Gui +Resize +LastFound
gui1ID := WinExist()
Gui, Add, Edit, w350 h250 vg1Edit, Hello
Gui, Add, Button, vg1Ok, Ok
Gui, Add, Button, x+ yp vg1Exit, Exit
Gui, Add, Button, x+ yp vg1Close, Close
Gui, Show,, MinMax`, No Aspect

Gui 2:+Resize +LastFound
gui2ID := WinExist()
Gui, 2:Add, Edit, w300 h200 vg2Edit, Hello
Gui, 2:Add, Button, vg2Ok, Ok
Gui, 2:Add, Button, x+ yp vg2Exit, Exit
Gui, 2:Add, Button, x+ yp vg2Close, Close
Gui, 2:Show,, MinMax`, With Aspect

Gui 3:+Resize +LastFound
gui3ID := WinExist()
Gui, 3:Add, Edit, w150 h100 vg3Edit, Hello
Gui, 3:Add, Button, vg3Ok, Ok
Gui, 3:Add, Button, x+ yp vg3Exit, Exit
Gui, 3:Add, Button, x+ yp vg3Close, Close
Gui, 3:Show,, NOT HANDLED

setGuiSize(gui1ID, "90%", "", "200%", "", False)
setGuiSize(gui2ID, "300", "", "550", "", True)

Return

GuiClose:
   ExitApp
Return

GuiSize:
   anchor("g1Edit","wh")
   anchor("g1Ok","y")
   anchor("g1Exit","y")
   anchor("g1Close","y")
Return

WM_SIZING(wParam, lParam, msg)
{
   global
   Critical
   static guiID, debounce
    WM_SIZING_Edge := wParam
   guiSizeAddr := lParam
   
   If GetKeyState("LButton","P") and (!debounce)   ;for each resizing, only get the gui id and info the first time through
   {   debounce=1
      CoordMode, MOUSE, SCREEN
      MouseGetPos,,, guiID
      getGuiSize(guiID, _ratio, _min1, _min2, _max1, _max2, _aspect)   ;get the ratio/min/max info for this gui
      SetTimer, WinSlowerDowner, %IncrementSpeed%
   }
   If !GetKeyState("LButton","P")   ;mouse released - reset
   {   debounce=0
      SetTimer, WinSlowerDowner, Off
   }

   IfEqual, _ratio, , Return False   ;if not a handled gui, exit func
    WinGetPos, CurrX, CurrY, CurrW, CurrH, ahk_id %guiID%   ;Get current x,y,w,h
   newCurrW := CurrX + CurrW
   newCurrH := CurrY + CurrH
   InsertIntegerAtAddress(CurrX, lParam, Rect_left, 4)   ;set x coord of left side of gui - these make sure the drag does not happen!
   InsertIntegerAtAddress(CurrY, lParam, Rect_top, 4)   ;set y coord of top side of gui
   InsertIntegerAtAddress(newCurrW, lParam, Rect_right, 4)      ;set x coord of right side of gui
   InsertIntegerAtAddress(newCurrH, lParam, Rect_bottom, 4)   ;set y coord of bottom side of gui
    Return True
   WinSlowerDowner:
      Critical
      SetWinDelay, 0
      If !GetKeyState("LButton","P")
      {   Exit
      }
      tmpBL := A_BatchLines
      SetBatchLines, 20ms
      
      CoordMode, MOUSE, SCREEN
      MouseGetPos, tX, tY
      WinGetPos, CurrX, CurrY, CurrW, CurrH, ahk_id %guiID%   ;Get current x,y,w,h

      If WM_SIZING_Edge in 2,8   ;right and bottom-right border drag      
      {   idealW := Abs(CurrX-tX)   ;what the width should be
         tmpCurrW := CurrW   ;current width
         If(tmpCurrW < idealW)   ;if current is less than it should be
         {   tmpCurrW += IncrementSize
            idealW := idealW < _max1 ? idealW : _max1   ;keep ideal width within max
            tmpCurrW := tmpCurrW > idealW ? idealW : tmpCurrW   ;if greater than ideal width, make equal
            tmpCurrH := _aspect ? Round(tmpCurrW * (1/_Ratio)) : CurrH   ;preserve aspect ratio or not
            WinMove, ahk_id %guiID% ,,,, tmpCurrW, tmpCurrH   ;do the deed
         }
         Else If(tmpCurrW > idealW)   ;current is greater than it should be
         {   tmpCurrW -= IncrementSize
            idealW := idealW > _min1 ? idealW : _min1   ;keep ideal width within min
            tmpCurrW := tmpCurrW < idealW ? idealW : tmpCurrW   ;if less than ideal width, make equal
            tmpCurrH := _aspect ? Round(tmpCurrW * (1/_Ratio)) : CurrH   ;preserve aspect ratio or not
            WinMove, ahk_id %guiID% ,,,, tmpCurrW, tmpCurrH   ;do the deed
         }
      }
      If(WM_SIZING_Edge = 6)   ;bottom border drag
      {   idealH := Abs(CurrY-tY)   ;what the height should be
         tmpCurrH := CurrH   ;current height
         If(tmpCurrH < idealH)   ;if current is less than it should be
         {   tmpCurrH += IncrementSize
            idealH := idealH < _max2 ? idealH : _max2   ;keep ideal height within max
            tmpCurrH := tmpCurrH > idealH ? idealH : tmpCurrH   ;if greater than ideal height, make equal
            tmpCurrW := _aspect ? Round(tmpCurrH * _Ratio) : CurrW   ;preserve aspect ratio or not
            WinMove, ahk_id %guiID% ,,,, tmpCurrW, tmpCurrH   ;do the deed
         }
         Else If(tmpCurrH > idealH)   ;current is greater than it should be
         {   tmpCurrH -= IncrementSize
            idealH := idealH > _min2 ? idealH : _min2   ;keep ideal height within min
            tmpCurrH := tmpCurrH < idealH ? idealH : tmpCurrH   ;if less than ideal height, make equal
            tmpCurrW := _aspect ? Round(tmpCurrH * _Ratio) : CurrW   ;preserve aspect ratio or not
            WinMove, ahk_id %guiID% ,,,, tmpCurrW, tmpCurrH   ;do the deed
         }
      }
      
;~    TODO:
;~    If(WM_SIZING_Edge = 3)   ;top border drag
;~    If(WM_SIZING_Edge = 4)   ;top-left border
;~    If WM_SIZING_Edge In 1,7   ;left, bottom-left borders

      SetBatchLines, %tmpBL%
   Return
   
   /*
   From MSDN (with edits):
   lParam - RECT Structure containing window coords
      typedef struct _RECT {
         LONG left;    (0) offset in structure
         LONG top;       (4)
         LONG right;    (8)
         LONG bottom;    (12)
      } RECT, *PRECT;
   
   wParam - Specifies which edge of the window is being sized. This
   parameter can be one of the following values.

      WMSZ_LEFT            (1)   Left edge
      WMSZ_RIGHT         (2)   Right edge
      WMSZ_TOP            (3)   Top edge
      WMSZ_TOPLEFT         (4)   Top-left corner
      WMSZ_TOPRIGHT      (5)   Top-right corner
      WMSZ_BOTTOM         (6)   Bottom edge
      WMSZ_BOTTOMLEFT   (7)   Bottom-left corner
      WMSZ_BOTTOMRIGHT   (8)   Bottom-right corner
   */
}


getGuiSize(_0, ByRef _1="", ByRef _2="", ByRef _3="", ByRef _4="", ByRef _5="", ByRef _6="", ByRef _7="", ByRef _8="", ByRef _9="", ByRef _10="", ByRef _11="", ByRef _12="", ByRef _13="", ByRef _14="")   ;get the info for the given gui - vars return blank if no match - allow up to 15 params (maybe the basis of another array handler?)
{
   global
   local tmp1
   
   Rect_left = 0   ;set up some constants for the sizing
   Rect_top = 4
   Rect_right = 8
   Rect_bottom = 12
   IncrementSize = 15
   IncrementSpeed = 50
   
   IfEqual, _0,, Return Please provide an ID or Gui Number
   If _0 Is Digit   ;must have passed gui number instead of ID
   {   Gui, %_0%:+LastFound
      _0 := WinExist()
   }
   StringSplit, _ggsStuff, %_0%_ggsArray, `,
   IfEqual, _ggsStuff0, 0, Return   ;if not a match, exit func
   Loop, %_ggsStuff0%
   {   tmp1 = _%A_Index%
      %tmp1% := _ggsStuff%A_Index%
   }
}

/*
   defaults:
      _ID = gui1 id
      _minwidth = guiID.width
      _minheight = guiID.height
      _maxWidth = system window max width
      _maxHeight = system window max height
*/
setGuiSize(_ID=1, _minWidth="", _minHeight="", _maxWidth="", _maxHeight="", _aspect=True)   ;set the ratio/min/max info for the given gui
{   
   SysGet, SM_CXMAXTRACK, 59   ;get largest window size
   SysGet, SM_CYMAXTRACK, 60

   If _ID Is Digit   ;must have passed gui number instead of window ID
   {   Gui, %_ID%:+LastFound
      _ID := WinExist()
   }
   WinGetPos,,,guiW, guiH, ahk_id %_ID%   ;get gui w,h and calc the size ratio
   _Ratio := guiW / guiH   ;multiply the current width by _Ratio to get the new height, multiply the current height by (1/_Ratio) to get the new width
   
   ;this sets the vars for max w,h to keep aspect ratio
   If(_minWidth)   ;if minimum width is given
   {   IfInString, _minWidth, `%   ;if a percent is specified
      {   StringReplace, _minWidth, _minWidth, `%,,All
         _minWidth := _minWidth / 100   ;did it this way because _minWidth/100 produced '0' - an integer
         _min1 := Round(guiW * _minWidth)   ;this is the width
         _min2 := Round(_min1 * (1/_Ratio))      ;this is the height
      }
      Else   ;must be 'px'
      {   StringReplace, _minWidth, _minWidth, px,,All   ;just in case
         _min1 := _minWidth         ;this is the width
         _min2 := Round(_min1 * (1/_Ratio))   ;this is the height
      }
   }
   Else If(_minHeight)   ;_minHeight given
   {   IfInString, _minHeight, `%   ;if a percent is specified
      {   StringReplace, _minHeight, _minHeight, `%,,All
         _minHeight := _minHeight / 100   ;did it this way because _minHeight/100 produced '0' - an integer
         _min2 := guiH * _minHeight   ;this is the height
         _min1 := Round(_min2 * _Ratio)      ;this is the width
      }
      Else   ;must be 'px'
      {   StringReplace, _minHeight, _minHeight, px,,All   ;just in case
         _min2 := _minHeight         ;this is the height
         _min1 := Round(_min2 * _Ratio)   ;this is the width
      }
   }
   Else   ;no min given
   {   _min1 := guiW   ;set min w,h = initial gui w,h
      _min2 := guiH
   }

   If(_maxWidth)   ;if maximum width is given
   {   IfInString, _maxWidth, `%   ;if a percent is specified
      {   StringReplace, _maxWidth, _maxWidth, `%,,All
         _maxWidth /= 100
         _max1 := guiW * _maxWidth   ;this is the width
         _max2 := (_max1 * (1/_Ratio))      ;this is the height
      }
      Else   ;must be 'px'
      {   StringReplace, _maxWidth, _maxWidth, px,,All   ;just in case
         _max1 := _maxWidth         ;this is the width
         _max2 := Round(_max1 * (1/_Ratio))   ;this is the height
      }
   }
   Else If(_maxHeight)   ;_maxHeight given
   {   IfInString, _maxHeight, `%   ;if a percent is specified
      {   StringReplace, _maxHeight, _maxHeight, `%,,All
         _maxHeight /= 100
         _max2 := guiH * _maxHeight   ;this is the height
         _max1 := (_max2 * _Ratio)      ;this is the width
      }
      Else   ;must be 'px'
      {   StringReplace, _maxHeight, _maxHeight, px,,All   ;just in case
         _max2 := _maxHeight      ;this is the height
         _max1 := Round(_max2 * _Ratio)   ;this is the width
      }
   }
   Else   ;no max given
   {   _max1 := SM_CXMAXTRACK   ;largest window possible in system
      _max2 := SM_CYMAXTRACK
   }
   %_ID%_ggsArray := _ratio "," _min1 "," _min2 "," _max1 "," _max2 "," _aspect

   globalWrapper(_ID "_ggsArray", %_ID%_ggsArray)

   OnMessage(0x214,"WM_SIZING")   ;this will happen once for every window set, but that shouldn't cause any problems
}

globalWrapper(victim, content)   ;this turns a dynamic local variable into a global variable
{
   global
   %victim% := content
}


InsertIntegerAtAddress(pInteger, pAddress, pOffset = 0, pSize = 4)    ;update this to putnum
{
   mask := 0xFF  ; This serves to isolate each byte, one by one.
   Loop %pSize%  ; Copy each byte in the integer into the structure as raw binary data.
   {
      DllCall("RtlFillMemory", UInt, pAddress + pOffset + A_Index - 1, UInt, 1
       , UChar, (pInteger & mask) >> 8 * (A_Index - 1))
      mask := mask << 8  ; Set it up for isolation of the next byte.
   }
}

   

/*

   Function: Anchor
      Defines how controls should be automatically positioned relative to the new dimensions of a window when resized.
   
   Parameters:
      cl - a control HWND, associated variable name or ClassNN to operate on
      a - (optional) one or more of the anchors: 'x', 'y', 'w' (width) and 'h' (height),
         optionally followed by a relative factor, e.g. "x h0.5"
      r - (optional) true to redraw controls, recommended for GroupBox and Button types
   
   Examples:
> "xy" ; bounds a control to the bottom-left edge of the window
> "w0.5" ; any change in the width of the window will resize the width of the control on a 2:1 ratio
> "h" ; similar to above but directrly proportional to height
   
   Remarks:
      To assume the current window size for the new bounds of a control (i.e. resetting) simply omit the second and third parameters.
      However if the control had been created with DllCall() and has its own parent window,
         the container AutoHotkey created GUI must be made default with the +LastFound option prior to the call.
      For a complete example see anchor-example.ahk.
   
   License:
      - Version 4.60a by Titan <http://www.autohotkey.net/~Titan/#anchor>
      - GNU General Public License 3.0 or higher <http://www.gnu.org/licenses/gpl-3.0.txt>

*/

Anchor(i, a = "", r = false) {
   static c, cs = 12, cx = 255, cl = 0, g, gs = 8, gl = 0, gpi, gw, gh, z = 0, k = 0xffff
   If z = 0
      VarSetCapacity(g, gs * 99, 0), VarSetCapacity(c, cs * cx, 0), z := true
   If (!WinExist("ahk_id" . i)) {
      GuiControlGet, t, Hwnd, %i%
      If ErrorLevel = 0
         i := t
      Else ControlGet, i, Hwnd, , %i%
   }
   VarSetCapacity(gi, 68, 0), DllCall("GetWindowInfo", "UInt", gp := DllCall("GetParent", "UInt", i), "UInt", &gi)
      , giw := NumGet(gi, 28, "Int") - NumGet(gi, 20, "Int"), gih := NumGet(gi, 32, "Int") - NumGet(gi, 24, "Int")
   If (gp != gpi) {
      gpi := gp
      Loop, %gl%
         If (NumGet(g, cb := gs * (A_Index - 1)) == gp) {
            gw := NumGet(g, cb + 4, "Short"), gh := NumGet(g, cb + 6, "Short"), gf := 1
            Break
         }
      If (!gf)
         NumPut(gp, g, gl), NumPut(gw := giw, g, gl + 4, "Short"), NumPut(gh := gih, g, gl + 6, "Short"), gl += gs
   }
   ControlGetPos, dx, dy, dw, dh, , ahk_id %i%
   Loop, %cl%
      If (NumGet(c, cb := cs * (A_Index - 1)) == i) {
         If a =
         {
            cf = 1
            Break
         }
         giw -= gw, gih -= gh, as := 1, dx := NumGet(c, cb + 4, "Short"), dy := NumGet(c, cb + 6, "Short")
            , cw := dw, dw := NumGet(c, cb + 8, "Short"), ch := dh, dh := NumGet(c, cb + 10, "Short")
         Loop, Parse, a, xywh
            If A_Index > 1
               av := SubStr(a, as, 1), as += 1 + StrLen(A_LoopField)
                  , d%av% += (InStr("yh", av) ? gih : giw) * (A_LoopField + 0 ? A_LoopField : 1)
         DllCall("SetWindowPos", "UInt", i, "Int", 0, "Int", dx, "Int", dy
            , "Int", InStr(a, "w") ? dw : cw, "Int", InStr(a, "h") ? dh : ch, "Int", 4)
         If r != 0
            DllCall("RedrawWindow", "UInt", i, "UInt", 0, "UInt", 0, "UInt", 0x0101) ; RDW_UPDATENOW | RDW_INVALIDATE
         Return
      }
   If cf != 1
      cb := cl, cl += cs
   bx := NumGet(gi, 48), by := NumGet(gi, 16, "Int") - NumGet(gi, 8, "Int") - gih - NumGet(gi, 52)
   If cf = 1
      dw -= giw - gw, dh -= gih - gh
   NumPut(i, c, cb), NumPut(dx - bx, c, cb + 4, "Short"), NumPut(dy - by, c, cb + 6, "Short")
      , NumPut(dw, c, cb + 8, "Short"), NumPut(dh, c, cb + 10, "Short")
   Return, true
}   

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 2nd, 2008, 11:56 pm 
Offline

Joined: May 4th, 2007, 7:59 pm
Posts: 102
Micahs!

I like what you did with this allot :D I've been working with something quite similar (see below), ... and just curious if you would take a quick looksee, and see if you can blend this into what you have -- or have your own personal take within it.

With this code, the GUI is designed to be open/closed by dragging the inside corridor ... and it would be so awesome if we could get the ratio perspective into this!!!, or yours vice-versa :)

Code:
xsize = 478
ysize = 478
xoffset = 40
yoffset = 40

xoffsethigh := xsize - xoffset
yoffsethigh := ysize - yoffset

Gui 2: -Border -caption +ToolWindow
Gui 2: Color, D3407E
Gui 2: Show, w%xsize% h%ysize%, a %xsize%x%ysize% GUI
WinGet, active_id, ID, A
OnMessage(0x201, "GUI_Expand")
return

GUI_Expand(wParam, lParam)
{
   global
   MouseGetPos, Xpos, Ypos, OutputvarWin,
    if (OutputvarWin = active_ID)
    {
      WinGetPos, winXpos, winYpos, Xsize, Ysize, ahk_id %active_ID%
       if ( (Xpos > xoffsethigh) and (Ypos > yoffset or Ypos < yoffsethigh) )
       {
         loop
         {
            GetKeyState, state, LButton
               if state = D
               {
                  prevXpos := Xpos
                  MouseGetPos, Xpos, Ypos,
                  Xsize := Xsize + Xpos - prevXpos
               Gui, Show, w%xsize% h%ysize%, a %xsize%x%ysize% GUI
               xoffsethigh := xsize - xoffset
               yoffsethigh := ysize - yoffset
               }
               else
                  break
            }
       }


       if ( (Ypos > yoffsethigh) and (Xpos > xoffset or Xpos < xoffsethigh) )
       {
         loop
         {
            GetKeyState, state, LButton
               if state = D
               {
                  prevYpos := Ypos
                  MouseGetPos, Xpos, Ypos,
                  Ysize := Ysize + Ypos - prevYpos
               Gui, Show, w%xsize% h%ysize%, a %xsize%x%ysize% GUI
               xoffsethigh := xsize - xoffset
               yoffsethigh := ysize - yoffset
               }
               else
                  break
            }
       }
   }
}



BTW, thanks allot to Z Gecko, Razlin and some others helping.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 3rd, 2008, 4:00 pm 
Offline

Joined: December 1st, 2006, 9:27 am
Posts: 460
This is one of the first iterations modified a little. It behaves like the bit that you posted. Note that I still haven't added sizing by dragging the left or top borders. I'll look into it if you want.

Code:
SetBatchLines, -1
SetWinDelay,10

Gui 2: -Border -caption +ToolWindow +LastFound
Gui 2: Color, D3407E
guiID := WinExist()
Gui, 2:Show, w300 h351
WinGetPos,,,winW, winH

changeArrow=0   ;change the cursor to arrows when over the drag area or not
constrainMouse=0   ;constrain the mouse to the border min/max during drag
fudgeFactor = 3   ;makes the border area larger for easier dragging, seems to be needed on the bottom border
GuiMinSize=300x351
GuiMaxSize=425x496

IDC_SIZEWE = 32644
IDC_SIZENS = 32645
SysGet, SM_CXFIXEDFRAME, 7
SysGet, SM_CYFIXEDFRAME, 8
leftBorder := SM_CXFIXEDFRAME + fudgeFactor
topBorder := SM_CYFIXEDFRAME + fudgeFactor
WM_MOUSEMOVE = 0x200
WM_LBUTTONDOWN = 0x201
 
hProp := winH / winW   ;multiply the current width by hProp to get the new height
wProp := winW / winH   ;multiply the current height by wProp to get the new width
WEcursor := DllCall("LoadCursor", "Uint", 0, "Int", IDC_SIZEWE)    ;load west-east cursor
NScursor := DllCall("LoadCursor", "Uint", 0, "Int", IDC_SIZENS)    ;load north-south cursor
StringSplit, guiMin, GuiMinSize, x   ;guiMin1 is width   ;guiMin2 is height
StringSplit, guiMax, GuiMaxSize, x   ;guiMax1 is width   ;guiMax2 is height

OnMessage(WM_MOUSEMOVE, "CheckDrag")
OnMessage(WM_LBUTTONDOWN, "CheckDrag")

Return

;need to make left and top border work.
;for left, have to make x smaller while making w larger.

CheckDrag(wparam, lparam, msg, hwnd)
{
   global
   MouseGetPos, mX, mY
   WinGetPos, oX, oY, oW, oH, ahk_id %guiID%
   rightBorder := oW - SM_CXFIXEDFRAME - fudgeFactor
   bottomBorder := oH - SM_CYFIXEDFRAME - fudgeFactor
   
   If(mX < leftBorder)
   {   If(changeArrow)
      {   DllCall("SetCursor", "uint", WEcursor)   ;set west-east cursor
      }
      direction = W
      SetTimer, sizer, 0
   }
   Else If(mX >= rightBorder)
   {   If(changeArrow)
      {   DllCall("SetCursor", "uint", WEcursor)   ;set west-east cursor
      }
      direction = E
      SetTimer, sizer, 0
   }
   Else If(mX < topBorder)
   {   If(changeArrow)
      {   DllCall("SetCursor", "uint", NScursor)   ;set north-south cursor
      }
      direction = N
      SetTimer, sizer, 0
   }
   Else If(mY > bottomBorder)
   {   If(changeArrow)
      {   DllCall("SetCursor", "uint", NScursor)   ;set north-south cursor
      }
      direction = S
      SetTimer, sizer, 0
   }
}

sizer:
   Critical
   If GetKeyState("LButton","P")
   {   CoordMode, MOUSE, SCREEN
      MouseGetPos, moveX, moveY
      If(direction = "W")   ;dragging left border   ******DOES NOT WORK*****
      {   If(changeArrow)
         {   DllCall("SetCursor", "uint", WEcursor)   ;set west-east cursor
         }
         newW := moveX - oX
         newH := newW * hProp
         newX := moveX
         newY :=
      }
      Else If(direction = "N")   ;dragging top border   ******DOES NOT WORK*****
      {   If(changeArrow)
         {   DllCall("SetCursor", "uint", NScursor)   ;set north-south cursor
         }
         newH := oY - moveY
         newH := newH < guiMin2 ? guiMin2 : newH   ;make sure its not smaller than minimum
         newH := newH > guiMax2 ? guiMax2 : newH   ;make sure its not bigger than maximum
         newW := newH * wProp
      }
      Else If(direction = "E")   ;dragging right border
      {   If(changeArrow)
         {   DllCall("SetCursor", "uint", WEcursor)   ;set west-east cursor
         }
         newW := moveX - oX
         newW := newW < guiMin1 ? guiMin1 : newW   ;make sure its not smaller than minimum
         newW := newW > guiMax1 ? guiMax1 : newW   ;make sure its not bigger than maximum
         newH := newW * hProp
         newX=
         newY=
         If(constrainMouse)
         {   moveX := moveX > oX + guiMax1 ? oX + guiMax1 : moveX   ;keep mouse within max
            moveX := moveX < oX + guiMin1 ? oX + guiMin1 : moveX   ;keep mouse within min
         }
      }
      Else If(direction = "S")   ;dragging bottom border
      {   If(changeArrow)
         {   DllCall("SetCursor", "uint", NScursor)   ;set north-south cursor
         }
         newH := moveY - oY
         newH := newH < guiMin2 ? guiMin2 : newH   ;make sure its not smaller than minimum
         newH := newH > guiMax2 ? guiMax2 : newH   ;make sure its not bigger than maximum
         newW := newH * wProp
         newX=
         newY=
         If(constrainMouse)
         {   moveY := moveY > oY + guiMax2 ? oY + guiMax2 : moveY   ;keep mouse within max
            moveY := moveY < oY + guiMin2 ? oY + guiMin2 : moveY   ;keep mouse within min
         }
      }
      MouseMove, moveX, moveY
      WinMove, ahk_id %guiID%,, %newX%, %newY%, %newW%, %newH%
   }
   Else
   {   SetTimer, sizer, Off
   }
Return

guiClose:
   ExitApp
Return

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 41 posts ]  Go to page Previous  1, 2, 3  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: JSLover, kkkddd1, Tipsy3000, Yahoo [Bot] and 73 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group