Home > Articles > Programming > Windows Programming

This chapter is from the book

Learning By Example: Adding Open and Save to FontPad

Recall FontPad from Chapter 6, "Font, Text, and Printing." This was our basic text editor to which we then added printing capabilities. We will round out this application by adding basic file I/O. After all, what's a text editor worth if it can't open and save files? By the time we're done, we should have completely replaced (or duplicated, anyway) the functionality of Notepad.

This example extends FontPad with an open and save dialog. Therefore, only the open and save dialogs are discussed here. To run the application, you should download the full source at http://www.samspublishing.com. After walking through the application, you should be able to extend the example as a test harness in which you can experiment with your own code.

Key Concepts Covered

The following represents the key class and concepts demonstrated with this sample application:

  • Accessing directory properties and enumerating directories with the DirectoryInfo class.

  • Accessing file properties and enumerating files in a directory with the FileInfo class.

  • Reading a file with the FileStream and StreamReader classes.

  • Persisting a file to disk with the FileStream and StreamWriter classes.

Open Dialog

To open files, we must present users with a method to browse the file system. .NET provides us with a FileDialog class specifically designed for this purpose. This class is similar to the common dialogs with which we're familiar from the VB of old. The .NET team built the dialog using the namespace we've presented in this chapter.

In our example application we will create our own dialog using the namespace rather than FileDialog. This makes sense because our objective is to teach the namespace. However, we suggest you further explore this class if you need fast and easy access to the file system. Figure 7.3 is a screen capture of our open dialog.

Obviously, this form will not win any usability or user interface design awards; it was built to illustrate code. There are two list boxes on the form. One maintains a current list of subdirectories of the given path. The other displays files of type text within the selected directory. Users navigate down through subdirectories by double-clicking a directory. To navigate back, they click the Up button. As directories and files are selected, we write related information to a couple of label controls.

Figure 7.3 FontPad: Open form screen shot.

Code Walkthrough

The code used by the open dialog should be very familiar to you by now. The code can be found in Listing 7.8.

The code starts with some form-level declarations for directory name and filename. This is followed by the basic code to build the form.

LISTING 7.8 FontPad: Open Form (formOpen.vb)

Public Class formOpen 

   Inherits System.Windows.Forms.Form 

   'form-level scope declarations 
   Dim myDirName As String 
   Dim myFileName As String 

# Region " Windows Form Designer generated code "

   Public Sub New() MyBase.New()
     'This call is required by the Windows Form Designer. 
     InitializeComponent() 

     'Add any initialization after the InitializeComponent() call 

   End Sub 
 
   'Form overrides dispose to clean up the component list. 
   Public Overloads Overrides Sub Dispose() 
     MyBase.Dispose() 
     If Not (components Is Nothing) Then 
        components.Dispose() 
     End If 
   End Sub 
   Private WithEvents buttonOk As System.Windows.Forms.Button 
   Private WithEvents buttonCancel As System.Windows.Forms.Button 
   Private WithEvents listBox1 As System.Windows.Forms.ListBox 
   Private WithEvents labelCurrentDir As System.Windows.Forms.Label 
   Private WithEvents buttonUp As System.Windows.Forms.Button 
   Private WithEvents labelDirInfo As System.Windows.Forms.Label 
   Private WithEvents label2 As System.Windows.Forms.Label 
   Private WithEvents label1 As System.Windows.Forms.Label 
   Private WithEvents labelFileInfo As System.Windows.Forms.Label 
   Private WithEvents listBoxFiles As System.Windows.Forms.ListBox 
   Private WithEvents listBoxDirectories As System.Windows.Forms.ListBox 
   Private WithEvents label5 As System.Windows.Forms.Label 
   Private WithEvents label3 As System.Windows.Forms.Label 

   'Required by the Windows Form Designer 
   Private components As System.ComponentModel.Container 

   'NOTE: The following procedure is required by the Windows Form Designer 
   'It can be modified using the Windows Form Designer. 
   'Do not modify it using the code editor. 
   < System.Diagnostics.DebuggerStepThrough()> Private Sub _ 
     InitializeComponent() 
     Me.labelDirInfo = New System.Windows.Forms.Label() 
     Me.listBoxFiles = New System.Windows.Forms.ListBox() 
     Me.labelCurrentDir = New System.Windows.Forms.Label() 
     Me.buttonCancel = New System.Windows.Forms.Button() 
     Me.buttonUp = New System.Windows.Forms.Button() 
     Me.listBoxDirectories = New System.Windows.Forms.ListBox() 
     Me.listBox1 = New System.Windows.Forms.ListBox() 
     Me.label5 = New System.Windows.Forms.Label() 
     Me.labelFileInfo = New System.Windows.Forms.Label() 
     Me.buttonOk = New System.Windows.Forms.Button() 
     Me.label1 = New System.Windows.Forms.Label() 
     Me.label2 = New System.Windows.Forms.Label() 
     Me.label3 = New System.Windows.Forms.Label()
     Me.labelDirInfo.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D
     Me.labelDirInfo.Location = New System.Drawing.Point(224, 96)
     Me.labelDirInfo.Size = New System.Drawing.Size(204, 72) 
     Me.labelDirInfo.TabIndex = 7 
     Me.listBoxFiles.Location = New System.Drawing.Point(8, 196) 
     Me.listBoxFiles.Size = New System.Drawing.Size(212, 134) 
     Me.listBoxFiles.TabIndex = 9 Me.labelCurrentDir.BorderStyle = _ 
         System.Windows.Forms.BorderStyle.Fixed3D 
     Me.labelCurrentDir.Location = New System.Drawing.Point(8, 28) 
     Me.labelCurrentDir.Size = New System.Drawing.Size(420, 16) 
     Me.labelCurrentDir.TabIndex = 6 
     Me.labelCurrentDir.Text = "Current: " 
     Me.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel 
     Me.buttonCancel.Location = New System.Drawing.Point(352, 336)   
     Me.buttonCancel.TabIndex = 0 
     Me.buttonCancel.Text = "Cancel" 
     Me.buttonUp.Location = New System.Drawing.Point(224, 48) 
     Me.buttonUp.Size = New System.Drawing.Size(28, 24) 
     Me.buttonUp.TabIndex = 5 Me.buttonUp.Text = "up" 
     Me.listBoxDirectories.Location = New System.Drawing.Point(8, 48) 
     Me.listBoxDirectories.Size = New System.Drawing.Size(212, 121) 
     Me.listBoxDirectories.TabIndex = 4 
     Me.listBox1.Location = New System.Drawing.Point(20, 60) 
     Me.listBox1.Size = New System.Drawing.Size(0, 4) 
     Me.listBox1.TabIndex = 3 
     Me.label5.Location = New System.Drawing.Point(224, 180) 
     Me.label5.Size = New System.Drawing.Size(92, 16) 
     Me.label5.TabIndex = 2 Me.label5.Text = "Info" 
     Me.labelFileInfo.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D 
     Me.labelFileInfo.Location = New System.Drawing.Point(224, 196) 
     Me.labelFileInfo.Size = New System.Drawing.Size(204, 132) 
     Me.labelFileInfo.TabIndex = 7 
     Me.buttonOk.Location = New System.Drawing.Point(272, 336) 
     Me.buttonOk.TabIndex = 1 
     Me.buttonOk.Text = "OK" 
     Me.label1.Location = New System.Drawing.Point(8, 8) 
     Me.label1.Size = New System.Drawing.Size(100, 16) 
     Me.label1.TabIndex = 8 
     Me.label1.Text = "Directories" 
     Me.label2.Location = New System.Drawing.Point(224, 80) 
     Me.label2.Size = New System.Drawing.Size(92, 16) 
     Me.label2.TabIndex = 2 
     Me.label2.Text = "Info" 
     Me.label3.Location = New System.Drawing.Point(6, 180) 
     Me.label3.Size = New System.Drawing.Size(100, 16) 
     Me.label3.TabIndex = 8 
     Me.label3.Text = "Files" 
     Me.AcceptButton = Me.buttonOk 
     Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13) 
     Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog 
     Me.CancelButton = Me.buttonCancel 
     Me.ClientSize = New System.Drawing.Size(433, 366) 
     Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.label5, _ 
        Me.labelFileInfo, Me.label3, Me.listBoxFiles, Me.label1, _ 
        Me.labelCurrentDir, Me.buttonUp, Me.listBoxDirectories, _ 
        Me.labelDirInfo, Me.label2, Me.listBox1, Me.buttonOk, _ 
        Me.buttonCancel}) 
        Me.Text = "Open Text File" 

End Sub 

On the form load event we simply make a call to the sub procedure that loads the directory list box.

Private Sub formOpen_Load(ByVal sender As System.Object, _ 
   ByVal e As System.EventArgs) Handles MyBase.Load 

   'purpose: load the form, init the controls 

   'local scope 

   'load the directory list box 
   Call loadDirListBox() 

End Sub 

The procedure loadDirListBox refreshes the contents of the directory list box when the form loads and as users double-click a subdirectory or press the Up button.

Private Sub loadDirListBox() 

   'purpose:    load the list box control based on the current path 

   'local scope 
   Dim myDirectory As System.IO.DirectoryInfo 
   Dim myDirectories() As System.IO.DirectoryInfo 
   Dim i As Integer 
   'clear the directory list box 
   listBoxDirectories().Items().Clear() 

   'create a new directory object 
   myDirectory = New System.IO.DirectoryInfo(path:=myPath) 

   'return the sub directories from the global directory object 
   myDirectories = myDirectory.GetDirectories() 

   'loop through the directories and add them to the list box 
   For i = 0 To UBound(myDirectories) - 1 

      'add the directory name to the list 
      listBoxDirectories().Items.Add(myDirectories(i).Name) 

   Next 

   'set the current label to indicate the current path 
   labelCurrentDir().Text = "Current: " & myPath 

   'select the first directory in the list 
   '  note:  this will trigger the events that fill the label control 
   '        and the files list box and its label control 
   If listBoxDirectories().Items.Count > 0 Then 
      listBoxDirectories().SelectedIndex = 0 
   End If 
End Sub 

Once the user has selected a file to open and has clicked the OK button, the button's click event calls a custom procedure we call readFile.

Private Sub buttonOk_Click(ByVal sender As System.Object, _ 
     ByVal e As System.EventArgs) Handles buttonOk.Click 

      'purpose:   respond to the OK button event 
      '          validate the form 
      '          open the user's selected file 

      'determine if the user does indeed have a text file selected 
      If Not (listBoxFiles().SelectedIndex > -1) Then 

        'tell the user to select a text file to continue 
        MsgBox(prompt:="Please select a text file.", _ 
              buttons:=MsgBoxStyle.Information, title:="FontPad Open") 

      Else 
        'open the text file as a stream and read it into our editor 
        'note: this new file will replace the current file without saving 
        Call readFile() 

         'close the form 
         Me.Close() 

      End If 
   End Sub 

The readFile procedure creates a StreamReader object, sets its read position to the start of the file, and reads the file line-by-line. Finally, our rich text box control is updated with the contents of the opened file.

Private Sub readFile() 
     'purpose:  read a file as a stream object 
     '         and put its content in the rich text box 

     'local scope 
     Dim fileStream As IO.FileStream 
     Dim streamReader As IO.StreamReader 

     'handle any errors the occur when loading the file stream 
     Try 
       'create a new instance of the file stream object 
       '   based on the current path and selected file 
       fileStream = New IO.FileStream(path:=myPath & myDirName & _ 
          myFileName, mode:=IO.FileMode.Open, access:=IO.FileAccess.Read) 

       'create a stream reader instance 
       streamReader = New IO.StreamReader(stream:=fileStream) 

       'set the file pointer to the start of the file 
       streamReader.BaseStream.Seek(offset:=0, _ 
       origin:=IO.SeekOrigin.Begin) 

       'set the textContents to nothing 
       'note the rich text box will be updated on form close 
       textContents = "" 

       'loop through the file and write to internal string variable 
       '   until end of file reached 
       Do While streamReader.Peek > -1 
           textContents = textContents & streamReader.ReadLine() & vbCrLf 
       Loop 

       'close the stream reader 
       streamReader.Close() 

    Catch 

       'indicate to the user that the file cannot be opened 
       MsgBox(prompt:="Sorry, unable to open the selected file", _ 
            buttons:=MsgBoxStyle.Exclamation, title:="FontPad Open") 

     End Try 
   End Sub 

Inside the listBoxDirectories double-click event we simply reset the path (myPath) and call load directories sub (loadDirListBox).

Private Sub listBoxDirectories_DoubleClick(ByVal sender As System.Object, _ 
      ByVal e As System.EventArgs) Handles listBoxDirectories.DoubleClick 

      'purpose:   manange the double-click event 
      '          which allows users to navigate down directories 

      'local scope 

      'set the new global path 
      myPath = myPath & myDirName
 
      'update the list directory list box 
      Call loadDirListBox() 
   End Sub 

When users select a directory from the list box, the directory list box's index change event gets fired. This event loads the file's list box based on the user-selected subdirectory. Inside this event, we trap for file security access issues. For instance, if you call the GetFiles method of the Directory object and the user is not granted access to the directory's files, we must raise this issue to our user.

Private Sub listBoxDirectories_SelectedIndexChanged( _ 
      ByVal sender As System.Object, ByVal e As System.EventArgs) _ 
      Handles listBoxDirectories.SelectedIndexChanged 

      'purpose:   update the directory info label and the file's list box 
      '          when users select a directory 

      'local scope 
      Dim myDirectory As System.IO.DirectoryInfo 
      Dim dirInfo As String 
      Dim myFiles() As System.IO.FileInfo 
      Dim i As Integer 

      'clear the listbox of its current contents 
      listBoxFiles().Items.Clear() 

      'clear the list box label 
      labelFileInfo().Text = "" 

      'get a directory info object based on the user's selection 
      myDirName = listBoxDirectories().SelectedItem.ToString & "\" 
      myDirectory = New System.IO.DirectoryInfo( _ 
          path:=(myPath & myDirName)) 

      'set the dir info 
      dirInfo = dirInfo & "Attributes: " & myDirectory.Attributes.ToString 
      labelDirInfo().Text = dirInfo 

      'get the files in the directory that are of type text 
      'NOTE: we handle security access exceptions 
      Try 
        myFiles = myDirectory.GetFiles(searchPattern:="*.txt") 

         'check for files 
         If UBound(myFiles) >= 0 Then 

           'loop through the files array and add to the listbox 
           For i = 0 To UBound(myFiles) - 1 
               listBoxFiles().Items.Add(myFiles(i).Name) 
            Next 

            'select the file in the list, this will trigger the event to
               change 

            ' the file info label control 
            If listBoxFiles().Items.Count > 0 Then 
              listBoxFiles().SelectedIndex = 0 
            End If 

         End If 

      Catch 
         MsgBox(prompt:= _ 
               "Sorry, but you do not have access to browse this folder's _
               files.", buttons:=MsgBoxStyle.Exclamation, title:="FontPad 
               Exception") 
      End Try 
   End Sub 

When a user selects a file, the SelectedIndexChanged event is fired. This event allows us to set the selected filename (myFileName) and update the file properties to the user.

Private Sub listBoxFiles_SelectedIndexChanged(ByVal sender As System.Object, _ 
      ByVal e As System.EventArgs) Handles listBoxFiles.SelectedIndexChanged 

       'purpose: change the contents of the file properties label 

       'local scope 
       Dim myFile As System.IO.FileInfo 
       Dim fileInfo As String 

       'set the file name 
       myFileName = listBoxFiles().SelectedItem.ToString 

       'create a new file object 
       myFile = New System.IO.FileInfo(fileName:=myPath & myDirName & _ 
            myFileName) 

        'set the file info to display 
        fileInfo = fileInfo & "Directory: " & _ 
          myFile.DirectoryName & vbCrLf & vbCrLf 
        fileInfo = fileInfo & "Created Time: " & _ 
          CStr(myFile.CreationTime) & vbCrLf & vbCrLf 
        fileInfo = fileInfo & "Size: " & _ 
          CStr(myFile.Length / 100) & " KB" & vbCrLf & vbCrLf 
        fileInfo = fileInfo & "Last Accessed: " & _ 
          CStr(myFile.LastAccessTime) & vbCrLf & vbCrLf 
        fileInfo = fileInfo & "Attributes: " & myFile.Attributes.ToString 
 
        'set the label to the file's info 
        labelFileInfo().Text = fileInfo 

   End Sub 

The Up button's click event simply navigates the user back up one folder.

Private Sub buttonUp_Click(ByVal sender As System.Object, _ 
      ByVal e As System.EventArgs) Handles buttonUp.Click 

      'purpose: move back one directory 

      'local scope 
      Dim intPos As Integer 

      'find the \ at the end of the path 
      intPos = InStrRev(stringCheck:=Mid(myPath, 1, Len(myPath) - 1), _ 
           stringMatch:="\") 
 
      If intPos = 0 Then 
         'no more path info 
         Beep() 
      Else 
         'trim the path back 
         myPath = Mid(myPath, 1, intPos) 
         Call loadDirListBox() 
      End If 

    End Sub 

#End Region 

End Class 

Save Dialog

Our application needs a way to persist its data to the file system. We create a Save dialog and associated code to do just that. Figure 7.4 is a screen capture of the Save dialog in action. Again, this dialog is sure to offend UI designers but it serves to illustrate the use of the classes.

The directory list box and associated Up button were stolen from the Open form. This simple paradigm provides users with access to the file system. A text box is provided for users to type the name to which they want to save the file.

Figure 7.4 FontPad: Save form.

The directory browsing provided by the form's code is nearly the same as the Open example (we might have considered creating a common dialog to be used by both features).

Code Walkthrough

Listing 7.9 presents the code behind the Open form.

Listing 7.9 starts with a form-level declare for storing the directory name. This is followed by the basic form code. After that, much of the code is similar to the code in the open dialog with the exception of the saveFile function.

LISTING 7.9 FontPad: Save Form (formSave.vb)

Public Class formSave 
      Inherits System.Windows.Forms.Form 
      'form-level scope declarations 
      Dim myDirName As String 

      'note: issues 
      '1. cannot save to the root directory
      '2. the return character not coming out right
      '3. files saved cannot be seen by the open
      '4. delete the file if exists??

#Region " Windows Form Designer generated code " 
   Public Sub New() 
      MyBase.New() 

      'This call is required by the Windows Form Designer. 
      InitializeComponent() 

      'Add any initialization after the InitializeComponent() call 

   End Sub 

   'Form overrides dispose to clean up the component list. 
   Public Overloads Overrides Sub Dispose() 
      MyBase.Dispose() 
      If Not (components Is Nothing) Then 
          components.Dispose() 
      End If 
   End Sub 
   Private WithEvents label1 As System.Windows.Forms.Label 
   Private WithEvents buttonOk As System.Windows.Forms.Button 
   Private WithEvents buttonCancel As System.Windows.Forms.Button 
   Private WithEvents buttonUp As System.Windows.Forms.Button 
   Private WithEvents label2 As System.Windows.Forms.Label 
   Private WithEvents textBoxFileName As System.Windows.Forms.TextBox 
   Private WithEvents listBoxDirectories As System.Windows.Forms.ListBox 
   Private WithEvents labelSaveTo As System.Windows.Forms.Label 

   'Required by the Windows Form Designer 
   Private components As System.ComponentModel.Container 

   'NOTE: The following procedure is required by the Windows Form Designer 
   'It can be modified using the Windows Form Designer. 
   'Do not modify it using the code editor. 
   <System.Diagnostics.DebuggerStepThrough()> Private Sub _ 
      InitializeComponent() 
      Me.label1 = New System.Windows.Forms.Label() 
      Me.buttonOk = New System.Windows.Forms.Button() 
      Me.label2 = New System.Windows.Forms.Label() 
      Me.buttonCancel = New System.Windows.Forms.Button() 
      Me.listBoxDirectories = New System.Windows.Forms.ListBox() 
      Me.labelSaveTo = New System.Windows.Forms.Label() 
      Me.textBoxFileName = New System.Windows.Forms.TextBox() 
      Me.buttonUp = New System.Windows.Forms.Button() 
      Me.SuspendLayout() 
      ' 
      'label1 
      '
      Me.label1.Location = New System.Drawing.Point(8, 8) 
      Me.label1.Name = "label1"1 
      Me.label1.Size = New System.Drawing.Size(124, 23) 
      Me.label1.TabIndex = 2 
      Me.label1.Text = "Save to directory:" 
      ' 
      'buttonOk 
      ' 
      Me.buttonOk.Location = New System.Drawing.Point(136, 220) 
      Me.buttonOk.Name = "buttonOk" 
      Me.buttonOk.TabIndex = 1 
      Me.buttonOk.Text = "OK" 
      ' 
      'label2 
      ' 
      Me.label2.Location = New System.Drawing.Point(4, 172) 
      Me.label2.Name = "label2" 
      Me.label2.TabIndex = 2 
      Me.label2.Text = "File name:" 
      ' 
      'buttonCancel 
      ' 
      Me.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel 
      Me.buttonCancel.Location = New System.Drawing.Point(216, 220) 
      Me.buttonCancel.Name = "buttonCancel" 
      Me.buttonCancel.TabIndex = 0 
      Me.buttonCancel.Text = "Cancel" 
      ' 
      'listBoxDirectories 
      ' 
      Me.listBoxDirectories.Location = New System.Drawing.Point(8, 72) 
      Me.listBoxDirectories.Name = "listBoxDirectories" 
      Me.listBoxDirectories.Size = New System.Drawing.Size(244, 95) 
      Me.listBoxDirectories.TabIndex = 3 
      ' 
      'labelSaveTo 
      ' 
      Me.labelSaveTo.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D 
      Me.labelSaveTo.Location = New System.Drawing.Point(8, 28) 
      Me.labelSaveTo.Name = "labelSaveTo" 
      Me.labelSaveTo.Size = New System.Drawing.Size(280, 36) 
      Me.labelSaveTo.TabIndex = 6 
      ' 
      'textBoxFileName 
      ' 
      Me.textBoxFileName.Location = New System.Drawing.Point(8, 192) 
      Me.textBoxFileName.Name = "textBoxFileName" 
      Me.textBoxFileName.Size = New System.Drawing.Size(280, 20) 
      Me.textBoxFileName.TabIndex = 5 Me.textBoxFileName.Text = "" 
     ' 
     'buttonUp 
     ' 
     Me.buttonUp.Location = New System.Drawing.Point(256, 72) 
     Me.buttonUp.Name = "buttonUp" 
     Me.buttonUp.Size = New System.Drawing.Size(32, 23) 
     Me.buttonUp.TabIndex = 4 
     Me.buttonUp.Text = "up" 
     ' 
     'formSave 
     ' 
     Me.AcceptButton = Me.buttonOk 
     Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13) 
     Me.CancelButton = Me.buttonCancel 
     Me.ClientSize = New System.Drawing.Size(298, 250) 
     Me.Controls.AddRange(New System.Windows.Forms.Control() _ 
         {Me.labelSaveTo, Me.textBoxFileName, Me.label2, Me.buttonUp, _ 
         Me.listBoxDirectories, Me.label1, Me.buttonOk, Me.buttonCancel}) 
     Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog 
     Me.Name = "formSave" 
     Me.Text = "Save Text File" 
     Me.ResumeLayout(False) 

   End Sub 
   Private Sub formSave_Load(ByVal sender As System.Object, _ 
      ByVal e As System.EventArgs) Handles MyBase.Load 

      'purpose: load the form 

      'local scope 

      'load the directory list box 
      Call loadDirListBox() 

   End Sub 

   Private Sub loadDirListBox() 

   'purpose:   load the list box control based on the current path 
   '          note: this procedure is the same as the one in formOpen 

   'local scope 
   Dim myDirectory As System.IO.DirectoryInfo 
   Dim myDirectories() As System.IO.DirectoryInfo 
   Dim i As Integer 

   'clear the directory list box 
   listBoxDirectories().Items().Clear() 

   'create a new directory object 
   myDirectory = New System.IO.DirectoryInfo(path:=myPath) 

   'return the sub directories from the global directory object 
   myDirectories = myDirectory.GetDirectories() 

   'loop through the directories and add them to the list box 
   For i = 0 To UBound(myDirectories) - 1 

        'add the directory name to the list 
        listBoxDirectories().Items.Add(myDirectories(i).Name) 

   Next 

   'select the first directory in the list 
   '   note: this will trigger the events that fill the label control 
   '       and the files list box and its label control 
   If listBoxDirectories().Items.Count > 0 Then 
     listBoxDirectories().SelectedIndex = 0 
   End If 
End Sub 
Private Sub listBoxDirectories_SelectedIndexChanged( _ 
   ByVal sender As System.Object, ByVal e As System.EventArgs) _ 
   Handles listBoxDirectories.SelectedIndexChanged 

   'purpose: update the directory name when users select a directory 

   'local scope 

   'set the directory's name 
   myDirName = listBoxDirectories().SelectedItem.ToString & "\" 

   'reset the save to directory 
   labelSaveTo().Text = myPath & myDirName 

End Sub 
Private Sub buttonUp_Click(ByVal sender As System.Object, _ 
    ByVal e As System.EventArgs) Handles buttonUp.Click 

    'purpose:  move back one directory 
    '         note: this proc. is the same as formOpen 

    'local scope 
    Dim intPos As Integer 

    'find the \ at the end of the path 
    intPos = InStrRev(stringCheck:=Mid(myPath, 1, Len(myPath) - 1), _ 
        stringMatch:="\") 

    If intPos = 0 Then 
        'no more path info 
        Beep() 
    Else 
        'trim the path back 
        myPath = Mid(myPath, 1, intPos) 
        Call loadDirListBox() 
    End If 

End Sub 
Private Sub listBoxDirectories_DoubleClick(ByVal sender As System.Object, _ 
    ByVal e As System.EventArgs) Handles listBoxDirectories.DoubleClick 

    'purpose:   manange the double-click event 
    '          which allows users to navigate down directories 
    '          note: same as formOpen's 

    'local scope 

    'set the new global path 
    myPath = myPath & myDirName 

    'reset the selected directory to nothing 
    myDirName = "" 

     'update the list directory list box 
     Call loadDirListBox() 

End Sub 
Private Sub buttonOk_Click(ByVal sender As System.Object, 
     ByVal e As System.EventArgs) Handles buttonOk.Click 
 
     'purpose: user has indicated they would like to apply their 
     'selections 

     'local scope 
     Dim fileName As String 

     'get the file name 
     fileName = Trim(textBoxFileName().Text) 

     'validate filename 
     If fileName = "" Then 

        'raise a message to the user 
        MsgBox(prompt:="Please enter a file name.", _ 
          buttons:=MsgBoxStyle.Exclamation, title:="FontPad Save") 

        'position cursor 
        textBoxFileName().Focus() 

     Else 

        'check the file name's extension 
        If Not fileName.EndsWith(".txt") Then 
           fileName = fileName.Insert(fileName.Length, ".txt") 
        End If 

        'call save file method 
        Call saveFile(fileName:=fileName) 

        'close the form 
        Me.Close() 

     End If 
End Sub 

The primary piece of functionality (save) can be found in the saveFile procedure. First, we use methods of the File class to determine if the file already exists. If a file does exist, we handle the situation by first deleting it and then saving it as new. This is a shortcut and not the best solution. A more robust design would tell the user the file already exists and prompt him to overwrite. Next, we create the FileStream object to write out the file. We open a StreamWriter instance and set it to start writing at the beginning of our file. After this, we call the Write method and pass it our contents as a string value. Finally we Flush and Close the StreamWriter instance. Our new file is now saved to disk.

Private Sub saveFile(ByVal fileName As String) 

      'purpose: save the contents of the rtb to a file 

      'local scope 
      Dim fileStream As IO.FileStream 
      Dim streamWriter As IO.StreamWriter 
      Dim filePath As String 

      'set the full path of the file 
      filePath = myPath & myDirName & fileName 

      'check if the file already exists in the directory 
      If IO.File.Exists(path:=filePath) Then 

         'the file already exists, we cheat and delete it 
         IO.File.Delete(path:=filePath) 

      End If 

      'create a new instance of the file stream object 
      'note:  if the file does not exist, the constructor will create it 
      fileStream = New IO.FileStream(path:=filePath, _ 
         mode:=IO.FileMode.OpenOrCreate, access:=IO.FileAccess.Write) 

      'create an instance of a character writer 
      streamWriter = New IO.StreamWriter(stream:=fileStream) 

      'set the file pointer to the end of the file 
      streamWriter.BaseStream.Seek(offset:=0, origin:=IO.SeekOrigin.Begin) 

      'write a line of text to the end of the file 
      streamWriter.Write(value:=textContents) 

      'apply the update to the file 
      streamWriter.Flush() 

      'close the stream writer 
      streamWriter.Close() 
      
      'close the file stream object 
      fileStream.Close() 

    End Sub 

#End Region 

End Class 

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020