Home

VCL File Buffering

   

Introduction

The Visual Component Library supports another technique of file processing. Instead of saving the components as "streamable" objects, it gives you the option of saving the contents of controls. These contents are taken as data and not as VCL components. We will refer to this technique as file buffering.

To process the contents of controls as "streamable" values, the value of each object of the application is taken in its C/C++ context, as a variable created from known data types. The application itself is created like any other.

Practical LearningPractical Learning: Introducing File Buffering

  1. To start a new project, on the main menu, click File -> New -> VCL Forms Application - C++Builder
  2. Change the Caption of the form to Clarksville Ice Cream
  3. Complete the design of the form as follows:
     
    Clarksville Ice Cream
    Control Name Caption Additional Properties
    TLabel Label   O&rder Date:  
    TEdit TEdit edtOrderDate    
    TLabel Label   Order Ti&me:  
    TEdit TEdit edtOrderTime    
    TLabel Label   &Flavor:  
    TEdit TEdit edtFlavor    
    TLabel Label   C&ontainer:  
    TEdit TEdit edtContainer    
    TLabel Label   &Ingredient:  
    TEdit TEdit edtIngredient    
    TLabel Label   &Scoops:  
    TEdit TEdit edtScoops   Alignment: taRightJustify
    NumbersOnly: True
    Text: 0.00
    TLabel Label   Or&der Total:  
    TEdit TEdit edtTotalOrder   Alignment: taRightJustify
    Text: 0.00
  4. Click the Scoops edit control
  5. In the Object Inspector, click Events
  6. Double-click OnExit
  7. Implement the event as follows:
    //---------------------------------------------------------------------------
    void __fastcall TfrmMain::ledScoopsExit(TObject *Sender)
    {
        double priceContainer = 0.00,
    	   priceIngredient = 0.00,
    	   priceScoops = 0.00,
    	   orderTotal = 0.00;
        int numberOfScoops = 1;
    
        // Find out what container the customer requested
        // The price of a container depends on which one the customer selected
        if (ledContainer->Text == "Cone")
    	priceContainer = 0.55;
        else if (ledContainer->Text == "Cup")
    	priceContainer = 0.75;
        else
    	priceContainer = 1.15;
    
        // If the customer selected an ingredient, which is not "None", add $.95
        if (ledIngredient->Text != "None")
    	priceIngredient = 0.95;
    
        // Get the number of scoops
        numberOfScoops = StrToFloat(ledScoops->Text);
    
        if (numberOfScoops == 2)
    	priceScoops = 2.55;
        else if (numberOfScoops == 3)
    	priceScoops = 3.25;
        else
    	priceScoops = 1.85;
    
        // Make sure the user selected a flavor,
        // otherwise, there is no reason to process an order
        if (ledFlavor->Text != "")
    	orderTotal = priceScoops + priceContainer + priceIngredient;
    
        ledOrderTotal->Text = FormatFloat("0.00", orderTotal);
    }
    //---------------------------------------------------------------------------
  8. Press F12 to return to the form
  9. In the Tool Palette, click Dialogs
  10. Click TOpenDialog and click the form
  11. In the Object Inspector, change its properties as follows:
    DefaultExt: cic
    Filter: Clarksville Ice Create File (*.cic)|*.cic|All Files (*.*)|*.*
    Name: dlgOpen
    Title: Open a Clarksville Ice Create Order
  12. In the Dialogs section of the Tool Palette, click TSaveDialog and click the form
  13. Using the Object Inspector, change its properties as follows:
    DefaultExt: cic
    Filter: Clarksville Ice Create File (*.cic)|*.cic|All Files (*.*)|*.*
    Name: dlgSave
    Title: Save the Current Clarksville Ice Create Order
  14.  In the Standard section of the Tool Palette, click TMainMenu Main Menu and click the form
  15. In the Object Inspector, click Name and type mnuMain and press Enter
  16. On the form, double-click mnuMain
  17. Right-click the Menu Designer and click Insert From Templates...
  18. In the list, click File Menu
  19. Click OK
  20. In the Menu Designer, double-click New
  21. Implement the event as follows:
    //---------------------------------------------------------------------------
    void __fastcall TfrmMain::New1Click(TObject *Sender)
    {
        edtOrderDate->Text = FormatDateTime("mm/dd/yyyy", TDateTime::CurrentDate());
        edtOrderTime->Text = FormatDateTime("hh:nn ampm", TDateTime::CurrentTime());
        ledFlavor->Text = "Vanilla";
        ledContainer->Text = "Cone";
        ledIngredient->Text = "None";
    }
    //---------------------------------------------------------------------------
  22. Press F12 to display the form
  23. Double-click an unoccupied area of the form
  24. Implement the event as follows:
    //---------------------------------------------------------------------------
    void __fastcall TfrmMain::FormCreate(TObject *Sender)
    {
        New1Click(Sender);
    }
    //---------------------------------------------------------------------------

 

Values Buffering

To create a file, you can use the TFileStream class reviewed earlier, using the same rules. To write data to a file, you can call the TFileStream::WriteBuffer() method. Its syntax is:

void __fastcall WriteBuffer(const void *Buffer, int Count);

The WriteBuffer() method is used when you must let the compiler know the amount of memory space you want to use for a particular variable. It requires two arguments. The first, Buffer, is the value that needs to be saved. The Count parameter specifies the number of bytes that the value will need to the stored.

 

Practical LearningPractical Learning: Writing Some Values

  1. In the Menu Designer, double-click Save
  2. Implement the event as follows:
    //---------------------------------------------------------------------------
    void __fastcall TfrmMain::Save1Click(TObject *Sender)
    {
    	TFileStream *fsIceCreamer;
    
    	wchar_t orderDate[40];
    	wchar_t orderTime[40];
    	wchar_t flavor[40];
    	wchar_t container[40];
    	wchar_t ingredient[40];
    	wchar_t scoops[20];
    	wchar_t orderTotal[20];
    
    	if( dlgSave->Execute() )
    	{
    	    try {
    		StrCopy(orderDate, edtOrderDate->Text.c_str());
    		StrCopy(orderTime, edtOrderTime->Text.c_str());
    		StrCopy(flavor, ledFlavor->Text.c_str());
    		StrCopy(container, ledContainer->Text.c_str());
    		StrCopy(ingredient, ledIngredient->Text.c_str());
    		StrCopy(scoops, ledScoops->Text.c_str());
    		StrCopy(orderTotal, ledOrderTotal->Text.c_str());
    
    		fsIceCreamer = new TFileStream(dlgSave->FileName, fmCreate);
    
    		fsIceCreamer->WriteBuffer(&orderDate, 40);
    		fsIceCreamer->WriteBuffer(&orderTime, 40);
    		fsIceCreamer->WriteBuffer(&flavor, 40);
    		fsIceCreamer->WriteBuffer(&container, 40);
    		fsIceCreamer->WriteBuffer(&ingredient, 40);
    		fsIceCreamer->WriteBuffer(&scoops, 20);
    		fsIceCreamer->WriteBuffer(&orderTotal, 20);
    
    		New1Click(Sender);
    	    }
    	    __finally
    	    {
    		delete fsIceCreamer;
    	    }
    	}
    }
    //---------------------------------------------------------------------------
  3. To execute, press F9
  4. Enter some values as follows:
     
    Clarksville Ice Cream
  5. Clisk Save
  6. Set the file name to 1001
  7. Click Save
  8. Enter some values as follows:
     
    Clarksville Ice Cream
  9. Click Save
  10. Set the file name to 1002 and click Save

Value Reading

Data reading in this context is performed using the ReadBuffer() method of the TFileStream class. Its syntax is:

void __fastcall ReadBuffer(void *Buffer, int Count);

The ReadBuffer() method also requires two pieces of information. The Buffer parameter is the value that needs to be read. The Count parameter is used to specify the number of bytes that need to be read for the Buffer value.

Practical LearningPractical Learning: Reading Some Values

  1. In the Menu Designer, double-click Open...
  2. Implement the event as follows:
    //---------------------------------------------------------------------------
    void __fastcall TfrmMain::Open1Click(TObject *Sender)
    {
        TFileStream *fsIceCream;
        wchar_t orderDate[40];
        wchar_t orderTime[40];
        wchar_t flavor[40];
        wchar_t container[40];
        wchar_t ingredient[40];
        wchar_t scoops[20];
        wchar_t orderTotal[20];
    
        if( dlgOpen->Execute() )
        {
    	try {
    		fsIceCream = new TFileStream(dlgOpen->FileName, fmOpenRead);
    
    		fsIceCream->ReadBuffer(&orderDate, 40);
    		fsIceCream->ReadBuffer(&orderTime, 40);
    		fsIceCream->ReadBuffer(&flavor, 40);
    		fsIceCream->ReadBuffer(&container, 40);
    		fsIceCream->ReadBuffer(&ingredient, 40);
    		fsIceCream->ReadBuffer(&scoops, 20);
    		fsIceCream->ReadBuffer(&orderTotal, 20);
    
    		edtOrderDate->Text = orderDate;
    		edtOrderTime->Text = orderTime;
    		ledFlavor->Text = flavor;
    		ledContainer->Text = container;
    		ledIngredient->Text = ingredient;
    		ledScoops->Text = scoops;
    		ledOrderTotal->Text = orderTotal;
    	}
    	__finally
    	{
    		delete fsIceCream;
    	}
        }
    }
    //---------------------------------------------------------------------------
  3. On the Menu Designer, double-click Exit
  4. Close the Menu Designer
  5. Implement the event as follows:
    //---------------------------------------------------------------------------
    void __fastcall TfrmMain::Exit1Click(TObject *Sender)
    {
        this->Close();
    }
    //---------------------------------------------------------------------------
  6. To execute, on the main menu, click Run -> Run
  7. Using the main menu, open one of the previously saved file
 
 
 

Home Copyright © 2010-2011 FunctionX, Inc.