Example of a Spin Gadget

Share your advanced PureBasic knowledge/code with the community.
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Don.

PB doesn't directly provide a spin gadget - this is a gadget that has a little up & down arrow that typically lets you increase or decrease a numeric counter. It's not difficult to provide this in PB, so here's a procedure to create a spin gadget and an example of how to use it. The inline comments should provide all the info needed.

Code: Select all

; SPIN GADGET - PROCEDURE AND EXAMPLE
; ===================================
;
; Declare these constants at the top of your program
;
#ES_NUMBER = $2000
#EDIT = #WS_CHILD | #WS_VISIBLE | #ES_NUMBER
#UPDOWN = #WS_CHILD | #WS_VISIBLE | #WS_BORDER


; This is the procedure to create the Spin gadget.
; Note that a spin gadget is really an edit gadget (the part that
; contains the numbers/text) plus an up/down gadget (the up and down
; arrows) joined together. You need the WindowID (ie. the window handle)
; for both of these gadgets if you want to use the Spin Gadget.
;
; Arguments
; ---------
; xoff: x offset of the Spin Gadget from the top left of its parent window
; yoff: y offset of the Spin Gadget from the top left of its parent window
; width: width of whole Spin Gadget (ie. string gadget + up/down gadget)
; height: height of Spin Gadget
; minval: minimum value of the Spin Gadget
; maxval: maximum value of the Spin Gadget
; startval: initial value of the Spin Gadget
; *hud: the address of a longword into which the procedure returns the
;       WindowID of the up/down gadget.
; Procedure Return Value: the WindowID of the edit gadget

Procedure.l SpinGadget(xoff,yoff,width,height,minval,maxval,startval,*hud)
  hwnupdown.l
  If xoff    65535 : maxval=65535 : EndIf
  If startval > maxval Or startval > 16                   ; the value returned by the up/down gadget
      SendMessage_(hed,#WM_SETTEXT,0,Str(nPos))    ; update the edit gadget with the up/down value
      SetGadgetState(0,nPos)                       ; and update the progress bar too.
    EndIf
    If SendMessage_(hed,#EM_GETMODIFY,0,0)         ; user has typed a value in to the edit gadget 
      SendMessage_(hed,#WM_GETTEXT,4,a.s)          ; get the updated value that was typed in
      SendMessage_(hwnupdown,#UDM_SETPOS,0,Val(a)) ; update the up/down gadget with the new value
      SetGadgetState(0,Val(a))                     ; and update the progress bar.
      SendMessage_(hed,#EM_SETMODIFY,#FALSE,0)     ; clear the edit gadget's modify flag
    EndIf
  Until EventID = #PB_EventCloseWindow            ; exit when the window is closed

EndIf

End
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by fred.

This is a good example of the flexibility of PureBasic, thanks Don. Even tough, I've found some little stuffs:

- The edit gadget can be changed with a standard StringGadget(). It works (tested) and allow to use the standard commands on it.

- a.s = "" allocate a '0' sized string variable, so it MUST be changed to a.s = " " or somthing like that.

Bye,

Fred - AlphaSND
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Franco.
- The edit gadget can be changed with a standard StringGadget(). It works (tested) and allow to use the standard commands on it.
Well it didn't work with Win98.
The debugger says 'There is no current Gadgetlist'

I suppose the procedure has to move after the OpenWindow and CreateGadgetList command...


Have a nice day...
Franco
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by fred.
I suppose the procedure has to move after the OpenWindow and CreateGadgetList command...
You guess it

Fred - AlphaSND
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Don.

Fred - thanks for the comments. You've made me realise something important about PureBasic gadgets ....

You said I could use a PureBasic string gadget instead .... well I can only see that this is possible if you can get the window handle of the string gadget ..... and guess what, the documentation doesn't say it, but it seems that the PB gadget statements return the window handle! For example, create a string gadget like this & you'll get its handle returned in shwn

Code: Select all

shwn = StringGadget(0,20,20,35,20,"25")
This is VERY useful and makes things much easier. I can forget about the procedure above because the code now becomes so simple:

Code: Select all

#WINDOW_PARAMETERS = #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget
#UPDOWN = #WS_CHILD | #WS_VISIBLE | #WS_BORDER
 
hwmain=OpenWindow(0,100,100,310,85, #WINDOW_PARAMETERS ,"Spin Control Example")
InitGadget(2)
 
If hwmain
  If CreateGadgetList(WindowID())
    shwn = StringGadget(0,20,20,35,20,"25")
    uhwn = CreateUpDownControl_(#UPDOWN,55,20,10,20,WindowID(),1,GetModuleHandle_(#NULL),shwn,100,0,25)    
    ProgressBarGadget(1,80,20,200,20,0,100)
    SetGadgetState(1,25)
  EndIf
EndIf
 
Repeat
  EventID = WaitWindowEvent()
  If EventID = #WM_VSCROLL
    nPos = EventwParam() >> 16
    SetGadgetText(0,Str(nPos))
    SetGadgetState(1,nPos)
  EndIf
  If SendMessage_(shwn,#EM_GETMODIFY,0,0)
    a.s = GetGadgetText(0)
    SetGadgetState(1,Val(a))
    SendMessage_(uhwn,#UDM_SETPOS,0,Val(a))
    SendMessage_(shwn,#EM_SETMODIFY,#FALSE,0)
  EndIf
Until EventID = #PB_EventCloseWindow
 
End
(Hope this one works on Win98 Franco )
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Franco.
(Hope this one works on Win98 Franco )





Have a nice day...
Franco
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Don.

Hi Fangbeast

The >> operator isn't documented in the PB Help files, but I found it in the Popupmenu.pb example. It's a right bit shift ie. x >> 16 takes the value of x and shifts all its bits 16 places to the right. In the code, when a #WM_VSCROLL event happens, Windows automatically puts two separate 16 bit values into EventwParam. The top 16 bits is all we're interested in here as it contains the value of the updown control. So bit shifting by 16 pushes the bottom 16 bits out and effectively replaces them with the top 16.

To remove the progress bar, just get rid of anything to do with gadget id 1.

There are actually 2 parts to a spin gadget - the up down arrows and the little text gadget joined on the left. You can use standard PB functions to set the text gadget, but the updown control values are internally managed by Windows. All you need to do is to set the max, min and start values for the updown control - these are the last 3 arguments in CreateUpDownControl. You also need to set the initial value seen in the text gadget. Hope this all makes sense!

Here's the code to use a spin gadget, min value of 1, max value of 255 and start value of 1. For the rest of the code, some of my inline comments from the original code I posted might help.

Code: Select all

#WINDOW_PARAMETERS = #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget
#UPDOWN = #WS_CHILD | #WS_VISIBLE | #WS_BORDER

hwmain=OpenWindow(0,100,100,100,85, #WINDOW_PARAMETERS ,"Spin Control Example")
InitGadget(1)

If hwmain
  If CreateGadgetList(WindowID())
    shwn = StringGadget(0,20,20,35,20,"1")
    uhwn = CreateUpDownControl_(#UPDOWN,55,20,10,20,WindowID(),1,GetModuleHandle_(#NULL),shwn,255,1,1) 
  EndIf
EndIf

Repeat
  EventID = WaitWindowEvent()
  If EventID = #WM_VSCROLL
    nPos = EventwParam() >> 16
    SetGadgetText(0,Str(nPos))
  EndIf
  If SendMessage_(shwn,#EM_GETMODIFY,0,0)
    a.s = GetGadgetText(0)
    SendMessage_(uhwn,#UDM_SETPOS,0,Val(a))
    SendMessage_(shwn,#EM_SETMODIFY,#FALSE,0)
  EndIf
Until EventID = #PB_EventCloseWindow

End
Don
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Danilo.

Hey FangBeast !!

The problem is in the line:

Code: Select all

    uhwn = CreateUpDownControl_(#UPDOWN,55,20,10,20,WindowID(),1,GetModuleHandle_(#NULL),shwn,255,1,1)
WindowID() is the handle to the MainWindow.
Make a Frame3DGadget, and pass this window handle
to the CreateUpDownControl.

Code: Select all

hFrame3D = Frame3DGadget(....
    uhwn = CreateUpDownControl_(#UPDOWN,55,20,10,20,hFrame3D,1,GetModuleHandle_(#NULL),shwn,255,1,1)
cya,
...Danilo


(registered PureBasic user)
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Don.

Hi Fangbeast - yes you're right, there are problems trying to use the updown control within a panel gadget. I got the alignment to the panel gadget working OK using the panel gadget's handle in the call to CreateUpDownControl_. The y alignment wasn't quite right though as it offsets from the very top of the panel, so you need to add a bit on to correct for this.

Anyway, the real problem is that adding a gadget to a panel by using an API call (ie. CreateUpDownControl_)is not really a good thing to do with PB. PB is designed to use PB gadgets in panels. If you create an updown gadget in a panel which has more than one area, it'll appear in every 'AddGadgetItem' area! Trying to use the Windows API to manage what goes into each area on a panel is horribly complicated, so I think for now you can't use this spin gadget in a panel - we'll just have to wait for Fred to add a spin gadget to PB!

Don
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Danilo.

Heya Don !!

Use another Window for the UpDown-Control,
and it works fine.
Thats why i said you should use a
Frame3DGadget (or another PanelGadget)
on the Panel and put the UpDown-Gadget
inside this Window.

Code: Select all

hFrame3D = Frame3DGadget(....
uhwn = CreateUpDownControl_(#UPDOWN,55,20,10,20,hFrame3D,1,GetModuleHandle_(#NULL),shwn,255,1,1)
cya,
...Danilo

(registered PureBasic user)
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Don.

Thanks Danilo, I tried that & everything looks fine ... except that the event loop no longer responds to #WM_VSCROLL events. Couldn't get it working in a SetWindowCallback procedure either

Don
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Danilo.

Best thing is to inplement the new Gadget
in a little Library, but before you can
do that the right way, you need more Infos
about the PureBasic internals.

Fred wanted to write some text about
PB internals, so you can include the
new gadgets better to the other Gadget-
commands.

cya,
...Danilo

(registered PureBasic user)
Post Reply