View previous topic :: View next topic |
Author |
Message |
wahorger
Joined: 13 Oct 2014 Posts: 1217 Location: Morrison, CO, USA
|
Posted: Sun Oct 14, 2018 5:28 pm Post subject: Address of data being modified by a control |
|
|
What way is best way to associate an address of data (specifically, character data, but extensible to others) with a control?
I ask this because I have different handlers doing the exact same task, but pointing to different data items. Yes, I could have separate callbacks, then invoke a common data handler using the specific data item in the call, but this kind of defeats the purpose of making the handler totally independent of the location of the data item itself.
I have two handlers to deal with similar data types. I want the user to enter numeric data into a single control as numeric fields separated by spaces. I want to attach a callback to see if all the data in the field is either a space or a digit. But only if I can access the character data field actually being modified. Luckily for me, the handler would only deal with character strings of identical length (i.e. if the control is 32 characters, it will always be 32 characters, regardless of where it might appear).
I can envision a very complex set of winio@() setup code to create a control and save the control window and LOC() of the data as the window is being built, but this is a complex solution to what might be a simple problem.
I've been through the documentation, searching for potential solutions, but don't see anything that looks good (except some of the vc() routines but they require a control ID number along with the window handle). If none exists, then so be it. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7931 Location: Salford, UK
|
Posted: Mon Oct 15, 2018 7:14 am Post subject: |
|
|
The first thing that comes to mind is to use the HWND (from %lc) of the control together with the Windows API functions SetWindowLong and GetWindowLong (with GWL_USERDATA). For 64 bits these become SetWindowLongPtr and GetWindowLongPtr with GWLP_USERDATA.
Let me know which type of control you wish to use so that I can check that ClearWin+ does not use this data point for its own purposes.
If this is of general interest then it may be possible to make this approach more user friendly for ClearWin+ users. |
|
Back to top |
|
|
John-Silver
Joined: 30 Jul 2013 Posts: 1520 Location: Aerospace Valley
|
Posted: Mon Oct 15, 2018 11:37 am Post subject: |
|
|
SETWINDOWLONG appears to have been first superceded by SETWINDOWLONGA, then more recently SETWINDOWLONGAPTR:
"Note This function has been superseded by the SetWindowLongPtr function. To write code that is compatible with both 32-bit and 64-bit versions of Windows, use the SetWindowLongPtr function."
REf. : https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setwindowlonga
(which to me is complete Double Dutch) (Note FK_GER ! )
Similarly for GETWINDOWLONG / A / APTR.
There's also a SETWINDOWLONGW.[/url] _________________ ''Computers (HAL and MARVIN excepted) are incredibly rigid. They question nothing. Especially input data.Human beings are incredibly trusting of computers and don't check input data. Together cocking up even the simplest calculation ... "
Last edited by John-Silver on Mon Oct 15, 2018 10:29 pm; edited 2 times in total |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7931 Location: Salford, UK
|
Posted: Mon Oct 15, 2018 1:20 pm Post subject: |
|
|
You use SetWindowLong in your program and this is translated to SetWindowLongA via INCLUDE <window.ins> or its equivalent.
Basically A is for ASCII characters and W is for "Wide" which means UNICODE. |
|
Back to top |
|
|
wahorger
Joined: 13 Oct 2014 Posts: 1217 Location: Morrison, CO, USA
|
Posted: Mon Oct 15, 2018 4:49 pm Post subject: |
|
|
Paul and Jon,
Thanks for the response!
Using SetWindowLong can certainly be used to attach a pointer to a control. I had seen something similar with the vc*() functions. I should have realized that there was a similar capability using MSWIN!
I intend to use this with %rs, %rd, %rf, %ls, and %lv controls. I have a dialog that allows the user to select an item from a list that is dynamically created from both %ls and %lv controls, then populate individual controls from that data in the list. It is this population after selection that will use the pointer to the data.
As an alternative, perhaps I could attach the address of a TYPE to the window itself, but only if %hw immediately returns the handle to the window/dialog being created.
I never have two instances of this window/dialog active at any time, so there are likely some other alternatives that can also be used with SetWindowLong and GETWINDOWLONG.
You both have given me some things to consider. I am interested to see if there are restrictions, Paul. Then, I'll work around them! |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7931 Location: Salford, UK
|
Posted: Tue Oct 16, 2018 7:19 am Post subject: |
|
|
I have given this some thought and it would be safer if ClearWin+ provided its own equivalent of GWL_USERDATA. If you can wait a week or two then I will see what can be done. |
|
Back to top |
|
|
wahorger
Joined: 13 Oct 2014 Posts: 1217 Location: Morrison, CO, USA
|
Posted: Tue Oct 16, 2018 2:23 pm Post subject: |
|
|
Paul, not a problem for me at all. Thanks for the consideration. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7931 Location: Salford, UK
|
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7931 Location: Salford, UK
|
Posted: Wed Oct 31, 2018 4:14 pm Post subject: |
|
|
Code: | WINAPP
program main
integer iw,winio@
character*1024 buffer
integer data1
integer,external::cb
data1 = 0
buffer = " "
iw = winio@("%ca[User data]&")
iw = winio@("%30.10^re&",buffer,cb)
iw = winio@("%ud&", loc(data1))
iw = winio@("%ff%nl%cn&")
iw = winio@("%10rd",data1)
end
integer function cb()
use clrwin
integer(7) addr
addr = clearwin_info@("USER_DATA")
core4(addr) = core4(addr)+1
cb = 1
end function |
|
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7931 Location: Salford, UK
|
Posted: Wed Oct 31, 2018 4:15 pm Post subject: |
|
|
Code: | WINAPP
program main
use clrwin
character*1024 buffer
integer iw,data1,ictrl
integer,external::cb
integer(7) hwnd
common hwnd
data1 = 0
buffer = " "
iw = winio@("%ca[User data]&")
iw = winio@("%30.10^re&",buffer,cb)
iw = winio@("%lc&", hwnd)
iw = winio@("%ff%nl%cn&")
iw = winio@("%10rd&",data1)
iw = winio@("%lw",ictrl)
call set_user_data@(hwnd, loc(data1))
end
integer function cb()
use clrwin
integer(7) addr,hwnd
common hwnd
addr = get_user_data@(hwnd)
core4(addr) = core4(addr)+1
cb = 1
end function |
|
|
Back to top |
|
|
wahorger
Joined: 13 Oct 2014 Posts: 1217 Location: Morrison, CO, USA
|
Posted: Wed Oct 31, 2018 5:49 pm Post subject: |
|
|
Nice, Paul! Thanks for the samples.
If I may put this in verbiage:
%ud assigns a user data field to the previous control, and the contents of the user data field is retrievable via clearwin_info@.
set_user_data@ and get_user_data@ allow the user to set and retrieve a user data field from a window.
Did I get it correct?
Thanks for the time and effort on this. It will be very useful to me (for sure) and others (I believe). |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7931 Location: Salford, UK
|
Posted: Wed Oct 31, 2018 6:21 pm Post subject: |
|
|
Yes. %ud works like %lc in this respect (using the previous control).
In this context, clearwin_info@ must only be called from a callback function for the corresponding control.
The two samples illustrate alternative approaches. Either approach can be used or the two can be mixed. |
|
Back to top |
|
|
wahorger
Joined: 13 Oct 2014 Posts: 1217 Location: Morrison, CO, USA
|
Posted: Wed Oct 31, 2018 9:16 pm Post subject: |
|
|
Thanks for verifying, Paul. I'll give it a go! |
|
Back to top |
|
|
wahorger
Joined: 13 Oct 2014 Posts: 1217 Location: Morrison, CO, USA
|
Posted: Thu Dec 13, 2018 4:16 pm Post subject: |
|
|
Paul, I've had a chance to play with these new capabilities. I have one question for you.
Can the same function be used to set the User Data for a window (or a dialog)? I can see that there may be some problem associated with this if ClearWin+ uses the User Data for the window or dialog for it's own purposes.
If the answer is yes it can be used, then at what point is the handle to the window (or dialog) created? For example: If I were to use the %hw, does this update the handle variable only AFTER the window is created, thus requiring %lw be used?
Bill |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7931 Location: Salford, UK
|
Posted: Thu Dec 13, 2018 4:37 pm Post subject: |
|
|
Bill
I would not recommend using GWL_USERDATA and SetWindowLongPtr in ClearWin+ programs. This data point may already be used or is reserved for future developments.
Something like %ud could be added for main windows (as at the moment for controls) if this was of general interest. |
|
Back to top |
|
|
|