01-07-2005, 04:48 PM
This seems easy, but I am trying to figure out the best way to do this. I have a picture box in which I have drawn controls. I would like to provide the ability to 'select' the controls (just like the VB ide) by drawing a box with the mouse. When I use the .Line method on the picture box, the line shows up behind the other controls. Other suggestions?
01-07-2005, 05:13 PM
Depends on what you are trying to achieve in the long run.
Is all you want is to select controls in the picturebox? They do not have to be live do they? (i.e. Type text into a textbox, Etc...)
If Selection is the only issue then I would make a picture of the controls in question and display it in the picturebox.picture property. Then your line will be on top.
You would have to have a map of the regions where the controls would be then build a list of selected controls.
If the controls need to actually be true controls then you would need to be using the GDI API to draw directly onto the main screen foreground.
01-07-2005, 05:37 PM
I am basically trying to have a 'form building' application. So, probably the best analogy I could use is I would like to behave the VB IDE at design time. So no, I don't want the controls live, but I do have to be able to determine which ones are selected easily.
I actually have them inside two picture boxes, the outer one enabled and the inner one disabled so that the controls do get any mouse movements, but the enabled picture box does so I can track which item(s) they have clicked and selected.
I am pretty green when it comes to drawing and the like in VB, so keep answers simple .. :p
01-07-2005, 05:54 PM
Controls occupy next to the top z order levels in windows. Drawing normally resides on the bottom layer.
So like I said if you really don't need the actual controls in the picturebox then making a picture of them and making selection routines for the picture would be the easiest way to go about it.
Further, if you are not stuck on the VB control panel format you could even get away with using the listimage control which is designed to allow image selection for you.
As far as dragging and dropping well you do not need the actual control to preform the drag and drop, just be able to know when a valid drop was made from the source and then place a new control of the correct type at that location.
May I ask what the final application goal is? You've peaked my curiousity.
I once started out to build such a program but found an easier way to achieve my goal.
In my case I needed to end up with form controls in another language that didn't have a visual builder IDE. I ended up designing my forms in VB6 saving the file then running a post processor on the vb6 output .frm file which is text based. The program converted the VBcontrols to the other language format.
Ended up being much easier than developing my own IDE.
01-07-2005, 10:34 PM
Did you want to select a group of controls with a rubberbanding dotted line box? Do a search for "marque select" or "marquee select"
Basically the way it works is that once the rubberband box selection is made (and a MouseUp event occurs) then save the x,y values of the origin (upper left hand corner) and x,y values of the lower right hand corner.
By checking whether the Left and Top value of any control (or graphic object) lie within the set of saved x,y boundaries values it can be determined if it has been selected.
01-10-2005, 09:02 AM
I am basically working on an application that will allow a user to define their own 'form' for the entry of data. I need to be able to let the user say 'I want a check box here, a text box there, a combo box over here', then let them define defaults and other criteria (IE, this text should be defaulted, here is the list of items to display in this combo box, etc...). I do need to allow limit interaction with one control, a spreadsheet. I need them, at form design time, to be able to select columns in the spreadsheet so that I can allow them to specify what types of columns they want (ie, text, check, etc...)
So, while doing this, I would like to provide the ability to do the 'rubberbanding dotted line box' approach to letting the user select, then drag and drop to a new location. So, my first problem is the drawing of the line using the .Line method of the picture box doesn't draw over the controls, which appears to be the way VB handles layers.
Second problem is dragging and dropping multiple controls. The built in Drag Drop doesn't support it. I know how to determine which controls should be selected, but I am having troubles visually indicating the dragging and dropping operations (similar layering problems since I was trying to use the .Line method multiple times).
I should also mention that I have currently got it work working by using 4 very thin picture boxes to act as the 'selection box', which isn't too bad. This gets me past the layers since they are on the same layer as the other controls. When I then select many controls, I also have it setup to display the 4 thin picture boxes around each control when dragging. However, it gets very messy because when you start dragging, the processor pegs out at 100% and the redraw is not very good and I get alot of ghost images. I am sure it is due to the constant moving of several picture boxes.
It seems like if I could figure out how to draw lines and make them always show up over controls, I would be in pretty good shape. Can I draw a line another way to get around the layers problem? Or, am I missing the boat and is there a much easier way to do what I am trying to do?
01-10-2005, 02:16 PM
Yikes! Sounds like you are trying to re-create Excel's VBA Interactive Development Environment(IDE). That is a huge task.
Why not just let them use Excel's VBA IDE to draw the controls on the forms then have them export the forms so they end up as textfiles on disk. You could have a post processor that adds your code to them and then imports them back in to Excel.
It could be automated from a master program in Excel.
It would greatly simplify your task without having to re-invent the wheel.
Another option is that Microsoft leases a VBA SDK (Software Development Kit) for those who want to add VBA to their own applications. I imagine it is a spendy proposition.
Finally, if you are still determined to create your own from scratch then I would still not try to use real controls in the form screen Just pictures of them. The image control can hold pictures and the shape and line controls will float on top of them.
01-10-2005, 02:27 PM
First off, thanks a ton for the replies, I appreciate it.
I do have 90% of what we need. It fairly simplistic, but it is going to meet my needs very well. If I can just get past this issue, I am good to go.
How do I get the images of the controls? I could see using the image control to hold the pictures working ok.
Again, thanks ...
01-10-2005, 05:08 PM
One way would be to take a snapshot of the screen with the controls on it. Alt-Printscreen. Open your Paint program and paste. Another would be to simply draw your controls with vector drawing information. so when the user resizes them you can update the picture. BTW if you look at VB when you are stretching or moving a control it doesn't even try to show the contents during the operation. Just a gray rectangle.
01-10-2005, 11:06 PM
Gruff is right, but I would also recommend you read through this thread:
"Some thoughts on the use of VB controls.."
Here's my view:
Essentially you are trying to get controls to act as if they are pure graphical objects.
They really are not.
Yes some controls come with an hDC, an Image property, or even a Picture property --that is really the front end for an attached (integrated) IPicture object. But there's no way to treat them as "layers" for you can not alphablend away the frame border of a picturebox, or make an image control (or line control) z-order over (above) a picture control.
All GDI graphics inside Windows (at the lowest level) are centered around DCs (Device Contexts) and dealing with the VB interface of controls just holds you back from accessing these powerful graphical structures directly.
The sad truth is (and sorry to have to say this) --all the controls that come with VB are really primarily oriented to designing office applications (including front-ends for databases). I truly doubt that the Microsoft software programmers who created them ever seriously thought they could/would be used to high performance graphical apps (much less produce an IDE-like piece of software).
It's a hard thing to give up controls in favor of "virtual controls" or graphics created and manipulated in memoryDCs, but to go down that road is to be unshackled from the limitations that controls force upon the developer, and be free to make a graphic interface that behaves exactly the way you want.
Just something to think about...
01-11-2005, 08:49 AM
OK, that is interesting. But I am not only building a 'mini-IDE', but have to have the 'office application' part of it as well, were the user will be able to enter data. How do you support data entry using purely graphical entities? Or are you saying only show the controls as needed?
And for my own research, where is the best place to learn about the right way to handle 'virtual controls' type of stuff in VB? (books, websites, whatever) That is the thing that has frustrated me the most about this whole thing: there seems to be 500 different ways of doing the same thing. And me, not knowing much about it, I just start to get lost in the details after a while. If you could help me clear the fog, I would greatly appreciate it.
01-13-2005, 12:34 AM
But I am not only building a 'mini-IDE', but have to have the 'office application' part of it as well, were the user will be able to enter data. How do you support data entry using purely graphical entities? Or are you saying only show the controls as needed?
And for my own research, where is the best place to learn about the right way to handle 'virtual controls' type of stuff in VB? (books, websites, whatever) Thanks ...
Hmmm...in you second post you said:
So no, I don't want the controls live
Now you seem to want user to enter data in a control --so, for example, you've gone from selecting a picture/image of textbox to a textbox that actually has text appear when user has selected it and starts typing.
This also may be possible with a virtual control (using the DrawText API and the form's KeyPreview property set to True), but is much more advanced thing to try and attempt.
I don't know what your general programming level (or VB-specific skill level) is since this is your first forum thread, so forgive me if I go over a few things (ie ramble on a bit...)
Most basic VB tutorials fall into a couple categories..
There are "VB-as-a-tool" type tutorials, like:
1.) How does a function/property method work (or how does the VB language/syntax work)
2.) How does a form/control work
3.) How is an API call coded
4.) How can I achieve a certain limited specialized "effect"
There are "theory and technique" tutorials, like:
1.) How does Bitblt masking work
2.) How do various methods of File I/O (reading, writing) work and how are they used
However, after a few years you generally becoming comfortable with VB as a programming tool and know the techniques for achieving most common programming tasks.
At this point (intermediate level of VB skill) most online tutorials are basically "cookbooks" - copy/paste a little code, adjust slightly to integrate/adapt the snippet into your own code, test, debug...move on to the next bit of application functionally.
However, you are never going to find a tutorials like:
1.) How do I create a best selling MMORPG (steps 1 thru 32,767)
2.) How can I make designing a DirectX game as simple as a data entry program
3.) How do I make VB do things it was never designed to do
Okay, so with that caveat out of the way, my comments are directed at going beyond intermediate mode. To take VB to the next level. Some people would call this the "expert" or "advanced" level, but really it's just the "level-were-things-get-interesting" level. :cool:
At this level even experienced VB programmers still may have difficulty with specific coding, but what's important is that at this level it's really all about design and what you want to achieve that transcends any specific set of code or coding technique.
That's probably what Gruff is hinting at with his "depends on what you are trying to achieve.." quote.
But just to give you one example of a virtual control, download the the ""VB_Virtual_Command_Button.zip" attached to this post:
It's a deceptively simple example.
You start out (at design time) with what looks like a command button, but it is not. It is, in fact, an image of a command button, that, when the VB program is run, certain VB code makes it "act" like a command button.
However, since it still uses a control (specifically, a picturebox control) that has been "re-purposed" to act like another control, it is not a true virtual control, but a pseudo (fake) command button control.
When you run the program, though, you'll also see what looks like another command button that appears above the picturebox-as-command button.
The second button IS the true virtual control. It contains (or is contained by) no VB controls.
Instead, it is an image created on the fly, that, when clicked, "acts' like a control because it has been coded in such a way to create a "virtual" control click event.
Although the example is simple, what it tries to demonstrate is a conceptual leap...a paradigm shift..that all you need to give the user the "experience" of a control is a bit of graphics that can be interacted with in a way that they are confortable with (used to).
Do you see the possibilities? Multiple virtual controls can be layered to create a virtual graphic user interface that can be almost anything you want!
It is easy to create such a custom GUI withing the Vb environment - no of course not...but it can be done.
Step 1 - Learn to manipulate graphics off screen, in a memory DC backbuffer:
Step 2 - Learn to do rubberbanding - Creating graphics thru mouse events
If you study this program closely you will see not only how it draw a rubberbanding dotted line, but how it stores the x,y values that represent the region bounded by the rubberbanding.
Once you know the origin and extents of the defined area it's just a matter of checking x,y values for any drawn graphic objects that may possibily appear within the boundaries of the rubberbanded (selected) area(s).
Going further, one excellent way is to store the location values of all graphic objects you draw/create as using RECT structures. The values inside the Rect's data structure are the same locational values as a control uses/stores as properties (.Left, .Top, etc).
For a group of drawn graphic objects you have a group of Rect UDTs (Private data types) stored in an array. Loop through the array to test if the Rect structures locational data "intersects" or overlaps with the X,Y and x2,y,2 rectangle of the rubberbanded box. If you don't understand about determining intersection/overlaps here's a thread with some examples:
Sorry for being so verbose, but hopefully this is enough to get you started. Let me know if you need more examples or what (conceptually) might be difficult to intake...I think you've stumbled upon an important topic that not only interests me, but also is not often well explored on the forum. I hope you will chose to explore it further.
P.S. The vector approach approach (that Gruff suggests) will probably take you farther than the other raster Screenprint-to-MsPaint approach when creating images of controls.
01-13-2005, 01:02 PM
First off, thanks to all responses ...
You make a good point in that I didn't clarify something on the interaction I need with the controls. At 'design' time, I do not need to interact with them at all, but at 'run-time' I do. So, at design time, they can't enter text in a text box, but at run-time, they should be able to.
This is great information and I will look it over. And this probably would solve my original question in the post. But it does beg the question, how do you handle data entry in 'virtual control'? I mean, the capturing of every Form_KeyDown and then drawing the text seems way over the top to me. Is there something I am missing on that or, as I suspect, I am once again trying to insert the square peg into a round hole? IE, graphical controls are not meant for data entry any more than data entry controls are meant to be handled as a graphic?
I guess one thing you could do is, when you need to enter data, overlay the image with the 'real control' to allow entry? But, once they enter data, now you have to continually refresh the image. Does that get processor intensive at some point?
01-13-2005, 11:28 PM
Yes, you are missing the point. :)
The virtual controls are for the Design-Time interface. The ability to have your user select, drag, position and stretch the virtual controls. Displaying your rubberband selection lines and marks. these all need to float above the virtual controls.
What your user is building with your virtual tools is really a map of what you intend to replace at Run-Time with real controls. (Probably all the target form load event.)