Silverfrost Forums

Welcome to our forums

Getting the handle of the button just clicked

21 Feb 2019 12:21 #23269

My issue: A large number of items that can either by typed in by hand, or selected from a list via a button click.

If it were just typed in, then I'd likely use a listview control. The button click is the issue. I'd like to get the window handle of the control (%lc) then use this value to identify which data item was being selected. What I do not see is a CLEARWIN_INFO@() parameter for the handle of the control that caused the callback function to be invoked.

Using CALL_BACK_WINDOW I get the handle of the parent window. I don't see anything in the HELP documentation that looks useful.

Any ideas, help?

Thanks, Bill

21 Feb 2019 1:00 #23270

'Never Mind'. I used the new function %ud to attach an index to the button, then get the index using CLEARWIN_INFO@('USER_DATA') and set the data appropriately.

Turned writing 40 nearly identical routines into writing two (one for each generic type in my data).

Great addition, Paul!

21 Feb 2019 6:53 #23271

The one you want is clearwin_info@('CURRENT_CONTROL'). This is not currently documented and I will fix that.

21 Feb 2019 3:11 #23272

Paul, thanks for this. I can also use this as well. I can see using this to change the color of a button when it is pressed, for example.

The addition of the %ud is a much better solution for this particular situation. I'd been working on this section of code for a while before the %ud was available, and suddenly realized my dream had already come true to attach data to a control!!

Mea maxima culpa. Bill

23 Feb 2019 2:22 #23275

This post caught my attention and I wondered if clearwin_info@('CURRENT_CONTROL') could be used to avoid having a separate call back for every %pl for a window with multiple %pl regions.

Yes it can, as the example below demonstrates.

module data_mod
implicit none
integer, parameter :: dp=kind(1.d0)
real(kind=dp) :: x1(1:10), y1(1:10), x2(1:10), y2(1:10)
integer(7) :: idplot1, idplot2
contains

  subroutine init_data
  integer i
    do i = 1,10,1 ; x1(i) = i ; end do
    x2=x1 ; y1=x1 ; y2=x2
  end subroutine init_data

  integer function plot()
  include<windows.ins>
  integer i
    call init_data
    i = winio@('%mn[Exit]&','exit')
    i = winio@('%fn[Tahoma]%bg[grey]&')
    i = winio@('%cn%ws&', 'Apply Left or Right Mouse Clicks in either pl region')
    call winop@('%pl[native,x_array,frame,gridlines]')
    i = winio@('%2nl%^pl&',400,250,10,x1,y1, pl_cb)
    i = winio@('%lc&', idplot1)
    call winop@('%pl[native,x_array,frame,gridlines]')
    i = winio@('%ta%^pl&',400,250,10,x2,y2, pl_cb)
    i = winio@('%lc&', idplot2)
    i = winio@(' ')
    plot = 1
  end function plot

  integer function pl_cb()
  include<windows.ins>
    if ( clearwin_string@('CALLBACK_REASON') .eq. 'MOUSE_LEFT_CLICK') then
      if ( clearwin_info@('CURRENT_CONTROL') .eq. idplot1 )  print *,'MOUSE_LEFT_CLICK in Left plot' 
      if ( clearwin_info@('CURRENT_CONTROL') .eq. idplot2 )  print *,'MOUSE_LEFT_CLICK in Right plot'
        
    else if ( clearwin_string@('CALLBACK_REASON') .eq. 'MOUSE_RIGHT_CLICK') then
      if ( clearwin_info@('CURRENT_CONTROL') .eq. idplot1 )  print *,'MOUSE_RIGHT_CLICK in Left plot' 
      if ( clearwin_info@('CURRENT_CONTROL') .eq. idplot2 )  print *,'MOUSE_RIGHT_CLICK in Right plot'
    end if
    
    pl_cb = 1
  end function pl_cb

end module data_mod

program test
use data_mod
implicit none
integer i
i = plot()
end program test
23 Feb 2019 3:03 #23276

I think this can work. Also, you might be able to use the %ud.

Using your first plot region as the example, instead of the %lc, you could use something similar to:

i = winio@('%ud&',1)

then in the call back use

 indx = clearwin_info@('USER_DATA')

to identify the specific plot area clicked upon.

It's the same idea. But, this allows you to use SELECT CASE to select which plotting region is being clicked on. You can't do that with the handle of the control.

If the returned USER_DATA is zero, then no value has been assigned. That is my experience with this new feature.

24 Feb 2019 8:31 #23277

Thank you, that works well.

Sample code for those who like to experiment.

module data_mod
implicit none
integer, parameter :: dp=kind(1.d0)
real(kind=dp) :: x1(1:10), y1(1:10), x2(1:10), y2(1:10)
contains

  subroutine init_data
  integer i
    do i = 1,10,1 ; x1(i) = i ; end do ; x2=x1 ; y1=x1 ; y2=0.1*x2**2
  end subroutine init_data

  integer function plot()
  include<windows.ins>
  integer i
    call init_data
    i = winio@('%mn[Exit]&','exit')
    i = winio@('%fn[Tahoma]%bg[grey]&')
    call winop@('%pl[native,x_array,frame,gridlines,title=1]')
    i = winio@('%2nl%^pl%ud&',400,250,10,x1,y1, cb, int(1,kind=7))
    call winop@('%pl[native,x_array,frame,gridlines,title=2]')
    i = winio@('%ta%^pl%ud&',400,250,10,x2,y2, cb, int(2,kind=7) )
    i = winio@('%ff%2nl%^bt[0]&', cb)
    i = winio@('%ta%^bt[3]%ud&', cb, int(3,kind=7))
    i = winio@('%ta%^bt[4]%ud%ta%^bt[5]%ud&', cb, int(4,kind=7), cb, int(5,kind=7))
    i = winio@(' ')
    plot = 1
  end function plot

  integer function cb()
  include<windows.ins>
  integer indx
    indx = clearwin_info@('USER_DATA')
    print *,indx
    cb = 1
  end function cb

end module data_mod

program test
use data_mod
implicit none
integer i
i = plot()
end program test
Please login to reply.