Snabbare ActiveX kontroller med vTableBinding
Förord
Active X kontroller är av sin natur mycket långsammare än andra COM objekt. Det beror på objektsmodellen som Visual Basic använder för kontrollerna: bild: ActiveX objektsmodell, tagen från Programming Visual Basic 6.0 av: Francesco BalenaInnehåll
»»
Bilden visar en ActiveX kontrolls 'Extender Object' som lägger sig runt om 'vår' kontroll och därigenom slöar ner den. Extender object ger oss en del properties för vår kontroll som vi kanske inte vill ha eller behöver.
Hur råder vi bot på det här? Jo genom enkel COM baserad teknik, kan vi hoppa över extender objektet och komma in 'bakvägen' till vår kontroll
Principen är enkel, en Active x control kan aldrig bindas med vTableBinding, men det kan däremot en klassmodul. Så till vårt Active X kontroll lägger vi in en klassmodul som i sin tur refererar till kontrollens kärna.
Här är ett exempel:
1 Öppna ett nytt Active X kontroll projekt. Kalla kontrollen FastLb
2 Lägg till en klass modul kallad clDirectLine, Instancing skall vara satt till PublicNotCreatable
3 Lägg till en listbox på Active X kontrollen kalla den lbDemo
Nu är förberedelserna klara, dags att plocka in lite kod.
I Active X kontrollen lägg till följande kod:
Vad gör koden? Koden i sig skapar först ett nytt objekt av vår klassmodul när kontrollen initieras. Klassmodulen kan inte skapas direkt av ett annat Vb projekt, utan måste skapas av Active X kontrollen. Detta föra att vara säkra på att referenser och dyl, är satt ordentligt. Minimerar felrisken från användaren. Den talar också om vem som skapat det, en property vi kommer att använda i klass modulen.
Efter det skapar vi en property som returnerar en referens till objektet vi skapat
Då var det dags att gå över till klass modulen. Koden i den ser ut så här:
Då var koden för kontrollen klar. Som synes gör inte klassmodulen speciellt mycket egentligen. Den vidarbefodrar bara vårt anrop på AddListItem till kontrollen. Men genom att göra detta hoppar vi över Extender Object. Och får istället ett objekt att kalla på som bundits med vTableBinding. Vilket är det optimala för ett COM objekt.
Lägg nu till ett projekt till, det är dags att kolla hur mycket snabbare det blev.
1 Skapa ett standard .EXE projekt.
2 Stäng ner alla fönster tillhörande Active X kontrollen
3 Skapa en instans av kontrollen i det nya projektet.
4 Lägg till en textbox (text1) och två knappar (cmdDL ; cmdAx). Lägg också till en label kontroll kallad lblTime.
Exempel:
5. Klipp nu in följande kod till formen:
För att märka störst skillnad bör projektet kompileras och köras. Men även i utvecklingsmiljön syns en
För att märka störst skillnad bör projektet kompileras och köras. Men även i utvecklingsmiljön syns en markant skillnad på de olika typerna.
Om du gör någon intressant (eller kanske något konstigt fel) på grund av detta material så skicka gärna det med ett mail eller bifoga en länk till mig så presenterar jag detta som ytterligare exempelfiler för kursen. Om detta innehållet är felaktigt eller du lärt dig fler finesser så skriv gärna en rad eller varför inte en egen kurs baserat på dina erfarenheter. Sänd gärna in dina tips till denna artikel.
/Patrik Löwendahl
Hur råder vi bot på det här? Jo genom enkel COM baserad teknik, kan vi hoppa över extender objektet och komma in 'bakvägen' till vår kontroll
Principen är enkel, en Active x control kan aldrig bindas med vTableBinding, men det kan däremot en klassmodul. Så till vårt Active X kontroll lägger vi in en klassmodul som i sin tur refererar till kontrollens kärna.
Hur?
Här är ett exempel:1 Öppna ett nytt Active X kontroll projekt. Kalla kontrollen FastLb
2 Lägg till en klass modul kallad clDirectLine, Instancing skall vara satt till PublicNotCreatable
3 Lägg till en listbox på Active X kontrollen kalla den lbDemo
Nu är förberedelserna klara, dags att plocka in lite kod.
I Active X kontrollen lägg till följande kod:
Dim DirectLine As clDirectLine
Private Sub UserControl_Initialize()
Set DirectLine = New clDirectLine
Set DirectLine.Target = Me
' Skapa nytt clDirectLine objekt och returnera en
' Tala om för objektet vem som skapade det.
End Sub
Property Get dLine() As clDirectLine
Set dLine = DirectLine
' ge en referens till DirectLine objektet
End Property
Public Sub AddListItem(Name As string)
LbDemo.AddItem Name
End Sub
Public Sub ClearBox()
lbDemo.Clear
lbDemo.Refresh
End Sub
Vad gör koden? Koden i sig skapar först ett nytt objekt av vår klassmodul när kontrollen initieras. Klassmodulen kan inte skapas direkt av ett annat Vb projekt, utan måste skapas av Active X kontrollen. Detta föra att vara säkra på att referenser och dyl, är satt ordentligt. Minimerar felrisken från användaren. Den talar också om vem som skapat det, en property vi kommer att använda i klass modulen.
Efter det skapar vi en property som returnerar en referens till objektet vi skapat
Då var det dags att gå över till klass modulen. Koden i den ser ut så här:
Dim TargetControl As FastLb
' Två 'friend properties' som bara kan kallas från
' objekt inom samma projekt som klasmodulen.
Friend Property Get Target() As FastLb
Set Target = TargetControl
End Property
Friend Property Set Target(ByVal axTarget As FastLb)
Set TargetControl = axTarget
End Property
' Vår funktion.
Public Sub AddListItem(Name As String)
' Kalla på AddListItem i kontrollen
Call TargetControl.AddListItem(Name)
End Sub
Då var koden för kontrollen klar. Som synes gör inte klassmodulen speciellt mycket egentligen. Den vidarbefodrar bara vårt anrop på AddListItem till kontrollen. Men genom att göra detta hoppar vi över Extender Object. Och får istället ett objekt att kalla på som bundits med vTableBinding. Vilket är det optimala för ett COM objekt.
Lägg nu till ett projekt till, det är dags att kolla hur mycket snabbare det blev.
1 Skapa ett standard .EXE projekt.
2 Stäng ner alla fönster tillhörande Active X kontrollen
3 Skapa en instans av kontrollen i det nya projektet.
4 Lägg till en textbox (text1) och två knappar (cmdDL ; cmdAx). Lägg också till en label kontroll kallad lblTime.
Exempel:
5. Klipp nu in följande kod till formen:
För att märka störst skillnad bör projektet kompileras och köras. Men även i utvecklingsmiljön syns en
Dim DirectLine As clDirectLine
Private Sub Form_Load()
Set DirectLine = FastLb1.dLine
Text1.Text = 10000
End Sub
Private Sub cmdDL_Click()
Dim tid As Single, i As Integer
FastLb1.ClearBox: DoEvents
tid = Timer
For i = 1 to Cint(Text1.Text)
DirectLine.AddListItem "Item number" & Cstr(i)
Next i
LblTime.Caption = "DirectLine add = " & Format$(Timer - tid, "###.##") & "sek."
End Sub
Private Sub cmdAx_Click()
Dim tid As single, i As Integer
FastLb1.ClearBox: DoEvents
tid = Timer
For i = 1 to Cint(Text1.Text)
Fastlb1.AddListItem "Item number" & Cstr(i)
Next i
LblTime.Caption = "FaslLb add = " & Format$(Timer - tid, "###.##") & "sek."
End Sub
För att märka störst skillnad bör projektet kompileras och köras. Men även i utvecklingsmiljön syns en markant skillnad på de olika typerna.
Var denna artikeln användbar?
Om du gör någon intressant (eller kanske något konstigt fel) på grund av detta material så skicka gärna det med ett mail eller bifoga en länk till mig så presenterar jag detta som ytterligare exempelfiler för kursen. Om detta innehållet är felaktigt eller du lärt dig fler finesser så skriv gärna en rad eller varför inte en egen kurs baserat på dina erfarenheter. Sänd gärna in dina tips till denna artikel./Patrik Löwendahl
0 Kommentarer