1 Attachment(s)
What are the limits of VB6? (Can't create autoredraw image)
Hello!
I am not about to testing how big image can i load, or resizing a form, but i'm want to test what are the outer limits (max) of VB6 mdi forms can handle.
In test 1, (for some reason) i can open up 97 mdi childs, with a gradient filled picturebox, but the next will give me a Can't create autoredraw image.
In test 2, i have using 4 pieces of half size pictureboxes, with gradient fill (on the same width and height form). There i can open up 100 instances but the 4th image on the 100th child will be failing in the same reason.
Well its quite strange, that i can open up 2 more forms, but fill the same area. What are the limits in real?! Is there any experiment about this thread?
This is only a test, but i am working on a big application, that is able to use numeros instances of the same form (designer). There, it raising me the Autoredraw error right after i instantiate 30 clones of it. Well, the reason is i know, i am using some pictureboxes, but i also use a lots of usercontrols placed on those form.
But its getting quite annoying, that i dont know what limits should i set to the program, to avoid this issue?
Re: What are the limits of VB6? (Can't create autoredraw image)
Ok, now theres Cubase running, that it is eat up 280Mbyte mem, and 581M vm. The whole sytem memory usage is around 1,45Gb. I can open up 42 instances, the 43th will raise the error.
Now i shut down the cubase, the memory usage is back to 737 mbyte, i can bring up 97 instances.
I am a bit confused, why it happens.
Re: What are the limits of VB6? (Can't create autoredraw image)
Not sure if this helps or even works as I'm not knowledgeable enough to really understand it, but I recently saw this posted on the vb.general newsgroup.
Code:
Option Explicit
Private Declare Function CreateCompatibleBitmap Lib "gdi32" _
(ByVal hdc As Long, _
ByVal nWidth As Long, ByVal nHeight As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" _
(ByVal hObject As Long) As Long
Private Declare Function CreateDIBSection Lib "gdi32" _
(ByVal hdc As Long, pBitmapInfo As BITMAPINFO, _
ByVal un As Long, ByVal lplpVoid As Long, _
ByVal handle As Long, ByVal dw As Long) As Long
Private Const BI_RGB = 0&
Private Const DIB_RGB_COLORS = 0
Private Type BITMAPINFOHEADER
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
Private Type RGBQUAD
rgbBlue As Byte
rgbGreen As Byte
rgbRed As Byte
rgbReserved As Byte
End Type
Private Type BITMAPINFO
bmiHeader As BITMAPINFOHEADER
bmiColors As RGBQUAD
End Type
Private Sub Command1_Click()
' Note: this creates a 32 bit bitmap on a
' machine running at 32 bit colour depth,
' just so we can compare it to the VB
' Autoredraw Picture Box Image, which is
' also 32 bit on such a machine
Dim bmp(1 To 1000000) As Long
Dim x As Long, y As Long
Dim n As Long, z As Long
x = 1024: y = 768 ' <<< set size here
Do
n = n + 1
bmp(n) = CreateCompatibleBitmap(Me.hdc, x, y)
Loop Until bmp(n) = 0
For z = 1 To n - 1
DeleteObject bmp(z)
Next z
MsgBox "We were able to create " & Format(n - 1) & " bitmaps"
End Sub
Private Sub Command2_Click()
Dim DIB(1 To 1000000) As Long
Dim x As Long, y As Long
Dim n As Long, z As Long
x = 400: y = 300' <<< set size here
Dim bi24BitInfo As BITMAPINFO
With bi24BitInfo.bmiHeader
.biBitCount = 24
.biCompression = BI_RGB
.biPlanes = 1
.biSize = Len(bi24BitInfo.bmiHeader)
.biWidth = x
.biHeight = y
End With
Do
n = n + 1
DIB(n) = CreateDIBSection(Me.hdc, bi24BitInfo, _
DIB_RGB_COLORS, ByVal 0&, ByVal 0&, ByVal 0&)
Loop Until DIB(n) = 0
For z = 1 To n - 1
DeleteObject DIB(z)
Next z
MsgBox "We were able to create " & Format(n - 1) & " DIBs"
End Sub
Private Sub Form_Load()
Command1.Caption = "How many bitmaps?"
Command2.Caption = "How many DIBs?"
End Sub
Re: What are the limits of VB6? (Can't create autoredraw image)
It happens because of the memory usage. When you have the other app running, you have less memory in which your app can be laoded. Once it is closed down, its memory is freed up, and you can use more.
think of it like this.... the computer's memory is a glass. and this glass can hold 4 cups of a liquid. Now, let's say your app is water... you can pour up to 4 cups of water into the glass. Any more than that, and it overflows. Now, let's say that this other app is oil. If you put a cup of the oil into the glass, then trry to fill it with water, you're only going to get 3 cups of water into the glass. If you then remove the oil, then you have more space again to add more water.
-tg
Re: What are the limits of VB6? (Can't create autoredraw image)
@edgemeral: Ah, thanks, its cool i just forget to make a small dib/dc test, to see what are the limit i can use! I will implement something like this to see can i open a new window or not! The problem is, i cant avoid to generate an error message, the Cant create autoredraw image error message is happens, even if i place an On error goto! This is might be a solution, to avoid to happening the error, i just have to implmenet as much dibs and dc's as like the form does, so i can track down it will fit in the memory or not!
@technogome: Hey thanks :) Glasses and water! Well. I am not sure i get your point, but if your just want to point on that the memory is not endless, yes i know. I have a pair of 1 Gb Adata ddr2's (2gb in twin), so 1,5 Gb should not raise any hardware error, but it does! That means, its not a hardware and memory problem, but its a software issue, that this is may be a limit vb6, or i just cant find the reason why it cannot open more windows.
I also have to note, that my test app, will use only a 4-6mbyte of memory, and less than 1 mbyte of vm, but the error is occurs!
Re: What are the limits of VB6? (Can't create autoredraw image)
Actually it could still raise an issue. Even though not all of the memory might seem in use, it is partitioned into different types (stack vs heap). It maybe that you are pushing the limits of the stack. It also depends on the paging, as, for speed reasons, Windows will try to assign starting memory block on a page break (it's faster to find something on a nice boundary, rather than in the middle of the block). so it's possible that the memory is fragmented (much like a hard drive gets after a while). Then again, it maybe that your problem has nothing to do with any of this.
I gotta think that it's a memory management issue somehow... which may or may not be directly related to VB6.... I wonder if this happens at the same threashold in .NET or not...
-tg
Re: What are the limits of VB6? (Can't create autoredraw image)
Quote:
so it's possible that the memory is fragmented
You might be right. But, i can avoid this problem, by using @edgemeral 's tip, to see that i can create (reserve) some dibs and bitmaps or not. In case it creates them successfully, the form should coming up without any autoredraw issue. But, in case the memory is filled up, the dibs should generate the failure error, so the app can pop up the messagebox "Please close any window, before continue", or something similar that will tell the user to not use too much windows, but close them, he wont need them.
Re: What are the limits of VB6? (Can't create autoredraw image)
Jim
I too am of the opinion that it is RAM or video-RAM related.
I had an app that had two PictureBoxes -- PB2 was contained
in PB1. While PB1 was only physically about 10 inches horiz by
6 inches vert, PB2 was physically about 7 feet horiz by 4 feet vert
( !! ). When I tried to increase PB2 to 5 feet vert, I got the same
error statement -- Can't create Autoredraw image
I never resolved it (never got more RAM, that is), and learned to
live with what I was able to get to work. Fortunately, I subsequently
developed a completely different approach, and no longer ran into
that error statement.
Not much help, I know, but hope it is worth something
Spoo
Re: What are the limits of VB6? (Can't create autoredraw image)
I didn't even think of the video memory.... I was thinking purely of the main memory of the system...
Quote:
PB2 was physically about 7 feet horiz by 4 feet vert
( !! ).
:eek2: WOW... I didn't think you could make a picture box that large... what the heck did you have in there?
-tg
Re: What are the limits of VB6? (Can't create autoredraw image)
The system also hard to update the image contained in such a huge picturebox.
I also run into this issue, then i rewritten my code, to work on the current picturebox, but i draw the items, that they should appear or not. I use PosX and PosY values, to determine what are the topleft corner of the work-area that is select the items what will be appear.
So i use picturebox that is big as it look alike, i wont use the scrollable picturebox inside a picturebox method.
Windows XP also using system memory on desktop works (GDI), the extended VGA memory (those huge 512/1024 mbyte or more) are only reserved for bitmaps that directx using for texturing the polygons.
Re: What are the limits of VB6? (Can't create autoredraw image)
techgnome
Quote:
WOW... I didn't think you could make a picture box that large... what the heck did you have in there?
Haha !!
It was a zoomed-in stock market chart (actually, S&P 500 futures).
I had a data-point every 10 seconds. The market is open for 6 3/4
hours, so that equates to 405 x 6 = 2,340 "dots" (PSets). The dots
were about 1/30 " apart.
I've since gone to a 1-minute bar chart arrangement, so I only need
405 "bars". Those can be regenerated on-demand, so, regardless of
my zoom factor, I just regenerate the chart each time I need a new
chart.
Spoo
Re: What are the limits of VB6? (Can't create autoredraw image)
Jim Davis. The persistant picture property when autoredraw=true appears to be a DDB not DIB. This can be checked with the following code. If bmBits=0 then bitmap is DDB vs DIB.
Code:
Private Declare Function apiGetObject Lib "gdi32.dll" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, ByRef lpObject As Any) As Long
Private Type BITMAP
bmType As Long
bmWidth As Long
bmHeight As Long
bmWidthBytes As Long
bmPlanes As Integer
bmBitsPixel As Integer
bmBits As Long
End Type
Private Sub Command1_Click()
Dim bmp As BITMAP
apiGetObject Me.Picture.Handle, Len(bmp), bmp
Debug.Print bmp.bmBits
End Sub
DDBs are hardware restricted. Here is an interesting column on Dr Dobbs site.
Re: What are the limits of VB6? (Can't create autoredraw image)
Ok, thanks LaVolpe. However, in either case i set autoredraw true or false on a picturebox, the bmBits will be zero, just like all the members of the bitmap structure. It doesnt matter i draw to the area by using the Line() method or not.
But, as long as i load an image to the picturebox, the bmBits will be the bits of picture (24 for example), also in both case.
I am a bit confused.
Re: What are the limits of VB6? (Can't create autoredraw image)
Quote:
In Windows 3.x, 95, 98, and Me, Windows allocates a fixed amount of memory to each of the GDI and User heaps at startup, and can never allocate any more to them no matter how much global memory is free. As a result, it is possible to run out of free system resources while there is still abundant free memory. Because GlobalMemoryStatus does not return information about the GDI and User heaps, it is not appropriate to use GlobalMemoryStatus to monitor these system resources.
To determine free system resources in a 32-bit Visual Basic application, you must create and call a 16-Bit application that calls GetFreeSystemResources and exposes the information to other applications.
Hmm, this one is getting interesting...
http://support.microsoft.com/default...;EN-US;q190217
Re: What are the limits of VB6? (Can't create autoredraw image)
Quote:
Originally Posted by Jim Davis
Ok, thanks LaVolpe. However, in either case i set autoredraw true or false on a picturebox, the bmBits will be zero, just like all the members of the bitmap structure. It doesnt matter i draw to the area by using the Line() method or not.
But, as long as i load an image to the picturebox, the bmBits will be the bits of picture (24 for example), also in both case.
I am a bit confused.
I think you missed my point. It appears VB's autoredraw image is a DDB and therefore has limits as discussed in the link I provided. And it appears you also found some additional information too.
Re: What are the limits of VB6? (Can't create autoredraw image)
Quote:
It appears VB's autoredraw image is a DDB and therefore has limits as discussed in the link I provided
OK i got it. What i still dont get where it is occupies the memory. I didnt found any reference about the memory model of ddbs. Everywhere i read about ddb, they tell "device drivers", so i thought it will reserve the memory area on the vga, not in the system, but im not sure it does. :(
About the 16bit thing, that looks promising, but im not sure it will run fine on vista. Also im not sure it covers the memory areas that ddb reserves.
Re: What are the limits of VB6? (Can't create autoredraw image)
Could it be a limitation of the device driver, rather than an actual hardware/memory limitation?
-tg
Re: What are the limits of VB6? (Can't create autoredraw image)
vb Code:
Function GetFreeVidMem(lhWnd As Long) As Long
Dim oDX As DirectX7
Set oDX = New DirectX7
Dim oDD As DirectDraw7
Dim hwCaps As DDCAPS
Dim helCaps As DDCAPS
Set oDD = oDX.DirectDrawCreate("")
oDD.SetCooperativeLevel lhWnd, DDSCL_NORMAL
oDD.GetCaps hwCaps, helCaps
GetFreeVidMem = hwCaps.lVidMemFree
Set oDD = Nothing
Set oDX = Nothing
End Function
By using Direct7 i can monitor the amount of total/available video memory. It doesnt count i am opening up new instances of my forms, the value is remains the same, that means it is not using the video memory either. But then, where it reserves memory, i'm want to monitor the available (remaining) amount of it.
Quote:
Could it be a limitation of the device driver
Ok, but how can i monitor the limits?
Re: What are the limits of VB6? (Can't create autoredraw image)
Here is a more accurate version, to get the available video memory.
vb Code:
Function GetFreeVidMem2(lhWnd As Long) As Long
Dim oDX As DirectX7
Set oDX = New DirectX7
Dim oDD As DirectDraw7
Dim ddsCaps As DDSCAPS2
Set oDD = oDX.DirectDrawCreate("")
ddsCaps.lCaps = DDSCAPS_VIDEOMEMORY Or DDSCAPS_LOCALVIDMEM
GetFreeVidMem2 = oDD.GetFreeMem(ddsCaps)
'GetFreeVidMem2 = oDD.GetAvailableTotalMem(ddsCaps)
Set oDD = Nothing
Set oDX = Nothing
End Function
Unfortunately, it also doesnt count any memory usage, but 32mbyte all the time.
And, here is a WMI version, that will display the total memory, just for fun. It is slow, but in some case its better than calling dx7 to determine the total vga memory.
vb Code:
Function GetTotalVidMemWMI()
Dim objWMIService As Object, colSettings As Object, objVideoControllers As Object, strComputer As String
strComputer = "."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colSettings = objWMIService.ExecQuery("Select * from Win32_VideoController")
For Each objVideoControllers In colSettings
Debug.Print objVideoControllers.AdapterRAM
Next
Set colSettings = Nothing
Set objWMIService = Nothing
End Function
Where are the ddb's contained at? What memory?