VBcoders Guest



Don't have an account yet? Register
 


Forgot Password?



Updated 27 VB Hints and Tricks you should know

by Filipe Lage (7 Submissions)
Category: Miscellaneous
Difficulty: Intermediate
Date Added: Wed 3rd February 2021
Rating: (14 Votes)

Just a bunch of VB6 hints and tricks I thought I could share with you.
Many new hints and tricks you should know in VB6.
How to add events to Windows Application log
How to add controls in run time
VB6 and the 2GB File limit - Be aware
How to hide your application from task manager
ASM Subclassing - Moving back is the safest way
How to check for non-Modal permitions
How to implement DIR$ correctly in your application.
Convert ByteArrays to String and vice versa
And more...

Rate Updated 27 VB Hints and Tricks you should know

VB Hints:


Give description to your print jobs:



Before printing set APP.TITLE to the description of 
the print job. 

This way, the description of the document being printer will appear in the 
printer job window instead of your application 

name.

Ex:



app.title = "Invoice #1234"



[do the printing code and enddoc]



Quickly get data from a separated string



Let's consider 



dim a as string

dim atmp() as string

a="Text1;Text2;Text3;Text4"

atmp=split(a,";")

Test = a(3)



Now let's look at...



dim a as string

a="Text1;Text2;Text3;Text4"

Test = split(a,";")(3)



This way you can get the "Text4" string directly 
from split instead of mapping a temporary string (previous example). 

It's actually faster too ;)



Naturally, this also applies to tab delimited files. Example, Create a file 
in excel and export as TXT (Tab delimited)

You can get the cell from the respective row and column after reading 
contents to memory



function CellData(data as string, row as 
integer, column as integer) as variant

CellData = split(split(data,vbcrlf)(Row),vbtab)(Column)

end function



 



Quickly get rounding of a number the right way:



Since VB rounds fail in mathematical functions (ex: 
Round(2.5) results in 2 instead of 3)

we can avoid that by creating a new Round Function in VB



function MathRound(value as Double, 
optional lngDecimals as Long = 0) as double

MathRound = CDbl(Format$(value * 10^lngDecimals, "0")) / 10^lngDecimals

end function



This function also supports negative decimal places.

Ex: MathRound(1100,-3)=1000



There's a faster function (also created by me) available on the net if you 
prefer speed over simplicity.

Check it at 

http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=61414&lngWId=1

 



Immediate window



In case you don't know, you can use "?" to replace "debug.print" 
in the immediate window

Ex:

Go to immediate window and type:



? 1+1



It will appear: 2 (naturally)

It's useful to test functions or parts of code parsing the output value to 
the immediate window, or simply to check variables.

Ex: 



? a=3

False



BTW, if type it in your VB code itself, the "?" will 
be replaced to "Print" just after you press enter.

Ex:



me.? "test"



will be automatically replaced to:



Me.Print test




Use mouseweelfix



VB6 doesn't support mousewheel natively, so you 
can't scroll up and down with your mouse.

But there's a fix... actually, it's an addon for VB that scrolls the text 
and implements that so-much-needed function.

You can find it in microsoft here: http://support.microsoft.com/?id=837910

 



How to register an ActiveX in code.



Just make a declaration such as:



Private Declare Function REGISTER_MYDLL 
Lib "MYDLL.DLL" _

  Alias "DllRegisterServer" () As Long

Private Declare Function UNREGISTER_MYDLL Lib "MYDLL.DLL" _

  Alias "DllUnregisterServer" () As 
Long

Private Const ERROR_SUCCESS = &H0



Then, simply call



REGISTER_DLL



or



UNREGISTER_DLL



in your code to register or unregister the dll.



There are more advanced functions that enable you to specify the DLL to get 
registered on code instead of 

mapping the actual DLL file in the declaration. But if you know your DLL's, 
then simply include the declarations in the EXE 

and add 

an option to Fix components by calling the respectivefunctions

This also works for OCX files.



XCOPY Install?



YES! That is, if you only use OCX files...

In case your EXE requires external OCX files, and you put them in the same 
path as the EXE, they are loaded without any 

problems! :)

Doesn't work for dll's though. You still have to register them using 
regsvr32 or using the previous hint.

If you want to make sure your app works even without VB6 Runtimes, simply 
include MSVBVM60.DLL to your EXE path, but don't 

register it.

But if you want to run your application even though you're not sure if the 
target system has VB6 runtimes, just include

the MSVBVM60.DLL in the same path as the EXE... it works :). 

Note for "Virgin" Win95/98: 

Must have DCOM previous installed (it is installed with IE 4.5 anyway and 
MDAC's, and other updates)

 



How to enable/disable all controls in a form/container



to disable:



on error resume next

for each o in me.controls: o.enabled = False: next



to enable:



on error resume next

for each o in me.controls: o.enabled = True: next

 




How to change container of an object.



Example, place a commandbutton in a form, and add a 
frame next to it. 

Note that both controls will have Form1 as a parent.

If you want commandbutton to be included inside the frame, but to make it 
work in runtime simply add:



SET Command1.container = Frame1

 




Avoid using VB strings greater than 32k



VB Strings is the "Achilles's heel" of VB in terms of 
speed. (ok, strings and threading/subclassing)

I recomend you use a stringhelper object (check AllocString page at http://www.xbeat.net/vbspeed/) 
if you want 

big strings (1MB or more) to store data. Beware of this AllocString since 
the data inside the string will not be blank!


 



[Added 2006-02-02]

Read file from disk into memory (Fastest way possible without API 
with low cpu usage)



I've done this function to obtain all data from an 
existing file to memory. Note that if you have very large files (like 1GB) 
it will take 1GB of RAM as well... It's great to read data and handle it in 
memory. I get about 7MBytes/second in my P4-3000.


Public Function ReadFullFile(file As String) 
As Byte()

Dim a As Long

a = FreeFile

Open file For Binary As #a

ReDim ReadFullFile(LOF(a)-1)

Get #a, , ReadFullFile

Close #a

End Function

 


It stores all data in a bytearray... It's better 
than storing in a VB String, since all VB strings are stored in UNICODE, 
meaning that for each byte in the file, it will take 2 bytes of RAM. So, if 
I used a string, I would need 200MB of RAM to read a file of 100MB.


Naturally, you can convert it to string using the 
code:


Dim FileData as string

FileData = StrConv(Readfullfile(file),vbUnicode)


Be careful, since you can run out of out of memory 
with very large files!

You should also take in consideration, that if the file has 0 bytes or 
simply doesn't exist, it will result in an error, so you should make sure 
that the file being read exists and it's not 0 bytes long.


You can also change the function to read the file 
directly to a string, by using


Public Function ReadFullFile(file As String) 
As String

Dim a As Long

a = FreeFile

Open file For Binary As #a

ReadFullFile = Space(LOF(a)) ' You can use the VBSpeed's StringHelper to 
make this faster for large files

Get #a, , ReadFullFile

Close #a

End Function

 



Avoid VB IDE bugs



I've used VB for several years now, and I've 
discovered several bugs that many times corrupt projects and you should be 
aware of that.


Lost bags

First of all, if you have an UserControl present in your EXE project, 
remember that if you change the project name, all properties previously set 
in your forms will be lost. To be exact, all propbag's in your user 
controls become "blanks" and defaults are used.

Example:

You've added an UserControl to your project and you're using it in Form1. 
One of the properties of that user control is "Caption" and you've set that 
to "Hello world"... Nice, that is saved on the usercontrol's propbag... If 
you change the EXE project name, and check your form again, the "Hello world" 
is now gone.


Corrupt VBP's

One of the most annoying things in VB6 is that it sometimes corrupts 
the VBP's by mistaking some ActiveX objects with ActiveX controls.

Example: If you have ActiveX DLL's in your project references, and you also 
use external ActiveX Objects (usercontrols) in your forms, sometimes VB6 
will list the object as a reference. In conclusion, when you open the VBP 
once again, it will give a load error and all forms that use the "mixed up" 
control will have their objects replaced with a picture box.


This happens when you open several projects in VB (ex: 
EXE + DLL) and use an external OCX UserControl, compile the DLL with the other projects loaded, quit VB 
and save changes. After that, just load the EXE VBP.

When this problem happens, the solution I've found is to open the VBP with 
notepad and delete the "Reference" line that includes the OCX/VBP. Open the 
VBP, include the OCX once again in the add controls, and re-save the project 
(just the VBP). Reopen the VBP and all is well again.





[Added 2006-03-07]

Avoid using Subclassing... At least with ASM code on it

    Until recently, I've been using the ASM subclassing from (the 
great) 
VBAccelerator.com. The file ssubtmr6.dll to be exact.

    Unfortunatly, I had to return to the previous non-ASM code since every call crashed my application in a computer I had... 


    I investigated, and I found 
the reason... DEP - Data Execution Prevention... 

    Naturally, when DEP is used Windows XP and 2003.NET with a 
DEP compliant CPU (ex: AMD64 or the latests Intel CPU's), Windows will deny the ASM part of the subclassing 
to run (since the code is stored in a variable area and not in a code execution 
area)... 

    Windows automatically shows a GPF when the subclassing is initialized in 
this mode and the application is closed.



    There are two ways to avoid the problem:

    1) Not recomended

   
    Change the boot.ini of 
the operating system (not recomended) or add your application to the DEP 'exclusion' 
lists.

        Either way, it doesn't garantee a crash free operation, 
and the user has to add your application to the exclusion list manually.

    2) Recomended

        Return to the previous subclassing that 
doesn't use the ASM code.

        A little slower, but it's crash free with DEP compliant cpu's.


    This is my recomendation if you want to make a stable, 
subclassing application to be used in Windows XP and/or 2003.NET.


 


On error resume next... Beware!

    If you want a 99% crash free app, you can always add the on 
error resume next on the first line of every sub and function... I don't 
recomend it, but at least it won't show any VB Runtime errors... However, 
remember to set "on error goto 0" before the end of the function/sub, if not, 
your code may not work at all (exits the first function calls another one 
without resuming the next line if an error was raised in the second function).    




 


DIR$ - A great thing if you implement it right.

    VB has the DIR$ function so you can list folders and files, 
however you should be aware that this function is shared across your entire 
application. So, if you have one function that does something like:



    Sub ListFolder()

    mainpath = "c:\windows"

    a$=Dir$(mainpath)

    do until a$=""

    b$=HowManyDirs(mainpath & "\" & a$)

    a$=Dir$

    Loop



    Function HowManyDirs(f) as long

    b$=dir$(f,vbDirectory)

    do until b$=""

    HowManyDirs=HowManyDirs+1

    b$=dir$

    loop

    end function



    This code won't work at all, since the Dir$ function is 
common in the entire application. If the first sub is using the Dir$, no 
function should use it before the first sub finishes. You won't get the right 
results if you do.


 


Beyond 2GB files with VB

     
All VB functions to get file size (LOF(x) or 
FileLen(f)) are limited to longs... 

    That means that you only have 31 bits (+1 bit for sign) to 
store the size of the file... That gives VB a limit of 2147483648 bytes (2GB).

    Using internal functions and calls, like OPEN, SEEK, etc, you 
can't get data beyond this point, so you'll need to use the API for that.

    Anyway, you should be aware of this VB6 limitation if your 
project deals with very large files (ex: VOB's, MPG's, AVI's, etc) so you can 
implement the necessary 64-bit functions to avoid this limitation.

    In terms of internal results (ex: a function you implement to 
get the file size in 64-bits), I recomend you use the CURRENCY to get the file 
size... Even though "Currency" data type isn't a full integer type, you'll have 
the limit raised to 922.337.203.685.477 bytes (around 920 TeraBytes) per file 
that I think is good enough for the next few years ;)



    Hint: If you're using a function to check if a file exists on 
the hard disk, and your code is similar to:

            
Function DoesFileExist(f as string) as Boolean

              
On error resume next

              
DoesFileExist = (filelen(f)>0)

              
End Function

    You should be aware that VB's 
FileLen function reports negative values when a file is bigger than 2GB, so 
avoid using it unless you know what you're doing. In some cases, it can even 
report that the file doesn't exist even though the file is there.


 


Use VB's Application LogEvent to track your 
application status:

    VB provides a good way to log events to a file or to 
Windows NT/XP Application Log.

    Note that this will only in the compiled file. No event will 
be logged in IDE mode.

  

    How to log events to an external file:

         
App.StartLogging "c:\test.log", vbLogToFile ' or 
VbLogOverwrite

              
App.LogEvent "Hello world", vbLogEventTypeError

              
App.LogEvent "Hello world", vbLogEventTypeWarning

              
App.LogEvent "Hello world", vbLogEventTypeInformation



    How to log events to NT 
Application Log:

              
App.StartLogging "My Application", vbLogToNT

              
App.LogEvent "Hello world", vbLogEventTypeError

              
App.LogEvent "Hello world", vbLogEventTypeWarning

              
App.LogEvent "Hello world", vbLogEventTypeInformation

      One great thing about 
this is that your other calls (ex: DLL's and OCX's) can use the logevent to the 
same log as the main EXE file.

    This is great to debug a applications or communication 
services. 

    Just remember not to log TOO MUCH or else it will be filled 
with irrelevent data.


 


Some functions that most people are unware of

    How to convert a byte array to a string: 

        
MyString = strconv(MyByteArray, vbUnicode)


    How to convert a string to a byte 
array: 

        
MyByteArray = StrConv(MyString, vbFromUnicode)


    How to add controls to your forms in
run mode

           
Private WithEvents Text1 As TextBox ' So you can also have events

            Sub 
AddTextBox()

            Set Text1 = 
Me.Controls.Add("VB.TextBox", "Text1")

            ' Now we have 
the control, just as if it was added on design mode.

            Text1.Move 0, 
0, 500, 100

            Text1.Visible 
= True

            End With

        This also 
works with other controls (ex: Winsock) as long as the control is present in 
your project's VB toolbox.

        In this case you also need to remove 
the check 'Remove information about unused ActiveX' in 

        the VB compilation options unless if 
you have at least one control present in any of your project forms.


    How can you check the number of forms 
currently loaded:

        
NumberOfFormsLoaded = vb.Forms.Count  


    How to unload all forms in a MDI 
project safely:

          
do until vb.Forms.Count <=0 

            unload 
vb.forms(0)

            loop

        Note: if 
you have in your form's QueryUnload or Unload events, the possibility of a 
cancel operation this code won't work properly.


    Check if you can show a non-Modal 
form before you try it to show it.

           
MyForm.Show (1+App.NonModalAllowed)

        This will automatically show your 
form in Modal mode is a previous form is already in that mode...

        Note that if you try to show a 
non-Modal form when a Modal form is visible, VB will stop the execution with a 
run time error, crashing your application entirely, so this is safe to use 
ensuring that no "Non-Modal" run time error occurs.


    How to hide your application from the 
Task Manager's "Applications" tab (however it will be visible in the "Processes" 
tab):

            
App.TaskVisible = False


Cheers



// FCLage 


2006-03-07

Download this snippet    Add to My Saved Code

Updated 27 VB Hints and Tricks you should know Comments

No comments have been posted about Updated 27 VB Hints and Tricks you should know. Why not be the first to post a comment about Updated 27 VB Hints and Tricks you should know.

Post your comment

Subject:
Message:
0/1000 characters