Visual Basic Projects

WritePrivateProfileString: Creating a Quiz Application
Step 1: Introduction and BAS Module
     
Posted:   Tuesday August 24, 1999
Updated:   Monday December 26, 2011
     
Applies to:   VB4-32, VB5, VB6, and VB3, VB4-16 with appropriate declarations
Developed with:   VB6, Windows NT4
OS restrictions:   None
Author:   VBnet - Randy Birch
     
 Other project pages:   Step 1: Introduction and BAS Module
Step 2: Building the 'TopScores' Form
Step 3: Building the Quiz Topic Selection Form
Step 4: Building the Main Quiz Form
Form Illustration Layouts
Downloadable Kidz Quiz INI file

Related:  

WritePrivateProfileString: INI Files - The Basics
WritePrivateProfileString: INI Files - Saving Entire Sections
     
 Prerequisites
None.

This project creates an INI file-based Kid's Quiz application that can be fully customized to suit the ages and interests of your children. And without too much extra work it could be expanded to an adult quiz, or one suitable for school use. The project draws upon several routines, principles and methods that have been presented separately on other VBnet pages.

The illustration to the right shows the main application form (scaled down considerably to fit the web pages). For those interested in creating this project, I have also provided a page with all the forms in design mode complete with control names and placement. The illustration below shows the same form running where the user had chosen the wrong answer, and the app is telling the user what the correct answer was. The remaining illustrations below show other forms that make up this project.

kidz2wrong.gif (6367 bytes)The principle of the application is pretty simple.

An ini file contains series of single-line entries, with each line containing a question, four possible answers and an indicator as to which of those four answers is the correct one. The application provides you with the ability to define multiple ini sections within the file that can be used to cover different topics or present questions of differing skill levels. The application has no practical limit to the number of questions it can load and present to the user, and the participant's score is tallied as each question is correctly answered.

As the quiz progresses the user's score is displayed and, if they meet acceptable criteria you set in the application, they can add their name to a "Top Scores" list. And, before displaying the Top Scores listing to the user, the user's current score is saved into a random-access format "score file" which is loaded and sorted by high score to show winners where they stand in the total listings. Sorting ensures the highest scorer is presented at the top of the list.

As the project is currently coded, the participant can, at any time, quit the program, select a different category of questions, or view top scores. But they cannot advance without at least attempting to answer a question -- and they are given only one attempt via pressing the "Am I Right" button. The app rewards users by presenting either a "Correct" statement when the answer is right, or points out the correct answer when wrong (as shown in these two illustrations). You will probably want to customize some aspects of these features to suit the intended purpose of the quiz..

Copiously commented, developers with an intermediate or better understanding of VB should find the code on this and the following three pages pretty easy to understand. This is not really a beginner's project unless the beginner is comfortable with another language; true programming newbies may get a bit lost, and will have to carefully scrutinize and understand each section of the code in order to understand the application's program flow before any attempt is made to customize the code for a specific purpose.

I originally developed this app back in VB3 days for a teacher who wanted to learn how to program a quiz for his grade 6 students. Since then I've migrated the code to VB6 and added a few enhancements, all presented here.

Could it be improved? Naturally. For example, I retained the use of public variables to store ini file and other data - some of these would now better be served becoming either properties of the form or, in a few cases, Public variables of the form. The top scores and questions could even become classes if you have the patience and inkling -- classes are not my cup of tea. As you work with this you'll discover plenty additional ideas to customize the project, but it is fully functional and easy to adapt just the way it is.

Enough talk .. lets get to it!

kidz5topscores.gif (4564 bytes)

kidz4name.gif (3341 bytes)

 BAS Code: KidzQuiz.bas
This module has some common routines, so just copy and place the following code into the general declarations area of a bas module:

Option Explicit
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Copyright ©1996-2011 VBnet/Randy Birch, All Rights Reserved.
' Some pages may also contain other copyrights by the author.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Distribution: You can freely use this code in your own
'               applications, but you may not reproduce 
'               or publish this code on any web site,
'               online service, or distribute as source 
'               on any media without express permission.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Public Const LB_SETTABSTOPS = &H192

Public 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
   
Public 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
   
Public Declare Function SendMessage Lib "user32" _
   Alias "SendMessageA" _
  (ByVal hwnd As Long, ByVal wMsg As Long, _
   ByVal wParam As Long, lParam As Any) As Long
    

'this array holds the questions loaded
'from the file. It's dimensions are set
'in the Begin routine once the number
'of questions in a section are known.
Public Questions() As String

'the ini file containing the questions
Public sIniQFile As String

'the ini section chosen by the user
Public iniQuizSection As String

'a flag to tell the HiScores form to display
'the Add Name dialog when shown.
Public GetHiScoreNameFlag As Long

'the name of the file containing the high scores
Public sHighScoreFile As String

'this is the user-defined type used to store
'the high scores. It is currently set for a
'maximum log of the 40 top scores.
Type QuizStudentsTopScores
  SNames(1 To 40)     As String * 24
  SDate(1 To 40)      As Single
  SScores(1 To 40)    As Integer
End Type

'this is what the above Type will be known
'as in the HiScore form routines
Public TopScores As QuizStudentsTopScores


Public Function ppGetItemsInfo(Group As String, _
                               item As String, _
                               sIniQFile As String) As String

'This function calls the GetPrivateProfileString
'function with the section title in Group.
'Returned is the string value corresponding to item.

  Dim ret As String
  Dim valid   As Long
  
  ret = Space(1024)
  valid = GetPrivateProfileString(Group, item, "", ret, Len(ret), sIniQFile)
  ppGetItemsInfo = Left(ret, valid)


End Function


Public Function ppStripItem(startStrg As String) As String

'this takes a string separated by Chr(0)'s,
'splits off 1 item, and shortens the string
'so that the next item is ready for removal.

  Dim pos As Long
  Dim item As String

  pos = InStr(startStrg, Chr$(0))

  If pos Then
    item = Mid(startStrg, 1, pos - 1)
    startStrg = Mid(startStrg, pos + 1, Len(startStrg))
    ppStripItem = item
  End If

End Function


Public Function ppExtractItem(startStrg As String) As String

'this takes a string separated by commas,
'splits off 1 item, and shortens the string
'so that the next item is ready for removal.

  Dim pos As Long
  Dim item As String
  
  pos = InStr(startStrg, ",")
     
  If pos Then
   
    item = Mid(startStrg, 1, pos - 1)
    startStrg = Mid(startStrg, pos + 1, Len(startStrg))
    ppExtractItem = item
    Exit Function
  
  Else
  
    ppExtractItem = startStrg
    startStrg = ""
    
  End If
  
End Function


Public Sub QuickSortScores(TopScores As QuizStudentsTopScores, l As Long, r As Long)
   
   'Dim working variables
    Dim i As Long, j As Long
    Dim x As Long
    
   'dim tmp variables for use below
    Dim tmp1 As Long
    Dim tmp2 As Single
    Dim tmp3 As String
    
   '----------------------------------------
   'begin sort
   
   'assign working variables the values
   'passed to the sub in L & R
    i = l
    j = r
    
   'get the item halfway (x) through the data
   'determined by the range passed (L to r)
    x = TopScores.SScores((l + r) / 2)
    
   'x now holds the last name halfway through the array
   
   'compare rank of i to j and assign the 2 temp
   'variables that data for comparison later
    While (i <= j)
        
      'compare strings of compareI, i and r with the name in x
      'and assign new tmp values if a lower item found
       While (TopScores.SScores(i) > x And i < r)
           i = i + 1
       Wend
       
      'compare strings of compareJ, j and l with the name in x
      'and assign new tmp values if a higher item found
       While (x > TopScores.SScores(j) And j > l)
           j = j - 1
       Wend

       'determine the assignment action based on
       'the final i & j relative positions.  When i <= j,
       'swap the values of the last highest and last lowest items.
        If (i <= j) Then
        
          '---------------------------------------------
           '1a. assign tmp the value of the type TopScores(i)
           '2a. swap TopScores(j) for TopScores(i)
           '3a. reassign the value of tmp to the type TopScores(j)
            tmp1 = TopScores.SScores(i)
            TopScores.SScores(i) = TopScores.SScores(j)
            TopScores.SScores(j) = tmp1

            tmp2 = TopScores.SDate(i)
            TopScores.SDate(i) = TopScores.SDate(j)
            TopScores.SDate(j) = tmp2

            tmp3 = TopScores.SNames(i)
            TopScores.SNames(i) = TopScores.SNames(j)
            TopScores.SNames(j) = tmp3

          '---------------------------------------------
          'change the start  stop items
            i = i + 1
            j = j - 1
            
      End If
    Wend
    
   'if the original l is still less than j, then call
   'the sub again with l & j as the start & stop points
    If (l < j) Then QuickSortScores TopScores, l, j
    
   'or if the original l is still less than j, then call
   'the sub again with i & r as the start & stop points
    If (i < r) Then QuickSortScores TopScores, i, r

End Sub


Public Function FileExists(ByVal strPathName As String) As Boolean
    
'Returns: True if file exists, False otherwise
    
  Dim hFile As Long
  On Local Error Resume Next

 'Remove any trailing directory separator character
  If Right$(strPathName, 1) = "\" Then
     strPathName = Left$(strPathName, Len(strPathName) - 1)
  End If

 'Attempt to open the file, return value of
 'this function is False if an error occurs
 'on open, True otherwise
  hFile = FreeFile
  Open strPathName For Input As hFile

  FileExists = Err = 0

  Close hFile
  Err = 0
    
End Function
 Comments
Save the file, and move on to Step 2 - Building the TopScores Form.

 
 

PayPal Link
Make payments with PayPal - it's fast, free and secure!

 
 
 
 

Copyright ©1996-2011 VBnet and Randy Birch. All Rights Reserved.
Terms of Use  |  Your Privacy

 

Hit Counter