First time posting here so bear with me if I'm asking the obvious. I searched the forums for how to solve this but I couldn't find what I was looking for exactly.
Okay, let's get the basics known so I get the right info: Using: Visual Basic 6.0 OS: Win XP Pro Experience with VB6: I'm new but I can do the basics like creating things and passing values of things back and forth.
Current project: A program similar to MS Paint. Simple, I know but I want to make one to gain experience. Gotta start somewhere, right?
I have several problems I'm not sure how to solve. First, is scrolling an image within a picture box with scroll bars. If I open a picture, I need to have it so that if it's bigger than the drawing area, I can scroll up/down/left/right smoothly to see the other parts of it. And, if I set the height and width in two text boxes, use those values to set the drawing area size but if they are bigger than the default drawing area, enable the scroll bars to see the rest of the drawing area.
Second problem is an undo function for drawing. Basically, my only question on that is "How?"
That's enough to ask for right now but I do have other questions and will ask them once I solve these two.
You could make two pictureboxes, one for the drawing and one as container, put the first picturebox (drawing) inside the second one (container) and just move the first picturebox around according to the values of your scrollbars.
the easiest way to do undo code is that you have 2 pictureboxes in the form, one to paint on, and one invisible.
when the user clicks the mouse on the visible picturebox, that image is stored to the invisible box. and when calling undo, restore it!
but that limits you to only 1 undo...
you can add some more invisible boxes and do the same thing with the others, but that is no good...
but its a good way for a biginner...
how far on the paint program have you come?
i've made tons of them, so i think i can help you!
Yeah, MS Paint does indeed support 3 undos. Not 1.
How far have I come? Well, keep in mind, I'm still really new at this so anying I do is probably ancient to everyone here.
Well, I've got basics like freehand drawing, spray brushing, changing the size of the pencil in both cases. Color choosing (for left/right buttons) by either clicking on a preset color, choosing from a pop up color box, or sliding gradient sliders (with colors in the gradients changin as you slide sliders), and I really want to try to make a color chooser like in Photoshop but I don't quite know how. I can get the four colors in each corner but it takes a while to draw a square that big. Anyone know how to speed it up so it's fast like Photoshop? I have figured out how to limit the movement of the mouse to within the color box but not completely. I can stop it at the top, left, and right sides of the picture box containing the colors but at the bottom, the mouse still can go out of it and it causes an error and it closes the program. But when I apply the same exact code to the drawing picture box, the limited mouse movement works fine on all sides. Can't for the life of me figure out what's going wrong.
I can also flip the image in the picture box horizontally and vertically. I can draw lines and rectangles but can't see the size of them until I release the mouse button. I'd like to be able to draw them like in MS Paint where you can see the size while dragging. I also have this funky invert brush that doesn't quite work right but it does vaguely interesting things.
I can open/save images I make/open as well.
That's about it so far. Not much, I know but it's a start.
Oh, I'm also having odd troubles with grayscale converting as well. For some reason it's not working quite properly.
Anyone have any solutions? I'd love to see the paint programs you've made, cyborg.
Last edited by creativ82; Oct 23rd, 2002 at 12:35 AM.
Most undo lists are created using Linked Lists. Each possible action is assigned a certain state, and the current image is created by applying those states in order. Undoing simpply moves the current state back one in the list, so the top item doesnt get applied. This behavior could be mimicked with arrays. The big problem you are going to have is creating the state system. You would need to figure out a way to generalize any action you might want to perform into a set of parameters.
Once that is in place, It is just a matter of determining when to add a state to the list. Paint does this when you Release the mouse button.
Wow Cyborg, that's a lot of coding. To be honest, I don't understand half of it. Could you explain it to me? I mean I can understand it somewhat but a lot of it confuses me. Like how did you get the gradients to always redraw themselves so quickly and smoothly? How did they draw themselves to begin with?
Also, that color pallet is great but I was actually thinking of the color pallet in Photoshop 7 that you see when you click on your forecolor and the box pops up with the big color box and you choose from there.
I used the code for limiting the cursor to within the color box on my form in the MouseMove function but it doesn't work at all. It doesn't limit the cursor movement at all.
you must have codes both for X and Y...and change picture1 to whatever your picturebox is called..
for the Y coord, you dont use scalewidth, use scaleheight.
put all that in the mousedown sub for the picturebox
i'll comment the RGB palette and upload it again later....
btw again!
when using the code for locking the mouse....you dont accually lock the mouse, you just prevent the coordinates from being outside the picturebox.
Sitting w/ Bob Status: -Next -To- Null- Friend: Philip
Posts
1,152
Originally posted by Zaei If you are good, you only need one undo .
Z.
LOL right
:::`DISCLAIMER`:::
Do NOT take anything i have posted to be truthful in any way, shape or form.
Thank You!
-------------------------------- "Never heard about "hiking" poles. I usualy just grab a stick from the nature, and use that as a pole." - NoteMe "Finaly I can look as gay as I want..." - NoteMe
Languages: VB6, BASIC, Java, C#. C++
I got the code for limiting the mouse movement working. I didn't use your code but modified mine a bit. I just had the order of some code reversed.
I downloaded your new pallet now with comments and it's easier to understand now. Thank you.
I still don't understand though why you gradient bars redraw themselves so much faster than mine. Mine are rather slow.
I tried using the the code in the program you gave me to get the RGB and Hex values from the color square but for some reason it wasn't working. Guess I'l have to work more at it.
Also, Cyborg, have you figured out how to program the color picker in Photoshop? Not the one you gave me already but the other one that opens up a whole new window and lets you change the colors in a large square box?
when drawing the bars.....dont calc things for the Y coords becase everything is the same for the Y coords...
and dont clear or refresh when drawing....only clear before drawing and refresh afterwards.
also use setpixelv instead of setpixel, because it does not return the previous pixel color, so its a bit faster...
if you show me the code, it will be easier to see what makes it slow...
I'll post it in a couple hours since I'm at work replying and I don't have access to my code here.
You programmed the color box already!? Geez. I feel so ignorant now. I don't understand how to use SetPixel. Could you explain it for me since I'm a total n00b?
I had it done so that it drew the colors in the color box once but it took a while to do it once so I couldn't make a slider to do it many times or it would slow down a lot. And I don't know how to make the vertical slider either.
Oh, and I'd love for you to show me how to do bezier lines as well. No clue how to even begin there.
Last edited by creativ82; Oct 23rd, 2002 at 07:34 PM.
cy = 3 * (y1 - y0)
by = 3 * (y2 - y1) - cy
ay = y3 - y0 - cy - by
the formula for the X values of the whole line is:
x(t) = ax * t^3 + bx * t^2 + cx * t + x0
and for the Y values
y(t) = ay * t^3 + by * t^2 + cy * t + y0
this changed to VBcode looks loke this:
VB Code:
Dim X0 As Single
Dim Y0 As Single
Dim X1 As Single
Dim Y1 As Single
Dim X2 As Single
Dim Y2 As Single
Dim X3 As Single
Dim Y3 As Single
Dim AX As Single
Dim BX As Single
Dim CX As Single
Dim AY As Single
Dim BY As Single
Dim CY As Single
Dim NewX As Single
Dim NewY As Single
Dim t As Single
'Set all 4 point before this code using mousedown or mousemove
Okay here's my entire program so far. It's basically a mish-mash of various things I just wanted to learn how to do. Sorry if it's completely confusing or very primative in the way the coding is done but I'm a beginner so this is all I know so far.
I honestly don't understand how that code is supposed to work quite right with the bezier lines so I didn't add it yet.
Use MDI and put about 5 picboxs in an alligned (docked) picbox as an array. On mouseup save your main form's pic to one. On the next mouseup save to the next one. On redo go to previous and load it to the main form, on redo go to next and load it. Never allow redo to go further than most current. Never allow undo to go further than most oldest. Do a search in maths page for "escalator" and that should get you on your way to looping through your designated array. Making the array grow dynamic on initialization may make it easier to know if the pics exist yet or you can code a whole lot to determine if there's anything to undo. Also keep in mind you can't have a "redo" if you haven't done an undo. Have fun!
Zaei, memory is cheep now and even if you got a little vb's ok with it. In vb you might as well save the pics to a memdc wether in a control or device independent 'cause your gonna loose on processing trying to calculate various regions anyway. I tryed that and found no gain. Also once a pic is drawn over if you depend on arrays to undraw what you have you will again be clobbered by memory issues if someone draws for a full minute without lifting the mouse. Using hidden pics and their dc's uses abrox 2% of my active memory (56k, win98 on a 333)to record a full screen pic. I have no reason to open 35 full screen bmp's but I can if I want to. This shouldn't be a concern. XP shows no difference at all for me but I've got 256 on that one.
A in-memory 32bit image (uncompressed) of 640x480 dimensions needs 1.2 MB. Memory is cheap, but not so cheap that you can use 7.2 MB when you could achieve the same effect with just 1.5 MB and a little more tricky code, and that would even be more flexible (like removing a single step from the undo stack that's not on the top).
And I sometimes load 20 640x480 or larger images at once.
All the buzzt CornedBee
"Writing specifications is like writing a novel. Writing code is like writing poetry."
- Anonymous, published by Raymond Chen
Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.