Spin control

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
Robbie
User
User
Posts: 10
Joined: Fri Nov 11, 2005 9:57 am

Spin control

Post by Robbie »

Hi,

I was wondering why the proper Windows Spin control was not included in PureBasic? I think it looks a lot nicer than the one currently included...

Image

Is there any way to use the standard Windows one, or could this be included in PureBasic? I only need it for Windows. I don't know how it looks on MacOS, or Linux.

Thanks,
Robbie.
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 »

It's definitely a standard Windows Spin Control. If you want it to look like your picture, go to 'Compiler Options' and check 'Enable XP Skin Support'.
BERESHEIT
Robbie
User
User
Posts: 10
Joined: Fri Nov 11, 2005 9:57 am

Post by Robbie »

I've done that, but it still doesn't look right. In PureBasic, the Up/Down part of it is outside of the textbox, but in the Windows control, it's inside. I know I'm being picky, but I care a lot about how my application will look. :)

This image shows the difference...

Image

Robbie.
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

It's a bit of a hack and you may need to fine tune the geometry, but try this.

Code: Select all

If OpenWindow(0, 0, 0, 240, 70, "SpinGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0)) 
  Frame3DGadget(0, 10, 10, 107, 22, "", #PB_Frame3D_Flat)
  hBuddy = SpinGadget (1, 11, 11, 98, 20, 1, 100, #PB_Spin_Numeric) 
  hSpin = FindWindowEx_(WindowID(0), hBuddy, 0, 0) 
  SetWindowLong_(hBuddy, #GWL_EXSTYLE, GetWindowLong_(hBuddy, #GWL_EXSTYLE) &(~#WS_EX_CLIENTEDGE))
  SetWindowPos_(hBuddy, 0, 0, 0, 0, 0, #SWP_NOMOVE | #SWP_NOSIZE | #SWP_NOZORDER | #SWP_FRAMECHANGED)
  SetWindowPos_(hSpin, 0, 0, 0, 17, 20, #SWP_NOMOVE | #SWP_NOZORDER)
  SetGadgetState (1, 15) 
  SetGadgetText(1, "15") 
  Repeat 
    Event = WaitWindowEvent() 
  Until Event = #PB_Event_CloseWindow 
EndIf 
Other than that, you can also try the CreateUpDownControl_() API function to create your own. :wink:
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
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 »

Fair enough, it looks different. This looks the way you want, I hope:

Code: Select all

;================================================= 
;       Custom Spinner Control Demo 
;================================================= 

Procedure SubClass_Spin(hwnd, msg, wparam, lparam) 

  Protected OldProc = GetProp_(hwnd, "OldProc") 
  Protected String = GetProp_(hwnd, "String") 
  Protected min = GetProp_(hwnd, "Min") 
  Protected max= GetProp_(hwnd, "Max") 

  result = CallWindowProc_(OldProc, hwnd, msg, wparam, lparam) 
  Select msg 
    Case #WM_LBUTTONDOWN 
        If lparam >> 16 > 10 
          current = Val(GetGadgetText(String)) 
          If current > min 
            current -1 
            SetGadgetText(string, Str(current)) 
          EndIf 
        Else 
          current = Val(GetGadgetText(String)) 
          If current < max 
            current +1 
            SetGadgetText(string, Str(current)) 
          EndIf 
        EndIf 
    Case #WM_DESTROY 
      RemoveProp_(hwnd, "OldProc") 
      RemoveProp_(hwnd, "String") 
      RemoveProp_(hwnd, "Min") 
      RemoveProp_(hwnd, "Max") 
      SetWindowLong_(hwnd, #GWL_WNDPROC, OldProc)
  EndSelect 

  ProcedureReturn result 
  
EndProcedure 

Procedure CustomSpinner(GadgetNumber, x, y, width, min, max, initialvalue) 
  If GadgetNumber = #PB_Any 
    ctrlid = 1000 
    While IsGadget(ctrlid) 
      ctrlid + 1 
    Wend 
    GadgetNumber = ctrlid 
  EndIf 
  colr = ContainerGadget(#PB_Any,x-1,y-1,width+2,25,#PB_Container_BorderLess) 
  SetGadgetColor(colr,#PB_Gadget_BackColor, #Blue) 
  cont = ContainerGadget(#PB_Any,1,1,width,23,#PB_Container_BorderLess) 
  updn = CreateWindowEx_(0, "msctls_updown32", "", #WS_CHILD|#WS_VISIBLE, width-18,1,20,21,GadgetID(cont),GadgetNumber,GetModuleHandle_(0),0) 
  stringg = StringGadget(#PB_Any,5,5,width-25,20,"",#PB_String_BorderLess|#PB_String_ReadOnly) 
  CloseGadgetList():CloseGadgetList() 
  SetGadgetColor(cont,#PB_Gadget_BackColor, #White) 
  SetGadgetColor(stringg,#PB_Gadget_BackColor, #White)    
  SetGadgetText(stringg, Str(initialvalue)) 
  OldProc = SetWindowLong_(updn, #GWL_WNDPROC, @SubClass_Spin()) 
  SetProp_(updn, "OldProc", OldProc) 
  SetProp_(updn, "String", stringg) 
  SetProp_(updn, "Min", min) 
  SetProp_(updn, "Max", max) 
  ProcedureReturn stringg
EndProcedure 

If OpenWindow(0, 0, 0, 200, 170, "SpinGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0)) 
  spin = CustomSpinner(#PB_Any, 40,40,100,0,10,0) 
    ; GetGadgetText(spin) will produce the current state of the spinner
  Repeat 
    Event = WaitWindowEvent() 
    If Event = #PB_Event_Gadget 
      If EventGadget() = 0 
        SetGadgetText(0,Str(GetGadgetState(0))) 
      EndIf 
    EndIf 
  Until Event = #PB_Event_CloseWindow 
EndIf 
You can include the top two procedures in your code and it will call with one line as shown. Note that you don't set the height, it's always 25 for this one. You can tweak the numbers and make it less tall if you want.

OK Sparkie, what'd I forget? :D
Last edited by netmaestro on Fri Feb 09, 2007 7:16 am, edited 8 times in total.
BERESHEIT
Robbie
User
User
Posts: 10
Joined: Fri Nov 11, 2005 9:57 am

Post by Robbie »

Thanks for the suggestions. They both look a LOT better. Thank you!

I'll have a play around with them and see what I can come up with. :)

It still would be nice to have the 'proper one' built in. ;)

Thanks again,
Robbie.
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 »

Oops, I forgot to close my gadget lists. I always forget something. Best use the latest code, it's fixed now. That was a bad bug.
BERESHEIT
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

netmaestro wrote:OK Sparkie, what'd I forget?
Tell me more about the GetProp_() / SetProp_() functions. :?
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
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 »

What did I miss on those? I'm doing a RemoveProp_() on WM_DESTROY, afaik that's all they warn about.
BERESHEIT
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

No...seriously...Tell me more about the GetProp_() / SetProp_() functions. I've never used them before :?
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
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 »

It's a way of attaching specific data of your own choosing to a window handle that it can carry with it wherever it goes. It's invaluable for subclassing gadgets because you might want different parameters for multiple created instances of the gadget and the subclass procedure has to know which is which. Globals and linklists are clunky and awkward and far inferior to using window properties. The only proviso is that MS says that any properties you set have to be removed by you at WM_DESTROY because they won't remove them for you.

Also, because you're using strings, compiled libs should be produced with threadsafe versions for use in applications which use threads.
Last edited by netmaestro on Fri Feb 09, 2007 6:29 am, edited 2 times in total.
BERESHEIT
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Hmmm....I'll have to take a closer look tomorrow with fresh eyes and a fully charged brain. 8)

Thanks for the info...and nice job on the custom SpinGadget. :)
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

Post by Fluid Byte »

Why someone should use WindowProps if he could asign a pointer with SetWindowLong_() wich holds the data of a custom structure for example?
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
Post Reply