Let's say I have an image background on a window, like for example a picture of piano keys, and I want to be able to click each piano key individually. I have never quite understood which way is better [or more common].
Should I...
Handle the main window's mouse events and then test to see which rectangle it is in?
or
Make each piano key a separate custom control?
or
Something else?
How do people usually do things like this?
I'm so used to using prebuilt controls like buttons and edit boxes that this was never an obstacle.
But now I really would like to get a grasp of better ways to do this.
Thanks if anyone can give me their thoughts.
savage,
Some time ago I wrote a Calculator program (actually, I built the front end and Ewayne build a lot of the backend.) Anyway, I had to deal with a similar situation. My decision was to create 5 toolbars, each created from its own bitmap. This way, the buttons were created for me by the toolbar support software.
Paul
If each piano key is the same width it's a simple MOD operation on the cursor X position to figure out which one was clicked. (Probably a rectangle check if the window is bigger than the keyboard / accidentals, etc.). This way is more economical than creating a custom control (though creating a 'Key' class is very OO... :naughty: :wink ) though requires more thought by the programmer. I don't think that's a bad tradeoff :bg
Cheers,
Zooba :U
Hi Savage
You can make a copy of your piano keys picture and change
all the keys to there own color save it and put it in memory.
c-1 = 1
c#1 = 2
d-1 = 3 etc.
Now you only have to test where you clicked your mouse on the
picture, get the coords and pic the color from the copy in memory
and there you have the number of the piano key you have clicked.
With this method you make controls that have all kinds of shapes.
Siekmanski
Siekmanski,
The reason I chose the method I chose is because I am not very good as a graphics programmer. I have seen you guys do some fastinating things. The way I see this problem is to just detect a key via a region is not good enough. There needs to be a satisfying response to the click by means of a visual representation (such as a button being clicked). Any solution that you suggest to savage should deal with that. In light of what I just said, how does that effect your response. Remember that I am not being critical, here, just want to see how another's mind works. In the Calculator, the multiplicity of toolbars solved this problem in a very satisfying way.
Paul
Hi Paul
Hope I uderstand what you where asking....
(I'm Dutch so English is not my native language
if I misunderstood tell me....)
This method is very usable within graphics programming.
I use this method because it is fast and easy.
The only drawback is you need an extra picture
to check where you clicked your mouse.
And if needed one extra to show which key was clicked.
Siekmanski
Siekmanski,
Do you know if there is a pre-existing example or tutorial about this method. I think you understand very well what I am saying. The problem is there is a risk you will talk over my head as you know a lot more about these things than I do (and probably savage, also). I know this is savage's thread and his question but I have gotten very curious and want to learn.
Thank you for your patience, by the way.
Paul
There is a tutorial/example in OpenGL (3D) at http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=32. The concept remains the same, though simpler in 2D and probably with a premade map.
Think of it like having two maps with the same scale. One looks pretty and the other tells you where you are. So if you have a point on the pretty one, the same point on the other one can give your location.
Cheers,
Zooba :U
Hi Paul
I'll make an example and post it.
Later Siekmanski
Hi Savage,
Try "Ownerdrawnbuttons" in Donkey's Stable GoAsm Projects as a starting point. You could draw larger keys that completely fill the window.
Get it at http://www3.telus.net/~edgarh1/files/OwnerDrawBtn.zip
Regards Roger
Thank you all.
Paul
Paul I feel exactly the same way you do, and anything I can learn about this would be much appreciated. I probably do not know much more about it than you do, like you said, I'm not that great at graphics yet either.
But thank you too, Zooba and Siek, for the help.
I'm hoping to have this mastered one day, I'm sure it will be a very common situation.
Here is a test project I made by using a custom control: http://notfed.tripod.com/files/MasmCustomButton.zip
EDIT: sigh... tripod won't let me directly download from them from an anonymous referrer. So I made a quick page to download from: http://notfed.tripod.com/cgi-bin/public.pl
Quote from: zooba on May 28, 2006, 12:28:02 PM
There is a tutorial/example in OpenGL (3D) at http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=32. The concept remains the same, though simpler in 2D and probably with a premade map.
Think of it like having two maps with the same scale. One looks pretty and the other tells you where you are. So if you have a point on the pretty one, the same point on the other one can give your location.
Cheers,
Zooba :U
By the way, this is an AMAZING tutorial. Very thorough and very well detailed and commented.
Quote from: savage on May 28, 2006, 08:22:39 PM
EDIT: sigh... tripod won't let me directly download from them from an anonymous referrer...
It worked for me out of the Sprint backbone in Chicago, USA. Nice example by the way. :U
Quote from: Mark Jones on May 28, 2006, 09:31:41 PM
Quote from: savage on May 28, 2006, 08:22:39 PM
EDIT: sigh... tripod won't let me directly download from them from an anonymous referrer...
It worked for me out of the Sprint backbone in Chicago, USA. Nice example by the way. :U
Others have told me the same thing when I've posted stuff before. How come I'm the only one who can't download my own stuff?? huh?? :lol
It may be a little too late for me to reply now, but i will anyway :8)
The way i would do this would be to create a custom control (window) for each key. Each control would be hooked to the same wndproc, that way you get identical functionality for each key/control. What you then do is create a struct for each key that contains its note and whatever other unique information it needs, and as you create each control you call SetWindowLong with the GWL_USERDATA flag to store a pointer to that control's custom struct.
So, each control is set up to go through the same click handler in the wndproc. In that click handler, call GetWindowLong to get the pointer to the custom struct, and you can use the info in that struct to generate the correct note etc.
I hope i have explained this well enough :eek This method of doing it is very OO, and you actually end up with very little code. Less code means less chance of errors, and doing it in an OO way means you get consistent handling of all the controls. I used this method in a game which had several hundred tiles on the screen at once - all the tiles went through the same click handler, and i had a struct attached to each tile. And the performance was great :U
Sluggy,
The explanation of this method proves that you can never be too late. I like this method of yours very much. It follows the idea I was presenting in the button method but has the benefit of being a lot more flexible and I would not be forced to work with the bounds of button generation. Are you willing to throw together a small example that would create, let's say, 3 custom controls?
Paul
Sluggy, if you didn't notice, I actually already already did exactly this and posted the program up here.
But it's good to have verification that I"m not heading the wrong direction.
Savage,
I missed that, also. What I usually when I awaken is catch up on the thread and make notes of external links. I make my comments and then I check external links. Moving off the forum to external sites is always a bother to me as it increases my risk of exposure to bad scripts. Some sites, I will not go to at all depending on the domain. If the domain has a reputation of negative re-enforcement, I stay away. I feel that tripod fits this definition. Anyway, why don't you attach your zip to this board?
Paul
Quote from: PBrennick on May 29, 2006, 06:44:14 AM
Anyway, why don't you attach your zip to this board?
Paul
Because I'm an idiot. :dance:
[attachment deleted by admin]
Hi Guys
Just finished the 2D example I promised to make.
Look at the source-code how I did it.
I made a piano bitmap with 3 octaves.
Then made a copy of it and gave every pianokey his own color,
key c-1 color 1
c#1 color 2 etc.
pianomap.gif is that bitmap and is saved as 8-bit raw data.
Now we have some kind of a lookup-table for the pianokeys.
This method is fast and you can use all kind of shaped buttons.
Enjoy.... lets make some music.
greetings Siekmanski
[attachment deleted by admin]
Quote from: Siekmanski on May 29, 2006, 08:39:06 PM
Hi Guys
Just finished the 2D example I promised to make.
Look at the source-code how I did it.
I made a piano bitmap with 3 octaves.
Then made a copy of it and gave every pianokey his own color,
key c-1 color 1
c#1 color 2 etc.
pianomap.gif is that bitmap and is saved as 8-bit raw data.
Now we have some kind of a lookup-table for the pianokeys.
This method is fast and you can use all kind of shaped buttons.
Enjoy.... lets make some music.
greetings Siekmanski
:eek :eek :eek :eek :eek :eek :eek :eek :eek
:red :thumbu :thumbu :dazzled: :eek :eek
How the...
Thanks for making me feel like a newb.
I will be quitting as a programmer now and go work at mcdonald's.
That just looks way too hard.
Lol.
Quote from: savage on May 29, 2006, 06:28:12 AM
Sluggy, if you didn't notice, I actually already already did exactly this and posted the program up here.
But it's good to have verification that I"m not heading the wrong direction.
Hehe :) I didn't check your code before commenting :red
Beautiful example Siekmanski! :U