Home

Memo

   

Introduction to the Memo Control

 

Description

While the edit control is used to hold a single line of text, to give you a control that can hold multiple lines of text, the VCL provides the memo control. Like the edit text, the memo control is used to display or receive text. Unlike the edit control, the memo can be used to display multiple lines of text and they can be divided in paragraphs.

 

Practical LearningPractical Learning: Introducing Memo Controls

  1. Start Embarcadero RAD Studio
  2. To create a new project, on the main menu, click File -> New -> VCL Forms Application - C++Builder
  3. In the Object Inspector, change the following properties:
    Caption: College Park Auto Repair
    Name: frmRepairOrders
    Position: poScreenCenter
  4. To save the project, on the Standard toolbar, click the Save All button
  5. Click New Folder
  6. Type CollegeParkAutoRepair1 as the name of the folder and press Enter twice to select it
  7. Type RepairOrder as the name of the unit and click Save
  8. Type CollegeParkAutoRepair as the name of the project and click Save

Creating a Memo

Like the edit control, the memo control is based on the TCustomEdit class. But there is an intermediary class between the TCustomEdit and the TMemo classes. It is the TCustomMemo class.

TMemo Inheritance

 

To visually add a memo to a form or another container, from the Standard section of the Tool Palette, click the TMemo button Memo and click the desired area on the form. To programmatically create a memo, declare a variable of type TMemo and use the new operator to specify its owner. You must also specify the parent of the variable. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::btnNotesClick(TObject *Sender)
{
	TMemo *Notes = new TMemo(Form1);
	Notes->Parent = Form1;
	Notes->Left = 350;
	Notes->Top = 20;
	Notes->Height = 120;
	Notes->Width = 320;
}
//---------------------------------------------------------------------------

Practical LearningPractical Learning: Creating a Memo

  1. Design the form as follows:
     
    College Park Auto Repair
    Control Alignment Caption Name Text
    TGroupBox TPanel   Repair Identification    
    TLabel Label   Customer Name:    
    TEdit Edit     edtCustomerName  
    TLabel Label   Address:    
    TEdit Edit     edtAddress  
    TLabel Label   City:    
    TEdit Edit     edtCity  
    TLabel Label   State:    
    TEdit Edit     edtState  
    TLabel Label   ZIP Code:    
    TEdit Edit     edtZIPCode  
    TLabel Label   Car Make/Model:    
    TEdit Edit     edtMakeModel  
    TLabel Label   Year:    
    TEdit Edit     edtYear  
    TLabel Label   Problem Description:    
    TMemo TMemo     mmoProblemDescription  
    TGroupBox TPanel   Repair Evaluation    
    TLabel Label   Total Parts:    
    TEdit Edit taRightJustify   edtTotalParts 0.00
    TLabel Label   Total Labor:    
    TEdit Edit taRightJustify   edtTotalLabor  
    TLabel Label   Tax Rate:    
    TEdit Edit taRightJustify   edtTaxRate 5.75
    TLabel Label   %    
    TLabel Label   Tax Amount:    
    TEdit Edit taRightJustify   edtTaxAmount 0.00
    TLabel Label   Total Order:    
    TEdit Edit taRightJustify   edtTotalOrder  
    TGroupBox TPanel   Parts Used    
    TLabel Label   Part Name    
    TLabel Label   Uni Price    
    TLabel Label   Qty    
    TLabel Label   Sub-Total    
    TEdit Edit     edtPartName1  
    TEdit Edit taRightJustify   edtUnitPrice1 0.00
    TEdit Edit taRightJustify   edtQuantity1 0
    TEdit Edit taRightJustify   edtSubTotal1 0.00
    TEdit Edit     edtPartName2  
    TEdit Edit taRightJustify   edtUnitPrice2 0.00
    TEdit Edit taRightJustify   edtQuantity2 0
    TEdit Edit taRightJustify   edtSubTotal2 0.00
    TEdit Edit     edtPartName3  
    TEdit Edit taRightJustify   edtUnitPrice3 0.00
    TEdit Edit taRightJustify   edtQuantity3 0
    TEdit Edit taRightJustify   edtSubTotal3 0.00
    TEdit Edit     edtPartName4  
    TEdit Edit taRightJustify   edtUnitPrice4 0.00
    TEdit Edit taRightJustify   edtQuantity4 0
    TEdit Edit taRightJustify   edtSubTotal4 0.00
    TEdit Edit     edtPartName5  
    TEdit Edit taRightJustify   edtUnitPrice5 0.00
    TEdit Edit taRightJustify   edtQuantity5 0
    TEdit Edit taRightJustify   edtSubTotal5 0.00
    TGroupBox TPanel   Jobs Performed    
    TLabel Label   Job Description    
    TLabel Label   Job Cost    
    TEdit Edit     edtJobDescription1  
    TEdit Edit taRightJustify   edtJobCost1 0.00
    TEdit Edit     edtJobDescription2  
    TEdit Edit taRightJustify   edtJobCost2 0.00
    TEdit Edit     edtJobDescription3  
    TEdit Edit taRightJustify   edtJobCost3 0.00
    TEdit Edit     edtJobDescription4  
    TEdit Edit taRightJustify   edtJobCost4 0.00
    TEdit Edit     edtJobDescription5  
    TEdit Edit taRightJustify   edtJobCost5 0.00
    TGroupBox TPanel   Recommendations    
    TMemo TMemo     mmoRecommendations  
    TLabel Label   Repair Order to Open:    
    TEdit Edit     edtFileOpen  
    TButton Button   Open btnOpen  
    TLabel Label   Save Repair Order As:    
    TEdit Edit     edtFileSave  
    TButton Button   Save btnSave  
    TButton Button   Reset/Start New Repair Order btnReset  
    TButton Button   Close btnClose  
     
  2. On the form, click the Customer Name edit control
  3. In the Object Inspector, click Events and double-click the right side of OnExit
  4. Implement the event as follows:
    //---------------------------------------------------------------------------
    void __fastcall TfrmAutoRepair::edtCustomerNameExit(TObject *Sender)
    {
    	edtFileSave->Text = edtCustomerName->Text;
    }
    //---------------------------------------------------------------------------
  5. On the main menu, click View -> C++ Class Explorer
  6. In the Class Explorer, click the + of $(Project) to expand it
  7. Right-click the name of the form class and click Add Method...
  8. Set the Name to Calculate
  9. Set the Return Type as void
  10. Click the fastcall check box
  11. Click Add
  12. Close the Class Explorer
  13. Implement the method as follows:
    //---------------------------------------------------------------------------
    void __fastcall TfrmAutoRepair::Calculate()
    {
    	double Part1UnitPrice = 0.00, Part2UnitPrice = 0.00,
    		   Part3UnitPrice = 0.00, Part4UnitPrice = 0.00,
    		   Part5UnitPrice = 0.00;
    	double Part1SubTotal, Part2SubTotal, Part3SubTotal,
    		   Part4SubTotal, Part5SubTotal, TotalParts;
    	int Part1Quantity = 0, Part2Quantity = 0, Part3Quantity = 0,
    		Part4Quantity = 0, Part5Quantity = 0;
    	double Job1Price = 0.00, Job2Price = 0.00, Job3Price = 0.00,
    		   Job4Price = 0.00, Job5Price = 0.00;
    	double TotalLabor;
    	double TaxRate = 0.00, TaxAmount, TotalOrder;
    
    	// Don't charge a part unless it is clearly identified
    	if (edtPartName1->Text == L"")
    	{
    		edtUnitPrice1->Text = L"0.00";
    		edtQuantity1->Text = L"0";
    		edtSubTotal1->Text = L"0.00";
    		Part1UnitPrice = 0.00;
    	}
    	else
    	{
    		try
    		{
    			Part1UnitPrice = edtUnitPrice1->Text.ToDouble();
    		}
    		catch(EConvertError *)
    		{
    			ShowMessage(L"Invalid Unit Price");
    			edtUnitPrice1->Text = L"0.00";
    		}
    
    		try
    		{
    		Part1Quantity = edtQuantity1->Text.ToInt();
    		}
    		catch(EConvertError *)
    		{
    			ShowMessage(L"Invalid Quantity");
    			edtQuantity1->Text = L"0";
    		}
    	}
    
    	if( edtPartName2->Text == L"" )
    	{
    		edtUnitPrice2->Text = L"0.00";
    		edtQuantity2->Text = L"0";
    		edtSubTotal2->Text = L"0.00";
    		Part2UnitPrice = 0.00;
    	}
    	else
    	{
    		try
    		{
    			Part2UnitPrice = edtUnitPrice2->Text.ToDouble();
    		}
    		catch(EConvertError *)
    		{
    			ShowMessage(L"Invalid Unit Price");
    			edtUnitPrice2->Text = L"0.00";
    		}
    
    		try
    		{
    			Part2Quantity = edtQuantity2->Text.ToInt();
    		}
    		catch(EConvertError *)
    		{
    			ShowMessage(L"Invalid Quantity");
    			edtQuantity2->Text = L"0";
    		}
    	}
    
    	if( edtPartName3->Text == L"" )
    	{
    		edtUnitPrice3->Text = L"0.00";
    		edtQuantity3->Text = L"0";
    		edtSubTotal3->Text = L"0.00";
    		Part3UnitPrice = 0.00;
    	}
    	else
    	{
    		try
    		{
    			Part3UnitPrice = edtUnitPrice3->Text.ToDouble();
    		}
    		catch(EConvertError *)
    		{
    			ShowMessage(L"Invalid Unit Price");
    			edtUnitPrice3->Text = L"0.00";
    		}
    
    		try
    		{
    			Part3Quantity = edtQuantity3->Text.ToInt();
    		}
    		catch(EConvertError *)
    		{
    			ShowMessage(L"Invalid Quantity");
    					edtQuantity3->Text = L"0";
    		}
    	}
    
    	if( edtPartName4->Text == L"" )
    	{
    		edtUnitPrice4->Text = L"0.00";
    		edtQuantity4->Text = L"0";
    		edtSubTotal4->Text = L"0.00";
    		Part4UnitPrice = 0.00;
    	}
    	else
    	{
    		try
    		{
    			Part4UnitPrice = edtUnitPrice4->Text.ToDouble();
    		}
    		catch(EConvertError *)
    		{
    			ShowMessage(L"Invalid Unit Price");
    			edtUnitPrice4->Text = L"0.00";
    		}
    
    		try
    		{
    			Part4Quantity = edtQuantity4->Text.ToInt();
    		}
    		catch(EConvertError *)
    		{
    			ShowMessage(L"Invalid Quantity");
    			edtQuantity4->Text = L"0";
    		}
    	}
    
    	if (edtPartName5->Text == L"" )
    	{
    		edtUnitPrice5->Text = L"0.00";
    		edtQuantity5->Text = L"0";
    		edtSubTotal5->Text = L"0.00";
    		Part5UnitPrice = 0.00;
    	}
    	else
    	{
    		try
    		{
    			Part5UnitPrice = edtUnitPrice5->Text.ToDouble();
    		}
    		catch(EConvertError *)
    		{
    			ShowMessage(L"Invalid Unit Price");
    			edtUnitPrice5->Text = L"0.00";
    		}
    
    		try
    		{
    			Part5Quantity = edtQuantity5->Text.ToInt();
    		}
    		catch(EConvertError *)
    		{
    			ShowMessage(L"Invalid Quantity");
    			edtQuantity5->Text = L"0";
    		}
    	}
    
    	// Don't bill the customer for a job that is not specified
    	if (edtJobDescription1->Text == L"")
    	{
    		edtJobCost1->Text = L"0.00";
    		Job1Price = 0.00;
    	}
    	else
    	{
    		try
    		{
    			Job1Price = edtJobCost1->Text.ToDouble();
    		}
    		catch(EConvertError *)
    		{
                        ShowMessage(L"Invalid Job Price");
    		   edtJobCost1->Text = L"0.00";
    		}
    	}
    
    	if (edtJobDescription2->Text == L"")
    	{
    		edtJobCost2->Text = L"0.00";
    		Job2Price = 0.00;
    	}
    	else
    	{
    		try
    		{
    			Job2Price = edtJobCost2->Text.ToDouble();
    		}
    		catch(EConvertError *)
    		{
                        ShowMessage(L"Invalid Job Price");
    			edtJobCost2->Text = L"0.00";
    		}
    	}
    
    	if (edtJobDescription3->Text == L"")
    	{
    		edtJobCost3->Text = L"0.00";
    		Job3Price = 0.00;
    	}
    	else
    	{
    		try
    		{
    			Job3Price = edtJobCost3->Text.ToDouble();
    		}
    		catch(EConvertError *)
    		{
                        ShowMessage(L"Invalid Job Price");
    		    edtJobCost3->Text = L"0.00";
    		}
    	}
    
    	if (edtJobDescription4->Text == L"")
    	{
    		edtJobCost4->Text = L"0.00";
    		Job4Price = 0.00;
    	}
    	else
    	{
    		try
    		{
    			Job4Price = edtJobCost4->Text.ToDouble();
    		}
    		catch(EConvertError *)
    		{
                        ShowMessage(L"Invalid Job Price");
    					edtJobCost4->Text = L"0.00";
    		}
    	}
    
    	if (edtJobDescription5->Text == L"")
    	{
    		edtJobCost5->Text = L"0.00";
    		Job5Price = 0.00;
    	}
    	else
    	{
    		try
    		{
    			Job5Price = edtJobCost5->Text.ToDouble();
    		}
    		catch(EConvertError *)
    		{
                        ShowMessage(L"Invalid Job Price");
    					edtJobCost5->Text = L"0.00";
    		}
    	}
    
    	Part1SubTotal = Part1UnitPrice * Part1Quantity;
    	Part2SubTotal = Part2UnitPrice * Part2Quantity;
    	Part3SubTotal = Part3UnitPrice * Part3Quantity;
    	Part4SubTotal = Part4UnitPrice * Part4Quantity;
    	Part5SubTotal = Part5UnitPrice * Part5Quantity;
    
    	edtSubTotal1->Text = FloatToStrF(Part1SubTotal, ffFixed, 8, 2);
    	edtSubTotal2->Text = FloatToStrF(Part2SubTotal, ffFixed, 8, 2);
    	edtSubTotal3->Text = FloatToStrF(Part3SubTotal, ffFixed, 8, 2);
    	edtSubTotal4->Text = FloatToStrF(Part4SubTotal, ffFixed, 8, 2);
    	edtSubTotal5->Text = FloatToStrF(Part5SubTotal, ffFixed, 8, 2);
    
    	TotalParts = Part1SubTotal + Part2SubTotal + Part3SubTotal +
    				 Part4SubTotal + Part5SubTotal;
    
    	TotalLabor = Job1Price + Job2Price + Job3Price +
    				 Job4Price + Job5Price;
    
    	try
    	{
    		TaxRate = edtTaxRate->Text.ToDouble();
    	}
    	catch(EConvertError *)
    	{
    		ShowMessage(L"Invalid Tax Rate");
    		edtTaxRate->Text = L"5.75";
    	}
    
    	double TotalPartsAndLabor = TotalParts + TotalLabor;
    	TaxAmount = TotalPartsAndLabor * TaxRate / 100;
    	TotalOrder = TotalPartsAndLabor + TaxAmount;
    
    	edtTotalParts->Text = FloatToStrF(TotalParts, ffFixed, 8, 2);
    	edtTotalLabor->Text = FloatToStrF(TotalLabor, ffFixed, 8, 2);
    	edtTaxAmount->Text = FloatToStrF(TaxAmount, ffFixed, 8, 2);
    	edtTotalOrder->Text = FloatToStrF(TotalOrder, ffFixed, 8, 2);
    }
    //---------------------------------------------------------------------------
  14. Press F12 to display the form
  15. On the form, click the Tax Rate edit control
  16. In the Object Inspector, click Events
  17. Double-click the right box of OnExit
  18. Call the Calculate() method as follows:
    //---------------------------------------------------------------------------
    void __fastcall TfrmAutoRepair::edtTaxRateExit(TObject *Sender)
    {
    	Calculate();
    }
    //---------------------------------------------------------------------------
  19. Press F12 to return to the form
  20. On the form click the edit control under Unit Price
  21. Press and hold Shift
  22. Click each of the edit controls under Unit Price, under Qty, and under Job Cost
  23. Release Shift
  24. In the Events section of the Object Inspector, click OnExit, then click the arrow of its combo box and select edtTaxRateExit
  25. In the Object Inspector, click Properties
 
 
 

Characteristics of a Memo

  

Introduction

A great deal of the functionality of a memo comes from the TCustomEdit class, which means that all the fundamental characteristics of a memo are the same as the edit control. Of course, the memo adds some features to support the lines of text.

The user has the ability to type text to alter the content of the memo box. This is possible only if the ReadOnly property is set to true, which is the default. If you want to prevent the user from altering the text in the memo, set the ReadOnly property to false. You can also do this programmatically.

When a memo box opens, the compiler registers the content of the control. If the user has the ability to change the text in the control and if the user changes it, the compiler flags the control as modified. To support this, the TCustomEdit class is equipped with a Boolean property named Modified and that its child controls inherit.

You can programmatically acknowledge that the control has been modified by setting the Modified property to true. If another control or some other action alters the contents of the memo, you can make sure that this property reflects the change. You can change this programmatically as follows:

//---------------------------------------------------------------------------
void __fastcall TForm1::Memo1KeyPress(TObject *Sender, char &Key)
{
	Memo1->Modified = True;
}
//---------------------------------------------------------------------------

Like the edit control, the only event that the Memo control can claim on its owns is the OnChange event which is a TNotifyEvent type. This occurs when the user changes the content of the control. This event is useful if you want to display a notification that the text is not as it was when the form opened.

When the application focus moves from one to another control or the application itself to a control, the OnEnter event is fired. When the control looses focus, an OnExit event is fired.

Although the user can enter any number of characters into a memo box, you can set a maximum number that would prevent the user from going over this number of characters. This characteristics is controlled by the MaxLength property of the TCustomEdit class. At design time, you can set the maximum number of characters in the MaxLength field. Programmatically, you can change it as follows:

//---------------------------------------------------------------------------
void __fastcall TForm1::Memo1KeyPress(TObject *Sender, char &Key)
{
	Memo1->MaxLength = 24;
}
//---------------------------------------------------------------------------

When entering text in a Memo control, the characters start on the left side of the memo and are subsequently added on the right side. The ability to align text is controlled by the Alignment property. For a Memo control, the alignment is configured using the TAlignment enumerator:

enum TAlignment { taLeftJustify, taRightJustify, taCenter };

This property works exactly as we reviewed it for the edit control.

The TMemo class supports regular operations performed on a text control such as undoing an action, cutting or copying text from the control, pasting text from another control. The methods used to accomplish these assignments are Undo(), CutToClipboard(), CopyToClipboard(), PasteFromClipboard().

The Control Alignment

By default, the memo control is positioned where you drop it at design time. The Align property specifies how the memo will be aligned with regard to its container. If the memo is used as the main area of a text editor application, you should set its Align property to alClient.

The Lines of a Memo

As mentioned already, a memo is used to hold many lines of text. To support its whole text, the TMemo class inherits a property named Lines from its parent, the TCustomMemo class:

__property Classes::TStrings * Lines = {read=FLines,write=SetLines};

As you can see, the TCustomMemo::Lines property is a collection of TStrings objects. The user mostly reads and/or enters text in the memo when interacting with the control. At design time, you can set the text that would display when the memo comes up. To enter this text, in the Object Inspector, click the Lines field to reveal its ellipsis button that allows you to open the String List Editor dialog box. If you want the control to be empty at startup, delete the content of the String List Editor and click OK. Otherwise, type the desired text and click OK.

To programmatically delete all lines of a memo, you can call the Clear() methods. To select all the text in a memo, you can call the SelectAll() method.

Practical LearningPractical Learning: Using the Lines of a Memo

  1. On the form, double-click the Reset button
  2. Implement its event as follows:
    //---------------------------------------------------------------------------
    void __fastcall TfrmAutoRepair::btnResetClick(TObject *Sender)
    {
    	edtCustomerName->Text = L"";
    	edtAddress->Text = L"";
    	edtCity->Text = L"";
    	edtState->Text = L"";
    	edtZIPCode->Text = L"";
    	edtMakeModel->Text = L"";
    	edtYear->Text = L"";
    	mmoProblemDescription->Lines->Clear();
    
    	edtTotalParts->Text = L"0.00";
    	edtTotalLabor->Text = L"0.00";
    	edtTaxRate->Text = L"5.75";
    	edtTaxAmount->Text = L"0.00";
    	edtTotalOrder->Text = L"0.00";
    
    	edtPartName1->Text = L"";
    	edtUnitPrice1->Text = L"0.00";
    	edtQuantity1->Text = L"0";
    	edtSubTotal1->Text = L"0.00";
    
    	edtPartName2->Text = L"";
    	edtUnitPrice2->Text = L"0.00";
    	edtQuantity2->Text = L"0";
    	edtSubTotal2->Text = L"0.00";
    
    	edtPartName3->Text = L"";
    	edtUnitPrice3->Text = L"0.00";
    	edtQuantity3->Text = L"0";
    	edtSubTotal3->Text = L"0.00";
    
    	edtPartName4->Text = L"";
    	edtUnitPrice4->Text = L"0.00";
    	edtQuantity4->Text = L"0";
    	edtSubTotal4->Text = L"0.00";
    
    	edtPartName5->Text = L"";
    	edtUnitPrice5->Text = L"0.00";
    	edtQuantity5->Text = L"0";
    	edtSubTotal5->Text = L"0.00";
    
    	edtJobDescription1->Text = L"";
    	edtJobCost1->Text = L"0.00";
    	edtJobDescription2->Text = L"";
    	edtJobCost2->Text = L"0.00";
    	edtJobDescription3->Text = L"";
    	edtJobCost3->Text = L"0.00";
    	edtJobDescription4->Text = L"";
    	edtJobCost4->Text = L"0.00";
    	edtJobDescription5->Text = L"";
    	edtJobCost5->Text = L"0.00";
    
    	mmoRecommendations->Lines->Clear();
    	edtFileOpen->Text = L"";
    	edtFileSave->Text = L"";
    }
    //---------------------------------------------------------------------------
  3. Press F12 to return to the form
  4. Double-click an unoccupied area of the form
  5. Implement the event as follows:
    //---------------------------------------------------------------------------
    void __fastcall TfrmAutoRepair::FormCreate(TObject *Sender)
    {
    	btnResetClick(Sender);
    }
    //---------------------------------------------------------------------------
  6. Press F12 to display the form
  7. Save all

Supporting Carriage Return

If the memo is used to receive text, the user can press Enter at the end of a line to move to the next line. This ability is controlled by the Boolean WantReturns property:

__property bool WantReturns = {read=FWantReturns,write=FWantReturns};

By default, this property is set to True, which means the user can press Enter when typing text. If you do not want to validate the Enter key in the memo control, set this property to False. To set it programmatically, assign the desired value to the WantReturns property:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
	Memo1->WantReturns = False;
}
//---------------------------------------------------------------------------

When the WantReturns property is set to false, if the user presses Enter while the memo has focus, the Enter action would be transferred to the form as the parent. The form in turn can find out what to do. For example, you may have configured the form to perform a particular action when the Enter key is pressed. The typical example is by setting a button’s Default property to true. In this case, pressing Enter from the memo control would cause the action associated with the button. Even if the WantReturns of a memo is set to false, the user can still press Ctrl + Enter to move to the next line.

Supporting Tabs

The user is accustomed to pressing Tab to insert tab characters in the text. By default, when the user presses Tab when interacting with your application, the focus moves from one control to the next, following the TabOrder value of the form. Even when using a memo to perform text editing, if the user presses Tab, the focus would switch to another control or to the form. If you want a memo to receive focus when the user presses the Tab key, use the WantTabs Boolean property:

__property bool WantTabs = {read=FWantTabs,write=FWantTabs};

The default value of the TCustomMemo::WantTabs property is False, which is the right one.

Wrapping the Text

As the user enters text in a memo box, the compiler considers that a paragraph starts from the user typing a character until he or she presses Enter. Therefore, a paragraph could be an empty space, a character, a word, a line of text, a whole page or an entire book. Depending on the width of the memo control, the text is incrementally added to the right side of each previous character. If the caret gets to the right border of the control, the text automatically continues to the next line, although it is still considered as one paragraph. To start a new paragraph, the user has to press Enter. The ability for the text to continue on the next line when the caret encounters the right border of the memo is controlled by the WordWrap property:

__property bool WordWrap = {read=FWordWrap,write=SetWordWrap};

The default value of this property is true. If you do not want text to wrap to the subsequent line, set the WordWrap property to false. You can also set it programmatically as follows:

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	Memo1->WordWrap = False;
}
//---------------------------------------------------------------------------

Practical LearningPractical Learning: Using a Memo

  1. On the form, click one of the memo controls
  2. In the Object Inspector, click ScrollBars, then click the arrow of its combo box and select ssVertical
  3. On the form, click the other memo control
  4. In the Object Inspector, click ScrollBars, then click the arrow of its combo box and select ssVertical
  5. On the form, double-click the Save button
  6. Implement its event as follows:
    //---------------------------------------------------------------------------
    void __fastcall TfrmAutoRepair::btnSaveClick(TObject *Sender)
    {
        if( edtFileSave->Text == L"" )
        {
    	ShowMessage(L"You must enter the name of the file to save");
    	return;
        }
        else
        {
    	// Declare a pointer to TFileStream
    	TFileStream *fstRepairOrder;
    
    	// Use the constructor of the TFileStream to create a file
    	try {
    		fstRepairOrder = new TFileStream(edtFileSave->Text + L".cpar", fmCreate);
    
    		fstRepairOrder->WriteComponent(edtCustomerName);
    		fstRepairOrder->WriteComponent(edtAddress);
    		fstRepairOrder->WriteComponent(edtCity);
    		fstRepairOrder->WriteComponent(edtState);
    		fstRepairOrder->WriteComponent(edtZIPCode);
    		fstRepairOrder->WriteComponent(edtMakeModel);
    		fstRepairOrder->WriteComponent(edtYear);
    		fstRepairOrder->WriteComponent(mmoProblemDescription);
    		fstRepairOrder->WriteComponent(edtTotalParts);
    		fstRepairOrder->WriteComponent(edtTotalLabor);
    		fstRepairOrder->WriteComponent(edtTaxRate);
    		fstRepairOrder->WriteComponent(edtTaxAmount);
    		fstRepairOrder->WriteComponent(edtTotalOrder);
    
    		fstRepairOrder->WriteComponent(edtPartName1);
    		fstRepairOrder->WriteComponent(edtUnitPrice1);
    		fstRepairOrder->WriteComponent(edtQuantity1);
    		fstRepairOrder->WriteComponent(edtSubTotal1);
    
    		fstRepairOrder->WriteComponent(edtPartName2);
    		fstRepairOrder->WriteComponent(edtUnitPrice2);
    		fstRepairOrder->WriteComponent(edtQuantity2);
    		fstRepairOrder->WriteComponent(edtSubTotal2);
    
    		fstRepairOrder->WriteComponent(edtPartName3);
    		fstRepairOrder->WriteComponent(edtUnitPrice3);
    		fstRepairOrder->WriteComponent(edtQuantity3);
    		fstRepairOrder->WriteComponent(edtSubTotal3);
    
    		fstRepairOrder->WriteComponent(edtPartName4);
    		fstRepairOrder->WriteComponent(edtUnitPrice4);
    		fstRepairOrder->WriteComponent(edtQuantity4);
    		fstRepairOrder->WriteComponent(edtSubTotal4);
    
    		fstRepairOrder->WriteComponent(edtPartName5);
    		fstRepairOrder->WriteComponent(edtUnitPrice5);
    		fstRepairOrder->WriteComponent(edtQuantity5);
    		fstRepairOrder->WriteComponent(edtSubTotal5);
    
    		fstRepairOrder->WriteComponent(edtJobDescription1);
    		fstRepairOrder->WriteComponent(edtJobCost1);
    		fstRepairOrder->WriteComponent(edtJobDescription2);
    		fstRepairOrder->WriteComponent(edtJobCost2);
    		fstRepairOrder->WriteComponent(edtJobDescription3);
    		fstRepairOrder->WriteComponent(edtJobCost3);
    		fstRepairOrder->WriteComponent(edtJobDescription4);
    		fstRepairOrder->WriteComponent(edtJobCost4);
    		fstRepairOrder->WriteComponent(edtJobDescription5);
    		fstRepairOrder->WriteComponent(edtJobCost5);
    
    		fstRepairOrder->WriteComponent(mmoRecommendations);
    
    		ShowMessage(L"The repair order has been saved");
    		btnResetClick(Sender);
    	}
    	__finally
    	{
    		delete fstRepairOrder;
    	}
        }
    }
    //---------------------------------------------------------------------------
  7. Press F12 to return to the form
  8. On the form, double-click the Open button
  9. Implement the event as follows:
    //---------------------------------------------------------------------------
    void __fastcall TfrmAutoRepair::btnOpenClick(TObject *Sender)
    {
        if( edtFileOpen->Text == L"" )
        {
    	ShowMessage(L"You must enter the name of the file to open ");
    	return;
        }
        else
        {
    	// Decalre a pointer to TFileStream
    	TFileStream *fstRepairOrder = NULL;
    
    	try {
    		fstRepairOrder = new TFileStream(edtFileOpen->Text + L".cpar",
    						  fmOpenRead | fmShareExclusive);
    		fstRepairOrder->ReadComponent(edtCustomerName);
    		fstRepairOrder->ReadComponent(edtAddress);
    		fstRepairOrder->ReadComponent(edtCity);
    		fstRepairOrder->ReadComponent(edtState);
    		fstRepairOrder->ReadComponent(edtZIPCode);
    		fstRepairOrder->ReadComponent(edtMakeModel);
    		fstRepairOrder->ReadComponent(edtYear);
    		fstRepairOrder->ReadComponent(mmoProblemDescription);
    		fstRepairOrder->ReadComponent(edtTotalParts);
    		fstRepairOrder->ReadComponent(edtTotalLabor);
    		fstRepairOrder->ReadComponent(edtTaxRate);
    		fstRepairOrder->ReadComponent(edtTaxAmount);
    		fstRepairOrder->ReadComponent(edtTotalOrder);
    
    		fstRepairOrder->ReadComponent(edtPartName1);
    		fstRepairOrder->ReadComponent(edtUnitPrice1);
    		fstRepairOrder->ReadComponent(edtQuantity1);
    		fstRepairOrder->ReadComponent(edtSubTotal1);
    
    		fstRepairOrder->ReadComponent(edtPartName2);
    		fstRepairOrder->ReadComponent(edtUnitPrice2);
    		fstRepairOrder->ReadComponent(edtQuantity2);
    		fstRepairOrder->ReadComponent(edtSubTotal2);
    
    		fstRepairOrder->ReadComponent(edtPartName3);
    		fstRepairOrder->ReadComponent(edtUnitPrice3);
    		fstRepairOrder->ReadComponent(edtQuantity3);
    		fstRepairOrder->ReadComponent(edtSubTotal3);
    
    		fstRepairOrder->ReadComponent(edtPartName4);
    		fstRepairOrder->ReadComponent(edtUnitPrice4);
    		fstRepairOrder->ReadComponent(edtQuantity4);
    		fstRepairOrder->ReadComponent(edtSubTotal4);
    
    		fstRepairOrder->ReadComponent(edtPartName5);
    		fstRepairOrder->ReadComponent(edtUnitPrice5);
    		fstRepairOrder->ReadComponent(edtQuantity5);
    		fstRepairOrder->ReadComponent(edtSubTotal5);
    
    		fstRepairOrder->ReadComponent(edtJobDescription1);
    		fstRepairOrder->ReadComponent(edtJobCost1);
    		fstRepairOrder->ReadComponent(edtJobDescription2);
    		fstRepairOrder->ReadComponent(edtJobCost2);
    		fstRepairOrder->ReadComponent(edtJobDescription3);
    		fstRepairOrder->ReadComponent(edtJobCost3);
    		fstRepairOrder->ReadComponent(edtJobDescription4);
    		fstRepairOrder->ReadComponent(edtJobCost4);
    		fstRepairOrder->ReadComponent(edtJobDescription5);
    		fstRepairOrder->ReadComponent(edtJobCost5);
    
    		fstRepairOrder->ReadComponent(mmoRecommendations);
    	}
    	__finally
    	{
    		delete fstRepairOrder;
    	}
        }
    }
    //---------------------------------------------------------------------------
  10. Press F12 to return to the form
  11. Double-click the Close button
  12. Implement its event as follows:
    //---------------------------------------------------------------------------
    void __fastcall TfrmAutoRepair::btnCloseClick(TObject *Sender)
    {
    	Close();
    }
    //---------------------------------------------------------------------------
  13. Save all
  14. Press F9 to execute the application
  15. Create a repair order
    College Park Auto Repair
  16. Click Save
  17. Close the form and return to your programming environment
  18. To execute the application, on the main menu, click Run -> Run
  19. In the File Open edit control, enter the name of the repair file you had saved
  20. Click Open
  21. Close the form and return to your programming environment
 
 
   
 

Home Copyright © 2010-2016, FunctionX