statusbar text, colors, blinking, mouse events

Share your advanced PureBasic knowledge/code with the community.
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

statusbar text, colors, blinking, mouse events

Post by luis »

Windows only / PB4.31

This is based on the previous code http://www.purebasic.fr/english/viewtopic.php?t=38189 , but I added a simple ownerdraw to draw a field in a statusbar with fore and back color, and a timer to make it blink.

Can blink the normal way (text appears disappears) or the reverse way (fore/back color inverted).

So in the end you can draw text on the satusbar (you can choose the font too), make it blink, and intercept mouse clicks.

You can expand/modify this to suit your needs :)


Example of the calls

Code: Select all

    ; this call enable you to trap click events in the statusbar
    StatusBar_GrabClickEvents (hStatus, @CallBack_StatusBarClickEvents())

    
    ; black on white, right aligned
    StatusBar_SetText (hStatus, 0, FIELD ZERO, #Black, #White, #TEXT_EX_RIGHT)
    
    ; yellow on red, centered
    StatusBar_SetText (hStatus, 1, FIELD ONE, #Yellow, #Red, #TEXT_EX_CENTER)
    ; field 1 blinking in reverse (swapping colors)
    StatusBar_SetBlink (hStatus, 1, #TEXT_EX_BLINK_REVERSE)
    
    ; use #TEXT_EX_BLINK_OFF to stop the blink
    ;StatusBar_SetBlink (hStatus, 1, #TEXT_EX_BLINK_OFF)
    
    ; blue on cyan, centered
    StatusBar_SetText (hStatus, 2, FIELD TWO, #Blue, #Cyan, #TEXT_EX_CENTER)
    ; field 2 blinking normally (text visible  invisible)
    StatusBar_SetBlink (hStatus, 2, #TEXT_EX_BLINK_NORMAL)

    
    ; black on transparent (statusbar color), centered
    StatusBar_SetText (hStatus, 3, FIELD THREE, #Black, #TEXT_EX_TRANSPARENT, #TEXT_EX_CENTER)
    ; field 3 blinking normally (text visible  invisible)
    StatusBar_SetBlink (hStatus, 3, #TEXT_EX_BLINK_NORMAL)


    ; black on transparent (statusbar color), left aligned, font bold
    StatusBar_SetText (hStatus, 4, FIELD FOUR, #Black, #TEXT_EX_TRANSPARENT, #TEXT_EX_LEFT, FontID(nFontBold))
        
    
    ; set speed for blinking (the speed is the same for every field, default is 500 ms)
    StatusBar_SetBlinkSpeed(700)

constants

Code: Select all

; iBackColor
#TEXT_EX_TRANSPARENT    = -1

; iTextPos
#TEXT_EX_LEFT       = #DT_LEFT  #DT_VCENTER  #DT_SINGLELINE
#TEXT_EX_CENTER     = #DT_CENTER  #DT_VCENTER  #DT_SINGLELINE
#TEXT_EX_RIGHT      = #DT_RIGHT  #DT_VCENTER  #DT_SINGLELINE

; flgBlinkStatus
#TEXT_EX_BLINK_OFF      = 0
#TEXT_EX_BLINK_NORMAL   = 1
#TEXT_EX_BLINK_REVERSE  = 2
Last edited by luis on Tue Jul 21, 2009 3:41 pm, edited 1 time in total.
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Post by luis »

Statusbar.pbi

Code: Select all

; iBackColor
#TEXT_EX_TRANSPARENT    = -1

; iTextPos
#TEXT_EX_LEFT       = #DT_LEFT | #DT_VCENTER | #DT_SINGLELINE
#TEXT_EX_CENTER     = #DT_CENTER | #DT_VCENTER | #DT_SINGLELINE
#TEXT_EX_RIGHT      = #DT_RIGHT | #DT_VCENTER | #DT_SINGLELINE

; flgBlinkStatus
#TEXT_EX_BLINK_OFF      = 0
#TEXT_EX_BLINK_NORMAL   = 1
#TEXT_EX_BLINK_REVERSE  = 2

; internally used 

#_TEXT_EX_MAX_FIELDS           =  16
#_TEXT_EX_BLINK_SPEED_DEFAULT  =  500

#_TEXT_EX_BLINKING_OFF         = -1
#_TEXT_EX_BLINKING_STATE_A     =  0
#_TEXT_EX_BLINKING_STATE_B     =  1

Macro _LOWORD (word) 
 (word & $FFFF)
EndMacro

Macro _HIWORD (word) 
 ((word >> 16) & $FFFF) 
EndMacro

Procedure _SB_FreeString (*StringAddress)
 Protected String.String 
 PokeI (@String, *StringAddress)  
EndProcedure

Structure T_SB_TEXT_ITEM
 iField.i
 sText.s  
 iTextPos.i
 
 iForeColor.i
 iBackColor.i
 
 hFont.i
 
 flgBlinking.i
 flgBlinkStyle.i
EndStructure 

Structure T_SB_TEXT
 hStatus.i
 hTimer.i
 iBlinkSpeed.i
 *aiFields.T_SB_TEXT_ITEM[#_TEXT_EX_MAX_FIELDS]
EndStructure : Define tSB_TEXT.T_SB_TEXT


Procedure _SB_WinMain_Subclass (hWnd, Msg, wParam, lParam)
 Shared tSB_TEXT.T_SB_TEXT
 
 Protected *tSB_TEXT_ITEM.T_SB_TEXT_ITEM
 Protected *DrawItem.DRAWITEMSTRUCT, tRECT.RECT 
 Protected *oldWinProc = GetProp_(hWnd, "oldWinProc")
 Protected hStatus, hBrush
 Protected iTextPos, iForeColor, iBackColor, k
 Protected flgTransparent, flgSkipDraw
   
 Select Msg
 
    Case #WM_SIZING
        ; update status bar
        hStatus = tSB_TEXT\hStatus
        InvalidateRect_(hStatus, 0, 0) 
        UpdateWindow_(hStatus)
         
    Case #WM_NCDESTROY
        ; cleanup props        
        RemoveProp_(hWnd, "oldWinProc")
        
        ; destroy timer (if any)
        If tSB_TEXT\hTimer > 0
            KillTimer_(0, tSB_TEXT\hTimer)
        EndIf
        
        ; cleanup allocated structures
        For k = 0 To #_TEXT_EX_MAX_FIELDS - 1
            If tSB_TEXT\aiFields[k] > 0                
                _SB_FreeString(@tSB_TEXT\aiFields[k]\sText)                
                FreeMemory(tSB_TEXT\aiFields[k])
            EndIf
        Next                
    
    Case #WM_DRAWITEM        
        hStatus = tSB_TEXT\hStatus
        
        If wParam = GetDlgCtrlID_(hStatus)
            
            flgSkipDraw = #False
            
            *DrawItem = lParam
            *tSB_TEXT_ITEM = tSB_TEXT\aiFields[*DrawItem\itemData]
            
            iTextPos = *tSB_TEXT_ITEM\iTextPos

            iForeColor = *tSB_TEXT_ITEM\iForeColor
            
            iBackColor = *tSB_TEXT_ITEM\iBackColor
                        
            If iBackColor = #TEXT_EX_TRANSPARENT
                flgTransparent = #True
            Else
                flgTransparent = #False
            EndIf

            ; some margins
                    
            If *tSB_TEXT_ITEM\iField = 0
                *DrawItem\rcItem\left + 1
            EndIf

            *DrawItem\rcItem\right - 3

            
            If *tSB_TEXT_ITEM\flgBlinking <> #_TEXT_EX_BLINKING_OFF                 
                ; text blinking 
                
                Select *tSB_TEXT_ITEM\flgBlinkStyle
                
                    Case #TEXT_EX_BLINK_REVERSE                  
                        If *tSB_TEXT_ITEM\flgBlinking = #_TEXT_EX_BLINKING_STATE_B
                            Swap iForeColor, iBackColor
                        EndIf
                                            
                    Case #TEXT_EX_BLINK_NORMAL                    
                        If *tSB_TEXT_ITEM\flgBlinking = #_TEXT_EX_BLINKING_STATE_B                               
                            flgSkipDraw = #True
                        EndIf

                EndSelect             
            EndIf
            

            SetTextColor_(*DrawItem\hDC, iForeColor)
            
            If flgTransparent
                SetBkMode_(*DrawItem\hDC, #TRANSPARENT)
            Else
                SetBkMode_(*DrawItem\hDC, #OPAQUE)
                SetBkColor_(*DrawItem\hDC, iBackColor)
                
                hBrush = CreateSolidBrush_(iBackColor)                                
                FillRect_(*DrawItem\hDC, *DrawItem\rcItem, hBrush)
                DeleteObject_(hBrush)                                                                                                                         
            EndIf                    
                        
            If flgSkipDraw = #False            
                InflateRect_(*DrawItem\rcItem, -2, 0)
                
                If *tSB_TEXT_ITEM\hFont <> #Null
                    SelectObject_(*DrawItem\hDC, *tSB_TEXT_ITEM\hFont)
                EndIf
                
                DrawText_(*DrawItem\hDC, *tSB_TEXT_ITEM\sText, -1, *DrawItem\rcItem, iTextPos)
            EndIf


            ProcedureReturn 1
        EndIf
  EndSelect
  
  ; This will call the original winproc of the parent window or it will chain up 
  ; to the new winproc you have defined with SetWindowCallback() in PB
  
  ; In short: it's compatible with your own SetWindowCallback()
  
  ProcedureReturn CallWindowProc_(*oldWinProc, hWnd, Msg, wParam, lParam)   
EndProcedure 

Procedure _SB_StatusBar_Subclass (hWnd, Msg, wParam, lParam)
 Protected tRECT.RECT
 Protected k, X, Y
 Protected *fpFunc
 Protected *oldWinProc = GetProp_(hWnd, "oldWinProc")
 
 Select Msg

    Case #WM_NCDESTROY
        ; cleanup
        RemoveProp_(hWnd, "oldWinProc")
        RemoveProp_(hWnd, "callback")
 
    Case #WM_LBUTTONDBLCLK, #WM_RBUTTONDBLCLK, #WM_LBUTTONDOWN, #WM_RBUTTONDOWN
        X = _LOWORD (lParam) ; X mouse coordinates
        Y = _HIWORD (lParam) ; Y mouse coordinates
        *fpFunc = GetProp_(hWnd, "callback") ; callback address
        
        If *fpFunc > 0               
            While SendMessage_(hWnd, #SB_GETRECT, k, @tRECT)           
                If X < tRECT\right
                    ; call callback procedure
                    CallFunctionFast(*fpFunc, Msg, k, X, Y)
                    Break
                EndIf                                            
                k + 1
            Wend
        EndIf
  EndSelect
 
  ProcedureReturn CallWindowProc_(*oldWinProc, hWnd, Msg, wParam, lParam)   
EndProcedure

Procedure _SB_TimerEvent()
 Shared tSB_TEXT.T_SB_TEXT
 
 Protected k, nBlinkingCount
 
 For k = 0 To #_TEXT_EX_MAX_FIELDS - 1
    If tSB_TEXT\aiFields[k] > 0
        If tSB_TEXT\aiFields[k]\flgBlinking <> #_TEXT_EX_BLINKING_OFF
            ; something found
            nBlinkingCount + 1
            ; invert status
            If tSB_TEXT\aiFields[k]\flgBlinking = #_TEXT_EX_BLINKING_STATE_A
                tSB_TEXT\aiFields[k]\flgBlinking = #_TEXT_EX_BLINKING_STATE_B
            Else
                tSB_TEXT\aiFields[k]\flgBlinking = #_TEXT_EX_BLINKING_STATE_A
            EndIf        
        EndIf
    EndIf
 Next                

 If nBlinkingCount > 0
    ; maybe we could invalidate only a smaller region here ...
    ; but probabably it's not worth the effort
    InvalidateRect_(tSB_TEXT\hStatus, 0, 1) 
 Else 
    ; if there is no need for timer anymore ...
    KillTimer_(0, tSB_TEXT\hTimer)
    tSB_TEXT\hTimer = 0 ; fix
 EndIf
             
EndProcedure

Procedure StatusBar_GrabClickEvents (hWnd, *fpFunc)
 SetProp_(hWnd, "oldWinProc", GetWindowLongPtr_(hWnd, #GWL_WNDPROC))   
 SetProp_(hWnd, "callback", *fpFunc)
 SetWindowLongPtr_(hWnd, #GWL_WNDPROC, @_SB_StatusBar_Subclass()) 
EndProcedure

Procedure.i StatusBar_SetBlinkSpeed (iBlinkSpeed)
 Shared tSB_TEXT.T_SB_TEXT
 
 If iBlinkSpeed < 100
    iBlinkSpeed = 100
 ElseIf iBlinkSpeed > 1000
    iBlinkSpeed = 1000
 EndIf
 
 If iBlinkSpeed <> tSB_TEXT\iBlinkSpeed
    ; if speed changed
    
    If tSB_TEXT\hTimer > 0
        KillTimer_(0, tSB_TEXT\hTimer)
    EndIf
    
    tSB_TEXT\iBlinkSpeed = iBlinkSpeed
    
    tSB_TEXT\hTimer = SetTimer_(0, 0, tSB_TEXT\iBlinkSpeed, @_SB_TimerEvent())            
 EndIf
 
 If tSB_TEXT\hTimer = 0
    ProcedureReturn #False
 EndIf
 
 ProcedureReturn #True
EndProcedure

Procedure.i StatusBar_SetBlink (hStatus, iField, flgBlinkStatus)
 Shared tSB_TEXT.T_SB_TEXT
 
 If iField < 0 Or iField > #_TEXT_EX_MAX_FIELDS - 1 
    ; out of range
    ProcedureReturn #False
 EndIf
 
 If tSB_TEXT\aiFields[iField] = 0 
    ; field not initialized
    ProcedureReturn #False
 EndIf

 If flgBlinkStatus < #TEXT_EX_BLINK_OFF Or flgBlinkStatus > #TEXT_EX_BLINK_REVERSE  
    ProcedureReturn #False ; invalid blink style
 EndIf
 
 If (tSB_TEXT\aiFields[iField]\iBackColor = #TEXT_EX_TRANSPARENT) And (flgBlinkStatus = #TEXT_EX_BLINK_REVERSE)
    ProcedureReturn #False ; blink style not compatible with transparent background
 EndIf
 
 If flgBlinkStatus = #TEXT_EX_BLINK_OFF
    tSB_TEXT\aiFields[iField]\flgBlinking = #_TEXT_EX_BLINKING_OFF
    InvalidateRect_(hStatus, 0, 0) ; fix  
    ProcedureReturn #True
 EndIf
 
 tSB_TEXT\aiFields[iField]\flgBlinking = #_TEXT_EX_BLINKING_STATE_A 
 tSB_TEXT\aiFields[iField]\flgBlinkStyle = flgBlinkStatus
 
 If tSB_TEXT\hTimer = 0 ; first time
    If tSB_TEXT\iBlinkSpeed = 0
        tSB_TEXT\iBlinkSpeed = #_TEXT_EX_BLINK_SPEED_DEFAULT
    EndIf
    
    tSB_TEXT\hTimer = SetTimer_(0, 0, tSB_TEXT\iBlinkSpeed, @_SB_TimerEvent())
 
    If tSB_TEXT\hTimer = 0
        tSB_TEXT\aiFields[iField]\flgBlinking = #_TEXT_EX_BLINKING_OFF
        ProcedureReturn #False
    EndIf
 EndIf
 
 ProcedureReturn #True
 
EndProcedure

Procedure.i StatusBar_SetText (hStatus, iField, sText.s, iForeColor, iBackColor = #TEXT_EX_TRANSPARENT, iTextPos = #TEXT_EX_LEFT, hFont = #Null) 
 Shared tSB_TEXT.T_SB_TEXT
 
 Protected tSB_TEXT_ITEM.T_SB_TEXT_ITEM
 Protected hWnd = GetParent_(hStatus)
 
 
 If iField < 0 Or iField > #_TEXT_EX_MAX_FIELDS - 1 ; out of range
    ProcedureReturn #False
 EndIf
 
 If GetProp_(hWnd, "oldWinProc") = 0 ; first time only
    tSB_TEXT\hStatus = hStatus 
    SetProp_(hWnd, "oldWinProc", GetWindowLongPtr_(hWnd, #GWL_WNDPROC))   
    SetWindowLongPtr_(hWnd, #GWL_WNDPROC, @_SB_WinMain_Subclass())
 EndIf
 
 If tSB_TEXT\aiFields[iField] = 0 ; if it's the first time this field is referenced
    tSB_TEXT\aiFields[iField] = AllocateMemory(SizeOf(T_SB_TEXT_ITEM))
    
    If tSB_TEXT\aiFields[iField] = 0 ; out of memory
        ProcedureReturn #False
    EndIf

    ; first time init    
    With tSB_TEXT\aiFields[iField]
        \iField = iField
        \flgBlinking = #_TEXT_EX_BLINKING_OFF
    EndWith    
 EndIf
 
 
 ; these can be changed calling StatusBar_SetText() again
 With tSB_TEXT\aiFields[iField]
    \sText = sText 
    \iTextPos = iTextPos
    \iForeColor = iForeColor 
    \iBackColor = iBackColor        
    \hFont = hFont
 EndWith
  
 SendMessage_(hStatus, #SB_SETTEXT, iField | #SBT_OWNERDRAW, iField)
 
 ProcedureReturn #True
EndProcedure
Test program

Code: Select all

EnableExplicit

; *******************
; ****** TEST *******
; *******************

XIncludeFile "Statusbar.pbi"

Enumeration 
 #WIN_MAIN
 #SBG_STATUS
 #EDG_EDITOR
EndEnumeration

Procedure.s ControlGetFontName (hWnd)
 Protected tLOGFONT.LOGFONT 
 Protected hWrkFont, sFontName.s
 
 hWrkFont = SendMessage_(hWnd, #WM_GETFONT, 0, 0)
 
 If hWrkFont
    GetObject_(hWrkFont, SizeOf(LOGFONT), @tLOGFONT) 
    sFontName = PeekS(@tLOGFONT\lfFacename[0])
 EndIf
 
 ProcedureReturn sFontName
EndProcedure 

Procedure.i ControlGetFontSize (hWnd)
 Protected tLOGFONT.LOGFONT 
 Protected hWrkFont, iFontSize
 
 hWrkFont = SendMessage_(hWnd, #WM_GETFONT, 0, 0)
 
 If hWrkFont
    GetObject_(hWrkFont, SizeOf(LOGFONT), @tLOGFONT) 
    iFontSize = tLOGFONT\lfHeight: If iFontSize < 0: iFontSize = -iFontSize: EndIf
    iFontSize = iFontSize * 72.0 / GetDeviceCaps_(GetDC_(GetDesktopWindow_()), #LOGPIXELSY)
 EndIf

 ProcedureReturn iFontSize
EndProcedure 


Procedure CallBack_StatusBarClickEvents (iMessage, iField, iXPos, iYPos)
 SetActiveGadget(#EDG_EDITOR)   
 
 Select iMessage
    Case #WM_RBUTTONDOWN
        AddGadgetItem(#EDG_EDITOR, -1, "RMB clicked on " + Str(iField) + " at (" + Str(iXPos) + ", " + Str(iYPos) + ")")        
    Case #WM_LBUTTONDOWN
        AddGadgetItem(#EDG_EDITOR, -1, "LMB clicked on " + Str(iField) + " at (" + Str(iXPos) + ", " + Str(iYPos) + ")")
    Case #WM_LBUTTONDBLCLK
        AddGadgetItem(#EDG_EDITOR, -1, "LMB double clicked on " + Str(iField) + " at (" + Str(iXPos) + ", " + Str(iYPos) + ")")
    Case #WM_RBUTTONDBLCLK
        AddGadgetItem(#EDG_EDITOR, -1, "RMB double clicked on " + Str(iField) + " at (" + Str(iXPos) + ", " + Str(iYPos) + ")")        
 EndSelect
EndProcedure

Procedure CallBack_MainWindow (hWnd, Msg, wParam, lParam)
 
 Select Msg    
    Case #WM_ERASEBKGND
         InvalidateRect_(GadgetID(#EDG_EDITOR), 0, 0)
         UpdateWindow_(GadgetID(#EDG_EDITOR))
         ProcedureReturn 1
    Case #WM_SIZE
        ResizeGadget(#EDG_EDITOR, #PB_Ignore, #PB_Ignore, WindowWidth(#WIN_MAIN), WindowHeight(#WIN_MAIN)- StatusBarHeight(#SBG_STATUS))
 EndSelect
 
 ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure 

Procedure Main()

 Protected iEvent, hStatus, nFontBold
 
 If OpenWindow(#WIN_MAIN, 10, 10, 640, 480, "Main Window", #PB_Window_SystemMenu | #PB_Window_SizeGadget)
     
    hStatus = CreateStatusBar(#SBG_STATUS, WindowID(#WIN_MAIN))    
     
    AddStatusBarField(110) 
    AddStatusBarField(110) 
    AddStatusBarField(110) 
    AddStatusBarField(110) 
    AddStatusBarField(#PB_Ignore) ; autosize
    
    EditorGadget(#EDG_EDITOR, 0, 0, 640, 480 - StatusBarHeight(#SBG_STATUS))
    
    nFontBold = LoadFont(#PB_Any, ControlGetFontName(StatusBarID(#SBG_STATUS)), ControlGetFontSize(StatusBarID(#SBG_STATUS)), #PB_Font_Bold)
       
    ; this call enable you to trap click events in the statusbar
    StatusBar_GrabClickEvents (hStatus, @CallBack_StatusBarClickEvents())

    
    ; black on white, right aligned
    StatusBar_SetText (hStatus, 0, "FIELD ZERO", #Black, #White, #TEXT_EX_RIGHT)
    
    ; yellow on red, centered
    StatusBar_SetText (hStatus, 1, "FIELD ONE", #Yellow, #Red, #TEXT_EX_CENTER)
    ; field 1 blinking in reverse (swapping colors)
    StatusBar_SetBlink (hStatus, 1, #TEXT_EX_BLINK_REVERSE)
    
    ; use #TEXT_EX_BLINK_OFF to stop the blink
    ;StatusBar_SetBlink (hStatus, 1, #TEXT_EX_BLINK_OFF)
    
    ; blue on cyan, centered
    StatusBar_SetText (hStatus, 2, "FIELD TWO", #Blue, #Cyan, #TEXT_EX_CENTER)
    ; field 2 blinking normally (text visible / invisible)
    StatusBar_SetBlink (hStatus, 2, #TEXT_EX_BLINK_NORMAL)

    
    ; black on transparent (statusbar color), centered
    StatusBar_SetText (hStatus, 3, "FIELD THREE", #Black, #TEXT_EX_TRANSPARENT, #TEXT_EX_CENTER)
    ; field 3 blinking normally (text visible / invisible)
    StatusBar_SetBlink (hStatus, 3, #TEXT_EX_BLINK_NORMAL)


    ; black on transparent (statusbar color), left aligned, font bold
    StatusBar_SetText (hStatus, 4, "FIELD FOUR", #Black, #TEXT_EX_TRANSPARENT, #TEXT_EX_LEFT, FontID(nFontBold))
        
    
    ; set speed for blinking (the speed is the same for every field, default is 500 ms)
    StatusBar_SetBlinkSpeed(700)
            
    
    ; you can still use SetWindowCallback() if you need it
    SetWindowCallback (@CallBack_MainWindow())   
        
    
    Repeat 
        iEvent = WaitWindowEvent()           
    Until iEvent = #PB_Event_CloseWindow
    
    FreeFont(nFontBold)
 EndIf
 
EndProcedure

Main()
Last edited by luis on Tue Jul 21, 2009 6:07 pm, edited 1 time in total.
User avatar
DoubleDutch
Addict
Addict
Posts: 3220
Joined: Thu Aug 07, 2003 7:01 pm
Location: United Kingdom
Contact:

Post by DoubleDutch »

Nice. :)
https://deluxepixel.com <- My Business website
https://reportcomplete.com <- School end of term reports system
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Post by luis »

Hi, fixed a couple of bugs I found actually using the code.

! - When killed the timer because no blinking items are left, it's not possible to restart a new timer

! - If the blink for a field is deactivated the field is not immediately redrawn and can remain stucked in the second frame of the blink

The original code has been updated in the post (marked as ; fix)
User avatar
DoubleDutch
Addict
Addict
Posts: 3220
Joined: Thu Aug 07, 2003 7:01 pm
Location: United Kingdom
Contact:

Post by DoubleDutch »

Thanks for the fixes, I currently use my own solution for status bar stuff - but may use yours in the future. If I modify it to have some of the 'features' mine has then I'll post the update here for you. :)
https://deluxepixel.com <- My Business website
https://reportcomplete.com <- School end of term reports system
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Post by luis »

DoubleDutch wrote:If I modify it to have some of the 'features' mine has then I'll post the update here for you. :)
Thanks :)

Bye!
Post Reply