Tuesday, December 16, 2008

[vb6] Use the IS operator to compare objects

With ordinary variables you would use the = operator to compare different variables. This does not work with object variables. Instead you have to use the IS operator, e.g.:
    Dim MyObject as MyClass
Dim MyOtherObject as MyClass

Set MyObject = New MyClass
Set MyOtherObject = MyObject

'Now, the two object variables reference the same object.

If MyOtherObject Is MyObject Then
'The message box should pop up:
MsgBox "Yes, MyObject points to the same object as MyOtherObject and vice versa"
End If
The IS operator must be used within an If - Then statement.

[vb6] Correct use of the Dir function

The Visual Basic Dir function is used to test if a certain file exists in a given directory. The Help topic in VB for the function states the function declaration: Dir[(pathname[, attributes])] The help topic incorrectly states that if the "attributes" parameter is omitted, all files are returned that match "pathname". In fact, if a file is flagged as Hidden, it will not be found by the Dir function, when no attributes are supplied to the function. Correct search for all files irrespective of their flags is therefore: Dir(pathname, vbNormal Or vbHidden Or vbSystem Or vbReadOnly)

[vb6] Disabling user input in combobox

If you don't want the user to be able to modify or delete text in the textbox part of a combobox control, you can set its style to 2 - dropdown list. However, in doing so, you also disable your own ability to do the same, because the text property is read-only at runtime. This means that if the style is set to 2 you cannot set the text property in code and you cannot link the combo box to a database either, because scrolling the database alters the textbox property. The solution is simple: Set the style to 0 - dropdown combo, its locked property to false and add the following to the combobox code:
    Private Sub Combo1_KeyDown(KeyCode As Integer, Shift As Integer)
If KeyCode <> vbKeyUp And KeyCode <> vbKeyDown Then
Combo1.Locked = True
End If
End Sub

' The up-down arrow keys must be allowed to enable
' mouse-less users to scroll the list.
' Unlock the combobox again on key up events:
Private Sub Combo1_KeyUp(KeyCode As Integer, Shift As Integer)
Combo1.Locked = False
End Sub

[vb6] Read the computer name and current user name

These functions may be used to retrieve the computer name and the name of the current user (or at least the names as they are known to the operating system).
    Private Declare Function GetComputerName& Lib "kernel32" Alias _
"GetComputerNameA" (ByVal lpBuffer As String, nSize As Long)
Private Declare Function GetUserName& Lib "advapi32.dll" Alias _
"GetUserNameA" (ByVal lpBuffer As String, nSize As Long)

Private Function ComputerName() As String
Dim s As String, l As Long
l = 15
s = String(l, Chr(32))
GetComputerName s, l
ComputerName = Left$(s, l)
End Function

Private Function UserName() As String
Dim s As String, l As Long
l = 255
s = String(l, Chr(32))
GetUserName s, l
UserName = Left$(s, l)
End Function

[vb6] Get the current color depth

If you are displaying graphics, you might like to learn the current color depth - true-color bitmaps generally don't look good on 256-color screens. The ColorDepth function returns the color depth as a bits per pixel number, for example on a true-color display the function will return 24. The function obtains a screen dc because the GetDeviceCaps function needs a dc for input.
    Private Const PLANES& = 14
Private Const BITSPIXEL& = 12
Private Declare Function GetDeviceCaps& Lib "gdi32" (ByVal hdc As Long, ByVal nIndex As Long)
Private Declare Function GetDC& Lib "user32" (ByVal hwnd As Long)
Private Declare Function ReleaseDC& Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long)

Private Function ColorDepth() As Integer
Dim nPlanes As Integer, BitsPerPixel As Integer, dc As Long
dc = GetDC(0)
nPlanes = GetDeviceCaps(dc, PLANES)
BitsPerPixel = GetDeviceCaps(dc, BITSPIXEL)
ReleaseDC 0, dc
ColorDepth = nPlanes * BitsPerPixel
End Function

[vb6] Convert global variables to global properties

You should consider removing all your global variables and implement them as private variables in a BAS module instead. Then, you can declare global property procedures in the BAS module to manipulate the private variables. This way, you can do parameter validation in the property let procedure.

[vb6] Make form stay on top

Sometimes you need a form to stay on top, even when another form has focus, so that its immediately available to the user. This code toggles the OnTop state for a form when passed the hwnd property of a form:
    Private Const GW_HWNDFIRST& = 0
Private Const HWND_NOTOPMOST& = -2
Private Const HWND_TOPMOST& = -1
Private Const SWP_NOMOVE& = &H2
Private Const SWP_NOSIZE& = &H1
Private Declare Function GetWindow& Lib "user32" _
(ByVal hwnd As Long, ByVal wCmd As Long)
Private Declare Function SetWindowPos& Lib "user32" _
(ByVal hwnd As Long, ByVal hWndInsertAfter As Long, _
ByVal x As Long, ByVal y As Long, ByVal cx As Long, _
ByVal cy As Long, ByVal wFlags As Long)

Private Sub ToggleTopmost(ByVal hWindow As Long)
Dim hw As Long
hw = GetWindow(hWindow, GW_HWNDFIRST)
If hw = hWindow Then
SetWindowPos hWindow, HWND_NOTOPMOST, 0, 0, 0, 0, _
SWP_NOMOVE Or SWP_NOSIZE
Else
SetWindowPos hWindow, HWND_TOPMOST, 0, 0, 0, 0, _
SWP_NOMOVE Or SWP_NOSIZE
End If
End Sub