Jalaj

December 14, 2006

Adding File Names to a ListBox - 3

Filed under: Visual Basic, WinAPI — Jalaj @ 4:02 am

Continued from Adding File Names to a ListBox - 2

The Performance degradation mentioned previously was due to the fact that all the instances of the app remained in the memory and kept querying for the Window handle until the form from the First instance gets fully loaded and handle made available. The answer to this problem would be that all instances other than the first one, store the filenames by some way and end up. The form window when gets completely loaded reads this filenames and add them to the listbox. Once loading communication as intended earlier would work normally.

This temporary storage medium can be anything, a plain text file, .ini file entry, registry entry, or MSMQ (Windows 2000 and above). To make least changes to our existing app I use here the intrinsic registry functions of VB. These function provides access to a part of registry i.e. “HKEY_CURRENT_USER\Software\VB and VBA Program Settings” and blocks access to rest of the registry. Our information being just a temporary data can live with it. So let’s get started with it.

For the part where duplicate instances keep looping until handle is obtained, we will change the code to that shown below.

        lngAppHandle = FindWindow(vbNullString, APPNAME)
        If lngAppHandle = 0 Then
            SaveSetting APPNAME, "FileNames", Trim(Mid(Command$, 2, Len(Command$) - 2)), "0"
	    End
        End If

This way when the duplicate instance fails to get window handle (this will happen only when form is not fully loaded), it will use SaveSetting function to write the filename to the registry under HKEY_CURRENT_USER\Software\VB and VBA Program Settings\My New App\FileNames\ as a value. All such instances keep adding a value until the form gets loaded.

When form gets activated the code below will search registry for all values and delete each one of them after adding the names to the list. The code below needs to be pasted in the code section of the Form.

Private Sub Form_Activate()
    Dim varSavedNames As Variant
    Dim i As Integer

    varSavedNames = GetAllSettings(APPNAME, "FileNames")

    If Not IsEmpty(varSavedNames) Then
        For i = LBound(varSavedNames) To UBound(varSavedNames)
            AddToList varSavedNames(i, 0)
        Next
        DeleteSetting APPNAME
    End If
End Sub

The GetAllSettings function reads the registry and places all values in a two dimesional array, the first column being the filenames. After adding all names to the list box, it will delete all entries added to the registry.

The complete code after this change would be as under

The Form’s Code Section

Private Sub cmdBrowse_Click()

    dlgBrowse.ShowOpen
    AddToList dlgBrowse.FileName

End Sub

Private Sub Form_Activate()
    Dim varSavedNames As Variant
    Dim i As Integer

    varSavedNames = GetAllSettings(APPNAME, "FileNames")

    If Not IsEmpty(varSavedNames) Then
        For i = LBound(varSavedNames) To UBound(varSavedNames)
            AddToList varSavedNames(i, 0)
        Next
        DeleteSetting APPNAME
    End If
End Sub

Private Sub lstFileNames_OLEDragDrop(Data As DataObject, Effect As Long, _
    Button As Integer, Shift As Integer, X As Single, Y As Single)

    Dim i As Integer

    For i = 1 To Data.Files.Count
        AddToList Data.Files(i)
    Next

End Sub

The Module Section

Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, _
    ByVal lpWindowName As String) As Long

Public Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, _
    ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long

Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, _
    ByVal wMsg As Long, ByVal wParam As Integer, ByVal lParam As Any) As Long

Public Const APPNAME = "My New App"
Public Const LB_ADDSTRING = &H180
Public Const LB_FINDSTRING = &H18F

Public lngAppHandle As Long
Public lngListBoxHandle As Long
Public blnCloseThisInstance As Boolean

Public varJunkVar As Variant
Public lngIndexToItem As Long

Sub Main()
    If Not App.PrevInstance Then
        Load Form1
        Form1.Visible = True
        Form1.Caption = APPNAME
        blnCloseThisInstance = False
        lngAppHandle = FindWindow(vbNullString, APPNAME)
    Else
        blnCloseThisInstance = True
        lngAppHandle = FindWindow(vbNullString, APPNAME)
        If lngAppHandle = 0 Then
            SaveSetting APPNAME, "FileNames", Trim(Mid(Command$, 2, Len(Command$) - 2)), "0"
        End If
    End If

    lngListBoxHandle = FindWindowEx(lngAppHandle, 0, "ThunderRT6ListBox", "")

    If lngListBoxHandle = 0 Then
        lngListBoxHandle = FindWindowEx(lngAppHandle, 0, "ThunderListBox", "")
    End If

    If Trim(Command$) <> "" Then
        AddToList Trim(Mid(Command$, 2, Len(Command$) - 2))
    End If

    If blnCloseThisInstance Then
        End
    End If

End Sub

Public Function AddToList(ByVal txtFileName As String)

    lngIndexToItem = SendMessage(lngListBoxHandle, LB_FINDSTRING, -1, ByVal CStr(txtFileName))
    If lngIndexToItem = -1 Then
        varJunkVar = SendMessage(lngListBoxHandle, LB_ADDSTRING, 0, ByVal CStr(txtFileName))
    End If

End Function

2 Comments »

  1. Nice…

    Comment by Eleni — August 20, 2007 @ 6:32 am

  2. helo everybody im mark…plz help me in my project on two-dimensional array using visual basic 6……..my project is “Airline Reservation”…….plz give me a code…….TNX

    Comment by mark — May 20, 2008 @ 12:27 am

RSS feed for comments on this post. TrackBack URI

Leave a comment

Blog at WordPress.com.