Layered Pictureboxes
Layered Pictureboxes
Layered Pictureboxes
Layered Pictureboxes
Layered Pictureboxes
Layered Pictureboxes Layered Pictureboxes Layered Pictureboxes Layered Pictureboxes Layered Pictureboxes Layered Pictureboxes Layered Pictureboxes Layered Pictureboxes
Layered Pictureboxes Layered Pictureboxes
Layered Pictureboxes
Go Back  Xtreme Visual Basic Talk > > > Layered Pictureboxes


Reply
 
Thread Tools Display Modes
  #1  
Old 07-03-2013, 05:11 PM
n2amg n2amg is offline
Junior Contributor
 
Join Date: Aug 2001
Posts: 279
Default Layered Pictureboxes


I am attempting to build a Gray Line Map in .net. My thinking is 3 picture boxes laid on top of each other.
One as the base which will hold the map image
A middle one that will hold the terminator painting and one to hold the position of the sun.

In .net I have not found the correct way to do this. In Pict1 The base map is loaded in Pict2 I have it's background set to transparent for the color and the same thing for Pict 3. But I have not been able to see the base map. It is blocked by one of the other 2 picture boxes.

Am I doing this the right way or should I go about it a different way..

Now another question.
For the base Picturebox To represent the Latitude and Longitude I would like the X coordinates to equal -85 to 85 and the Y coordinates to equal -180 to 180. How can I do this??

TIA Rick
Reply With Quote
  #2  
Old 07-04-2013, 12:56 AM
Gruff's Avatar
GruffLayered Pictureboxes Gruff is offline
Bald Mountain Survivor

Retired Moderator
* Expert *
 
Join Date: Aug 2003
Location: Oregon, USA - deceased
Posts: 6,440
Default

Hi Rick,

I am not a ham radio operator nor an expert in Visual Studio Graphics.

I can tell you that there are two separate areas of windows desktop programming.

Winforms: Most likely the one you are trying to use.
WPF: A more powerful Graphics based windows forms interface.

They are quite different to use.

If you want to pursue the WPF option I can pass along your request to the one or two experts that know something of the topic.

Regarding WinForms. The transparent Color is not a true transparency It basically copies the background color of the parent control.

The picturebox supports two images. Background and ForeGround. You can make areas of the ForeGround transparent by filling them with the color defined in the Transparency Color Property of the PictureBox.

If your going to refresh your picturebox once a minute or longer then you do not need to worry about speed of redraw or flicker. You might just consider drawing your lines and other objects one after the other in the ForeGround.

Can you give some more specifics as to what your image has to do?
__________________
Burn the land and boil the sea
You can't take the sky from me


~T
Reply With Quote
  #3  
Old 07-04-2013, 07:32 AM
n2amg n2amg is offline
Junior Contributor
 
Join Date: Aug 2001
Posts: 279
Default

I am using Winforms for this project.
There are 3 levels of things happening you have the background image of the world and you have a moving layer that gets updated every minute that shows the daylight/darkness terminator. and you have the movement of the sun. Take a look at this link. This shows what I am building in. I have a working copy that works in vb6 but with so many changes between vb6 and .net I wanted to start from scratch. http://dx.qsl.net/propagation/greyline.html
Reply With Quote
  #4  
Old 07-04-2013, 07:36 AM
n2amg n2amg is offline
Junior Contributor
 
Join Date: Aug 2001
Posts: 279
Default

I also just noticed I did not mention the other thing that the map will do. On the background it will be indicating spots on the world map of stations that have been heard..

The attachment is what the app looks like when run in vb6..
Attached Images
File Type: jpg Clipboard04.jpg (38.5 KB, 24 views)

Last edited by n2amg; 07-04-2013 at 08:16 AM.
Reply With Quote
  #5  
Old 07-04-2013, 08:16 AM
snarfblam's Avatar
snarfblamLayered Pictureboxes snarfblam is offline
Senior Contributor

Forum Leader
* Expert *
 
Join Date: Apr 2005
Location: USA
Posts: 896
Default

Quote:
Originally Posted by n2amg View Post
I also just noticed I did not mention the other thing that the map will do. On the background it will be indicating spots on the world map of stations that have been heard..
I can explain a quick and dirty approach if you want to use pictureboxes for layering, but the best simple way to do layering in a WinForms app is to render your layers to Bitmap objects, and then draw each layer onto the control in the Paint event. It's not very much extra work.

If Q&D is your style, place a panel on the form where you want to show your image. Set your bottommost layer as the background image of the panel. Then place your picturebox inside the panel, with a backcolor of transparent. Set your intermediate layer as the picturebox's background image. Finally, set your topmost layer as the picturebox's image.

Nesting the picturebox inside the panel will cause the panel's background to show through in transparent areas of the picturebox.


Quote:
Originally Posted by n2amg View Post
For the base Picturebox To represent the Latitude and Longitude I would like the X coordinates to equal -85 to 85 and the Y coordinates to equal -180 to 180. How can I do this??
The Graphics class provides two relevant methods to adjust the coordinates: ScaleTransform and TranslateTransform.

Suppose you have an image with a width of 400 and you want the x coordinates to range from -85 to 85 instead of 0 to 399. You're going from a range of 400 to 170, so you would scale it as follows:
Code:
graphicsObject.ScaleTransform(400.0 / 170.0, 1)
Now that things are to scale, you want to move things to the right 85 units, so that the left edge will be -85.
Code:
graphicsObject.TranslateTransofrm(85, 0)
__________________
C# _VB.NET _

Last edited by snarfblam; 07-04-2013 at 08:25 AM.
Reply With Quote
  #6  
Old 07-04-2013, 09:18 AM
Gruff's Avatar
GruffLayered Pictureboxes Gruff is offline
Bald Mountain Survivor

Retired Moderator
* Expert *
 
Join Date: Aug 2003
Location: Oregon, USA - deceased
Posts: 6,440
Default

Can you post the link to your VB6 source or the source as an attached zip file?

I could be wrong, but except for the video routines I would imagine the conversion would be fairly straight forward. (If you are familiar with VB.NET.)

By the looks of your link the Sun position is always in the same spot relative to the sine wave of darkness as it moves across the map. I would assume from right to left.

The hard part for me would be to come up with some sort of scalar that fit the map image proportionally. Same with the cities. Their coordinates need to fit the map as well... Sorry just thinking our loud.

Painting in VB.NET is very different than it was in VB6. Essentially you build a drawing engine and run it in the picture box's paint event. Your image gets updated whenever windows decides it needs to update the image or when you force a redraw by telling windows the control needs to be redrawn. You use the picture box invalidate method to do this.
__________________
Burn the land and boil the sea
You can't take the sky from me


~T
Reply With Quote
  #7  
Old 07-04-2013, 09:42 AM
n2amg n2amg is offline
Junior Contributor
 
Join Date: Aug 2001
Posts: 279
Default

With the graphicsobject Where should that be placed and how would it effect the x/y coordinates so I could use those to plot a small circle on the picturebox?? or a mouseover event?
Reply With Quote
  #8  
Old 07-04-2013, 10:06 AM
n2amg n2amg is offline
Junior Contributor
 
Join Date: Aug 2001
Posts: 279
Default

I have attached my source to this..
Attached Files
File Type: zip GrayLine.ZIP (1.91 MB, 22 views)
Reply With Quote
  #9  
Old 07-07-2013, 07:09 PM
n2amg n2amg is offline
Junior Contributor
 
Join Date: Aug 2001
Posts: 279
Default

Back after a few days in the woods. Now back to the conversion.. If I have questions I will ask..
Reply With Quote
  #10  
Old 07-08-2013, 06:05 PM
n2amg n2amg is offline
Junior Contributor
 
Join Date: Aug 2001
Posts: 279
Default

I'm playing around getting the hang of drawing in the picturebox and placing items on the form. In my vb6 version I use a label array that gets placed in the picturebox so I can convey info to the user via a tooltip. I am trying to do the same thing in vb.net .If I draw a marker on the picturebox using the commented out line they mark no problem. But I want to place the markers on the form as a label so i can use tooltips. Only the last marker shows up. I would think that all 3 markers would show. To recreate this you need a picturebox w/image, a button and a label (6x6 in size) that has no text and has a colored background.The button and Label should be placed inside the picturebox.

Code:
Public Class Form1
    Dim SpotMarker(100) As Label
    Dim SN As Integer
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        SN = 0
    End Sub
    Sub mapcoords(ByVal latitude As Double, ByVal longitude As Double)
        Dim pbwidth As Double = PictureBox1.Width
        Dim pbheight As Double = PictureBox1.Height
        Dim latratio As Double = pbheight / 180
        Dim longratio As Double = pbwidth / 360
        Dim latcord As Double = 90 - latitude
        Dim longcord As Double = (180 + longitude)
        latcord = latratio * latcord
        longcord = longratio * longcord
        'Dim g = PictureBox1.CreateGraphics
        'Dim pen1 = New Pen(Brushes.Red, 3)
        'g.DrawRectangle(pen1, CInt(longcord) - 1, CInt(latcord) - 1, 3, 3)
        SpotMarker(SN) = Label1
        SpotMarker(SN).Visible = True
        SpotMarker(SN).Location = New Point(CLng(longcord), CLng(latcord))
        SpotMarker(SN).BackColor = Drawing.Color.Yellow
        SN = SN + 1
    End Sub
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        mapcoords(43.104166, -76.04166)
        mapcoords(-43.104166, 76.04166)
        mapcoords(83.104166, 26.04166)
    End Sub
    Private Sub Label1_MouseHover(ByVal sender As Object, ByVal e As System.EventArgs) Handles Label1.MouseHover
        Me.ToolTip1.SetToolTip(Me.Label1, Label1.Tag)
    End Sub
    Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
        Debug.Print("X=" & e.X & "   Y= " & e.Y)
    End Sub
End Class
What am I doing wrong? or am I doing something I can't??

Rick
Reply With Quote
  #11  
Old 07-08-2013, 07:52 PM
snarfblam's Avatar
snarfblamLayered Pictureboxes snarfblam is offline
Senior Contributor

Forum Leader
* Expert *
 
Join Date: Apr 2005
Location: USA
Posts: 896
Default

Well, you're only using one label, so it can only show up in one place. Are you trying to create a control array? If so, you just need to create a new label for each blip. Then you can then set the tooltip for each label individually too.

I also see second problem. You're using SN as an index to your SpotMarker array, but you're setting SN to zero in FormLoad, and never changing it, so even if you had a properly implemented control array, you would still always be accessing the first item in the array.
__________________
C# _VB.NET _
Reply With Quote
  #12  
Old 07-08-2013, 08:04 PM
n2amg n2amg is offline
Junior Contributor
 
Join Date: Aug 2001
Posts: 279
Default

I think I have it figured out. I'm using this below..

Code:
    Sub mapcoords(ByVal latitude As Double, ByVal longitude As Double)
        Dim pbwidth As Double = PictureBox1.Width
        Dim pbheight As Double = PictureBox1.Height
        Dim latratio As Double = pbheight / 180
        Dim longratio As Double = pbwidth / 360
        Dim latcord As Double = 90 - latitude
        Dim longcord As Double = (180 + longitude)
        latcord = latratio * latcord
        longcord = longratio * longcord
        'Dim g = PictureBox1.CreateGraphics
        'Dim pen1 = New Pen(Brushes.Red, 3)
        'g.DrawRectangle(pen1, CInt(longcord) - 1, CInt(latcord) - 1, 3, 3)

        SpotMarker(SN) = New System.Windows.Forms.Label
        SpotMarker(SN).AutoSize = False
        SpotMarker(SN).Tag = "Test" & SN
        Me.ToolTip1.SetToolTip(Me.SpotMarker(SN), SpotMarker(SN).Tag)
        SpotMarker(SN).Visible = True
        SpotMarker(SN).Size = New Point(6, 6)
        SpotMarker(SN).Location = New Point(CLng(longcord), CLng(latcord))
        SpotMarker(SN).BackColor = Drawing.Color.Yellow
        PictureBox1.Controls.Add(SpotMarker(SN))
        SN = SN + 1
    End Sub

    Private Sub Button1_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim x As Short
        For x = 0 To SN
            PictureBox1.Controls.Remove(SpotMarker(SN))
        Next
        Array.Clear(SpotMarker, 0, SpotMarker.Length)
        SN = 0
        mapcoords(43.104166, -76.04166)
        mapcoords(-43.104166, 76.04166)
        mapcoords(83.104166, 26.04166)
    End Sub
The button click event will be replaced by reading data from a database. But this looks like it will work.
Reply With Quote
  #13  
Old 07-09-2013, 07:25 PM
n2amg n2amg is offline
Junior Contributor
 
Join Date: Aug 2001
Posts: 279
Default

While everything is working ok for placing the markers I started working on the terminator.
I placed a second picturebox over the top of the first one and made the background transparent. But in doing so I am no longer able to see the first the markers I placed in the Picturebox.
So I did as suggested and I tried both a panel and the form itself for placing the map image and placing the spotmarkers.. Both of these work but when I add a picturebox and make the background as transparent I can no longer see the spotmarkers.
I need the picturebox to draw the terminator in..

Lost in VB.net graphics
Rick
Reply With Quote
  #14  
Old 07-09-2013, 09:00 PM
snarfblam's Avatar
snarfblamLayered Pictureboxes snarfblam is offline
Senior Contributor

Forum Leader
* Expert *
 
Join Date: Apr 2005
Location: USA
Posts: 896
Default

Part of the problem is that you're using WinForms to render graphics, which isn't what it's meant for. The other problem is you're mixing nested and layered controls, which is just confusing.

The terminator you're talking about, is this just a graphic? If so, you can keep going the route you've been going by programatically inserting another picturebox inside the first one.
Code:
Dim terminatorPictureBox as New PictureBox
terminatorPictureBox.Image = My.Resources.AppropriateImage
' Plus whatever other initialization is necessary

pictureBoxWithMap.Controls.Add(terminatorPictureBox)
Alternatively, you could do your rendering/layering manually instead of by nesting controls.
Code:
Dim Buffer As New Bitmap(someWidth, someHeight)
Dim gBuffer As Graphics = Graphics.FromImage(Buffer)

Sub DrawLayeredImage
    gBuffer.Clear(Color.HotPink)
    gBuffer.DrawImage(layer1Image, otherstuffs)
    gBuffer.DrawImage(layer2Image, otherstuffs)
    gBuffer.DrawImage(terminatorImage, otherstuffs)
    ' Draw other stuffs if necessary

    ' If image isn't placed in picturebox already
    somePictureBox.Image = Buffer
    ' Otherwise, just tell the picturebox to redraw
    somePictureBox.Invalidate()
End Sub
__________________
C# _VB.NET _
Reply With Quote
  #15  
Old 07-09-2013, 09:18 PM
n2amg n2amg is offline
Junior Contributor
 
Join Date: Aug 2001
Posts: 279
Default

If you look at the image above.. The map background and spot markers are loaded into one picturebox and the darker shaded area is drawn on picturebox 2 and the contents of PB2 is blended over PB1. For some reason I wasn't thinking of the blending operation going on. In the vb app PB2 is hidden and just it's contents are placed over PB1 using the AlphaBlend API.

Last edited by n2amg; 07-09-2013 at 09:24 PM.
Reply With Quote
  #16  
Old 07-10-2013, 06:57 AM
AtmaWeapon's Avatar
AtmaWeaponLayered Pictureboxes AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

Quote:
Originally Posted by snarfblam
Part of the problem is that you're using WinForms to render graphics, which isn't what it's meant for.
Off-topic, but can you explain this a little better? It's the kind of sound byte that some cargo cultist will pick up on and use as justification to write entire apps using nothing but BitBlt() because "this guy said WinForms isn't for graphics". There's kind of a Graphics object with several dozen members related to rendering immediate-mode bitmapped graphics.
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
  #17  
Old 07-10-2013, 07:56 PM
passel's Avatar
passelLayered Pictureboxes passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,024
Default

Quote:
Originally Posted by n2amg View Post
... I have a working copy that works in vb6 but with so many changes between vb6 and .net I wanted to start from scratch. ...
I haven't replied to this thread before because I really don't have enough time to properly address the issues, but if you really do want "to start from scratch", then you really need to not jump right into this project, but study the VB.Net WinForms GDI+ based graphics paradigm a bit so you can know what capabilities you have available and design how you will apply them.
The understanding of the methods of doing graphics in legacy VB in almost entirely useless in VB.Net. Of course, you were bypassing VB6 and using windows GDI functions for a lot of your functionality, and that too is mostly not applicable to using VB.net, which provides graphics methods that provide access to GDI+ as the basis for WinForms graphics.

For instance, with your existing VB6 application, if you resize the form, the graphic is resized, not proportionally, to fill the given area of the form.
In VB.Net this (the stretching resizing) could be accomplished automatically without you having to redraw the image or resize the graphics container yourself.
For instance, you can dock a picturebox within a form so that it will automatically grow and shrink with the form resize (no code needed on your part).
You can assign a bitmap you've drawn to the image property of the picturebox and the picturebox can automatically stretch or shrink that image as it resizes (again, no code needed on your part).

What you would do is create a bitmap to draw on, do your drawing and assign it to the picturebox. You can update the bitmap as needed and have the picturebox refresh itself. If the user resizes the form, or moves windows over the form, the picturebox will automatically handle refreshing the screen image from the bitmap and growing or shrinking as necessary.

You shouldn't have to worry about scaling issues and changing coordinate systems since you would always be drawing in a fixed sized bitmap.

GDI+ is geared for bitmaps with alpha so has inherit support for the type of translucent night shading of the image you need, i.e. just create a dark blue brush with an alpha of 128 (50%), for instance and draw the night area.

If you really need to maintain different graphical elements and layer them transparently, then this is simple as well since when you create a bitmap object (without loading an image in it), all the pixels values are 0, which is fully transparent. You draw what symbols, lines, etc. you need in the bitmap, and when you use DrawImage to draw the bitmap in a graphics object, all the pixels you didn't draw into are still 0, so have no effect on the destination graphic.

Probably the trickiest thing to implement is the tooltip annunciations. I don't think that I would implement that by using a bunch of label controls, but would rather use mouse coordinates to hit test against a list of hotspot rectangles or a radius from hotspot points and display the information in a manner similar to a tooltip.
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
Reply With Quote
  #18  
Old 07-10-2013, 09:04 PM
snarfblam's Avatar
snarfblamLayered Pictureboxes snarfblam is offline
Senior Contributor

Forum Leader
* Expert *
 
Join Date: Apr 2005
Location: USA
Posts: 896
Default

Quote:
Originally Posted by AtmaWeapon View Post
Off-topic, but can you explain this a little better? It's the kind of sound byte that some cargo cultist will pick up on and use as justification to write entire apps using nothing but BitBlt() because "this guy said WinForms isn't for graphics".
Fair enough. It seems like what we're doing here is compositing several layers and graphics into a single image. The PictureBox in a Panel approach works well enough to draw a three-layered image for a quick and dirty project, but then if you start trying to do something more complicated you run into issues like "transparent controls aren't really transparent" or "this control was added as a child to the wrong control."

In the past I've been guilty of putting together the same sort of concoction. (In my case it was video game maps.) I've learned that using WinForms controls isn't a good solution for graphic complexity. You get an unnecessarily complex control hierarchy with slow reaction to input and ugly/slow redrawing.
__________________
C# _VB.NET _
Reply With Quote
  #19  
Old 07-10-2013, 09:26 PM
passel's Avatar
passelLayered Pictureboxes passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,024
Default

I started off putting together a simple project that illustrated the auto stretching capability as I described it above, but for a dynamically updating bitmap, while it works, might be a little less traditional.
So, despite the name of the project example, I modified it so it is less automatic, but along the lines of what you should normally see around the web.
In this case, because I don't have the time, it is a very simple example. It just has a static image captured from the vb6 version to represent the lower layer, and a second created bitmap object that you can draw on with the left mouse button to represent a method of drawing a transparent overlay layer. Added comments so is mostly self explanatory hopefully.
You can resize the form to see the image scale in a manner similar to the VB6 version.

p.s. Updated example to draw in the overlay Bitmap with a 10 pixel wide mostly transparent dark blue pen if you drag with the right mouse button.
Attached Files
File Type: zip AutoStretchExample.zip (157.0 KB, 7 views)
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.

Last edited by passel; 07-10-2013 at 10:09 PM. Reason: Updated example
Reply With Quote
  #20  
Old 07-20-2013, 09:25 PM
n2amg n2amg is offline
Junior Contributor
 
Join Date: Aug 2001
Posts: 279
Default

Sorry I haven't replied.. Just got out of the hospital today after 12 days for a bad infection..

But time was not lost. due to having a good wifi connection I was able to download and search for formula's and such that I needed to calculate the position of the sun and such. I am using just one picturebox. The map is the background and I'm drawing the terminator on the picturebox. Also using the labels for the indicator's.

I have attached the source to this.

There are 2 issues that I am having issues with.
The code that plots the terminator came from a a program that was using an image that was 360x180 If I keep the image at that size it works 98% correct. But I do not know what I would need to change so that the plotting follows the picturebox size and draw it to scale. I think the not scaling is causing the 2% of the oddities that occur.

The second thing is the terminator will not display unless I click on one of the borders to start a resize event then it will display. It should show as soon as the program loads..
I can only spend a little time in the chair working on until my leg is healed but I will try to explain anything I need to..

Rick
p.s. Passel I will look at your code later tonight..
Attached Files
File Type: zip GRAYLINE.ZIP (1.33 MB, 17 views)
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
Layered Pictureboxes
Layered Pictureboxes
Layered Pictureboxes Layered Pictureboxes
Layered Pictureboxes
Layered Pictureboxes
Layered Pictureboxes Layered Pictureboxes Layered Pictureboxes Layered Pictureboxes Layered Pictureboxes Layered Pictureboxes Layered Pictureboxes
Layered Pictureboxes
Layered Pictureboxes
 
Layered Pictureboxes
Layered Pictureboxes
 
-->