-
I've got a program which uses +/- 24 image boxes, they are being constantly updated. What would be the most efficient way to do this?
Is a picture box quicker to load or smaller in size than an image control?
Is there another way altogether?
Any ideas?
-
Try going to the project Menu and Selecting Components.
You will be presented with a huge list of additional controls to use select Microsoft Windows common Controls 6.0
and close the window, You should get some extra controls in your toolbox one of which should be an Imagelist control.
you can use this to hold all the images you need(just put one on the form and right click it then select Properties from the menu, the wizard is fairly self explanitory)
once you have all the pictures you need in the control use as few image controls as you need to display all the images you want at the same time then you can set which image to display in the immage box with the command line
Image1.picure=imagelist1.item(x)
where image1 is the imagebox you want to put the image in
imagelist1 is the image list controll youve just added and
x is the index of the image you want to display
image boxes use less memory than picture boxes but have an annoying habit of flickering.
I'm going to write you some code for using the BitBlt API to put these images directly on the form if you want to use a whole shitload of images at the same time. It Should be there in 5 or 10 minutes.
(or I might have a cup of coffe and a *** first)
(*** is Engish for cigarette so don't go thinking i'm strange)
-
Thanks, actually,
I'm using an imagelist control(well, 5 of them) to store the images. Theres +/- 500 at last count, and storing them in invisible frames/forms/whatever just seemed way too tedious.
I smoke myself, always good to hear that I'm not alone in that so-unpc habit.
its the actual placing of images which seems to slow things down, as oppossed to the storing of image.
I'm curious about this Bitblt API, I've noticed it mentioned on several other postings, and have not had a clue as to what it is about.
Any help you could give would be great.
-
Sory that took a bit longer than I expected
Add a new class module to your project and put the following code in it
Option Explicit
'ApiStructures
Private Type BITMAPINFOHEADER '40 bytes
biSize As Long
biWidth As Long
biHeight As Long
biPlanes As Integer
biBitCount As Integer
biCompression As Long
biSizeImage As Long
biXPelsPerMeter As Long
biYPelsPerMeter As Long
biClrUsed As Long
biClrImportant As Long
End Type
'API Constants
Const LENBITMAPINFOHEADER = 40
'API Declares
Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, _
ByVal x As Long, ByVal y As Long, _
ByVal nWidth As Long, ByVal nHeight As Long, _
ByVal hSrcDC As Long, _
ByVal xSrc As Long, ByVal ySrc As Long, _
ByVal dwRop As RasterOpConstants) As Long
Private Declare Function GetbitmapInfo Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, _
ByVal cLenth As Long, _
lpObject As BITMAPINFOHEADER) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc As Long, _
ByVal nWidth As Long, ByVal nHeight As Long) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, _
ByVal hObject As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
'Property Variables
Dim propTargetDC As Long
Dim propBitmap As Long
Dim propTop As Long
Dim propLeft As Long
Dim hBackgroundbitmap As Long
Dim lngBitmapWidth As Long
Dim lngBitmapHeight As Long
Dim boolIsShowing As Boolean
Public Property Let TargetDC(data As Long)
If Not boolIsShowing Then propTargetDC = data
End Property
Public Property Get TargetDC() As Long
TargetDC = propTargetDC
End Property
Public Property Let Picture(data As StdPicture)
Dim apiBitmapInfo As BITMAPINFOHEADER
Dim boolTemp As Boolean
boolTemp = boolIsShowing
'hide old picture
If boolTemp Then Me.Hide
'Change bitmap
propBitmap = data.Handle
'Get size
GetbitmapInfo propBitmap, LENBITMAPINFOHEADER, apiBitmapInfo
'Set Size Variables
lngBitmapWidth = apiBitmapInfo.biWidth
lngBitmapHeight = apiBitmapInfo.biHeight
'Show New one
If boolTemp Then Me.Show
End Property
Public Sub Hide()
Dim hMemDC As Long
If boolIsShowing And Not propTargetDC = 0 Then
'Create dc
hMemDC = CreateCompatibleDC(propTargetDC)
'Put bitmap into dc
DeleteObject SelectObject(hMemDC, hBackgroundbitmap)
BitBlt propTargetDC, _
propLeft, propTop, _
lngBitmapWidth, lngBitmapHeight, _
hMemDC, _
0, 0, _
vbSrcCopy
'deletedc
DeleteDC hMemDC
hBackgroundbitmap = 0
boolIsShowing = False
End If
End Sub
Public Sub Show()
Dim hMemDC As Long
If Not (boolIsShowing Or propTargetDC = 0) Then
'Create dc
hMemDC = CreateCompatibleDC(propTargetDC)
'Create background bitmap
hBackgroundbitmap = CreateCompatibleBitmap(propTargetDC, _
lngBitmapWidth, lngBitmapHeight)
'Put bitmap into dc
DeleteObject SelectObject(hMemDC, hBackgroundbitmap)
'get background
BitBlt hMemDC, _
propLeft, propTop, _
lngBitmapWidth, lngBitmapHeight, _
propTargetDC, _
0, 0, _
vbSrcCopy
'put bitmap into dc
SelectObject hMemDC, propBitmap
'paste bitmap onto target area
BitBlt propTargetDC, _
propLeft, propTop, _
lngBitmapWidth, lngBitmapHeight, _
hMemDC, _
0, 0, _
vbSrcCopy
'get bitmap out of dc
SelectObject hMemDC, CreateCompatibleBitmap(hMemDC, 1, 1)
'deletedc
DeleteDC hMemDC
boolIsShowing = True
End If
End Sub
Public Property Get Height() As Long
Height = lngBitmapHeight
End Property
Public Property Get Width() As Long
Width = lngBitmapWidth
End Property
Public Property Get Top() As Long
Top = propTop
End Property
Public Property Get Left() As Long
Left = propLeft
End Property
Public Property Let Top(data As Long)
Me.Move data, propLeft
End Property
Public Property Let Left(data As Long)
Me.Move propTop, data
End Property
Public Sub Move(NewTop As Long, NewLeft As Long)
Dim boolTemp As Boolean
boolTemp = boolIsShowing
'Hide old bitmap
If boolTemp Then Me.Hide
'set new variables
propTop = NewTop
propLeft = NewLeft
'Show Bitmap
If boolTemp Then Me.Show
End Sub
Private Sub Class_Terminate()
DeleteObject hBackgroundbitmap
End Sub
this class acts almost exactly like an image control but uses much less memory
NB all mesurements must be in pixels
also dont show it in the form load event because it wont show. Something to do width the way vb handles messages and raises its events which I wont go into
it doesnt work too well when it overlaps with other images and you can't do anything with it at design time (if you want to do that you have to use the extra memory)
I hope this helps
-
Merci,
your assistance is greatly appreciated.
-
Me again,
I've just seen your message after posting all that code plus I forgot to explain about the target dc property
set this property to form1.hdc if you want the code to work
you've got the declare statement for Bitblt up there, use this one instead of the one you get in the API Viewer and you get a nice picklist for the raster operation
First you should know what a DC is
DC is short for Device Contect which is the way windows handles all graphics operations
A device context is an area of memory which can be drawn to.
you can get the DC for VB Forms and picture boxes with the hDC property (not available at design time, Read only at run time)
You can draw to DCs with the APIs eg Circle,Line RoundRect etc Which are all in the API Viewer and fairly self explanitory but again all mesurements are in pixels.
Basicly the bitblt API copies an image from one device contect to another.
if you declare it like I did just select scrCopy for the last parameter and it should always work (The other parameters are easy)
the microsoft documentation is quite good for most of these APIs
I also Recomend "WIN32 API Programming" by seven Roman from O'Reilly Publishing which explains all this in much more detail.
NB Go to Addins Addin manager to get the API Viewer, I cant emember exactly how to set it up but the text file you need is win32api.txt which should be in microsoftvisualstudio\common\tools\api or something.
select view, Load last file and you wont have to load it every time you use the api viewer
-