Hi,
Thought I would take the mouse over a control program a little further and try to write some of it into an include file, this would then allow me to make some commands that I could use in other programs.
1. You need the include line in a program...
$include "MouseOverControls.inc"
2. You need to tell it what controls you want to monitor.....here I've stated three buttons....
MouseOverControl(win,button_1)
MouseOverControl(win,button_3)
MouseOverControl(win,button_5)
3. Start a timer in the program.....
starttimer win,100
4. Check to see if mouse is over the control, this is done in the CASE @IDTIMER section.....
if MouseOver(win,button_1) - will be true (returns 1) if the cursor is over that control.
I have not tried this for programs with multiple screens yet, but as far as I can see it should work as long as no button is used twice or more.
Not saying this is perfect, and perhaps someone could do it another way - but it does add another function to IWB.
What does anyone think about it?
See attached.
--------Update-----------
The attached program now has two screens, I have done some more testing and you can (if you want) use a button / control more than once i.e. button_1 exists on screen1 and screen2.
Thanks,
Andy.
I have updated the include file here and documented it more fully.
I noticed that closing and re-opening a window caused the window's handle to change (of course!), so although the controls were stored, it added them again.
There was a possibility (although small) that the arrays would be filled up causing the program to crash.
No matter how many times you open and close a window within a program it will not now duplicate the control details.
In other words, when you specify you want to keep track of 6 buttons, 3 on one screen and 3 on another - it will only ever store 6 control details and I have allowed for 1,000 controls.
Attached is the updated include file and a test program.
Andy.
:)
This I think is the final release of the MouseOverControls inc file.
This is the one to use now.
Whilst trying to detect just the mouse over the actual window, I noticed that when I move or re-sized the window the code was not detecting when the mouse was over the controls anymore.
So I have amended the include file to detect and change the coordinates of the controls when the window is moved / re-sized.
I have also created a help file and as always included an example program.
Please let me know if this is helpful to anyone - Maybe this (or something like it) could be added into IWB as a command / function?
Attached are the files.
Thanks,
Andy.
:) :)
Great idea, Andy!
Thanks for sharing.
One last question, what tool are you using for making the help file?
Egil
Hi Egil,
Thanks for that, it took some working out!
The help file I use is Visacc help maker, It is free and you download it, just google it.
If you cannot find it just message me and I will send a link to you.
Andy.
:)
Andy,
I think there is still some work to be done on your mouse over code.
When compiling the file ButtonTest.iwb, included in your zipfile, and moving the window a little, the picture below show what happens when the mouse pointer is over the 2nd Screen button.
Before I moved the window all worked OK.
Egil
Hi Egil,
Thanks for the feedback.
I struggled to reproduce your problem but I have now re-coded the include file.
I've used the GETSIZE command to always get the control locations instead of calculating them myself, seems to be a rock solid way to do it.
Using the GETSIZE command also allows for updating the control's width and height which could be important to someone's code.
I've also updated the help file.
Please give it a go and remove any copy on the MouseOverControls.inc files first from your download location or the IWBDev / Include folder.
Attached are the files.
Thanks,
Andy.
It's rock steady now Andy.
Thanks again.
Egil
Great!
Thanks for trying.
Andy.
:)
Hi,
I've optimised the include file to only track the specifed window.
I've done some testing on the time it takes to track the controls, and I have allowed for 1,000 controls and 1,000 windows in the include file, but you can always up that number if you need.
What's the difference now?
Well..... Say you have 3 screens... and 20 controls in total over the 3 screens.
Screen 1 has 9 controls
Screen 2 has 5
Screen 3 has 6.
Instead of going through all 20 controls, screen 1 only tracks it's 9 controls, likewise screen 2 tracks it's 5, and screen 3 tracks it's 6 controls.
This means that if you have say 200 controls in total in your program the screen you are tracking will only look for "it's" controls.
Thought this might be important when you have many controls you want to track.
I used the precision timing code I found on the forum to time the include files response.
With the previous include file, the average (for 20 controls) was 0.08 millisecs, where now the average is 0.045 millisecs.
I have as always updated the example program and the help file.
Thanks,
Andy.
:)
If you want to really "tighten things up a bit"
Right now you are hard coding 1000 of array to handle your house keeping information
I would suggest that either a TYPE/ENDTYPE structure to hold related data elements
for each control location old/new and window
and then creating a new entry via the either the NEW statement or via a linked listlist
may prove beneficial and any cleanup could be done in an ONEXIT command.
Just saying it may be worth looking into.
Thanks Larry,
Just looking at what you suggested.
But... as always I have a question.
When I use:
int x = 5
TYPE MYUDT
DEF name[255] as STRING
ENDTYPE
DEF pUdt as POINTER
pUdt = NEW(MYUDT,x)
Where x (size is set to 5) - why can I keep adding beyond the fifth entry?
int x = 5
TYPE MYUDT
DEF name[255] as STRING
ENDTYPE
DEF pUdt as POINTER
pUdt = NEW(MYUDT,x)
SETTYPE pUdt, MYUDT
#pUdt.name[1] = "=1"
#pUdt.name[2] = "=2- Joe Smith"
#pUdt.name[3] = "=3- aaaaaaaaabbbbbbbbbbbbbbbbbbbbbcccccccccccccccc1"
#pUdt.name[4] = "=4"
#pUdt.name[5] = "=5"
#pUdt.name[6] = "=6"
#pUdt.name[7] = "=7"
#pUdt.name[8] = "=8"
#pUdt.name[9] = "=9"
#pUdt.name[10] = "=10 - Last entry."
openconsole
print
for y = 1 to 10
print y,#pUdt.name[y]
next y
do:until inkey$ <> ""
closeconsole
DELETE pUdt
end
Thanks,
Andy.
because you are just sticking characters out at a memory location and you are not exceeding the definition of of your structure.
so the array index is just moving the index of a memory pointer; that;s where you can wind up with one of those memory overwrite bugs that are next to impossible to find sometime.
BTW array indexiing starts at 0 and not at 1 array of 5 is 0 to 4 for 5 elements
Thanks Larry for the explanation.
I decided to take Larry's advice, and use pointers, types etc in the include file.
So this keeps running and running....
I have added two commands:
WindowMoved - checks if the window has move or been re-sized.
StopTracking - deletes the pointers & frees up memeory when exiting.
You can have more than 1000 controls and 1000 windows? - probably depends on the memory you have?
we shall see.
Help file updated, as is the example program.
Pointers work for me in testing, maybe the purist's might alter the code a little, but like I say, it worked all day today for me.
Could some kind person test it for me please...
Thanks,
Andy.
:)
Sorry forgot to say, I did not add the graphics in this download.
So please download and extract MouseOverOntrols3 first, then this update and overwrite any files.
Otherwise remove load images and deleteimages calls from the code.
Will update this update soon.
Thanks,
Andy.
Andy
I believe I didn't explain the concept I was trying to get across very well about using NEW or linked list.
Yes, you are using pointers now but you are still creating a predefined finite number of memory locations to hold information about controls/windows that might not exist in the users program.
You're allowing for 1000 controls and the user's app might only have 10.
I was looking to use NEW/linked list to created the memory for just the 10 or however many were actually needed as opposed to always the 1000. Since your program is working, it is probably more trouble than it is worth to rewrite it entirely and that is most likely what it would take at this point.
Thanks Larry,
Yes I'm now to using pointers, did try my best as I always try to improve my coding.
So for everyone, for now, use MouseOverControls3 download.
You can always up the numbers from 1,000 but think that should be enough for most people.
Thanks so much.
Andy.
andy,
Why use MouseOverControls3 instead of *4?
Bill
Bill,
Thanks for that, but how do I use it? and what does it mean?
Thanks,
Andy.
:)
andy,
you attached MouseOverControls3 and MouseOverControls4, yet you indicate to use MouseOverControls3. I used *4 instead of typing out MouseOverControls4. Sorry for the confusion. I just wondered why use an earlier version over an updated one.
Bill
Thanks Bill,
I understand you now.
LarryMc suggested I could change my code to use pointers, something I've not really tried before as I don't use them.
The mouseovercontrol4 download was re-written to use pointers, however, Larry said I wasn't doing it correctly.
So, I suggested using mouseovercontrol3 (the previous download) which does not use pointers, but has a fixed limiit of 1,000 controls and 1,000 windows - but you can always up that number if you need too.
I am currently updating mouseovercontrol3 with some more commands, as the more I look into it, the more I find I can add to it.
I will post an update soon.
I will however post another question (new post) on pointers as I have a few questions about them.
Pointers are one of the few areas of the language I'm not sure about and would like to learn more.
Some of the examples don't work like I expect them to do.
New post on this tomorrow I think.
Thanks,
Andy.
:)
andy,
Understood, and thanks.
Bill
Hopefully, with Larry's explanation of pointers I've got this right now.
I've changed the include file to use pointers now which increase in size everytime a new window or control is created for the first time to make room for them.
The example program can open 5 windows, which together have over 20 controls tracked.
Please let me know if this works for you.
See attached.
Thanks,
Andy.
Hi everyone,
I've now added some more commands to the include file, looks like the pointers are working well now.
New commands added:
WindowExists - check if a window exists or not.
WindowHasFocus - Window currently being worked on or topmost.
WindowMinimised - check if a window is minimised.
WindowMaximised - check if a window is maximised.
WindowNormal - check if a window is neither minimised or maximised.
DeleteControl - deletes a control from a window.
The example program works mainly on buttons2,4, and 6 - move mouse over buttons 1,3, and 5 respectively.
1. Compile and run the program.
2. Move the window over to the left.
3. Click on Window 2 button to open the second screen.
4. Mimimise window 2 and move to button 1 (which becomes button 2)
5. Click button 2
6. Console screen opens
7. Press any key to close it
8. Restore window 2
9. Move to button 1 (which becomes button 2) again
10 Click button 2 again - now nothing happens - which is correct as window 2 is no longer minimised.
You can do the same for button 3 (which becomes button 4) to check if window 2 is maximised, and
button 4 (which becomes button 6) to check if window 2 is neither minimised or maximised.
You can also play around with these and the other commands, but please read the new help file.
Let me know how you get on.
Thanks,
Andy.
:)