Nifty Fancy Window Code [Windows]
Posted: Sat Aug 11, 2012 1:53 am
I coded this to do exactly what I wanted it to. You can change it to however you'd like it. I have lots of ideas, but I just got this done and decided to post it because I don't know *WHEN* I'll get around to finishing it up enough to be called a "Library". But, it's very cool and very useful for little screen pops, or even pop up windows that a user needs to select something from. I have it set to go away if the mouse moves out of the window RECT, so that it doesn't interfere with work flow it you just need it to pop up a quick bit of info.
Code: Select all
;- Jelly Window Library
;- by Justin Jack
;- Use as you please
Structure MOVE_TO
x.i
y.i
cx.i
cy.i
cxAdjust.i
bounceback.i
iNumSteps.i
iStepCounter.i
iRemainder.i
bIsAnimating.b
changePerScoop.i
cAlpha.i
EndStructure
Structure JELLY_CONTROL_SET
iMouseInTimer.i
bMouseIn.b
moveto.MOVE_TO
EndStructure
Enumeration
#MOUSE_TIMER = 763
#ANIMATION_SHOW
EndEnumeration
Structure JELLY_WINDOW_INFO
hDcWnd.i
iJellyColor.i
iWindowBMP.i
hOldDcWnd.i
hOldBMP.i
numWindow.i
hRgn.i
*lpOldWndProc
control.JELLY_CONTROL_SET
EndStructure
Procedure Make_Jelly_Images_Window( w_Window )
If Not(IsWindow(w_Window))
If Not(IsWindow_(w_Window))
ProcedureReturn #False
Else
hWnd = w_Window
EndIf
Else
hWnd = WindowID(w_Window)
EndIf
*lpjiw.JELLY_WINDOW_INFO = GetWindowLongPtr_(hWnd, #GWLP_USERDATA)
oldRgn = *lpjiw\hRgn
btn_size.SIZE\cx = WindowWidth(*lpjiw\numWindow)
btn_size\cy = WindowHeight(*lpjiw\numWindow)
jelly_color = *lpjiw\iJellyColor
oldImage = *lpjiw\iWindowBMP
If btn_size\cx <= 0
btn_size\cx = 1
EndIf
*lpjiw\iWindowBMP = CreateImage(#PB_Any, btn_size\cx, btn_size\cy, 24)
StartDrawing(ImageOutput(*lpjiw\iWindowBMP))
Box(0, 0, btn_size\cx, btn_size\cy, jelly_color)
DrawingMode(#PB_2DDrawing_AlphaBlend)
RoundBox(0, 0, btn_size\cx, btn_size\cy, 20, 20, jelly_color)
DrawingMode(#PB_2DDrawing_Gradient|#PB_2DDrawing_AlphaBlend)
BackColor(RGBA(0, 0, 0, 130))
FrontColor(RGBA(0, 0, 0, 00))
LinearGradient(-10, 0, (btn_size\cx / 3), 0)
RoundBox(0, 0, btn_size\cx, btn_size\cy, 4, 4)
FrontColor(RGBA(0, 0, 0, 130))
BackColor(RGBA(0, 0, 0, 00))
LinearGradient(btn_size\cx - (btn_size\cx / 3), 0, (btn_size\cx + 10), 0)
RoundBox(0, 0, btn_size\cx, btn_size\cy, 4, 4)
FrontColor(RGBA($FF, $FF, $FF, 00))
BackColor(RGBA($FF, $FF, $FF, 150))
LinearGradient(0, 0, 0, (btn_size\cy / 3) * 2)
RoundBox(0, 0, btn_size\cx, btn_size\cy, 4, 4)
;DrawingMode(#PB_2DDrawing_Outlined)
;rr = 12
;RoundBox(0, 0, btn_size\cx - 1, btn_size\cy - 1,rr, rr, #Black)
StopDrawing()
*lpjiw\hRgn = CreateRoundRectRgn_(0, 0, WindowWidth(*lpjiw\numWindow), WindowHeight(*lpjiw\numWindow), 20, 20)
SetWindowRgn_(hWnd, *lpjiw\hRgn, 0)
SelectObject_(*lpjiw\hDcWnd, ImageID(*lpjiw\iWindowBMP))
DeleteObject_(oldRgn)
If IsImage(oldImage)
FreeImage(oldImage)
EndIf
EndProcedure
Procedure enFunc( hWnd, hDc )
Static ControlDC, OrigBmp, iCurrentBMP
If ControlDC = 0
hDcx = GetDC_(#Null)
ControlDC = CreateCompatibleDC_(hDcX)
iCurrentBMP = CreateCompatibleBitmap_(hDcx, 100, 100)
OrigBmp = SelectObject_(ControlDC, iCurrentBMP)
ReleaseDC_(#Null, hDcx)
EndIf
If hWnd <> 0
snName.s = Space(100)
GetClassName_(hWnd, @snName, 100)
If snName <> "SysHeader32"
GetWindowRect_(hWnd, @clrc.rect)
gp.POINT\x = clrc\left
gp\y = clrc\top
ScreenToClient_(GetParent_(hWnd), @gp)
xDiff = clrc\right - clrc\left
ydiff = clrc\bottom- clrc\top
clrc\left = gp\x
clrc\top = gp\y
clrc\right = gp\x + xDiff
clrc\bottom = gp\y + ydiff
iCurrentBMP = CreateCompatibleBitmap_(ControlDC, clrc\right - clrc\left, clrc\bottom - clrc\top)
DeleteObject_(SelectObject_(ControlDC, iCurrentBMP))
SendMessage_(hWnd, #WM_PRINT, ControlDC, #PRF_CLIENT|#PRF_NONCLIENT|#PRF_CHILDREN)
BitBlt_(hDc, clrc\left, clrc\top, clrc\right - clrc\left, clrc\bottom - clrc\top, ControlDC, 0, 0, #SRCCOPY)
EndIf
EndIf
ProcedureReturn hWnd
EndProcedure
Procedure jelly_window_wndproc( hWnd, uMsg, wParam, lParam )
*lpJwInfo.JELLY_WINDOW_INFO = GetWindowLongPtr_(hWnd, #GWLP_USERDATA)
If *lpJwInfo = 0
ProcedureReturn 0
EndIf
Select uMsg
Case #WM_TIMER
Select wParam
Case #MOUSE_TIMER
GetCursorPos_(@mt.POINT)
inRect = #False
If mt\x >= WindowX(*lpJwInfo\numWindow) And mt\x <= WindowX(*lpJwInfo\numWindow) + WindowWidth(*lpJwInfo\numWindow)
If mt\y >= WindowY(*lpJwInfo\numWindow) And mt\y <= (WindowY(*lpJwInfo\numWindow) + WindowHeight(*lpJwInfo\numWindow))
inRect = #True
EndIf
EndIf
If inRect = #False
SendMessage_(hWnd, #WM_CLOSE, 0, 0)
EndIf
Case #ANIMATION_SHOW
If *lpJwInfo\control\moveto\iStepCounter <= *lpJwInfo\control\moveto\iNumSteps
cX = WindowX(*lpJwInfo\numWindow)
cCx = *lpJwInfo\control\moveto\cx
cX = cX - 100
*lpJwInfo\control\moveto\iStepCounter + 1
SetLayeredWindowAttributes_(hWnd, #Null, *lpJwInfo\control\moveto\cAlpha, #LWA_ALPHA)
*lpJwInfo\control\moveto\cAlpha + *lpJwInfo\control\moveto\changePerScoop
If *lpJwInfo\control\moveto\iStepCounter = *lpJwInfo\control\moveto\iNumSteps
*lpJwInfo\control\moveto\cAlpha = 255
SetLayeredWindowAttributes_(hWnd, #Null, 255, #LWA_ALPHA)
KillTimer_(hWnd, #ANIMATION_SHOW)
SetTimer_(hWnd, #ANIMATION_SHOW, 20, #Null)
EndIf
SetWindowPos_(hWnd, #Null, cX, *lpJwInfo\control\moveto\y, cCx, *lpJwInfo\control\moveto\cy, #SWP_NOZORDER|#SWP_SHOWWINDOW|#SWP_NOSENDCHANGING|#SWP_NOREDRAW|#SWP_NOACTIVATE)
If *lpJwInfo\control\moveto\iStepCounter = 2
Make_Jelly_Images_Window(*lpJwInfo\numWindow)
hDc = GetDC_(hWnd)
BitBlt_(hdc, 0, 0, cCx, *lpJwInfo\control\moveto\cy, *lpJwInfo\hDcWnd, 0, 0, #SRCCOPY)
ReleaseDC_(hWnd, hdc)
InvalidateRect_(hWnd, 0, 1)
EndIf
justMoved = #True
Else
cX = WindowX(*lpJwInfo\numWindow)
cCx = *lpJwInfo\control\moveto\cx
If cX <> *lpJwInfo\control\moveto\x
If cX < *lpJwInfo\control\moveto\x
cX = cX + *lpJwInfo\control\moveto\bounceback
Else
cX = cX - 1
EndIf
cCx = *lpJwInfo\control\moveto\cx
SetWindowPos_(hWnd, #Null, cX, *lpJwInfo\control\moveto\y, cCx, *lpJwInfo\control\moveto\cy, #SWP_NOZORDER|#SWP_NOSENDCHANGING|#SWP_NOACTIVATE)
Else
KillTimer_(hWnd, #ANIMATION_SHOW)
*lpJwInfo\control\moveto\bIsAnimating = #False
done = #True
InvalidateRect_(hWnd, 0, 1)
EndIf
EndIf
If justMoved = #True
InvalidateRect_(hWnd, 0, 1)
EndIf
EndSelect
Case #WM_DESTROY
*lpOldWndProc = *lpJwInfo\lpOldWndProc
SetWindowLongPtr_(hWnd, #GWLP_WNDPROC, *lpOldWndProc)
ProcedureReturn CallWindowProc_(*lpJwInfo\lpOldWndProc, hWnd, uMsg, wParam, lParam)
Case #WM_MOUSEMOVE
If *lpJwInfo\control\moveto\bIsAnimating = #False
If *lpJwInfo\control\bMouseIn = #False
*lpJwInfo\control\bMouseIn = #True
SetTimer_(hWnd, #MOUSE_TIMER, 50, #Null)
EndIf
EndIf
Case #WM_ERASEBKGND
ProcedureReturn 1
Case #WM_WINDOWPOSCHANGED
If *lpJwInfo\control\moveto\bIsAnimating = #False
*lpwposc.WINDOWPOS = lParam
If (*lpwposc\flags & #SWP_NOSIZE) = 0
Make_Jelly_Images_Window( hWnd )
EndIf
EndIf
Case #WM_PAINT
BeginPaint_(hWnd, @ps.PAINTSTRUCT)
EnumChildWindows_(hWnd, @enFunc(), *lpJwInfo\hDcWnd)
BitBlt_(ps\hdc, ps\rcPaint\left, ps\rcPaint\top, ps\rcPaint\right - ps\rcPaint\left, ps\rcPaint\bottom - ps\rcPaint\top, *lpJwInfo\hDcWnd, ps\rcPaint\left, ps\rcPaint\top, #SRCCOPY)
;EnumChildWindows_(hWnd, @enFunc(), ps\hdc)
EndPaint_(hWnd, @ps)
ProcedureReturn 0
EndSelect
ProcedureReturn CallWindowProc_(*lpJwInfo\lpOldWndProc, hWnd, uMsg, wParam, lParam)
EndProcedure
Procedure Make_Jelly_Window( w_Window, iColor )
If Not(IsWindow(w_Window))
ProcedureReturn #False
EndIf
hWnd = WindowID(w_Window)
dwStyle = #WS_POPUP
dwExStyle = #WS_EX_TOOLWINDOW|#WS_EX_LAYERED
SetWindowLongPtr_(hWnd, #GWL_STYLE, dwStyle)
SetWindowLongPtr_(hWnd, #GWL_EXSTYLE, dwExStyle)
*lpjwi.JELLY_WINDOW_INFO = AllocateMemory(SizeOf(JELLY_WINDOW_INFO))
*lpjwi\iJellyColor = iColor
*lpjwi\lpOldWndProc = GetWindowLongPtr_(hWnd, #GWLP_WNDPROC)
*lpjwi\numWindow = w_Window
hdc = GetDC_(#Null)
*lpjwi\hDcWnd = CreateCompatibleDC_(hdc)
ReleaseDC_(#Null, hDc)
SetWindowLongPtr_(hWnd, #GWLP_USERDATA, *lpjwi)
SetWindowLongPtr_(hWnd, #GWLP_WNDPROC, @jelly_window_wndproc())
Make_Jelly_Images_Window(w_Window)
*lpjwi\hOldBMP = SelectObject_(*lpjwi\hDcWnd, ImageID(*lpjwi\iWindowBMP))
*lpjwi\hRgn = CreateRoundRectRgn_(0, 0, WindowWidth(w_Window), WindowHeight(w_Window), 20, 20)
SetWindowRgn_(hWnd, *lpjwi\hRgn, #False)
SetWindowPos_(hWnd, #Null, #Null, #Null, #Null, #Null, #SWP_NOZORDER|#SWP_NOSIZE|#SWP_NOMOVE)
ProcedureReturn *lpjwi\iWindowBMP
EndProcedure
Procedure Show_Jelly_Window( w_Window, x, y, cx, cy )
If Not(IsWindow(w_Window))
ProcedureReturn #False
EndIf
hWnd = WindowID(w_Window)
*lpjwi.JELLY_WINDOW_INFO = GetWindowLongPtr_(hWnd, #GWLP_USERDATA)
*lpjwi\control\moveto\bIsAnimating = #True
*lpjwi\control\moveto\x = x
*lpjwi\control\moveto\y = y
*lpjwi\control\moveto\cx = cx
*lpjwi\control\moveto\cy = cy
GetWindowRect_(GetDesktopWindow_(), @rcdt.RECT)
*lpjwi\control\moveto\iStepCounter = 1
*lpjwi\control\moveto\iNumSteps = ((rcdt\right - x) / 100) + 1
*lpjwi\control\moveto\iRemainder = Abs((rcdt\Right - x) - (*lpjwi\control\moveto\iNumSteps * 100))
*lpjwi\control\moveto\cxAdjust = (cx / *lpjwi\control\moveto\iNumSteps)
*lpjwi\control\moveto\bounceback = *lpjwi\control\moveto\iRemainder / 10
*lpjwi\control\moveto\changePerScoop = 205 / *lpjwi\control\moveto\iNumSteps
*lpjwi\control\moveto\cAlpha = 50
SetWindowPos_(hWnd, #Null, rcdt\right, y, 0, WindowHeight(*lpjwi\numWindow), #SWP_NOZORDER|#SWP_SHOWWINDOW)
SetLayeredWindowAttributes_(hWnd, #Null, 00, #LWA_ALPHA)
SetTimer_(hWnd, #ANIMATION_SHOW, 10, #Null)
EndProcedure
Procedure Create_Jelly_Window( cx, cy, iColor )
mWindow = OpenWindow(#PB_Any, 0, 0, 400, 200, "", #PB_Window_ScreenCentered|#PB_Window_SystemMenu|#PB_Window_Invisible)
StickyWindow(mWindow, 1)
Make_Jelly_Window(mWindow, iColor)
ProcedureReturn mWindow
EndProcedure
;- Test!
OpenWindow(1, 0, 0, 500, 500, "Test Window", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
ButtonGadget(1, 10, 10, 100, 20, "Click Me!")
Repeat
dwEvent = WaitWindowEvent()
If dwEvent = #PB_Event_Gadget
If EventGadget() = 1
If EventType() = #PB_EventType_LeftClick
If Not(IsWindow(jWindow))
jWindow = Create_Jelly_Window(300, 300, $CE7272)
TextGadget(#PB_Any, 10, 20, 280, 20, "To close me, move your mouse into, and out of me.", #PB_Text_Center)
StringGadget(3, 10, 50, 280, 20, "")
ButtonGadget(2, 10, 80, 280, 20, "Or click here!")
Show_Jelly_Window(jWindow, 500, 200, 300, 200)
SetActiveGadget(3)
EndIf
EndIf
ElseIf EventGadget() = 2
If EventType() = #PB_EventType_LeftClick
CloseWindow(EventWindow())
EndIf
EndIf
EndIf
If dwEvent = #PB_Event_CloseWindow
CloseWindow(EventWindow())
EndIf
Until dwEvent = #PB_Event_CloseWindow And EventWindow() = 1
End