|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
DanRRight
Joined: 10 Mar 2008 Posts: 2815 Location: South Pole, Antarctica
|
Posted: Fri Oct 09, 2009 6:02 pm Post subject: |
|
|
Well...that was not easy...it's like going to Microsoft Windows programmers dirty internal kitchen ))
I've tried to extend your example above but still failed, clearly i do not understand something. Is there any example of using %mg? Without code sample the %mg description in the help file looks unfortunately like highly encrypted message. Reading its description below i felt completely lost at the WM_NOTIFY and already at the next sentence got very bad feeling reading about set_mg_return_value@
Ideally would be to see simplest working code snippet of using keyboard with %gr[full_mouse_input] which, say, is reacting on key for letter A or number 5 or left arrow from Windows messages
-------------------------
winio@(‘%mg’, msg_no, cb_func)
integer msg_no (input)
external cb_func
This format provides direct access to specified Windows messages. It should be used with care since it is possible to interfere with other ClearWin+ processing.
msg_no is the message number of the message to be processed. User numbers should begin at WM_USER +1000. cb_func is the call-back function that is to be called when the message is received. The call-back function can use clearwin_info@ with the strings 'MESSAGE_HWND', 'MESSAGE_WPARAM', and 'MESSAGE_LPARAM' in order to get the standard arguments for a Windows call-back function.
When writing the %mg call-back function, use a return value of 3 if you want ClearWin+ to apply the default processing of the message msg_no. Other values have the usual effect (zero closes the window etc.) but cause the default processing to be bypassed. Occasionally the internal Windows dialog procedure that processes messages requires a particular return other than the default value which is zero (e.g. under certain conditions when using WM_NOTIFY). In this case you should make a call to the subroutine set_mg_return_value@ before returning. This subroutine takes one integer argument which is the value to be returned by the internal Windows dialog procedure. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7924 Location: Salford, UK
|
Posted: Fri Oct 09, 2009 6:52 pm Post subject: |
|
|
OK I will aim to put together some sample code when I get a minute. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7924 Location: Salford, UK
|
Posted: Sat Oct 10, 2009 8:58 am Post subject: |
|
|
Here is a program that uses a %gr area and allows you to type into the status bar.
Code: | winapp
c---------------------------------------------------------------
include <windows.ins>
integer i,gr_func,mg_func
external gr_func,mg_func
character*40 cstat
common cstat
cstat=' '
i=winio@('%ww[no_border]&')
i=winio@('%ca[Sample]&')
i=winio@('%mn[E&xit]&','EXIT')
i=winio@('%ob&')
i=winio@('%mg&', WM_KEYDOWN, mg_func)
i=winio@('%^gr[black,full_mouse_input]&',300,300,gr_func)
i=winio@('%cb%ob[status]%20st%cb',cstat)
end
c-----------------------------------------------------------
integer function mg_func()
include <windows.ins>
integer wparam,i
save i
character*40 cstat
common cstat
wparam=clearwin_info@("MESSAGE_WPARAM")
if(wparam==8 .and. i>0)then
cstat(i:i)=' '
i=i-1
call window_update@(cstat)
else if(wparam > 31 .and. wparam < 127)then
if(and(GetKeyState(VK_SHIFT),Z'80') == 0)then
wparam=wparam+ichar('a')-ichar('A')
endif
i=i+1
cstat(i:i)=char(wparam)
call window_update@(cstat)
endif
mg_func=1
end
c-----------------------------------------------------------
integer function gr_func()
c Process mouse keys here
gr_func=1
end
c-----------------------------------------------------------
|
|
|
Back to top |
|
|
DanRRight
Joined: 10 Mar 2008 Posts: 2815 Location: South Pole, Antarctica
|
Posted: Sat Oct 10, 2009 9:06 pm Post subject: |
|
|
Holly shmolly...thanks for the example, i'd crash before finding this solution. But we have to admit, the solution is kind of antiintuitive. I still do not understand how this line works
i=winio@('%mg&', WM_KEYDOWN, mg_func)
And since all the warnings about %mg is also such specific callback content important? This is because as to the keys generated, the get_wkey@ or get_wkey1@ look more familiar for Salford/Silverfrost compiler users then wparam which not everywhere coincides with key and seems misses arrow keys. All in all is the code below without clearwin_info@ etc calls legitimate? Seems it works fine...
Code: |
winapp
c---------------------------------------------------------------
include <windows.ins>
integer gr_func,mg_func
external gr_func,mg_func
character*40 cstat
common cstat
cstat=' '
i=winio@('%ww[no_border]&')
i=winio@('%ca[Sample]&')
i=winio@('%mn[E&xit]&','EXIT')
i=winio@('%ob&')
i=winio@('%mg&', WM_KEYDOWN, mg_func)
i=winio@('%^gr[black,full_mouse_input]&',300,300,gr_func)
i=winio@('%cb%ob[status]%20st%cb',cstat)
end
c-----------------------------------------------------------
integer function mg_func()
include <windows.ins>
integer wparam,i
character*40 cstat
common cstat
integer key, get_wkey@
save i
data i/0/
i=i+1
key=get_wkey@()
cstat(i:i)= char(key)
call window_update@(cstat)
if(i > 39) i=0
mg_func=1
end
c-----------------------------------------------------------
integer function gr_func()
c Process mouse keys here
gr_func=1
end
c-----------------------------------------------------------
|
Please don't forget to include your sample in the Examples and in the Help - allowing keyboard and full mouse simultaneously is important design feature. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7924 Location: Salford, UK
|
Posted: Sun Oct 11, 2009 9:44 am Post subject: |
|
|
I am not sure that your code will always work but it is an interesting approach.
The difference is that get_wkey@ takes the value from a buffer whilst WM_KEYDOWN responds the the current key stroke. Maybe if you included a way to clear the buffer then the two would be equivalent and yours would be the simpler approach. |
|
Back to top |
|
|
DanRRight
Joined: 10 Mar 2008 Posts: 2815 Location: South Pole, Antarctica
|
Posted: Fri Oct 16, 2009 3:24 am Post subject: |
|
|
As i wrote before i still do not understand how this code works. What specifically do you mean with cleaning the buffer, why it is needed and how it can be done?
Does %mg following any changes in WM_KEYDOWN (and this variable seems tracks any keyboard presses in Windows) and if it sees change in WM_KEYDOWN it calls call-back function? is this how it works?
I was testing this approach for a while and initially all was ok as well as it is seems ok with the small example i wrote above. But installing it into large code i found recently it stopped to work properly. I have to push button several times to get action. Could be other bug, the code is almost out of damn 32-bit OS stack limit 1.6GB ... |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7924 Location: Salford, UK
|
Posted: Fri Oct 16, 2009 8:01 am Post subject: |
|
|
Basically you need to get some idea of how the Windows messaging works particularly via the Windows API SendMessage. %mg provides a way for ClearWin+ to pick up a message (in this case a key down message) and pass it on to you the user. So if you look up SendMessage and find out what is delivered with the ID WM_KEYDOWN then you will see how the parameters wparam and lparam are used for this message.
The traditional way of handling keyboard input was to put the actions into a buffer so that programs could pick up the information via a sutable read buffer function. A number of key strokes can thus be stored before a program starts to get them. get_wkey@ either emulates this kind of buffer or uses an existing one provided by the system (the former I think).
What I was trying to say was that there is a possiblitily for a particular WM_KEYDOWN to get out of sync with the first key in the keyboard buffer, in which case the wparam info will not match the result of the call to get_wkey@. |
|
Back to top |
|
|
DanRRight
Joined: 10 Mar 2008 Posts: 2815 Location: South Pole, Antarctica
|
Posted: Sun Oct 18, 2009 5:15 pm Post subject: |
|
|
I will put this into followup and investigate how both methods differ later after resolving more serious issue -- why my code above stopped working when placed in the larger code which is balancing near the limit of another "buffer" - stack size approaching now 1.4GB almost nothing leaving for the code (here even debugger sometimes hiccups showing A = 0 in the equation A = B + C with B>0 and C>0 requiring Windows reboot)
Yes, handling keyboard could sometimes be tricky. In regards of your initial code example on the first page of this thread with full_mouse_input: is there any way in Clearwin to handle mouse scroll wheel ? |
|
Back to top |
|
|
JohnHorspool
Joined: 26 Sep 2005 Posts: 270 Location: Gloucestershire UK
|
|
Back to top |
|
|
DanRRight
Joined: 10 Mar 2008 Posts: 2815 Location: South Pole, Antarctica
|
Posted: Sun Oct 18, 2009 11:51 pm Post subject: |
|
|
Thanks...I've made this small addition to the code above to demonstrate it, please check if this is how wheel supposed to work?
Code: |
!
! compile FTN95 filename.f95 /link
!
!---------------------------------------------------------------
include <windows.ins>
integer gr_func,mg_func
external gr_func,mg_func
character*40 cstat
common cstat
integer, parameter:: WM_MOUSEWHEEL = Z'020A'
integer OnMouseWheel
external OnMouseWheel
cstat=' '
i=winio@('%ww[no_border]&')
i=winio@('%ca[Sample]&')
i=winio@('%mn[E&xit]&','EXIT')
i=winio@('%ob&')
i=winio@('%mg&', WM_KEYDOWN, mg_func)
i=winio@('%mg&', WM_MOUSEWHEEL, OnMouseWheel)
i=winio@('%^gr[black,full_mouse_input]&',300,300,gr_func)
i=winio@('%cb%ob[status]%20st%cb',cstat)
end
!-----------------------------------------------------------
integer function mg_func()
include <windows.ins>
integer wparam,i
character*40 cstat
common cstat
integer key, get_wkey@
save i
data i/0/
i=i+1
key=get_wkey@()
cstat(i:i)= char(key)
call window_update@(cstat)
if(i > 39) i=0
mg_func=1
end
!-----------------------------------------------------------
integer function OnMouseWheel()
use mswin
integer wparam
wparam = clearwin_info@('MESSAGE_WPARAM')
wheel_rot = HIWORD@(wparam) / 120 ! rotations reported as *120
print*,'wheel_rot=',wheel_rot
OnMouseWheel=1
end function OnMouseWheel
!-----------------------------------------------------------
integer function gr_func()
! Process mouse keys here
gr_func=1
end
|
|
|
Back to top |
|
|
JohnHorspool
Joined: 26 Sep 2005 Posts: 270 Location: Gloucestershire UK
|
Posted: Mon Oct 19, 2009 7:55 am Post subject: |
|
|
Dan, yes, rightly or wrongly that's how I use it. I don't find the actual value reported is much use, so I just check for a negative or positive value and act on that. |
|
Back to top |
|
|
DanRRight
Joined: 10 Mar 2008 Posts: 2815 Location: South Pole, Antarctica
|
Posted: Tue Oct 20, 2009 4:02 am Post subject: |
|
|
OK. And it shows larger values then +1 and -1 when you move it fast, like 6-7, right? I am trying to understand if this hidden trickery is PC specific, mouse driver specific or OS specific... |
|
Back to top |
|
|
JohnHorspool
Joined: 26 Sep 2005 Posts: 270 Location: Gloucestershire UK
|
Posted: Tue Oct 20, 2009 7:59 am Post subject: |
|
|
Dan, you must have quicker fingers than me, if I try really hard I might get a 4 !
I don't think this is important though, for every ratchet on the scroll wheel I get a returned value, so simply the more you rotate the wheel the more returns you see, I think that this is sufficient for a continuous zoom in/out effect on a graphics screen for instance. |
|
Back to top |
|
|
DanRRight
Joined: 10 Mar 2008 Posts: 2815 Location: South Pole, Antarctica
|
Posted: Sun Oct 25, 2009 5:28 pm Post subject: |
|
|
Just make your mouse and keyboard a bit faster then in default settings, John |
|
Back to top |
|
|
aebolzan
Joined: 06 Jul 2007 Posts: 229 Location: La Plata, Argentina
|
Posted: Wed Jun 09, 2010 9:53 pm Post subject: |
|
|
Well, well, I have eventually found how to manage Simpleplot plots within a %dw graphic window, and how to get the value of the points inside it. As it seems to work very well, I would like to share my findings in this respect, as it could be usefull for someone else. Here is the code for a simple plot (remember that one has to link it with the simpleplot.dll library). My previous solution was based on a pure use of Simpleplot and Simpleplot windows, which is not very nice if one is deeply involved with a Clearwin approach. The powerful facilities of the old Simpleplot are extremely useful for making almost any graphics (thanks David Butland & Co.!).
Agustin
MODULE SPWIN ! Contains definition of values to pass to DDDATA
INTEGER,PARAMETER :: SIMPLE_WINDOWS_WINDOW=1,SIMPLE_WINDOWS_PRINTER=2, &
&SIMPLE_WINDOWS_DIB=4,SIMPLE_WINDOWS_METAFILE=8,SIMPLE_PERCENT=0,SIMPLE_PIXELS=1,SIMPLE_MM=2
TYPE SIMPLE_WINDOWS_DATA_STRUCT_T
INTEGER :: iOpc ! Corresponds to C++ long int
INTEGER :: iPtr ! Address of OpCode specific data
END TYPE SIMPLE_WINDOWS_DATA_STRUCT_T
TYPE SIMPLE_WINDOWS_HDC_DATA_T
INTEGER :: hDC ! device context handle
INTEGER :: iWidth, iHeight ! plotting area
END TYPE SIMPLE_WINDOWS_HDC_DATA_T
TYPE SIMPLE_WINDOWS_SIZE_T
INTEGER :: iUnits ! SIMPLE_PERCENT, ..._PIXELS, ..._MM
INTEGER :: iWidth, iHeight, iDepth
END TYPE SIMPLE_WINDOWS_SIZE_T
TYPE SIMPLE_WINDOWS_ORIGIN_T
INTEGER :: iUnits ! SIMPLE_PERCENT, ..._PIXELS, ..._MM
INTEGER :: iX, iY
END TYPE SIMPLE_WINDOWS_ORIGIN_T
TYPE HDC_DIM_TYPE
INTEGER*4 iBitmapDC, iWidth, iHeight
END TYPE HDC_DIM_TYPE
TYPE (HDC_DIM_TYPE) :: HDC_DIM
INTEGER, PARAMETER :: SIMPLE_WINDOWS_END_LIST = 0
INTEGER, PARAMETER :: SIMPLE_WINDOWS_SET_WINDOWNAME = 6
INTEGER, PARAMETER :: SIMPLE_WINDOWS_SET_HDC_DIM = 7
! Useful definition of data structure to hold BitmapDC to pass to SIMPLEPLOT
Contains
SUBROUTINE SP_SupplyBitmap ! Pass Bitmap to SIMPLEPLOT
! Set up a Static (SAVEd) array of OpCodes. Each OpCode consists of an
! OpCode ID followed by an optional address of a data structure.
! The parameter block address is passed to SIMPLEPLOT by SUBROUTINE DDDATA.
!
! In this example:
! SIMPLE_WINDOWS_SET_HDC_DIM specifies that the next integer is the address
! of a data structure consisting of a Bitmap DC followed by its dimensions
! SIMPLE_WINDOWS_END_LIST is the mandatory end of list item which does not
! require the address of a structure
TYPE(SIMPLE_WINDOWS_DATA_STRUCT_T), DIMENSION(2) :: OpCodes
SAVE OpCodes
OpCodes(1)%iOpc = SIMPLE_WINDOWS_SET_HDC_DIM ! hDC + dimensions
OpCodes(1)%iPtr = LOC(HDC_DIM) ! See definition of SPWIN above
OpCodes(2)%iOpc = SIMPLE_WINDOWS_END_LIST! End of list
CALL DDDATA(LOC(OpCodes))! Notify SIMPLEPLOT
CALL DEVNAM('WINDOW') ! Select Window
CALL OWNNEW(.TRUE.) ! Inhibit 'Continue' button
END subroutine SP_SupplyBitmap
SUBROUTINE UpdateWin
CALL OUTBUF ! Flush buffers
CALL WINDOW_UPDATE@(HDC_DIM%iBitmapDC) ! Copy Bitmap to window
END subroutine UpdateWin
END MODULE SPWIN
Last edited by aebolzan on Thu Jun 10, 2010 12:37 am; edited 2 times in total |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|