this is not a GUI creator. there is a good one here http://autohotkey.com/boards/viewtopic.php?f=6&t=10157 by Alguimist. it's a full fledged one, and there are more, so there is no need to reinvent the wheel.
Code: Select all
#NoEnv
OnExit, Terminate
PicSize := 5 ; set the resing border size: width and height
ResizeColor := DllCall("User32.dll\GetSysColor", "Int", 13, "UInt") ; COLOR_HIGHLIGHT:=13
ResizeColorBrush := DllCall("Gdi32.dll\CreateSolidBrush", "UInt", ResizeColor, "UPtr")
OnMessage(0x138, "WM_CTLCOLORSTATIC") ; to set the resizing static control's color
OnMessage(0x020, "WM_SETCURSOR") ; change the cursor
OnMessage(0x201, "WM_LBUTTONDOWN") ; set the resizing borders and moving the controls
OnMessage(0x204, "WM_RBUTTONDOWN") ; set the resizing borders on right click
OnMessage(0x007, "WM_SETFOCUS") ; no focus for our controls
OnMessage(0x200, "WM_MOUSEMOVE") ; in order not to change buttons style (state) or edit control when the mouse moves over them
OnMessage(0x100, "WM_KEYDOWN") ; no selecting child controls using TAB
SS_NOTIFY:=0x0100 ; static controls must have this style so that they get treated using WM_SETCURSOR, without this style, wParam=hWnd in WM_SETCURSOR func
WS_CLIPSIBLINGS:=0x04000000 ; Clips child windows relative to each other: combined with WinSet, Top; always the selected control is ontop off all others
ControlsList :=[] ; added controls
Controls:="Text,Edit,UpDown,Picture,Button,Checkbox,Radio,DropDownList,ComboBox,ListBox,ListView,TreeView,Link,Hotkey,DateTime,MonthCal,Slider,Progress,GroupBox,Tab2,StatusBar"
Loop, Parse, Controls, csv
Menu, Controls2Add, Add, %A_LoopField%, AddControl
Menu, FileMenu, Add, Copy`tCtrl+C, CopyControls
Menu, FileMenu, Add
Menu, FileMenu, Add, Exit`tCtrl+X, GuiClose
Gui, +resize +hWndhMainwin
Loop, 8
{
Gui, Add, Text, x0 y20 w%PicSize% h%PicSize% vSResize%A_Index% hWndhSResize%A_Index% gOnMoveMakeThemMove Hidden
SResizeHANDLES .= hSResize%A_Index% ","
}
SResizeHANDLES := trim(SResizeHANDLES, ",") ; for selecting controls using tab
;{ set the cursor for each control
; we need the next 5 cursors only
;IDC_SIZENWSE = 32642 Double-pointed arrow pointing northwest and southeast
;IDC_SIZENS = 32645 Double-pointed arrow pointing north and south
;IDC_SIZENESW = 32643 Double-pointed arrow pointing northeast and southwest
;IDC_SIZEWE = 32644 Double-pointed arrow pointing west and east
;IDC_SIZEALL = 32646 Four-pointed arrow pointing north, south, east, and west
;IDC_APPSTARTING = 32650 Standard arrow and small hourglass
;IDC_ARROW = 32512 Standard arrow
;IDC_CROSS = 32515 Crosshair
;IDC_HAND = 32649 Hand
;IDC_HELP = 32651 Arrow and question mark
;IDC_IBEAM = 32513 I-beam
;IDC_ICON = 32641 Obsolete for applications marked version = 4.0 or later.
;IDC_NO = 32648 Slashed circle
;IDC_SIZE = 32640 Obsolete for applications marked version = 4.0 or later. Use IDC_SIZEALL.
;IDC_UPARROW = 32516 Vertical arrow
;IDC_WAIT = 32514 Hourglass
;}
SizingCursor:={(hSResize1):32642, (hSResize2):32645, (hSResize3):32643, (hSResize4):32643, (hSResize5):32645, (hSResize6):32642,(hSResize7):32644, (hSResize8):32644}
Menu, ControlsMenu, Add, File, :FileMenu
Menu, ControlsMenu, Add, Controls, :Controls2Add
Gui, Menu, ControlsMenu
Gui, show, w400 h400, Resize Controls using Mouse
Return
OnMoveMakeThemMove: ;{
CoordMode, mouse, client
Gui, %A_Gui%:+LastFound
hWin:=WinExist("")
MouseGetPos, omx, omy ;, W_hWnd_Temp ; get the window under the mouse handle and position
GuiControlGet, oc, %A_Gui%:pos, %conUnderMouse% ; the current window position
ncx:=ncy:=ncw:=nch:=0
Sizing:=true
VarSetCapacity(rect, 16, 0)
HDC := DllCall("User32.dll\GetDC", "Ptr", hWin, "UPtr")
if (A_GuiControl="SResize1") { ; x+y+w+h
while GetKeyState("Lbutton", "P") {
MouseGetPos, mx, my
nch:=och-(my-ocy)
ncw:=ocw-(mx-ocx)
if (mx=omx) ; prevent flicker: redrawing the rect focus
continue
DllCall("User32.dll\DrawFocusRect", "Ptr", HDC, "Ptr", &RECT)
SetRect(rect, mx, my, ncw+mx, nch+my)
DllCall("User32.dll\DrawFocusRect", "Ptr", HDC, "Ptr", &RECT)
omx:=mx
}
ncx:=mx, ncy:=my
}
else if (A_GuiControl="SResize2") { ; y+h
while GetKeyState("Lbutton", "P") {
MouseGetPos, mx, my
nch:=och-(my-ocy)
if (omy=my)
continue
DllCall("User32.dll\DrawFocusRect", "Ptr", HDC, "Ptr", &RECT)
SetRect(rect, ocx-1, my, ocw+ocx+1, my+nch+1)
DllCall("User32.dll\DrawFocusRect", "Ptr", HDC, "Ptr", &RECT)
omy:=my
}
ncx:=ocx, ncy:=my, ncw:=ocw
}
else if (A_GuiControl="SResize3") { ; y+w+h
while GetKeyState("Lbutton", "P") {
MouseGetPos,mx,my
nch:=och-(my-ocy)
ncw:=mx-ocx+PicSize
if (mx=omx) ; prevent flicker: redrawing the rect focus
continue
DllCall("User32.dll\DrawFocusRect", "Ptr", HDC, "Ptr", &RECT)
SetRect(rect, ocx-1, my-1, ncw+ocx+1, nch+my+1)
DllCall("User32.dll\DrawFocusRect", "Ptr", HDC, "Ptr", &RECT)
omx:=mx
}
ncx:=ocx, ncy:=my
}
else if (A_GuiControl="SResize4") { ; x+w+h
while GetKeyState("Lbutton", "P") {
MouseGetPos, mx, my
nch:=ocy+(my-ocy)
ncw:=ocw-(mx-ocx)
if (mx=omx) ; prevent flicker: redrawing the rect focus
continue
DllCall("User32.dll\DrawFocusRect", "Ptr", HDC, "Ptr", &RECT)
SetRect(rect, mx, ocy, ncw+mx, nch)
DllCall("User32.dll\DrawFocusRect", "Ptr", HDC, "Ptr", &RECT)
omx:=mx
}
ncx:=mx, ncy:=ocy, nch:=nch-ocy
}
else if (A_GuiControl="SResize5") { ; h
while GetKeyState("Lbutton", "P") {
MouseGetPos, mx, my
nch:=ocy+(my-ocy)
if (omy=my)
continue
DllCall("User32.dll\DrawFocusRect", "Ptr", HDC, "Ptr", &RECT)
SetRect(rect, ocx, ocy, ocw+ocx-2, nch)
DllCall("User32.dll\DrawFocusRect", "Ptr", HDC, "Ptr", &RECT)
omy:=my
}
ncx:=ocx, ncy:=ocy, ncw:=ocw, nch:=nch-ocy
}
else if (A_GuiControl="SResize6") { ; w+h
while GetKeyState("Lbutton", "P") {
MouseGetPos, mx, my
nch:=ocy+(my-ocy)
ncw:=ocx+(mx-ocx)
if (nch=och) && (ncw=ocw) ; prevent flicker: redrawing the rect focus
continue
DllCall("User32.dll\DrawFocusRect", "Ptr", HDC, "Ptr", &RECT)
SetRect(rect, ocx, ocy, ncw, nch)
DllCall("User32.dll\DrawFocusRect", "Ptr", HDC, "Ptr", &RECT)
och:=nch,ocw:=ncw
}
ncx:=ocx, ncy:=ocy, nch:=nch-ocy, ncw:=ncw-ocx
}
else if (A_GuiControl="SResize7") { ; x+w
while GetKeyState("Lbutton", "P") {
MouseGetPos, mx
ncw:=ocw-(mx-ocx)
if (mx=omx) ; prevent flicker: redrawing the rect focus
continue
DllCall("User32.dll\DrawFocusRect", "Ptr", HDC, "Ptr", &RECT)
SetRect(rect, mx, ocy, ncw+mx, och+ocy)
DllCall("User32.dll\DrawFocusRect", "Ptr", HDC, "Ptr", &RECT)
omx:=mx
}
ncx:=mx, ncy:=ocy, nch:=och
}
else if (A_GuiControl="SResize8") { ; w
while GetKeyState("Lbutton", "P") {
MouseGetPos, mx
ncw:=ocw - (omx-mx)
if (ncw=oldncw) ; prevent flicker: redrawing the rect focus
continue
DllCall("User32.dll\DrawFocusRect", "Ptr", HDC, "Ptr", &RECT)
SetRect(rect, ocx,ocy,ncw+ocx, och+ocy)
DllCall("User32.dll\DrawFocusRect", "Ptr", HDC, "Ptr", &RECT)
oldncw:=ncw
}
ncx:=ocx, ncy:=ocy, nch:=och
}
DllCall("User32.dll\DrawFocusRect", "Ptr", HDC, "Ptr", &RECT) ; Because DrawFocusRect is an XOR function, calling it a second time with the same rectangle removes the rectangle from the screen
DllCall("User32.dll\ReleaseDC", "Ptr", hWin, "Ptr", HDC)
Sizing:=false
MouseGetPos, mx, my
if (mx!=omx) || (my!=omy) ; eliminate sizing|moving the control if only click
{
newpos := "x" ncx "y" ncy "w" ncw "h" nch
GuiControl, MoveDraw, %conUnderMouse%, % newpos
gosub, SetControlForSizing ; move the resizing borders to the new location of the control
}
return
;}
SetControlForSizing: ;{
GuiControlGet, con, pos, %conUnderMouse%
GuiControl, movedraw, SResize1, % "x" conx-PicSize "y" cony-PicSize
GuiControl, MoveDraw, SResize2, % "x" conx+((conw-PicSize)/2) " y" cony-PicSize
GuiControl, MoveDraw, SResize3, % "x" conx+conw " y" cony-PicSize
GuiControl, MoveDraw, SResize4, % "x" conx-PicSize "y" cony+conh
GuiControl, MoveDraw, SResize5, % "x" conx+((conw-PicSize)/2) " y" cony+conh
GuiControl, MoveDraw, SResize6, % "x" conx+conw "y" cony+conh
GuiControl, MoveDraw, SResize7, % "x" conx-PicSize "y" cony+((conh-PicSize)/2)
GuiControl, MoveDraw, SResize8, % "x" conx+conw "y" cony+((conh-PicSize)/2)
Loop, 8
GuiControl, show, SResize%A_Index%
return
;}
WM_RBUTTONDOWN(wParam, lParam, Msg, hWnd) { ; select control if there is one
global conUnderMouse
MouseGetPos,,,, c, 2 ; old mouse move x,y. and to eliminate our resizing controls
GuiControlGet, s, %A_Gui%:Name, %c%
if !c ; there is no control under the mouse
Loop, 8
GuiControl, hide, SResize%A_Index%
else if !(s~="i)SResize[1-8]"){
conUnderMouse := c
WinSet, Top,, ahk_id %conUnderMouse% ; the selected child widow on top of the z-order, to always be redrawn on top
gosub, SetControlForSizing
return, 0
}
}
WM_LBUTTONDOWN(wParam, lParam, Msg, hWnd) { ; select and move control on mouse move
global conUnderMouse, hMainwin, onTheMove, PicSize
VarSetCapacity(rect, 16)
MouseGetPos, ommx ,ommy , win, c, 2 ; old mouse move x,y. and to eliminate our resizing controls
GuiControlGet, s, %A_Gui%:Name, %c%
if !c ; there is no control under the mouse
Loop, 8
GuiControl, hide, SResize%A_Index%
else if !(s~="i)SResize[1-8]"){ ; the control isn't one of our sizing ones
conUnderMouse := c
WinSet, Top,, ahk_id %conUnderMouse% ; the selected child widow on top of the z-order, to always be redrawn on top
gosub, SetControlForSizing
GuiControlGet, con, %A_Gui%:pos, %conUnderMouse%
GetClientSize(win, ww, wh) ; neede for out of client area pos
onTheMove:=true
VarSetCapacity(RECT, 16, 0)
;GuiControl, %A_Gui%:-Redraw, %conUnderMouse% ; if moving create an undesired redrawing problems
HDC := DllCall("User32.dll\GetDC", "Ptr", hMainwin, "UPtr")
MouseGetPos, mmxx, mmyy ; to prevent non moving control from coming fully in client area even without use moving the mouse
nx:=ny:=""
while GetKeyState("Lbutton", "P") {
MouseGetPos, mmx, mmy
if !(mmx=mmxx && mmy=mmyy){ ; only if the mouse's moved,
; to NOT prevent controls from going out of the client area ucomment the next line
; nx:=conx+(mmx-ommx), ny:=cony+(mmy-ommy)
; to prevent contols from going out of the client area
; comment the next two lines if that's not desired
nx := (nx:=conx+(mmx-ommx))<0 ? 0: (nx+conw)>ww ? ww-conw : nx
ny := (ny:=cony+(mmy-ommy))<0 ? 0: (ny+conh)>wh ? wh-conh : ny
; to keep all the resizing borders visible, instead of the previous two lines use the next two
;nx := (nx:=conx+(mmx-ommx))<PicSize ? PicSize: (nx+conw)>ww ? ww-conw-PicSize : nx
;ny := (ny:=cony+(mmy-ommy))<PicSize ? PicSize: (ny+conh)>wh ? wh-conh-PicSize : ny
; or you can set based on the GUI Margins, MUST SET THE GuiMargin VARIABLE
;nx := (nx:=conx+(mmx-ommx))<GuiMargin ? GuiMargin: (nx+conw)>ww ? ww-conw-GuiMargin : nx
;ny := (ny:=cony+(mmy-ommy))<GuiMargin ? GuiMargin: (ny+conh)>wh ? wh-conh-GuiMargin : ny
DllCall("User32.dll\DrawFocusRect", "Ptr", HDC, "Ptr", &RECT)
SetRect(RECT, nx, ny, nx+conw, ny+conh)
DllCall("User32.dll\DrawFocusRect", "Ptr", HDC, "Ptr", &RECT)
mmxx:=mmx, mmyy:=mmy
}
}
;GuiControl, %A_Gui%:+Redraw, %conUnderMouse%
if !(nx="") ; explicitly an EMPTY STRING: we just clicked over the control, no drag
GuiControl, MoveDraw, %conUnderMouse%, % "x" nx " y" ny
onTheMove:=false
DllCall("User32.dll\DrawFocusRect", "Ptr", HDC, "Ptr", &RECT) ; Because DrawFocusRect is an XOR function, calling it a second time with the same rectangle removes the rectangle from the screen
DllCall("User32.dll\ReleaseDC", "Ptr", hMainwin, "Ptr", HDC)
gosub, SetControlForSizing
return, 0
}
}
WM_SETCURSOR(wParam, lParam, Msg, hWnd) { ; set the cursor to indicate the state for moving resizing and what direction
; change the mouse to indicate a movable control
; wParam: handle to the window that contains the cursor, given that the mouse isn't captured
; if the mouse were to be captured, it's better using MouseGetPos
Global SizingCursor, Sizing, onTheMove
static CurrentCursorControl, hCursor
if Sizing{
DllCall("SetCursor", "uint", hCursor)
return, true
}
if SizingCursor[wParam]{ ; get the sizing cursor style
hCursor := DllCall("LoadCursor", "uint", 0, "uint", SizingCursor[wParam]) ;IDC_SIZEWE=32644, IDC_SIZENS=32645
DllCall("SetCursor", "uint", hCursor)
CurrentCursorControl:=wParam
return true
}
if (wParam!=hWnd)||onTheMove{ ; a control other than the window and the sizing borders, or we're moving a control
hCursor := DllCall("LoadCursor", "uint", 0, "uint", 32646) ; IDC_SIZEALL:=32646 : Four-pointed arrow pointing north, south, east, and west
DllCall("SetCursor", "uint", hCursor)
CurrentCursorControl:=wParam
return true
}
}
WM_CTLCOLORSTATIC(wParam, lParam) {
global StaticTextBackgroundColor, ResizeColorBrush
Critical 50
GuiControlGet, s, %A_Gui%:Name, %lParam%
if (s~="i)SResize[1-8]"){ ; only our 8 static controls so we don't change other controls background
DllCall("SetBkColor", UInt, wParam, UInt, StaticTextBackgroundColor)
return ResizeColorBrush ; Return the HBRUSH to notify the OS that we altered the HDC.
}
}
WM_SETFOCUS(){
return, 0
}
WM_MOUSEMOVE() {
return, 0 ; in order not to change controls state. button'ss style changes on mouse move, edit controls also, headers....
}
WM_KEYDOWN(wParam, lParam, Msg, hWnd) {
global conUnderMouse, SResizeHANDLES, hSResize1
;return, 0 ; no keys
if (wParam=9){ ; tab
Loop, parse, SResizeHANDLES, csv
WinSet, Top,, ahk_id %A_LoopField% ; set the resizing border to the top of the z-order, so that they donot interfere with our window's added controls(real controls)
if conUnderMouse is not integer
ControlGet, conUnderMouse, hWnd,, %conUnderMouse%, ahk_id %hWnd%
; one thing to notice is that the Z-Order changes based of the last control tha
if !conUnderMouse:=DllCall("GetWindow", "Ptr", conUnderMouse, "uint", 2) ; GW_HWNDNEXT:=2 : get next control
if !conUnderMouse := DllCall("GetWindow", "Ptr", hSResize1, "uint", 2) ; GW_HWNDNEXT:=2 : get the first control after our resizig
return 0
gosub, SetControlForSizing
}
return, 0 ; no keys
}
SetRect(byref rect, x,y,w,h){ ; just a simple helper function
DllCall("SetRect", "Ptr", &RECT, "UInt", x, "UInt", y, "UInt", w, "UInt", h)
}
GetClientSize(hwnd, ByRef wr, ByRef hr) { ;client area excludes the window's borders, title bar, and menu bar
VarSetCapacity(rc, 16)
DllCall("GetClientRect", "uint", hwnd, "uint", &rc)
wr := NumGet(rc, 8, "int")
hr := NumGet(rc, 12, "int")
}
AddControl: ;{
c := A_ThisMenuItem
GetClientSize(hMainwin, ww, wh)
try Gui, Add, %c%, hWndconUnderMouse Hidden %WS_CLIPSIBLINGS%, %c%
catch e { ; might be error sometimes, (e.g second statusbar)
MsgBox, 0, error, % "Error Adding the control:`n" e.Message
return
}
GuiControlGet, cpos, pos, %conUnderMouse%
ControlsList[conUnderMouse] := c
cposw := cposw<50 ? 50 : cposw
cposh := cposh<50 ? 50 : cposh
GuiControl, Move, %conUnderMouse%, % "x" (ww-cposw)//2 " y" (wh-cposh)//2 " w" cposw " h" cposh
if (c~="i)Picture|Text")
GuiControl, +%SS_NOTIFY%, %c%
GuiControl, Show, %conUnderMouse%
addedcontrol:=true
gosub, SetControlForSizing
return
;}
CopyControls: ;{
addedcontrol:=txt := ""
for hwnd, ctl in ControlsList
{
GuiControlGet, c, pos, %hwnd%
txt .= "Gui, Add, " ctl ", x" cx " y" cy " w" cw " h" ch ", " ctl "`r`n"
}
GetClientSize(hMainwin, ww, wh)
txt=
(
%txt%Gui, Show, w%ww% h%wh%, GUI Controls
return
GuiEscape:
GuiClose:
ExitApp
)
Clipboard := trim(txt, "`n")
return
;}
GuiClose:
GuiEscape:
ExitApp
Terminate: ;{
if addedcontrol{
MsgBox, 8227, save, you have added controls without saving`nwould you like to copy the gui?
IfMsgBox, Yes
gosub, CopyControls
else IfMsgBox, Cancel
return
}
ExitApp
return
;}