Connessione al database con Visual Basic NET? Lo trovi su Opentraining.it Visual Basic Italia
OCX in primo piano (a cura di Vito Perrotta):
Seconda lezione:

Scopo della lezione:
Ho inserito nella prima parte la trattazione e la risoluzione di un problema abbastanza frequente : l'ordinamento di un array numerico (di tipo integer). Questo per creare una esigenza reale, in quanto gli OCX standard di VB, mentre eseguono egregiamente l'ordinamento al loro interno di stringhe (che poi sono gli elementi che inseriamo con Additem) tramite la proprietà Sort, non hanno un la stessa funzionalità per i valori numerici. Risolto il problema dell'ordinamento a livello di algoritmo possiamo ora dedicarci alla costruzione di un semplice OCX che fornisca questa funzionalità a livello nativo.

Seconda lezione
Per prima cosa apriamo un progetto nuovo in VB, di tipo StandardExe, che chiameremo PrjStub.vbp, il Form1 creato in automatico lo rinominiamo frmStub. Subito dopo aggiungiamo un progetto, nella stessa istanza di VB, di tipo ActiveXControl (OCX). Diamo il nome di ComboOCX a questo progetto.

Come prima cosa notiamo che, aprendo un progetto di tipo ActiveXControl, viene aperto uno UserControl, l'equivalente del Form1 di un progetto StandardExe. Le proprietà dello UserControl sono pressocchè uguali a quelle del Form, sulle differenze peraltro significative ritorneremo in seguito.

Per costruire un oggetto ComboOCX, con delle funzionalità aggiuntive, ovviamente, partiamo da un oggetto ComboBox di base. Dalla casella degli strumenti selezioniamo una ComboBox e inseriamola nello UserControl, diamo il nome di cboBase a questa combo. Non importa se la centriamo perfettamente. Per questa funzionalità utilizzeremo alcune istruzioni nell'evento UserControl_Resize() come riportato :

Private Sub UserControl_Resize()
'ad ogni ridimensionamento centro la combo box nello
'UserControl
cboBase.Left = 30
cboBase.Width = UserControl.Width - 60
cboBase.Top = 30
UserControl.Height = cboBase.Height + 60
End Sub


Notiamo che, mentre Left, Top e Width della combo sono legate alle dimensioni dello UserControl, Height non è influenzata ma influenza l'altezza dello UserControl. Questo perché in una combo l'altezza dipende dal Font.Size. Un effetto gradevole di queste istruzioni è quello di ottenere una ComboOCX resizable, proprio come una combo di tipo tradizionale.

Notiamo che la casella degli strumenti si è arricchita di una nuova icona, quella del nostro nuovo controllo OCX, che risulterà disabilitata fintanto che continueremo a scrivere codice negli eventi e/o proprietà del controllo stesso. Prima di chiudere la finestra di editino del codice del nuovo controllo, inseriamo questa istruzione nell'evento GotFocus dello UserControl :

Private Sub UserControl_GotFocus()
cboBase.SetFocus
End Sub


Questo farà si che, quando il controllo avrà il fuoco, quest'ultimo passerà direttamente alla cboBase. Chiudiamo l'editing dello UserControl. Ci ritornerà il Form frmStub del prjStub. Notiamo che l'icona del nuovo controllo che abbiamo creato è abilitata. Inseriamo il nuovo controllo sul form nella maniera solita e proviamo a ridimensiarlo un po' di volte. Il comportamento, limitatamente al resize, ovviamente, risulta essere identico ad una combo tradizionale.

Considerazioni conclusive:
La strada è ancora lunga per ottenere una ComboOCX di un certo peso. Nelle prossime lezioni le potenti funzionalità verranno via via incluse nel nostro nuovo OCX.

Prima di lasciarvi, come promesso, vi illustro l'algoritmo della ricerca dicotomica.
  • Si parte da una lista ordinata sul campo di ricerca
  • Si impostano tre indici : Elemento Iniziale, Elemento Medio, elemento Finale Dove l'elemento medio si ricava dalla formula:

    M = Int((F - I) / 2) + I


  • Si confronta il valore dell'Elemento Medio con il valore da ricercare Se è minore, il valore da ricercare può esistere solo nella parte di elementi da quello da quello Medio +1 a quello Finale, per cui non ho bisogno della parte di elementi da quello Iniziale a quello Medio. Scarto, quindi la parte di elementi che non mi servono semplicemente reimpostando:

    I = M


    ritornando al punto secondo. Se è maggiore, per le considerazioni opposte, imposto:

    F = M


    e ritorno al punto secondo. Se sono uguali si utilizza ugualmente F =M e al prossimo ottengo:

    F-I = 1


    che mi indica la corrispondenza o il primo elemento immediatamente successivo permettendo di uscire dal ciclo.

    Per permettervi di utilizzare da subito questo algoritmo l'ho applicato ad un controllo ComboBox ed inserito in una funzione che ne restituisce il ListIndex. Nelle prossime lezioni illustreremo l'utilità di questo potentissimo algoritmo di ricerca In applicazioni dove il normale comportamento della ComboBox per la ricerca dell'item desiderato ha tempi di risposta inaccettabili.

    Function basDicotomSearcCombo(sTarget As String, cboBase _
    As Object) As Long
    ' ----------------------------------------------------
    ' Funzione che restituisce la riga di un controllo
    ' su cui si opera una ricerca Dicotomica
    ' ----------------------------------------------------
    Dim I As Long
    Dim M As Long
    Dim F As Long
    Dim ncol As Integer
    F = cboBase.ListCount - 1
    If F < 1 Then
    basDicotomSearcCombo = F
    Exit Function
    End If

    I = 0 ' La Riga 0 è presa in esame

    Do
    ' -------------------------------------------------------
    ' Imposto i limiti di ricerca
    ' I = Indice minore, M = Indice Medio, F = Indice Massimo
    ' -------------------------------------------------------
    M = Int((F - I) / 2) + I

    If cboBase.List(M) < sTarget Then
    ' ----------------------------------------
    ' Scartiamo la parte inferiore della lista
    ' ----------------------------------------
    I = M
    Else
    ' ----------------------------------------
    ' Scartiamo la parte superiore della lista
    ' ----------------------------------------
    F = M
    End If
    If F - I = 1 Then
    ' ------------------------------
    ' Se Inizio e fine coincidono
    ' si trova la corrispondenza,
    ' o la prima corrispondenza
    ' immediatamente superiore
    ' ------------------------------
    Do
    ' La riga in esame è quella successiva
    ' ------------------------------------
    I = I + 1

    If I > cboBase.ListCount - 1 Then
    basDicotomSearcCombo = -1
    Exit Function
    End If

    ' Se si, ho trovato la riga iniziale
    ' ----------------------------------
    If cboBase.List(I) = sTarget Then Exit Do
    ' Altrimenti è la successiva
    ' --------------------------
    Loop
    basDicotomSearcCombo = I
    Exit Function
    End If
    Loop

    End Function


    Questo è, per il momento, tutto. Alla prossima.

    Scarica qui l'esempio

    Archivio lezioni OCX:
    28.11.00
    Lezione 1 (di Vito Perrotta)
    1.12.00
    Lezione 2 (di Vito Perrotta)
    7.12.00
    Lezione 3 (di Vito Perrotta)

    Visual Basic Italia© copyright 2000 - tutti i diritti riservati
    E-mail:
    vbitalia@libero.it