Tag Archives: Visual Basic

Visual Basic 6.0 na een upgrade van een windows 7 machine

Toen ik gisteren de windows 7 pc uitschakelde kreeg ik melding dat er tal van updates zouden plaatsvinden.
Deze morgen werden deze updates uitgevoerd en toen ik voor de dagtaak één van de visual basic6.0 projecten opende kreeg ik verschillende meldingen van niet geregistreerde objecten.

Ik opende enkele andere projecten en steevast met hetzelfde resultaat.
Dan de laptop maar eens ingeschakeld en daar openden de projecten, op een xp computer, wel nog.

Toen ik in de componenten van het project ging kijken zag ik dat het object mscomctl.oxc niet meer geladen was.

Ik opende een run box en voerde onderstaande in:

regsvr32 c:\windows\syswow64\MSCOMCTL.OCX

Nadien werkten al de projecten als voorheen, maar het was toch even schrikken.

Ik weet niet of dit ook voor zal doen op 32 bits pc’s die windows 7 draaien.

Visual basic en .ico

Zelf een icoontje maken om te fungeren als icoon van de geschreven software is mooi.
Maar het icoontje moet van het juiste formaat zijn. Zo zal een transparent gif bestand dat je via het net tot een favicon.ico omtoverde niet goed zijn. Visual basic geeft de melding Invalid picture.

Wat moet je dan wel doen?
Exporteer je afbeelding naar een jpg afbeelding.
Ga het vervolgens het net op en zoek een favicon maker. Ik gebruik deze.

Sla het bestand op en selecteer vervolgens jou hoofdscherm van het programma.
Klik in het venster eigenschappen op icon en selecteer vervolgens het favicon.ico.

In de properties van het project (menu project – properties) selecteer je het 2de tabblad (make).
Kies bij Icon in het frame Application voor het icon dat op jou hoofdformulier staat.

Compileer en de executable heeft nu jouw icon als icoon voor het programma.

XSD en XML

Ik zit al een tijdje te zwoegen op het inlezen van een XML bestand dat moet voldoen aan de normen van een XSD bestand.
Ik doe dit in VB6.0

Als ik mijn variabelen als volgt declareer :


' maak een referentie naar microsoft xml4.0 (project - references)
' declareer variabelen
Dim sSchemaFile As String
Dim sWorkFile As String
sSchemaFile = txtSchemaPath.Text
sWorkFile = txtPath.Text
Dim schemaCache As MSXML2.XMLSchemaCache40
Set schemaCache = New MSXML2.XMLSchemaCache40
' toevoegen van de namespace aan de schemacache
schemaCache.Add "http://mijnnamespace.be/xml", sSchemaFile
Dim xml_document As MSXML2.DOMDocument40
Set xml_document = New MSXML2.DOMDocument40
Set xml_document.Schemas = schemaCache

Dan wordt de XML file getoetst door
Set xml_document.Schemas = schemaCache

Inlezen van het bestand in onze variabele:
xml_document.async = False
If Not xml_document.Load(sWorkFile) Then
MsgBox "Error - : " & xml_document.parseError.reason
Exit Sub
End If

Maar als ik nu een enkele node of een reeks nodes in een nodeobject wens in te lezen dan krijg ik steeds een ‘Nothing’ als return waarde.


' declareer node objecten
Dim values_node As IXMLDOMNode ' single node
Dim values_nodelist As IXMLDOMNodeList ' nodelijst (array)

Set values_node = xml_document.SelectSingleNode("form//contactperson/name") --> Nothing
Set values_node = xml_document.SelectSingleNode("form//contactperson/name") --> Nothing

Ik heb de namespace dan toegevoegd aan de eigenschappen van het xml object (xml_document in mijn geval)

xml_document.validateOnParse = True 'nodig vooraleer we de namespace property instellen
xml_document.setProperty "SelectionNamespaces", "xmlns:x='http://mijnnamespace.be/xml'"

We gebruiken x als prefix.

Uitlezen:
Set values_node = xml_document.SelectSingleNode("x:form//contactperson/nom") --> Nothing
' Attributen uitlezen:
Set values_nodelist = xml_document.SelectNodes("x:form//@bedrag") --> array van bedragen

(Tijdelijke) Work around om ook die single node uit te lezen.

' in plaats van naar domdocument40 te refereren:
'Set xml_document.Schemas = schemaCache
Set xml_document = New MSXML2.DOMDocument
'Het xml_document valideren dmv de validate functie
Validate sWorkFile, sSchemaFile

Private Function Validate(ByVal strXMLPath As String, _
ByVal strXSDPath As String) As Boolean

Dim objSchemas As MSXML2.XMLSchemaCache40
Dim objXML As MSXML2.DOMDocument40
Dim objXSD As MSXML2.DOMDocument40
Dim strNamespace As String
Dim objErr As MSXML2.IXMLDOMParseError

' load XSD as DOM to populate in Schema Cache
Set objXSD = New MSXML2.DOMDocument40
objXSD.async = False
If Not objXSD.Load(strXSDPath) Then
Err.Raise 1, "Validate", "Load XSD failed: " & objXSD.parseError.reason
Else
' get namespace name from XSD targetNamespace attribute
strNamespace = objXSD.documentElement.getAttribute("targetNamespace")
End If

' populate schema cache
Set objSchemas = New MSXML2.XMLSchemaCache40
objSchemas.Add strNamespace, objXSD

' load XML file (without validation - that comes later)
Set objXML = New MSXML2.DOMDocument40
objXML.async = False
objXML.validateOnParse = False
objXML.resolveExternals = False

' load XML, without any validation
If Not objXML.Load(strXMLPath) Then
Err.Raise 1, "Validate", "Load XML failed: " & objXML.parseError.reason
End If

' bind Schema Cache to DOM
Set objXML.Schemas = objSchemas

' does this XML measure up?
Set objErr = objXML.Validate()

' any good?
Validate = (objErr.errorCode = 0)
If objErr.errorCode <> 0 Then
Err.Raise 1, "Validate", objErr.reason
End If

End Function

En dit werkt dus wel. Ook al vind ik het maar een beetje viesjes.

Openen van een visual basic project

Als je een Visual Basic project opent, is de kans groot dat al de forms die je de laatste keer bezoek bewerkt hebt, zich openen in de Editor.

Ik ben voorstander om een project te openen in een cleane werkomgeving.
Om dat te doen volstaat het om het vbw (Visual Basic Workspace) bestand van het project read only te maken.
Open het vbw bestand met een externe editor (vb notepad). Verwijder al de tekst die in het bestand staat en maak er een read only bestand van.

Als je nu de volgende keer jou visual basic project opstart, zal de editor geen forms meer openen.

Werken met een inifile

In het ‘oude’ visual basic werkte ik regelmatig met een inifile waarin veel settings stonden.
Omdat ik af en toe wel bezoek over de vloer krijg met als zoektermen visual basic6 of bestanden + visual basic geef ik hier graag de werkwijze weer om gegevens van en naar een inifile te schrijven.

Declaratie van functies:
Declare Function GetPrivateProfileString Lib "kernel32" Alias _
"GetPrivateProfileStringA" (ByVal lpApplicationName _
As String, ByVal lpKeyName As Any, ByVal lpDefault _
As String, ByVal lpReturnedString As String, ByVal _
nSize As Long, ByVal lpFileName As String) As Long
Declare Function WritePrivateProfileString Lib "kernel32" Alias _
"WritePrivateProfileStringA" (ByVal lpApplicationName _
As String, ByVal lpKeyName As Any, ByVal lpString As Any, _
ByVal lpFileName As String) As Long

Gegevens uit een inifile halen:

Public Function sGetINI(sINIfile As String, sSection As String, sKey _
As String, sDefault As String) As String

Dim sTemp As String * 256
Dim nLength As Integer

sTemp = Space$(256)

nLength = GetPrivateProfileString(sSection, sKey, sDefault, sTemp, _
255, sINIfile)
sGetINI = Left$(sTemp, nLength)

End Function

Gegevens naar een inifile schrijven
Public Sub writeINI(sINIfile As String, sSection As String, sKey _
As String, sValue As String)

Dim n As Integer
Dim sTemp As String

sTemp = sValue

'Replace any CR/LF characters with spaces
For n = 1 To Len(sValue)
If Mid$(sValue, n, 1) = vbCr Or Mid$(sValue, n, 1) = vbLf _
Then Mid$(sValue, n) = " "
Next n

n = WritePrivateProfileString(sSection, sKey, sTemp, sINIfile)

End Sub

Schermresolutie

Soms is het wel handig om te weten welke de schermresolutie van de computergebruiker is.
In Visual Basic 6 deed ik dat via een eenvoudige functie.

Public Function ScreenResolution()
Dim iW As Integer
Dim iH As Integer

iW = Screen.Width / Screen.TwipsPerPixelX
iH = Screen.Height / Screen.TwipsPerPixelY
ScreenResolution = iW & " x " & iH
End Function

In het form_load event van het formulier dat u wilt openen plaats je dan gewoon een if then constructie.

Bijvoorveeld:

If ScreenResolution = "1024 x 768" Then
Me.WindowState = vbMaximized
Else
Me.Width = 16290
Me.Height = 10545
End If

Beveiliging

Als we een programma hebben waarbij paswoorden of waarbij licentiessleutels gebruikt worden dienen we die paswoorden of sleutels te beveiligen.
Paswoorden dienen niet onbeveiligd over het netwerk gestuurd te worden.

Een voorbeeld om paswoorden in visual basic te encryperen en terug te decryperen geef ik hieronder mee.

Encoderen:
Public Function encode(str As String) As String
Dim i As Long
Dim r As String
For i = 1 To Len(str)
r = r & Chr(255 - Asc(str))
str = Right$(str, Len(str) - 1)
Next
encode = r
End Function

Decoderen:

Public Function decode(str As String) As String
Dim i As Long
Dim r As String
For i = 1 To Len(str)
r = r & Chr(255 - Asc(str))
str = Right$(str, Len(str) - 1)
Next
decode = r
End Function

Update:
Serge kwam me meldden dat dit niet echt encryperen is maar een reversible hash.

ADO Connections

Normaal leg ik de connectie naar een database via ODBC-gegevensbronbeheer. Zo voeg ik een DSN toe via mijn installatieprogramma (wise installmaster). Een probleem stelt zich echter wanneer de gebruiker van de pc niet voldoende rechten heeft om naar het register te schrijven.

Ik los dit dan op aan de hand van een inifile. De datasource wordt uit de inifile gelezen en de connectie kan gemaakt worden.
Maar wat als je nu een ado connectie wil maken naar een access database die met een paswoord beveiligd is?

Dan moeten we het paswoord natuurlijk in onze connectiestring opnemen. En dat werkt als volgt:

db.Open "PROVIDER=Microsoft.Jet.OLEDB.4.0;data source=" & strDSN & ";Jet OLEDB:Database Password=paswoord"

strDSN is dan het path naar waar de database zich bevindt en welk dus in de inifile vermeld staat.

dim strDSN as string
strDSN = sGetINI(sINIfile, "Data", "MijnDatabase", "")