by Chuck Kraatz
Graphics are of constant interest to VB developers, so this month I'm going to discuss a couple more graphics-related issues. I really enjoy getting your E-mail—keep it coming to chuck_kraatz@msn.com. I use them tips more each day, and I hope they help you in your development work.
I'll flip you for it32 Bit
Let's explore how to repaint existing graphics. The example I'll use flips a graphic either horizontally or vertically on demand. As always these days, Internet-style interfaces—with their greater dependency on graphics—drive our need to produce unique forms for our clients.
My sample form contains two command buttons and a picture box. I've chosen (for no particular reason) to use a control array for the command buttons. Like many design choices, this one is neither right nor wrong. The only request I make of my co-workers is that their choices be consistent.
Listing A shows the code related to this topic. Two form-level variables, one each for the image's vertical and horizontal position, work in concert to determine which formula to use to paint the image within the picture box. A simple If…ElseIf…End If group holds all four formulas, one for each combination of the two choices.
Listing A: Code to flip pictures
Option Explicit
Dim bHort As Boolean
Dim bVert As Boolean
Private Sub Command1_Click(Index As Integer)
Dim pic As StdPicture
Set pic = Picture1.Picture
Picture1.Cls
Select Case Index
Case 0 'Horoz
bHort = Not bHort
Case 1 'Vert
bVert = Not bVert
End Select
If bHort And bVert Then
Picture1.PaintPicture pic, _
Picture1.Width, Picture1.Height, _
Picture1.Width * -1, Picture1.Height * -1
ElseIf bHort And Not bVert Then
Picture1.PaintPicture pic, _
Picture1.Width, 0, Picture1.Width * -1, _
Picture1.Height
ElseIf Not bHort And bVert Then
Picture1.PaintPicture pic, 0, _
Picture1.Height, Picture1.Width, _
Picture1.Height * -1
Else
Picture1.PaintPicture pic, 0, 0
End If
End Sub
The real gist of this method lies in the Width and Height properties of the PictureBox control's PaintPicture method. By multiplying by –1, we create an inverted image.
You must also realize and account for the point at which you wish to start the drawing process. To draw the image at its original position and aspect, you need to set the X1 and Y1 parameters to 0. These correspond to the PictureBox control's Top and Left properties. When you wish to invert the image—horizontally, for example—you need to start at the upper-right corner of the picture box, which corresponds to the PictureBox.Width property.
You'll notice that I declare a variable of type StdPicture and assign the PictureBox's Picture property to this variable. You may wonder why I didn't place this information in a form variable or take into account the current aspect of the image before I try to repaint the image. My reason lies in the significant difference between a control's Image property and its Picture property. The Picture property is a bitmap, GIF, or other image that VB places in the control's graphic area. On the other hand, the Image is the area itself—so you can draw with the graphic methods Pset, Line, Circle, and so on.
We're actually painting the Picture property graphic into the image area of the picture box. The Picture property never changes—only the control's Image changes. Thus, I can use that original Picture property as my base aspect at all times.
Finally, many of the more experienced developers may say, "This technique sounds a lot like BitBlt." That's right! I define BitBlt as painting an onscreen image area one pixel at a time. Once you know the target region you want to paint from and the destination region you want to paint to, the rest of the process simply moves pixels to their new positions onscreen. (Remember the negative numbers in the Listing A calculations.) The PaintPicture function, which is simply a wrapper function of the BitBlt Window API function, lets us avoid making an API declaration.
Using PaintPicture to resize graphics 32 BitI have another cool use for the PaintPicture function. Sometimes, I'd like to be able to resize graphics in code rather than depend on a graphic artist. Plus, I'd like to resize on demand. To accomplish these tasks, you can add an Image control's Stretch property to a form or PictureBox control.
First, let's look at the function parameters for this VB tool. The function call and parameter list are as follows:
object.PaintPicture picture, x1, y1, width1, _
height1, x2, y2, widtb, height2, opcode
Table A shows the parameter definitions.
Table A: PaintPicture parameters
Parameter | Description |
object | Optional. Object expression that evaluates to an object in the Applies To list. If you omit object, VB assumes that the Form object with focus is object. |
picture | Required. The source of the graphic to be drawn onto object. Must be the Picture property of a form or picture box. |
Width1Optional. Indicates the destination width of picture. If the destination width is larger or smaller than the source width (widtb), VB stretches or compresses picture to fit. If omitted, VB uses the source width.
Height1Optional. Indicates the destination height of picture. If the destination height is larger or smaller than the source height (height2), VB stretches or compresses picture to fit. If omitted, VB uses the source height.
x2, y2Optional. Indicates the coordinates (X-axis and Y-axis) of a clipping region within picture. If omitted, VB assumes a 0 value.
WidtbOptional. Indicates the source width of a clipping region within picture. If omitted, VB uses the entire source width.
Height2Optional. Indicates the source height of a clipping region within picture. If omitted, VB uses the entire source height.
OpcodeOptional. Long value or code used only with bitmaps. Defines a bit-wise operation (such as vbMergeCopy or vbSrcAnd) that VB performs on picture as it's drawn on object.
First, let's consider the problem I needed to cure. Figure A show a series of controls with buttons on top; these controls will end up looking and behaving much like the Outlook 97 button bar.
Figure A: These controls illustrate three different looks.In the center, you can see the bitmap without buttons—it looks pretty good. In the control on the right, the buttons on top seem obscured by the background, and the titles are hard to read. In the control on the left, I've shrunk the background image and tiled it both vertically and horizontally. This control lets the buttons and their captions stand out while maintaining a cool look and feel.
Now, let's examine the code. Listing B shows a simple loop that handles the tiling and sizing. Notice I've cut the background image's size in half—as a result, I had to adjust the X and Y coordinates of the image's neighbor, as well.
Listing B: Tiling and sizing an image
Public Sub TileBitmapsProcessBar( _
ByRef ctl As Object, ByRef pic As PictureBox)
Dim lRet As Long
Dim nOuterCount As Integer
Dim nInnerCount As Integer
For nOuterCount = _
0 To (ctl.Width \ pic.Width \ 2) + 1
For nInnerCount = _
0 To (ctl.Height \ pic.Height \ 2) + 1
Picture1.PaintPicture pic.Picture, _
0 + nOuterCount * pic.ScaleWidth \ 2, _
0 + nInnerCount * _
pic.ScaleHeight \ 2, _
pic.ScaleWidth / 2, pic.ScaleHeight / 2
Next
Next
End Sub
My shrinking/stretching technique comes with one warning. If you change the overall proportions between the height and width, the image could become distorted very quickly. This result may be desirable if you want to place a co-worker's picture onscreen and resize the control's proportions on the fly. However, if it's your supervisor's image, he or she may not find your image contortions quite so cool….
Happy Computing!
Copyright © 1998, ZD
Inc. All rights reserved. ZD Journals and the ZD Journals logo are trademarks of ZD
Inc. Reproduction in whole or in part in any form or medium without
express written permission of ZD Inc. is prohibited. All other product
names and logos are trademarks or registered trademarks of their
respective owners.