VistaClock II - a gadget for your gui

Developed or developing a new product in PureBasic? Tell the world about it.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

A new version of the VistaClock dll is available. It is a total rewrite, approaching the task from an entirely different angle. Gone is the need for directx, gone are the drawing problems for 16-bit desktops, and gone jumpiness in "floating desktop clock" implementations. Performance is, if I may say, close to perfect. And, touch wood, it should run everywhere, even on old junkers, with just the tiniest sip from the CPU. It doesn't even register above 0 on my machine. However, all this comes at a price. The dll is 390 kb in size, upx'd to the max. Ouch. But that's what it costs. I can't put out this kind of look and performance together for less. Here it is:

http://www.networkmaestro.com/vistaclock128.zip

and here's two example programs. The first one shows how to drop the gadget on a form, the second is a full working desktop clock:

Code: Select all

; Add a clock gadget to your gui

OpenWindow(0,0,0,320,240,"VistaClock",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
CreateGadgetList(WindowID(0))
ImageGadget(0,80,40,144,144,0)
OpenLibrary(0,"VistaClock128.dll")

CallFunction(0,"InitClock", RGB(224,223,227), 0) ; pass it your window color and 0 = no floating.

Repeat 
  EventID=WaitWindowEvent(1) 
 
  ret = CallFunction(0,"UpdateClock")
  If ret
    SetGadgetState(0,ret)
  EndIf
Until EventID=#PB_Event_CloseWindow 

Code: Select all

; Make a floating desktop clock

OpenWindow(0,0,0,144,144,"VistaClock",#PB_Window_BorderLess|#PB_Window_ScreenCentered|#PB_Window_Invisible)
SetWindowLong_(WindowID(0),#GWL_EXSTYLE,GetWindowLong_(WindowID(0),#GWL_EXSTYLE)|#WS_EX_LAYERED) 
SetLayeredWindowAttributes_(WindowID(0),0,0,1)
CreatePopupMenu(0)
MenuItem(0, "Close the VistaClock")
MenuItem(1, "Sticky")
SetMenuItemState(0,1,1)

Import "vistaclock128.lib"
  InitClock(color.l,floating.l)
  UpdateClock()
EndImport

InitClock(0,1) ;floating = true will look best for this job
HideWindow(0,0)
StickyWindow(0,1)

Repeat 
  EventID=WaitWindowEvent(1) 
  Select EventID
  Case #WM_LBUTTONDOWN 
    SendMessage_(WindowID(0), #WM_NCLBUTTONDOWN, #HTCAPTION, 0) 
  Case #WM_RBUTTONDOWN
    DisplayPopupMenu(0,WindowID(0))
  Case #PB_Event_Menu
    Select EventMenu()
      Case 0
        End
      Case 1
        If GetMenuItemState(0,1)
          SetMenuItemState(0,1,0)
          StickyWindow(0,0)
        Else
          SetMenuItemState(0,1,1)
          StickyWindow(0,1)
        EndIf
    EndSelect
  EndSelect
  ret = UpdateClock()
  If ret
    StartDrawing(WindowOutput(0))
      DrawImage(ret,0,0)
    StopDrawing()
  EndIf
Until EventID=#PB_Event_CloseWindow 
I should say a word here about the floating parameter for InitClock(). You pass windowcolor and either 1 for floating version or 0 for normal. The difference is that if you are displaying the clock on a window, 0=no floating will look best. If you're building a desktop clock that will float on its own, 1 will look best. It just controls whether a dark fringe gets drawn around the clock, which looks good against a window and crappy against light backgrounds like web surfing, etc.

Note: Resizing is done and works well, I just haven't included it in this release. If any bugs show up here, they'll be fixed and released with the resizable version.

Oh yes, I forgot, the InitClock() function will return 1 if all is ok, otherwise 0. So you can test it and go to plan B if the clock dll is gone for a sh**
BERESHEIT
mskuma
Enthusiast
Enthusiast
Posts: 573
Joined: Sat Dec 03, 2005 1:31 am
Location: Australia

Post by mskuma »

Hi Netmaestro - on my machine, the demo code using the DLL didn't work for me (window visible but no clock seen; loadlibrary returned non-zero & this time, initclock returned zero), but the the library version worked (initclock returned one). Looks excellent. Thanks alot! :)
josku_x
Addict
Addict
Posts: 997
Joined: Sat Sep 24, 2005 2:08 pm

Post by josku_x »

@mskuma: copy the vistaclock DLL into your purebasic /compilers/ folder. Does it work now?
mskuma
Enthusiast
Enthusiast
Posts: 573
Joined: Sat Dec 03, 2005 1:31 am
Location: Australia

Post by mskuma »

@josku_x: no it doesn't. I've tried providing the full path to the saved pb file & also to the compilers folder - same result. I think it's not a path issue since I get a non-zero return value, as I've indicated (suggesting DLL is found). If I purposely point it to the wrong path, I get a zero result (as expected).
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

What does it use if not DirectX?
And there is still a problem with the background colour when I add it to a window.

I don't know if this is on purpose but it's no longer see-through and no longer has antialiased edges.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Hi guys. mskuma, that is really interesting. I wonder if it's an issue for Fred to figure out, as I can't see a reason why Import should work and OpenLibrary fails. Odd for sure.

Trond, it is straight 2d drawing. When a minute is up it draws the clock face, hourhand and minutehand and when a second is up it draws the secondhand and the glass face. Unfortunately the seethrough clock face isn't something I'm going to try for anymore. Seethrough is reasonably easy to achieve, as are the highlights and shadowing you can get from alpha drawing. But try to combine the two and you're in for a fight. It is extremely difficult, and I could only manage it for the original VistaClock by taking screenshots of the background and using that for a texture. You can see for yourself the problems with that. It disappears briefly every time the screen behind it changes and it makes mistakes. See the difference by running the original Vistaclock in sticky mode, put the forum behind it and scroll up and down. Jump, jump, jump. Now try with the 2d drawing version. It shows perfect and totally ignores what's going on behind it. A much more professional presentation, I think. As far as the window transparency goes, are you passing your exact window color to InitClock? The example I posted works for my machine but if your window color is a bit different the code won't work as posted on the forum. The function needs your window color. I hope that's all it is anyway.
BERESHEIT
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

Oh sorry, I didn't see the color parameter.
User avatar
GeoTrail
Addict
Addict
Posts: 2794
Joined: Fri Feb 13, 2004 12:45 am
Location: Bergen, Norway
Contact:

Post by GeoTrail »

That is soo cool.
Works perfectly on my machine, and looks great too :)
Incredible work m8 :)
I Stepped On A Cornflake!!! Now I'm A Cereal Killer!
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Ack, found a bug where the hour hand disappeared from 12 noon to 1pm. Maybe it was getting some lunch. Anyways, fixed now. If you're using this you should re-download.
BERESHEIT
Dare2
Moderator
Moderator
Posts: 3321
Joined: Sat Dec 27, 2003 3:55 am
Location: Great Southern Land

Post by Dare2 »

netmaestro wrote:Maybe it was getting some lunch.
:lol:
@}--`--,-- A rose by any other name ..
akj
Enthusiast
Enthusiast
Posts: 668
Joined: Mon Jun 09, 2003 10:08 pm
Location: Nottingham

Post by akj »

Netmaestro:

Your zip file contains a .DLL file and a .LIB file.

I saw from a posting that the .DLL should reside in the folder ...\PureBasic \Compilers\ but where should the .LIB file reside?
Anthony Jordan
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

The .lib file must be available to the compiler, so it can be in the same folder with the sourcecode, as can the dll. The dll will have to be distributed with an application that you make if you distribute it, as it must be available to the program at runtime. I recommend using the Import approach as opposed to OpenLibrary, as it will automatically give the end user a nice message saying it is looking for that dll if it can't find it. Otherwise you'd have to program an error message yourself.

Actually I've already made the VistaClock128 commands into a userlibrary, dunno if people are interested having it that way or not. Then nothing has to be distributed with your exe.
BERESHEIT
akj
Enthusiast
Enthusiast
Posts: 668
Joined: Mon Jun 09, 2003 10:08 pm
Location: Nottingham

Post by akj »

Thanks for your reply, Netmaestro.
In it, you suggest that using Import is a good way to access VistaClock. My attempt at coding your first demo program using Import is:

Code: Select all

Import "VistaClock128.dll"
  InitClock.l(Colour.l, Floating.l)
  UpdateClock.l()
EndImport

OpenWindow(0,0,0,320,240,"VistaClock",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
CreateGadgetList(WindowID(0))
ImageGadget(0,80,40,144,144,0)

InitClock(RGB(224,223,227), 0) ; Pass it your window colour and 0 = no floating.

Repeat
  EventID=WaitWindowEvent(1)
  ret = UpdateClock()
  If ret
    SetGadgetState(0,ret)
  EndIf
Until EventID=#PB_Event_CloseWindow
However, when I compile the program, I get a POLINK fatal error:
Invalid machine type in object 'vistaclock128.dll'.
What am I doing wrong?
Anthony Jordan
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

You have to import the .lib, not the dll.
BERESHEIT
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Post by Flype »

yeah, that's good, thank you netmaestro.

just playing with it, and i must say that's easy to use.

here an example code (PB4 and XP) :

Code: Select all

; VistaClock II

EnableExplicit

Import "vistaclock128.lib" 
  InitClock(color.l, floating.l) 
  UpdateClock() 
EndImport

Macro MoveWindow(window)
  ReleaseCapture_()
  SendMessage_(WindowID(window), #WM_NCLBUTTONDOWN, #HTCAPTION, #Null) 
EndMacro

Macro AlphaWindow(window, color, alpha)
  SetWindowLong_(WindowID(window), #GWL_EXSTYLE, GetWindowLong_(WindowID(window), #GWL_EXSTYLE) | #WS_EX_LAYERED) 
  SetLayeredWindowAttributes_(WindowID(window), color, ((alpha)*255)/100, #LWA_COLORKEY | #LWA_ALPHA)
EndMacro

Define hClock.l

If OpenWindow(0, 0, 0, 160, 160, "VistaClock", #PB_Window_ScreenCentered|#PB_Window_BorderLess|#PB_Window_Invisible)
  
  SetWindowColor(0, #Green)
  StickyWindow(0, #True)
  AlphaWindow(0, #Green, 100)
  
  If CreateGadgetList(WindowID(0))
    InitClock(#Green, #True)
    ImageGadget(0, 0, 0, WindowWidth(0), WindowHeight(0), 0) 
  EndIf
  
  If CreatePopupMenu(0) 
    MenuItem(1, "Alpha, 25%") 
    MenuItem(2, "Alpha, 50%") 
    MenuItem(3, "Alpha, 75%") 
    MenuItem(4, "Alpha, 100%") 
    MenuBar()
    MenuItem(0, "Exit") 
  EndIf
  
  HideWindow(0, #False) 
  
  Repeat 
    Select WaitWindowEvent(25) 
      Case #PB_Event_Menu
        Select EventMenu()
          Case 1: AlphaWindow(0, #Green, 25)
          Case 2: AlphaWindow(0, #Green, 50)
          Case 3: AlphaWindow(0, #Green, 75)
          Case 4: AlphaWindow(0, #Green, 100)
          Case 0: Break
        EndSelect
      Case #PB_Event_CloseWindow
        Break
      Case #PB_Event_Gadget
        Select EventType()
          Case #PB_EventType_LeftClick:  MoveWindow(0)
          Case #PB_EventType_RightClick: DisplayPopupMenu(0, WindowID(0)) 
        EndSelect
      Case #Null
        hClock = UpdateClock() 
        If hClock 
          SetGadgetState(0, hClock) 
        EndIf
    EndSelect
  ForEver
  
EndIf

End
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
Post Reply