while button pressed

Started by raymw, July 31, 2018, 09:16:57 PM

Previous topic - Next topic

José Roca

I must be missing something. Why he doesn't use an UpDown control?

Paul Squires

Quote from: José Roca on August 02, 2018, 01:40:58 PM
I must be missing something. Why he doesn't use an UpDown control?

Regardless of what control is used he will eventually run into the same problem that keeping the button down will block an Event handler from completing. He doesn't want to use a toggle approach of click On and then click Off.

I will post in a minute a thread version that works perfectly for this scenario.
Paul Squires
PlanetSquires Software

Paul Squires

Here you go. A VERY simple thread example that uses globals to indicate direction for the values (rather than using conditional signals). I am also not using mutexes because it is only one thread that only gets invoked once.


' You should always include a resource file that references a valid manifest.xml
' file otherwise your application will not properly display Windows themed controls.
' Sample resource.rc and manifest.xml files can be found in the WinFormsX download.
' The following WinFBE directive includes the resource in your application. If you
' are using WinFBE's project management features then omit the following line because
' one will be generated automatically.
'#RESOURCE "resource.rc"


''
''  Remove the following Application.Run code if it used elsewhere in your application.
Application.Run(Form1)


type ThreadTYPE
   pThread   as any ptr
   Direction as long      ' -1 down, 0 stop, +1 up
   bQuit     as Boolean
END TYPE
dim shared gtThread as ThreadTYPE


''
''
Sub WorkerThread( ByVal id_ptr As Any Ptr )
   dim as long nValue

   do until gtThread.bQuit
      if gtThread.Direction < 0 then
         nValue = val(Form1.TextBox1.text) - 1
         Form1.TextBox1.text = str(nValue)
      elseif gtThread.Direction > 0 then
         nValue = val(Form1.TextBox1.text) + 1
         Form1.TextBox1.text = str(nValue)
      end if   
      sleep 10  ' allow timeslice to switch
   loop   
End Sub


''
''
Function Form1_Load( ByRef sender As wfxForm, ByRef e As EventArgs) As LRESULT
   ' Create the worker thread
   gtThread.pThread = ThreadCreate(@WorkerThread, 0)
   if gtThread.pThread = 0 then print "Error creating thread"
   Function = 0
End Function


''
''
Function Form1_FormClosed( ByRef sender As wfxForm, ByRef e As EventArgs) As LRESULT
   ' Set boolean to exit out of thread loop
   gtThread.bQuit = true
   ' Wait for the worker thread to end and release its resources
   ThreadWait(gtThread.pThread)
   Function = 0
End Function

''
''
Function Form1_btnUp_MouseDown( ByRef sender As wfxButton, ByRef e As EventArgs) As LRESULT
   gtThread.Direction = +1
   Function = 0
End Function

''
''
Function Form1_btnUp_MouseUp( ByRef sender As wfxButton, ByRef e As EventArgs) As LRESULT
   gtThread.Direction = 0
   Function = 0
End Function

''
''
Function Form1_btnDown_MouseDown( ByRef sender As wfxButton, ByRef e As EventArgs) As LRESULT
   gtThread.Direction = -1
   Function = 0
End Function

''
''
Function Form1_btnDown_MouseUp( ByRef sender As wfxButton, ByRef e As EventArgs) As LRESULT
   gtThread.Direction = 0
   Function = 0
End Function


Paul Squires
PlanetSquires Software

raymw

Thanks Paul, I'll have a look. I've also found that 'jogger.startx.Text = format(millout,"#.0000")'  gives an error  message - error 42: variable not declared, format
Function jogger_Buttonx_Click( ByRef sender As wfxButton, ByRef e As EventArgs) As LRESULT
 
jogger.startx.Text = format(millout,"#.0000")
jogger.nowx.Text = jogger.startx.text
mainloop()
Function = 0
End Function


I put another button, to jump out of the up/down loop, and close the form and put the code into a subroutine named mainloop. Works OK, if I make form border style none, else still a chance of trying to close form via the normal window border x.

Paul Squires

Per the FB help, you need to include "string.bi" in order to use the Format command.

#include "string.bi"
result = Format[$]( numerical_expression, formatting_expression )

You will need to use the Thread method that I showed above. Any other approach will fail.


Paul Squires
PlanetSquires Software

raymw

Hi Paul, Thanks. even though it's simple, it is still too much to think about... I didn't/don't know much about threads, but looks as if it will be useful. So, if it's a separate core running a user thread, presumably it will not do much of the windows housekeeping, looking for the mouse, waiting for files to load, etc. That means it could be useful for what I thought I may have to use, instead of  either using micro processors or a rtos. I guess you can't include it in your visual designer - maybe open a separate properties window?

face slap wrt "string.bi"

raymw

Hi Paul, thanks for the threading sample, I've worked with it, and done some more development on my program but I've hit another button problem, perhaps best shown by the code below.
Three buttons, which when you press any one, it's highlighted, and stays highlighted until another of the three buttons are pressed. Using mouse down for each button seems to work as expected, setting the highlight and non-highlight background colours for the three buttons. I have introduced a fourth button but if that is pressed, then the last selected button colour is frozen, not changed by pressing one of the other three. (This is under your winfbe v 1.7.2)
''
''  Remove the following Application.Run code if it used elsewhere in your application.
Application.Run(Form1)


''
Function Form1_Button1_MouseDown( ByRef sender As wfxButton, ByRef e As EventArgs) As LRESULT
   form1.button1.BackColor = colors.Azure
  form1.button2.BackColor = colors.Azure
  form1.button3.BackColor = colors.Azure
   form1.button1.BackColor = colors.Aqua
   Function = 0
End Function

''
''
Function Form1_Button2_MouseDown( ByRef sender As wfxButton, ByRef e As EventArgs) As LRESULT
   form1.button1.BackColor = colors.Azure
  form1.button2.BackColor = colors.Azure
  form1.button3.BackColor = colors.Azure
   form1.button2.BackColor = colors.Aqua
  Function = 0
End Function

''
''
Function Form1_Button3_MouseDown( ByRef sender As wfxButton, ByRef e As EventArgs) As LRESULT
    form1.button1.BackColor = colors.Azure
   form1.button2.BackColor = colors.Azure
   form1.button3.BackColor = colors.Azure
   form1.button3.BackColor = colors.Aqua
   Function = 0
End Function

''
''
Function Form1_Button4_MouseDown( ByRef sender As wfxButton, ByRef e As EventArgs) As LRESULT
   Function = 0
End Function



after pressing the fourth button, I would expect pressing any of the other three would continue the highlighting behavior , in exactly the same way as if the fourth had not been pressed.

Paul Squires

This would be a button refresh issue. By default, when you change the backcolor of a button the refresh is not called. Maybe by default it should be. To fix your issue call a routine that refreshes your buttons like the following:

Also, why in your MouseDown are you setting the backcolor of a button twice? For example, for button1 mousedown you set it to Azure and then to Aqua all in the MouseDown?

Function Form1_Button1_MouseDown( ByRef sender As wfxButton, ByRef e As EventArgs) As LRESULT
   form1.button1.BackColor = colors.Azure
  form1.button2.BackColor = colors.Azure
  form1.button3.BackColor = colors.Azure
   form1.button1.BackColor = colors.Aqua
   Function = 0
End Function



' You should always include a resource file that references a valid manifest.xml
' file otherwise your application will not properly display Windows themed controls.
' Sample resource.rc and manifest.xml files can be found in the WinFormsX download.
' The following WinFBE directive includes the resource in your application. If you
' are using WinFBE's project management features then omit the following line because
' one will be generated automatically.
'#RESOURCE "resource.rc"


''
''  Remove the following Application.Run code if it used elsewhere in your application.
Application.Run(Form1)

function RefreshButtons() as Long
   form1.button1.Refresh
  form1.button2.Refresh
  form1.button3.Refresh
   function = 0
end function

''
Function Form1_Button1_MouseDown( ByRef sender As wfxButton, ByRef e As EventArgs) As LRESULT
   form1.button1.BackColor = colors.Azure
  form1.button2.BackColor = colors.Azure
  form1.button3.BackColor = colors.Azure
   form1.button1.BackColor = colors.Aqua
   RefreshButtons
   Function = 0
End Function

''
''
Function Form1_Button2_MouseDown( ByRef sender As wfxButton, ByRef e As EventArgs) As LRESULT
   form1.button1.BackColor = colors.Azure
  form1.button2.BackColor = colors.Azure
  form1.button3.BackColor = colors.Azure
   form1.button2.BackColor = colors.Aqua
  RefreshButtons
  Function = 0
End Function

''
''
Function Form1_Button3_MouseDown( ByRef sender As wfxButton, ByRef e As EventArgs) As LRESULT
    form1.button1.BackColor = colors.Azure
   form1.button2.BackColor = colors.Azure
   form1.button3.BackColor = colors.Azure
   form1.button3.BackColor = colors.Aqua
   RefreshButtons
   Function = 0
End Function

''
''
Function Form1_Button4_MouseDown( ByRef sender As wfxButton, ByRef e As EventArgs) As LRESULT
   RefreshButtons
   Function = 0
End Function

Paul Squires
PlanetSquires Software

José Roca

> This would be a button refresh issue.

I warned you. If you want I can add a call to the Refresh method in all these properties.

raymw

Thanks Paul, and and Jose. an auto refresh would be nice. I was, for the simplicity of cutting and pasting, setting the background twice. I can't see that should be a problem, but it actually does the colour change to aqua, its the not colour changing for the other buttons that is the snag. I'd actually experimented with dropping form refreshes in each function, I thought a refreshed form refreshed all its components. I'll refresh each button individually.

Best wuishes,

Ray

raymw

Now sorted, thanks.
''  Remove the following Application.Run code if it used elsewhere in your application.
Application.Run(Form1)

function refreshbuttons()  as long
        form1.button1.refresh
        form1.button2.refresh
        form1.button3.refresh
   
    function=0
END FUNCTION

function setback() as Long
  form1.button1.BackColor = colors.Azure
  form1.button2.BackColor = colors.Azure
  form1.button3.BackColor = colors.Azure
    function=0
END FUNCTION

''
Function Form1_Button1_MouseDown( ByRef sender As wfxButton, ByRef e As EventArgs) As LRESULT
   setback()
   form1.button1.BackColor = colors.Aqua
   refreshbuttons()
   Function = 0
End Function

''
''
Function Form1_Button2_MouseDown( ByRef sender As wfxButton, ByRef e As EventArgs) As LRESULT
   setback()
   form1.button2.BackColor = colors.Aqua
   refreshbuttons()
  Function = 0
End Function

''
''
Function Form1_Button3_MouseDown( ByRef sender As wfxButton, ByRef e As EventArgs) As LRESULT
   setback()
   form1.button3.BackColor = colors.Aqua
   refreshbuttons()
   Function = 0
End Function

''
''
Function Form1_Button4_MouseDown( ByRef sender As wfxButton, ByRef e As EventArgs) As LRESULT
   Function = 0
End Function

''
''
Function Form1_Load( ByRef sender As wfxForm, ByRef e As EventArgs) As LRESULT
    setback()
   refreshbuttons()

   Function = 0
End Function



(There is a trade off in key presses between cutting and pasting and writing a function and calling lines...)

José Roca

@Paul,

I have added a call to the Redraw method in the properties.

Paul Squires

Thanks Jose - I will integrate it into the code immediately.
Paul Squires
PlanetSquires Software

Paul Squires

Looks good. Everything seems to be working well with the new code.
Paul Squires
PlanetSquires Software