[RESOLVED] Shape controls not drawn very precisely.
Can anyone explain why the shape controls don't draw very precisely?
I draw a square shape with an invisible background then diagonal line controls from corner to corners but the drawn points don't quite line up. Hoping it's visalble on the attached picture.
Top Left corner is ok but the rest of the square is offset.
Also keep in mind that if you tell Vb the shape is a square, it will draw a square centered in the shape. So, if the shape's size is not exactly a square (i.e., width=height), then the drawn square will be offset/centered within the shape's bounding rectangle.
Insomnia is just a byproduct of, "It can't be done"
To elaborate on what La Volpe said - it is not a bug:
Switch back and forth between rectangle and square if the shapes are not the same size then the shape control is not a square and the left coordinate is the upper left when the shape control is a rectangle. The shape is not the control it is within the control and the properties don't necessarily reflect the shapes dimensions.
technorobbo,
I don't understand how it's not a bug. The defined shape was actually a rectangle, but even then shouldn't make any difference from a square.
I define the shape .left , .top , .width, & .height . BorderWidth = 1 so should draw it as specified without be needing to make any manual tweaks.
I've worked out that a 10 "twip" adjustment seem to do the job though.
What technorobbo and I were trying to highlight is that the geometric shape drawn in the control is not necessarily the same size of the control.
If you said the shape is a square, and the control's width > height or height > width, then a square would be drawn, but centered within the shape. A shape set to rectangle, of course would draw a rectangle from edge to edge.
So, drawing a line from the bottom left corner to the top right corner of a "square" shape control that has unequal width & height is not guaranteed to line up correctly from corner to corner. If you define the shape with .Left, .Top, .Width, .Width then I would think the diagonal lines would line up correctly. Not on a VB machine at the moment, so I can't back that statement up.
Insomnia is just a byproduct of, "It can't be done"
Thanks,
It was a "rectangle" that I was drawing, I should have specified that even though the example happened to be a square. (width = height)
Still seems like a bug. Why wouldn't they make the shape the same size as the control?
Well, generally, unless a control has some sort of "AutoSize" property, controls will not size themselves to what is drawn inside of them. The Shape control doesn't have an AutoSize property so it resizes the drawn figure to the control's dimensions instead of the other way around. Why does it center the drawn figure? The control author had to make a decision: center, left justify or right justify or don't draw it.
Insomnia is just a byproduct of, "It can't be done"
I have a .left , .top, .height, and .width. And I want it to draw a rectangle to those specified dimensions. The lines I drew inside make no difference to the size of the shape, they only highlighted the problem.
My problem is that it doesn't draw the correct size and I can't imagine the situation where someone didn't want vb to follow their requirements
I think I now see what you are describing. It isn't a bug, but rather a function.
Without decompiling VB, I am pretty confident that the Rectangle drawn in the shape control is done via the API Rectangle. That API's description follows, notice the last line
Originally Posted by MSDN
...The extreme bottom and right edges of rectangle are not drawn because the bottom and right coordinates are treated as the width and height respectively of the rectangle instead of its edges
The above simply states that the far right and bottom edges are not included in the rectangle.
To highlight this, add the following code to a new form and run that form. You will see that the red rectangle is a shape control and only has its top/left corner centered in the little blue handles when all corners are really expected to be centered also. The black rectangle is done with the API Rectangle -- it is identical to the red rectangle and using the same dimensions.
Add a Shape control to the form first
Code:
Option Explicit
Private Declare Function Rectangle Lib "gdi32.dll" (ByVal hdc As Long, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Sub Form_Load()
Me.ScaleMode = vbPixels
Me.AutoRedraw = True
Shape1.BorderColor = vbRed
Show
Shape1.Move 10, 10, 50, 50
Me.Line (8, 8)-(12, 12), vbBlue, B
Me.Line (58, 8)-(62, 12), vbBlue, B
Me.Line (58, 58)-(62, 62), vbBlue, B
Me.Line (8, 58)-(12, 62), vbBlue, B
Dim offset As Long
offset = 70
Me.Line (8 + offset, 8)-(12 + offset, 12), vbBlue, B
Me.Line (58 + offset, 8)-(62 + offset, 12), vbBlue, B
Me.Line (58 + offset, 58)-(62 + offset, 62), vbBlue, B
Me.Line (8 + offset, 58)-(12 + offset, 62), vbBlue, B
Rectangle Me.hdc, 10 + offset, 10, 60 + offset, 60
End Sub
Now change this line: Shape1.Move 10, 10, 50, 50
To this & see the difference: Shape1.Move 10, 10, 50+1, 50+1
You will notice it is exactly what we wanted in the first place. So, bottom line, it is simply the result of a very common API function. BTW, many APIs/functions have the same restrictions, including regions and other shape drawing APIs. They will not include the far right/bottom edges. Just the way it is.
Last edited by LaVolpe; Jul 17th, 2009 at 06:17 PM.
Insomnia is just a byproduct of, "It can't be done"