Sorry to bump but here's an update:
REM Project: Vista Basic Window
REM Created: 11/14/2007 9:49:06 PM
REM
REM ***** Main Source File *****
REM
sync on
sync
wndx = 5
wndy = 5
wndwidth = 320
wndheight = 240
set text font "MS Sans Serif"
hide mouse
if file exist("icon.bmp")
load image "icon.bmp", 1, 1
endif
if file exist("cur.bmp") and file exist("cur_h.bmp") and file exist("cur_v.bmp") and file exist("cur_hv.bmp")
load image "cur.bmp", 10, 1
load image "cur_h.bmp", 11, 1
load image "cur_v.bmp", 12, 1
load image "cur_hv.bmp", 13, 1
endif
if file exist("bg.png")
load image "bg.png", 20, 1
endif
`Constants
#constant WM_NULL 0 `Not used at all
#constant WM_CREATE 1 `wParam - Not used, lParam - Not used
#constant WM_CLOSE 2 `wParam - Not used, lParam - Not used
#constant WM_DESTROY 3 `wParam - Not used, lParam - Not used
#constant WM_MOVE 4 `wParam - X, lParam - Y
#constant WM_SIZE 5 `wParam - Width, lParam - Height
#constant WM_PAINT 6 `wParam - Not used, lParam - Not used
`Types
type sMessage `A structure to contain the message given to an event
m_Window as integer `What window got this message? (Specified by handle ID)
m_Message as integer `What is the message for the window?
m_WParam as integer `Additional parameter W
m_LParam as integer `Additional parameter L
endtype
type sWindow `A structure to contain window information
m_Valid as byte `Is this a valid entry in the list?
m_WindowType as integer `What type of window is this? (Window, Form/Panel, Button, Slider, etc)
m_Visible as byte `Is this window visible?
m_Enabled as byte `Is this window enabled?
m_PosX as integer `Where is this window? (X)
m_PosY as integer `Where is this window? (Y)
m_Width as integer `What is the width of the window?
m_Height as integer `What is the height of the window?
m_Text$ as string `What is the text/title of the window (usually caption)
m_IconImg as integer `What icon image befalls the window?
m_ClientColor as dword `What is the client color of the window?
m_Style as dword `What is the window style?
m_Parent as integer `What's the parent of the window? (handle ID)
m_Next as integer `What is the next entry item? (handle ID)
m_Prev as integer `And the previous entry item? (handle ID)
endtype
type sGuiContext `A structure used to give information about the GUI
m_MouseClick as integer `Is the mouse clicked?
m_MouseX as integer `Where is the mouse on the x axis?
m_MouseY as integer `Where is the mouse on the y axis?
m_Cursor as integer `What is the cursor image?
m_CursorH as integer `What is the horizontal resizing cursor image?
m_CursorV as integer `What is the vertical resizing cursor image?
m_CursorHV as integer `What is the horizontal/vertical resizing cursor image?
m_CursorEdit as integer `What is the cursor image for typing in an edit?
m_Operation as dword `What operation?
m_OpWindow as integer `What is the handle to the window of the operation?
m_MessageQueCount as dword `What's left in the message que?
m_MessageQue as dword `This is a pointer to the message que
m_Message as sMessage `The message loaded in the message que
m_ClipX as integer `clip x
m_ClipY as integer `clip y
m_ClipWidth as integer `clip width
m_ClipHeight as integer `clip height
endtype
`Globals
global g_GuiContext as sGuiContext
global dim g_WindowList(0xffff) as sWindow
wnd as sWindow
wnd.m_PosX = 0
wnd.m_PosY = 0
wnd.m_Width = 320
wnd.m_Height = 240
wnd.m_ClientColor = 0xffc9c9c9
wnd.m_IconImg = 1
wnd.m_Text$ = "Hello World! ~ Vista Basic GUI Window!"
ConstructGuiContext()
g_GuiContext.m_Cursor = 10
g_GuiContext.m_CursorH = 11
g_GuiContext.m_CursorV = 12
g_GuiContext.m_CursorHV = 13
g_WindowList(0).m_ClientColor = 0xff007777
while escapekey() = 0
mc = mouseclick()
mx = mousex()
my = mousey()
if image exist(20) = 1
paste image 20, 0, 0, 0
else
cls g_WindowList(0).m_ClientColor
endif
wndx = wnd.m_PosX
wndy = wnd.m_PosY
wndwidth = wnd.m_Width
wndheight = wnd.m_Height
if mc = 1
if drag = 0 and hresize = 0 and vresize = 0
if mx > wndx and my > wndy
if mx < wndx + wndwidth and my < wndy + 23
drag = 1
dragx = mx - wndx
dragy = my - wndy
endif
endif
`HResize
if mx > wndx + wndwidth - 7 and my > wndy + 23
if mx < wndx + wndwidth + 1 and my < wndy + wndheight + 1
hresize = 1
endif
endif
`VResize
if mx > wndx and my > wndy + wndheight - 7
if mx < wndx + wndwidth + 1 and my < wndy + wndheight + 1
vresize = 1
endif
endif
endif
else
drag = 0
hresize = 0
vresize = 0
endif
if drag = 1
wndx = mx - dragx
wndy = my - dragy
endif
if hresize = 1
wndwidth = mx - wndx + 2
if wndwidth < 120 then wndwidth = 120
if wndwidth > screen width() then wndwidth = screen width()
endif
if vresize = 1
wndheight = my - wndy + 2
if wndheight < 32 then wndheight = 32
if wndheight > screen height() then wndheight = screen height()
endif
wnd.m_PosX = wndx
wnd.m_PosY = wndy
wnd.m_Width = wndwidth
wnd.m_Height = wndheight
DrawVistaBasicWindow(wnd)
if spacekey() = 1
VistaBasicMessageBox("Hi! ~ ABCDEFGHIJKLMNOPQRSTUVWXYZ ~ abcdefghijklmnopqrstuvwxyz", "Hello!")
endif
if hresize = 0 and vresize = 0
paste image 10, mx, my, 1
endif
if hresize = 1 and vresize = 0
paste image 11, mx, my, 1
endif
if hresize = 0 and vresize = 1
paste image 12, mx, my, 1
endif
if hresize = 1 and vresize = 1
paste image 13, mx, my, 1
endif
UpdateGuiContext()
sync
endwhile
DestructGuiContext()
`A Vista-Basic Messagebox
function VistaBasicMessageBox(text$, title$)
c = 0x77010101
img = 0x7c00
sync
get image img, 0, 0, screen width(), screen height(), 1
ready = 0
wndwidth = 320
wndheight = 200
wndx = (screen width() * 0.5) - (wndwidth * 0.5)
wndy = (screen height() * 0.5) - (wndheight * 0.5)
while ready = 0
paste image img, 0, 0, 0
box -1, -1, screen width(), screen height(), c, c, c, c
mc = mouseclick()
mx = mousex()
my = mousey()
g_GuiContext.m_MouseClick = mc
g_GuiContext.m_MouseX = mx
g_GuiContext.m_MouseY = my
if mc = 1
if drag = 0 and hresize = 0 and vresize = 0
if mx > wndx and my > wndy
if mx < wndx + wndwidth and my < wndy + 23
drag = 1
dragx = mx - wndx
dragy = my - wndy
endif
endif
`HResize
if mx > wndx + wndwidth - 7 and my > wndy + 23
if mx < wndx + wndwidth + 1 and my < wndy + wndheight + 1
hresize = 1
endif
endif
`VResize
if mx > wndx and my > wndy + wndheight - 7
if mx < wndx + wndwidth + 1 and my < wndy + wndheight + 1
vresize = 1
endif
endif
endif
else
drag = 0
hresize = 0
vresize = 0
endif
if drag = 1
wndx = mx - dragx
wndy = my - dragy
endif
if hresize = 1
wndwidth = mx - wndx + 2
if wndwidth < 120 then wndwidth = 120
if wndwidth > screen width() then wndwidth = screen width()
endif
if vresize = 1
wndheight = my - wndy + 2
if wndheight < 32 then wndheight = 32
if wndheight > screen height() then wndheight = screen height()
endif
cur = g_GuiContext.m_Cursor
if hresize = 1 and vresize = 0
cur = g_GuiContext.m_CursorH
endif
if hresize = 0 and vresize = 1
cur = g_GuiContext.m_CursorV
endif
if hresize = 1 and vresize = 1
cur = g_GuiContext.m_CursorHV
endif
DrawVistaBasicWindowFrame(wndx, wndy, wndwidth, wndheight)
DrawVistaBasicWindowClient(wndx, wndy, wndwidth, wndheight, 0xffc9c9c9)
DrawVistaBasicWindowCaption(wndx, wndy, wndwidth, wndheight, title$, 0)
inbound = mx > wndx + 8 and my > wndy + wndheight - 30 and mx < wndx + wndwidth - 8 and my < wndy + wndheight - 8
ready = mc and inbound and (hresize = 0) and (vresize = 0) and (drag = 0)
_PrepareClip(wndx + 7, wndy + 25, wndwidth - 14, wndheight - 32)
GuiDrawRect(1, 1, g_GuiContext.m_ClipWidth - 1, g_GuiContext.m_ClipHeight - 27, 0xffffffff)
if inbound = 0 and ready = 0 then tc = 0xff000000
if inbound = 1 and ready = 0 then tc = 0xff0000ff
if ready = 1 then tc = 0xff002266
GuiDrawText(16, g_GuiContext.m_ClipHeight - 23, "Click here to continue...", tc)
_PrepareClip(wndx + 7, wndy + 25, wndwidth - 14, wndheight - 61)
GuiDrawText(2, 2, text$, 0xff000000)
if cur > 0
if image exist(cur)
paste image cur, mx, my, 1
endif
endif
fastsync
endwhile
endfunction
`GUI context functions
function ConstructGuiContext()
g_GuiContext.m_MouseClick = 0
g_GuiContext.m_MouseX = 0
g_GuiContext.m_MouseY = 0
g_GuiContext.m_Cursor = 0
g_GuiContext.m_CursorH = 0
g_GuiContext.m_CursorV = 0
g_GuiContext.m_CursorHV = 0
g_GuiContext.m_CursorEdit = 0
g_GuiContext.m_Operation = 0
g_GuiContext.m_OpWindow = 0
g_GuiContext.m_MessageQueCount = 0
g_GuiContext.m_MessageQue = make memory(16 * 256) `256 message, each containing 16 bytes of data (4 integers)
g_GuiContext.m_Message.m_Window = 0
g_GuiContext.m_Message.m_Message = 0
g_GuiContext.m_Message.m_WParam = 0
g_GuiContext.m_Message.m_LParam = 0
for i = 0 to 0xffff
g_WindowList(i).m_Valid = 0
next i
endfunction
function DestructGuiContext()
delete memory g_GuiContext.m_MessageQue
g_GuiContext.m_MouseClick = 0
g_GuiContext.m_MouseX = 0
g_GuiContext.m_MouseY = 0
g_GuiContext.m_Cursor = 0
g_GuiContext.m_CursorH = 0
g_GuiContext.m_CursorV = 0
g_GuiContext.m_CursorHV = 0
g_GuiContext.m_CursorEdit = 0
g_GuiContext.m_Operation = 0
g_GuiContext.m_OpWindow = 0
g_GuiContext.m_MessageQueCount = 0
g_GuiContext.m_MessageQue = 0
g_GuiContext.m_Message.m_Window = 0
g_GuiContext.m_Message.m_Message = 0
g_GuiContext.m_Message.m_WParam = 0
g_GuiContext.m_Message.m_LParam = 0
for i = 0 to 0xffff
g_WindowList(i).m_Valid = 0
next i
endfunction
function UpdateGuiContext()
g_GuiContext.m_MouseClick = mouseclick()
g_GuiContext.m_MouseX = mousex()
g_GuiContext.m_MouseY = mousey()
if g_GuiContext.m_MouseClick = 0
g_GuiContext.m_Operation = 0
g_GuiContext.m_OpWindow = 0
endif
endfunction
`Event Que functions
function AddEvent(msg as sMessage)
_SetMemMessage(g_GuiContext.m_MessageQue, msg, g_GuiContext.m_MessageQueCount)
inc g_GuiContext.m_MessageQueCount
endfunction
function GetEvent()
if g_GuiContext.m_MessageQueCount <> 0
_GetMemMessage(g_GuiContext.m_MessageQue, g_GuiContext.m_MessageQueCount)
dec g_GuiContext.m_MessageQueCount
else
_GetMemMessage(g_GuiContext.m_MessageQue, 0)
endif
endfunction
function GetEventCount()
msgCount = g_GuiContext.m_MessageQueCount
endfunction msgCount
`Event data retrieval information
function GetEventWindow()
msgHandle = g_GuiContext.m_Message.m_Window
endfunction msgHandle
function GetEventMessage()
msgMessage = g_GuiContext.m_Message.m_Message
endfunction msgMessage
function GetEventWParam()
msgWParam = g_GuiContext.m_Message.m_WParam
endfunction msgWParam
function GetEventLParam()
msgLParam = g_GuiContext.m_Message.m_LParam
endfunction msgLParam
`Our beloved Vista-Basic themed window drawing function
function DrawVistaBasicWindow(wnd as sWindow)
DrawVistaBasicWindowFrame(wnd.m_PosX, wnd.m_PosY, wnd.m_Width, wnd.m_Height)
DrawVistaBasicWindowClient(wnd.m_PosX, wnd.m_PosY, wnd.m_Width, wnd.m_Height, wnd.m_ClientColor)
DrawVistaBasicWindowCaption(wnd.m_PosX, wnd.m_PosY, wnd.m_Width, wnd.m_Height, wnd.m_Text$, wnd.m_IconImg)
endfunction
`Draw individual components of a Vista Basic window
function DrawVistaBasicWindowFrame(x, y, width, height)
topc = rgb(152, 180, 208)
btmc = rgb(219, 231, 244)
solc = rgb(185, 209, 234)
bx0 = x + 2
by0 = y + 2
bx1 = bx0 + width - 4
by1 = by0 + height - 8
box bx0, by0, bx1 + 1, by1 + 1, btmc, topc, btmc, topc
box bx0, by1 + 1, bx1 + 1, y + height - 1, solc, solc, solc, solc
ink 0xff000000, 0
`Top
line x + 4, y, bx1 - 2, y
`Left side
line bx0, y + 1,bx0 + 2, y + 1
line x + 1, by0, x + 1, by0 + 2
line x, by0 + 2, x, y + height
dot x + 2, by0, 0xff777777
dot x + 2, by0+1, 0xffcccccc
dot x + 3, by0, 0xffcccccc
`Right side
line bx1 - 2, y + 1, bx1, y + 1
line x + width - 1, by0, x + width - 1, by0 + 2
line x + width, by0 + 2, x + width, y + height
dot bx1, by0, 0xff777777
dot bx1, by0+1, 0xffcccccc
dot bx1-1, by0, 0xffcccccc
`Bottom
line x, y + height, x + width, y + height
ink 0xffffffff, 0
`Top
line x + 4, y + 1, bx1 - 2, y + 1
`Left
line x + 1, y + 4, x + 1, y + height - 1
ink rgb(40, 207, 228), 0
`Bottom
line x + 1, y + height - 1, x + width - 1, y + height - 1
`Right
line x + width - 1, y + 4, x + width - 1, y + height - 1
endfunction
function DrawVistaBasicWindowClient(x, y, width, height, color)
if color <> 0
bx0 = x + 7
by0 = y + 25
bx1 = x + width - 7
by1 = y + height - 7
box bx0, by0, bx1, by1, color, color, color, color
endif
endfunction
function DrawVistaBasicWindowCaption(x, y, width, height, text$, iconimg)
ink 0xff000000, 0
exist = 0
if iconimg > 0
if image exist(iconimg)
exist = 1
endif
endif
_PrepareClip(x, y, width - 72, 25)
if exist = 1
paste image iconimg, x + 8, y + 5, 1
GuiDrawText(32, 5, text$, 0xff000000)
else
GuiDrawText(8, 5, text$, 0xff000000)
endif
posy = y
modex = 0
modemx = 0
modemn = 0
posx = x+width-32
if g_GuiContext.m_MouseX > posx and g_GuiContext.m_MouseY > posy
if g_GuiContext.m_MouseX < posx+25 and g_GuiContext.m_MouseY < posy + 18
modex = 1
if g_GuiContext.m_MouseClick = 1
modex = 2
endif
endif
endif
posx = posx - 20
if g_GuiContext.m_MouseX > posx and g_GuiContext.m_MouseY > posy
if g_GuiContext.m_MouseX < posx+20 and g_GuiContext.m_MouseY < posy + 18
modemx = 1
if g_GuiContext.m_MouseClick = 1
modemx = 2
endif
endif
endif
posx = posx - 20
if g_GuiContext.m_MouseX > posx and g_GuiContext.m_MouseY > posy
if g_GuiContext.m_MouseX < posx+20 and g_GuiContext.m_MouseY < posy + 18
modemn = 1
if g_GuiContext.m_MouseClick = 1
modemn = 2
endif
endif
endif
posx = posx + 40
DrawVistaBasicMinMaxButton(posx-38, posy, 20, 18, modemn)
DrawVistaBasicMinMaxButton(posx-19, posy, 20, 18, modemx)
DrawVistaBasicCloseButton(posx, posy, 25, 18, modex)
DoubleDrawChar(posx-32, posy+2, "_", 0xffffffff, 0x77010101)
DoubleDrawChar(posx-13, posy+2, "^", 0xffffffff, 0x77010101)
DoubleDrawChar(posx+9, posy+2, "X", 0xffffffff, 0x77010101)
endfunction
`Draw a Vista Basic button
function DrawVistaBasicCloseButton(x, y, width, height, mode)
tc0 = rgb(233, 169, 156)
bc0 = rgb(222, 146, 132)
tc1 = rgb(191, 84, 63)
bc1 = rgb(213, 133, 118)
bgc = rgb(184, 67, 44)
if mode = 1
tc0 = rgb(252, 200, 191)
bc0 = rgb(250, 164, 149)
bgc = rgb(210, 35, 2)
tc1 = rgb(213, 51, 13)
bc1 = rgb(250, 238, 107)
endif
if mode = 2
tc0 = rgb(207, 163, 139)
bc0 = rgb(195, 135, 110)
bgc = rgb(137, 25, 0)
tc1 = rgb(137, 44, 1)
bc1 = rgb(245, 236, 106)
endif
ink 0xff080808, 0
line x+1, y, x+width-1, y
line x, y+1, x, y+height-1
line x+width, y+1, x+width, y+height-1
line x+1, y+height, x+width-1, y+height
ink bgc, 0
box x+1, y+1, x+width, y+height
box x+1, y+1, x+width, y+7, bc0, tc0, bc0, tc0
box x+1, y+height-7, x+width, y+height, bc1, tc1, bc1, tc1
endfunction
function DrawVistaBasicMinMaxButton(x, y, width, height, mode)
tc0 = rgb(195, 232, 231)
bc0 = rgb(190, 231, 232)
tc1 = rgb(158, 183, 209)
bc1 = rgb(183, 208, 233)
bgc = rgb(152, 177, 204)
if mode = 1
tc0 = rgb(170, 213, 243)
bc0 = rgb(125, 190, 233)
bgc = rgb(45, 115, 163)
tc1 = rgb(44, 123, 175)
bc1 = rgb(36, 198, 235)
endif
if mode = 2
tc0 = rgb(127, 154, 172)
bc0 = rgb(90, 116, 138)
bgc = rgb(32, 59, 82)
tc1 = rgb(35, 98, 115)
bc1 = rgb(39, 201, 200)
endif
ink 0xff080808, 0
line x+1, y, x+width-1, y
line x, y+1, x, y+height-1
line x+width, y+1, x+width, y+height-1
line x+1, y+height, x+width-1, y+height
ink bgc, 0
box x+1, y+1, x+width, y+height
box x+1, y+1, x+width, y+7, bc0, tc0, bc0, tc0
box x+1, y+height-7, x+width, y+height, bc1, tc1, bc1, tc1
endfunction
function DoubleDrawChar(x, y, char$, foreground, background)
ink background, 0
text x-1, y-1, char$
text x+1, y-1, char$
text x-1, y+1, char$
text x+1, y+1, char$
text x-1, y, char$
text x+1, y, char$
text x, y-1, char$
text x, y+1, char$
ink foreground, 0
text x, y, char$
endfunction
`GUI Drawing Funcs
function GuiDrawPixel(x, y, color)
if _TestClip(x, y)
dot g_GuiContext.m_ClipX + x, g_GuiContext.m_ClipY + y, color
endif
endfunction
function GuiDrawLine(x, y, x2, y2, color)
if x < 1 then x = 0
if y < 1 then y = 0
if x2 > g_GuiContext.m_ClipWidth then x2 = g_GuiContext.m_ClipWidth
if y2 > g_GuiContext.m_ClipHeight then y2 = g_GuiContext.m_ClipHeight
ink color, 0
line g_GuiContext.m_ClipX + x, g_GuiContext.m_ClipY + y, g_GuiContext.m_ClipX + x2, g_GuiContext.m_ClipY + y2
endfunction
function GuiDrawRect(x, y, x2, y2, color)
if x < 1 then x = 0
if y < 1 then y = 0
if x2 > g_GuiContext.m_ClipWidth then x2 = g_GuiContext.m_ClipWidth
if y2 > g_GuiContext.m_ClipHeight then y2 = g_GuiContext.m_ClipHeight
ink color, 0
box g_GuiContext.m_ClipX + x, g_GuiContext.m_ClipY + y, g_GuiContext.m_ClipX + x2, g_GuiContext.m_ClipY + y2
endfunction
function GuiDrawText(x, y, text$, color)
tw = 0
length = len(text$)
g = 1
if length > 0
if _TestClip(x, y)
if text height(text$) < g_GuiContext.m_ClipHeight + 1
ink color, 0
for i = 1 to length
t$ = mid$(text$, i)
ttw = text width(t$)
if x + tw + ttw < g_GuiContext.m_ClipWidth and g = 1
text g_GuiContext.m_ClipX + x + tw, g_GuiContext.m_ClipY + y, t$
tw = tw + ttw
else
g = 0
endif
next i
endif
endif
endif
endfunction
`Default Window Func
remstart
function DefWindowFunc(Window, Message, wParam, lParam)
select Message
case WM_CREATE
g_WindowList(Window).m_ClientColor = 0xffc9c9c9
g_WindowList(Window).m_PosX = (screen width() * 0.5) - (g_WindowList(Window).m_Width * 0.5)
g_WindowList(Window).m_PosY = (screen height() * 0.5) - (g_WindowList(Window).m_Height * 0.5)
g_WindowList(Window).m_IconImg = 0
g_WindowList(Window).m_Valid = 1
endcase
`case WM_CLOSE
`DestroyWindow(Window)
`endcase
`WM_DESTROY (No need to process
case WM_MOVE
AddEvent(Window, WM_PAINT, 0, 0)
endcase
case WM_SIZE
AddEvent(Window, WM_PAINT, 0, 0)
endcase
case WM_PAINT
DrawVistaBasicWindowClient(g_WindowList(Window).m_PosX, g_WindowList(Window).m_PosY, g_WindowList(Window).m_Width, g_WindowList(Window).m_Height, g_WindowList(Window).m_ClientColor)
endcase
endselect
endfunction
remend
`Internal functions - THESE ARE OF NO USE TO YOU!
function _SetMem32(memPtr, memIndex, memValue)
memPtr = memPtr + (memIndex * 4)
*memPtr = memValue
endfunction
function _GetMem32(memPtr, memIndex)
memPtr = memPtr + (memIndex * 4)
xv = *memPtr
endfunction xv
function _SetMemMessage(memPtr, msg as sMessage, index)
pos = index * 4
_SetMem32(memPtr, pos, msg.m_Window)
_SetMem32(memPtr, pos + 1, msg.m_Message)
_SetMem32(memPtr, pos + 2, msg.m_WParam)
_SetMem32(memPtr, pos + 3, msg.m_LParam)
endfunction
function _GetMemMessage(memPtr, index)
pos = index * 4
g_GuiContext.m_Message.m_Window = _GetMem32(memPtr, pos)
g_GuiContext.m_Message.m_Message = _GetMem32(memPtr, pos + 1)
g_GuiContext.m_Message.m_WParam = _GetMem32(memPtr, pos + 2)
g_GuiContext.m_Message.m_LParam = _GetMem32(memPtr, pos + 3)
endfunction
function _TestClip(x, y)
res = 0
if x > -1 and y > -1
if x < g_GuiContext.m_ClipWidth and y < g_GuiContext.m_ClipHeight
res = 1
endif
endif
endfunction res
function _PrepareClip(x, y, w, h)
g_GuiContext.m_ClipX = x
g_GuiContext.m_ClipY = y
g_GuiContext.m_ClipWidth = w
g_GuiContext.m_ClipHeight = h
endfunction
Here's a screenshot showing the update... This should be self-explanatory.
Cheers,
-naota
"I'd newbie slap here, but I've no idea how far I'd need slap before they'd come back with a clue." - VanB
Aex.Uni forums