I have already earned $35 within month spending few minutes only

Tuesday, November 24, 2009

Programmatic Updates to the Registry

Programmatic Updates to the Registry
You can update the registry from within your application. This is most useful when saving application information that may change from session to session. For example, you may want your application to save the placement and size of the application window as well as options selected by the user.


MFC provides registry support through member functions of the CWinApp class. For more sophisticated manipulation of the registry, use API calls, as described below.

Registry Support in MFC

To programmatically work with data in the registry, the first step is to call CWinApp::SetRegistryKey. AppWizard will include a call to this function in your CWinApp-derived InitInstance function.

BOOL CMyApp::InitInstance()
{
//...
SetRegistryKey("_T("Local AppWizard-Generated Applications"));
//...
}

SetRegistryKey is used to select the "Company Name" key in the registry. You, as a developer, will change the AppWizard-generated string to the name of your company. If the key is not found when the call is made, one will be created in the registry. Under the company name key, the framework will also generate a subkey using the name of the application as the subkey name. It is under this key where reads and writes to the registry occur for your application. By default, MFC stores application-specific data under HKEY_CURRENT_USER\Software\<CompanyName>\<ApplicationName>\<SectionName>. "SectionName" is a string that you specify when reading or writing a particular key value; it can be used to organize the location of the saved values.

* To create an .ini file that is compatible with 16-bit Windows applications, remove the call to SetRegistryKey. The framework will create the file using the application's name as the .ini file name and will place it in the WIndows directory.

CWinApp provides four functions for reading and writing key values. The following table describes them.

Function Name Description


CWinApp::WriteProfileString Writes a string value to a key in a given section. If the specified section or key does not exist, it is created. A NULL value for the string value will delete the key.


CWinApp::GetProfileString Reads a string value from a key in a given section. A default return value can be specified if the key is not found.


CWinApp::WriteProfileInt Writes an integer value to a key in a given section. If the specified section or key does not exist, it is created. A NULL value for the integer value will delete the key.


CWinApp::GetProfileInt Reads an integer value from a key in a given section. A default return value can be specified if the key is not found.



Use the integer functions for storing and retrieving integer-like values. Use the string functions for all other values. Functions such as CString::Format and sscanf can be used to do the conversion between the string and desired data type.

To see sample code that shows how to read from and write to the registry programmatically, click this icon.


// Class definition file
class CPhraseApp : public CWinApp
{
...
CString m_defaultPhrase;
CPoint m_defaultLocation;
COLORREF m_defaultColor;
...
}
// Class implementation file
// Phrase Initialization
BOOL CPhraseApp::InitInstance()
{
...
// Force all subsequent calls to "Profile" functions
// to read and write from the registry under the key
// HKEY_CURRENT_USER\Software\MasteringVisualC++\Phrase
SetRegistryKey("MasteringVisualC++");
// Call "Profile" functions for registry information
LoadPhraseDefaults();
...
}

void CPhraseApp::LoadPhraseDefaults()
{// Load information from the registry
CString msg;
msg.LoadString(IDS_WELCOME_MSG);
int r, g, b;
m_defaultPhrase =
GetProfileString ("Settings", "DefaultPhrase", msg);
m_defaultLocation.x =
GetProfileInt ("Settings", "X-location", 100);
m_defaultLocation.y =
GetProfileInt ("Settings", "Y-location", 100);
r = GetProfileInt ("Settings", "Red-intensity", 0);
g = GetProfileInt ("Settings", "Green-intensity", 0);
b = GetProfileInt ("Settings", "Blue-intensity", 0);
m_defaultColor = RGB(r,g,b);
}
int CPhraseApp::ExitInstance()
{// Save information to the registry
WriteProfileString ("Settings", "DefaultPhrase", m_defaultPhrase);
WriteProfileInt ("Settings", "X-location", m_defaultLocation.x);
WriteProfileInt ("Settings", "Y-location", m_defaultLocation.y);
WriteProfileInt ("Settings", "Red-intensity", GetRValue(m_defaultColor));
WriteProfileInt ("Settings", "Green-intensity", GetGValue(m_defaultColor));
WriteProfileInt ("Settings", "Blue-intensity", GetBValue(m_defaultColor));
return CWinApp::ExitInstance();
}

Registry Support in the Win32 API

For information about registry support in the API, search for "RegCreateKeyEx," "RegDeleteKey," "RegEnumKey," "RegOpenKeyEx," and "RegQueryInfoKey" in Visual C++ Help.

Self-Check Questions

1. Which one of the following statements is true about the registry?
A. Like .ini files, the registry is a text-based storage for configuration information.
B. Text-based registry entry files that usually have the extension .reg can be used to update the registry.
C. There are four primary branches, called "keys," in the registry.
D. The registry editors supplied with Windows NT or Windows 95 make backup copies of changes and only commit these changes when you exit the editor.

2. Which one of the following statements is true about MFC's programmatic support of the registry?
A. You must override CWinApp::SetRegistryKey to cause the application settings to be stored in the registry instead of an .ini file.
B. MFC's registry functions can be used to manage any key in the registry.
C. Registry functions are typically used in the overridden CWinApp::InitInstance and CWinApp::ExitInstance functions.
D. Binary data is typically written to the registry by using CWinApp::WriteProfileString.
3. Which one of the following statements about MFC serialization is true?
A. Both SDI and MDI applications can use CDocument::OnNewDocument for per-document initialization, and CDocument::DeleteContents for per-document cleanup.
B. The information to be serialized can be located in any of the framework classes.
C. MFC serialization supports incremental transfers and random access to information.
D. CDocument::SetModified must be called before serialization writes can occur.

4. Which of the following types is supported by MFC's serialization operators, the archive insertion (<<), and extraction (>>) operators?
A. int
B. CObject
C. CObList
D. DWORD
5. Which of the following conditions or steps is not required to add support for serialization to a class?
A. The class must be publicly derived from CObject or a class derived from CObject.
B. The class declaration must declare both an overridden version of CObject::Serialize and invocation of the
DECLARE_SERIAL macro.
C. The class implementation file must contain the implementation for Serialize and an invocation of the IMPLEMENT_SERIAL macro.
D. Each class in an application must have different, sequentially numbered schema.

Lab 11.1: Persisting Data

In this lab, you will write the code to serialize document and state data for an application.

Estimated time to complete this lab: 40 minutes
To complete the exercises in this lab, you must have the required software. For detailed information about the labs and setup for the labs, see Labs in this course.

Objectives

After completing this lab, you will be able to:

® Transfer data between a document's collection and a data file.
® Save and retrieve application state data in the registry.

Prerequisites

There are no prerequisites for this lab.

Exercises

The following exercises provide practice with the concepts and techniques covered in this chapter:

® Exercise 1: Implementing Serialization

In this exercise, you will implement serialization for an application's document, which consists of a single collection of polygon and text items. Here you will implement transferring data between the document's collection and a data file.

® Exercise 2: Saving State Data to the Registry

In this exercise, you will serialize application-state information. You will load the most recently used data file and the view on it, and you will recall the view options on that data file. In addition, you will add code to set your company's registry key in the user's registry.

Exercise 1: Implementing Serialization

The code that forms the basis for this exercise is in \Labs\Ch11\Lab01\Baseline. Copy these files to your working directory.

In this exercise, you will implement serialization for an application's document, which consists of a single collection of polygon and text items. Here you will implement transferring data between the document's collection and a data file.

Edit the Serialize function in CPolyEditDoc

— Replace the if/else code with a direct call to the collection's serialization function. This function will, in turn, call each of the collection members’ serialization functions.

// Serialize the items in the list.
m_items.Serialize(ar);

Edit the Serialize function in CItem

— Within the inner brackets, add code to check the direction flag and then either to store or load the variable.

CItem, the base class for polygons and text objects, maintains a position member variable for the object.

if (ar.IsStoring())
{
ar << m_pos;
}
else
{
ar >> m_pos;
}

Edit the Serialize function in CPolygon
— Within the inner brackets, add code to serialize the polygon's brush, border, and position data.

CPolygon is the class that represents polygons in the document. Each polygon object maintains its brush and border properties as well as an array of data points.

if (ar.IsStoring())
{
// Serialize brush properties
ar << m_styleBrush;
ar << m_colorBrush;
ar << m_hatchBrush;
// Serialize border properties
ar << m_colorLine;
ar << m_styleLine;
ar << m_thickLine;

// Serialize the position data

int count= GetSize();
ar << count;
for (int idx=0; idx<count; idx++)
ar << m_pts[idx];
}
else
{
// Serialize brush properties
ar >> m_styleBrush;
ar >> m_colorBrush;
ar >> m_hatchBrush;

// Serialize border properties

ar >> m_colorLine;
ar >> m_styleLine;
ar >> m_thickLine;

// Serialize the position data

int count;
ar >> count;
for (int idx=0; idx<count; idx++)
{
CPoint pt;
ar >> pt;
m_pts.Add(pt);
}
}

Edit the Serialize function in CText

— Within the inner brackets, add code to serialize the text object's string, color, and font data.

CText is the class for representing text in the document. Each object contains a CString, a color, and a LOGFONT structure containing font information. Remember that the base class, CItem, maintains the positional information.

if (ar.IsStoring())
{
ar << m_string;
ar << m_color;
ar.Write(&m_lf, sizeof(m_lf));
}
else
{
ar >> m_string;
ar >> m_color;
ar.Read(&m_lf, sizeof(m_lf));
}

Edit NewPolygon in CPolyEditDoc
1. Before the call to UpdateAllViews, insert the following code. SetModifiedFlag informs the framework that document data has changed. This will serve to prompt the user to have the file saved before quitting. Search for other occurrences of this call in the project.
SetModifiedFlag();
2. Build and run the application.
3. Test this version of the application by creating a new document and adding several polygons and text objects. Save the document and then clear the current view by opening up a new document. Using the FileOpen menu, open the document you just saved.
You can find the code for this completed exercise in \Labs\Ch11\Lab01\Ex01.

Exercise 2: Saving State Data to the Registry

Continue working with the files you created in Exercise 1, or you can find the code that forms the basis for this exercise in \Labs\Ch11\Lab01\Ex01.

In this exercise, you will serialize application-state information. In particular, you will load the most recently used data file and the view on it, and you will recall the view options on that data file. In addition, you will add code to set your company's registry key in the user's registry.

Edit InitInstance in CPolyEditApp

1. Search for the call to SetRegistryKey. Replace the existing call with the following:
SetRegistryKey(_T("Microsoft Mastering Series"));
2. In the same function and between the calls to ParseCommandLine and ProcessShellCommand, add the following code. This code will inform the framework that the most recently used file is to be loaded at startup of the application.
// check that the user did not specify filename on command line.
if (cmdInfo.m_strFileName == "")
{
CString lastFileUsed= GetProfileString("Recent File List", "File1",NULL);
if (lastFileUsed != "")
{
cmdInfo.m_strFileName = lastFileUsed;
cmdInfo.m_nShellCommand = CCommandLineInfo::FileOpen;
}
}


Edit CPolyEditView
1. Add the following code to the destructor to save the application view state and option selections upon quitting.
// View scale
CString strScale;
strScale.Format("%lg",m_scale);
AfxGetApp()->WriteProfileString("Settings", "Scale", strScale);

// View center

AfxGetApp()->WriteProfileInt("Settings", "CenterX", m_x);
AfxGetApp()->WriteProfileInt("Settings", "CenterY", m_y);

// View options

AfxGetApp()->WriteProfileInt("Settings", "ShowInnerBox", m_bShowInnerBox);
AfxGetApp()->WriteProfileInt("Settings", "ShowOrigin", m_bShowOrigin);

2. Edit the CPolyEditView constructor. Replace the code that initializes the view and options with the following code. This code will obtain the settings that were stored in the registry to initialize the view.

// View scale
CString strScale = AfxGetApp()->GetProfileString("Settings", "Scale", "1.0");
sscanf(strScale,"%lg", &m_scale);

// View center

m_x = AfxGetApp()->GetProfileInt("Settings", "CenterX", 0);
m_y = AfxGetApp()->GetProfileInt("Settings", "CenterY", 0);

// View options

int option;
option = AfxGetApp()->GetProfileInt("Settings", "ShowInnerBox", 1);
m_bShowInnerBox = option ? true : false;
option = AfxGetApp()->GetProfileInt("Settings", "ShowOrigin", 1);
m_bShowOrigin = option ? true : false;
3. Build and run the application.
4. Test it by creating a document and adjusting the zoom level and center values. Quit the application and then restart it. The view should contain the same document and view parameters.

You can find the code for this completed exercise in \Labs\Ch11\Lab01\Ex02.

Schema Numbering

Schema Numbering

Over time, and given changes in versions, a program often changes the data set contained within its document class. This could become a source of serious errors, because a file saved with a previous version of a program could be erroneously loaded into a newer version. For example, suppose a document contains a pointer to an object of class CSerializedPhrase, version 1. If the class CSerializedPhrase is then updated to version 2 to include additional data members, the application must keep the document from inadvertently using the new version, or errors will result.

To guard against version changes that cause errors, your application can use and check a schema number, which represents the version of the dataset composition or format of your serializable class. When you change the data members in the serializable class, you should also change the schema number of that class. In order to take advantage of schema numbering, there are issues to be handled in both the serializable class and in the document class.

Using a Schema Number in the Serializable Class

To use schema numbering in a serializable class, you need to add code. To see sample code that shows how to add serialization with schema numbering to the serializable class, click this icon.
// Serializ.cpp : implementation file
// Defines version as 1 and "versionable"
IMPLEMENT_SERIAL(CSerializedPhrase, CObject, VERSIONABLE_SCHEMA | 1)
CSerializedPhrase::CSerializedPhrase()
{
}
void CSerializedPhrase::Serialize(CArchive & ar)
{
int nVersion;
// The base function is called first.
CObject::Serialize(ar);
if (ar.IsLoading())
{
nVersion = ar.GetObjectSchema();
switch (nVersion)
{
case -1:
::AfxMessageBox("Unknown Version");
break;
case 1:
::AfxMessageBox("Version 1");
ar >> m_phrase >> m_location >> m_color;
break;
default:
::AfxMessageBox("Future version");
}
}
else
// Files are always saved in the current version.
ar << m_phrase << m_location << m_color;
}

Using a Schema Number in the Document Class

In addition to adding the necessary code to a serializable class to use schema numbering, there are conditions in the document that must be met in order to get the correct schema number.

If the document calls Serialize directly, the call to CArchive::GetObjectSchema in the serializable class's Serialize function will always return – 1, indicating an unknown version number. To see sample code that illustrates this problem, click this icon.
// An Example of Problems with Schema Numbering
class CPhraseDoc : public CDocument
{
...
CSerializedPhrase m_Phrase;
// or
CSerializedPhrase * m_pPhrase;
...
};
CPhraseDoc:: CPhraseDoc()
{
m_pPhrase = new CSerializedPhrase;
}
void CPhraseDoc::Serialize(CArchive & ar)
{
//Warning: In both cases below, a -1 is returned
// in the serializable class instead of
// the object's schema number
m_Phrase.Serialize(ar);
// or
m_pPhrase ->Serialize(ar);
}
Taking Advantage of Schema Numbering
To guard against serious errors, use the following steps to have your application use and check a schema number.

To get schema numbering to work correctly

1. Define a pointer to the serializable class in the document's definition file.

2. Initialize that pointer to 0 in the document's constructor.

3. Use the archive class's overloaded << and >> operators for serialization on that pointer.

To see sample code that shows the method of doing serialization in the document so that schema numbering will work correctly, click this icon.
// PhrasDoc.cpp : implementation file
CPhraseDoc :: CPhraseDoc()
:m_pPhrase(0)
{
// ...
}
void CPhraseDoc::Serialize(CArchive & ar)
{
if (ar.IsLoading())
ar >> m_pPhrase;
else
ar << m_pPhrase;
}
BOOL CPhraseDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
m_pPhrase = new CSerializedPhrase;
// fill object as appropriate
return TRUE;
}
void CPhraseDoc::DeleteContents()
{
delete m_pPhrase;
m_pPhrase = 0;
CDocument::DeleteContents();
}


For more information about persistence and schema numbering, search for "TN002: Persistent Object Data Format" in Visual C++ Help.

The Registry
One purpose of the registry is to store information that will be used by an application from one session to the next. Most recently used files, application-specific folders, and user-selected options are commonly stored in the registry.

In past versions, Windows stored application information in .ini files. This storage method posed a number of problems, however, because the settings for each application were stored in a separate file that could be easily deleted, moved, or modified by the user. The registry makes the storage of configuration information for all applications more manageable by placing it in a single location: the registry database.

Another difference between the registry and .ini files is how the data is stored. While .ini files are written to as text — either by an application or by someone using a text editor — the registry is binary. Its contents are accessible through a tool, RegEdit, or accessible programmatically by means of CWinApp methods.

This section explains the registry in more detail. First, it discusses the organization of the registry database. Then it explains how to view and edit the information contained in the registry using the registry editor. Finally, it shows you two techniques for manipulating the registry from within your application: through registry entry files and programmatic access to the registry through CWinApp methods.

This section includes the following topics:

Registration Database Structure

The registration database (another name for the registry) is a hierarchical database of configuration information. At the root of the hierarchy are six predefined primary keys, or branches, that provide entry points into the registry. The primary keys contain keys, which can contain other keys. Keys can also contain values. A value associates a keyword parameter with a configuration value, which is similar to the entries in an .ini file, except that the data itself is binary. To see an illustration that contains sample keys and their values, click this icon.





Predefined Primary Keys

The following table lists the six primary keys that provide entry points into the registry, and their purpose.

Key name Purpose

HKEY_CLASSES_ROOT Contains software configuration information, particularly for use with COM objects. Includes file extensions /application associations, drag-and-drop protocols, printing configurations, and what to do when a file name receives a double-click.HKEY_CURRENT_USER Contains user-specific settings for the system and applications. Created when the user logs on, and is loaded to this key from that user's entry in HKEY_USERS. MFC applications store registry information under this primary key.HKEY_LOCAL_MACHINE Contains specifications for the computer and drivers and other system settings for the type of hardware installed. Entries in this section are shared by all users of the system.HKEY_USERS Contains information about all the users who log on to the computer. Includes both user-specific information and generic user information. Generic system settings are available to all users of the system.HKEY_CURRENT_CONFIG Contains information about the current configuration of the hardware that is attached to a dockable computer that supports multiple configurations.HKEY_DYN_DATA Contains the dynamic status information for various devices. This information is used in the implementation of Plug and Play technology.The Registry Editor

The registry editor provides a graphical interface to view and edit the key hierarchy and values within the registration database.

Viewing the Registry

To view the registry, run RegEdit. The left pane of RegEdit contains a tree view of the database with the primary keys at the root of the view. Key values that contain other keys can be expanded and collapsed in this view. The right view contains keys and their values at the currently selected key in the Tree View pane. Keys can be modified, renamed, or deleted by right-clicking on the key name in the right pane.

To see an illustration that shows how RegEdit displays information about application-specific keys in the registry, click this icon.





Modifying the Registry Safely

You should take care when changing registry settings. Any changes that you make to the registration database take effect immediately. There is no separate Save command in the registry editor.

If there is an error in your registry, your computer may become nonfunctional. If this happens in Windows 95, you can restore the registry to its previous state when you last successfully started your computer.

The following procedure is from the Windows 95 Registry Editor online Help.

To restore the registry in the Windows 95 operating system

1. Click Start, and then click Shut Down.
2. Click Restart the computer in MS-DOS mode, and then click Yes.
3. Switch to your Windows directory. For example, if your Windows directory is C:\Windows, you would type the following:

cd c:\windows

4. Type the following commands, pressing ENTER after each one. (Note that System.da0 and User.da0 contain the number zero.)
attrib -h -r -s system.dat
attrib -h -r -s system.da0
copy system.da0 system.dat
attrib -h -r -s user.dat
attrib -h -r -s user.da0
copy user.da0 user.dat
5. Restart your computer.

Registry Entry Files

A registry entry file is a text file that contains data for the registration database. When the registry editor processes a registry entry file, it uses the information contained there to add and update values within the registration database. Registry entry files cannot be used to remove information from the database.

Registry Entry File Structure

Structurally, registry entry files are simple. The typical file extension is .reg. The first line contains the single word REGEDIT to mark the file as a registry entry file. Comments are marked by an initial semicolon and continue to the end of the line. Individual entries appear one per line in the following format:

branch\key name = value

For example, a registry entry file might appear as follows:
REGEDIT ; This .REG file may be used by your SETUP program.
HKEY_CLASSES_ROOT\.PHR = Phrase.Document


Registry Entry File Use

Setup programs use registry entry files to register their data files for shell activation. A setup program calls the registry editor and passes the registry entry file name to it as a command-line argument. The file is verified by ensuring that the first line of the file contains REGEDIT, and then the individual entries are parsed and added to the database.

Creating a Registry Entry File with AppWizard

You can use AppWizard to create a registry entry file for your application. To see an illustration of the Advanced Options dialog box in Step 4 of AppWizard, which is used to set a default file extension for documents associated with your application, click this icon.





To see a sample registry entry file, click this icon.



; phrase.reg

REGEDIT; This .REG file may be used by your SETUP program.
; If a SETUP program is not available, the entries below will be
; registered in your InitInstance automatically with a call to
; CWinApp::RegisterShellFileTypes and COleObjectFactory::UpdateRegistryAll.

HKEY_CLASSES_ROOT\.PHR = Phrase.Document
HKEY_CLASSES_ROOT\Phrase.Document\shell\open\command = PHRASE.EXE %1
HKEY_CLASSES_ROOT\Phrase.Document\shell\open\ddeexec = [open("%1")]
HKEY_CLASSES_ROOT\Phrase.Document\shell\open\ddeexec\application = PHRASE
; note: the application is optional
; (it defaults to the app name in "command")
HKEY_CLASSES_ROOT\Phrase.Document = Phrase Document

Serializing Data Structures

Serializing Data Structures

Arbitrary data structures can be serialized by using the member functions CArchive::Write and CArchive::Read. Each of these functions takes as parameters a pointer to a buffer and the number of bytes to transfer. The following code example uses these functions to serialize a LOGFONT data structure:

void CMyFont::Serialize(CArchive& ar)
{
LOGFONT logfont;
if (ar.IsStoring())
{
// call user function to initialize the structure.
InitLogFont(&logfont);
ar.Write(&logfont, sizeof(logfont));
}
else
{
ar.Read(&logfont, sizeof(logfont));
// call user function to save the structure.
SaveLogFont(&logfont);
}
}

Serializing Class Objects
Class objects can be serialized if they have been derived from CObject and have overridden the Serialize member function. For example, many of the MFC collection classes override this function for you. To serialize a document that contains such an object, call the Serialize function of the member directly.


Making a Serializable Class
You can implement object persistence for any class by adding serialization support for that class. You add this support by first declaring the class as serializable and then implementing the necessary serialization code.


To make a serializable class

1. Publicly derive the class from CObject or from a class that was derived from CObject.
2. In the class declaration, provide a default constructor. The framework requires a default constructor (a constructor with no arguments) to create objects when loading data from a data file. If you use ClassWizard to add a new class, it will automatically add a default constructor.
3. In the class declaration, add the DECLARE_SERIAL macro. Provide the class name as the single argument.
4. In the implementation file, add the IMPLEMENT_SERIAL macro. The three parameters to IMPLEMENT_SERIAL are the class being serialized, its base class, and a schema number.
5. Override the CObject::Serialize function. This is easily done by right-clicking the class name in ClassView and then selecting the menu item Add Virtual Function.


To see sample code that declares a serializable class, click this icon.

// Serializ.h - header file

// Publicly derive the class from CObject
class CSerializedPhrase : public CObject
{
protected:
// Provide a default constructor
CSerializedPhrase();
public:
// Override Serialize
void Serialize(CArchive &);
// Invoke the DECLARE_SERIAL macro
DECLARE_SERIAL(CSerializedPhrase)
...
};

To see sample code that implements serialization for a class, click this icon.

// Serializ.cpp - implementation file
IMPLEMENT_SERIAL(CSerializedPhrase, CObject, 1)
CSerializedPhrase::CSerializedPhrase()
{

}
void CSerializedPhrase::Serialize(CArchive & ar)
{
// The base function is called first.
CObject::Serialize(ar);
if (ar.IsLoading())
ar >> m_phrase >> m_location >> m_color;
else
ar << m_phrase << m_location << m_color;
}

Using a Serializable Class
How you use a serializable class depends upon whether you are working with an object of the serializable class or a pointer to an object of the serializable class. This topic also covers how to handle issues of schema numbering both in the serializable class and in the document class.

Serializing Objects
If your document class uses your serializable class as an embedded member, you can invoke the Serialize method directly, as shown in the following example code:

class CPhraseDoc : public CDocument
{
...
// Define a CSerializedPhrase object
CSerializedPhrase m_Phrase;
...
}
// CPhraseDoc.cpp implementation file
void CPhraseDoc::Serialize(CArchive& ar)
{
m_Phrase.Serialize(ar);
}

Serializing Objects via Pointers

Using a pointer for the serializable object has its own set of considerations. How you handle the serialization depends upon whether or not the pointer was initialized.

Deserializing to Uninitialized Object Pointers

If the class contains an uninitialized object pointer, then you should rely on the extraction and insertion operators (>> and <<) for serialization of the object. In the case of reading from the data file, the archive object will build the object using its default constructor and then call the object's Serialize function. As an alternative, you can explicitly construct the object pointer and then call the Serialize function. To see sample code that uses the archive to handle memory allocation when you deserialize an object, click this icon.

// PhrasDoc.h
class CPhraseDoc : public CDocument
{
...
// Define a CSerializedPhrase pointer
CSerializedPhrase * m_pPhrase;
...
}
// PhrasDoc.cpp
CPhraseDoc :: CPhraseDoc()
:m_pPhrase(0)
{

}
void CPhraseDoc::Serialize(CArchive& ar)
{
if (ar.IsLoading())
ar >> m_pPhrase;
else
ar << m_pPhrase;
}
BOOL CPhraseDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
m_pPhrase = new CSerializedPhrase;
// fill object as appropriate
return TRUE;
}
void CPhraseDoc::DeleteContents()
{
delete m_pPhrase;
m_pPhrase = 0;
CDocument::DeleteContents();
}

Deserializing to Initialized Object Pointers

If the object pointer is already initialized, then you can use either the extraction and insertion operators (>> and <<), or you can call the object's Serialize function directly. What is important is that you make sure that the object cleans up its data members before deserializing from the data file. Not adhering to this rule will generate memory leaks in your application. Cleaning up an object's data members is often done by calling a user-defined member function that frees memory allocated from the heap.

The document object provides a convenient place for deleting its contents in the CDocument::DeleteContents member function. The MFC framework is structured so that it will call this function when a document is to be reused or destroyed. A useful strategy is to create a DeleteContents member function for each serialized class that you create and then have each object call the DeleteContents function of each of its contained objects. Since the framework calls the document's DeleteContents member function, the entire document will be efficiently and correctly deleted.


Whichever method you decide to use, you must be consistent. Use the same method — either the Serialize function or the CArchive << and >> operators — for both the loading and storing of any one object.

Opening a New File

Opening a New File

When a user chooses the New command on the File menu in an AppWizard-generated application, the default framework behavior is as follows.

1. Checks whether the current document has been modified and, if so, prompts the user to save it. Saves the current document if the user says yes.
2. Removes the contents of the old document.
3. Creates a new document.


Virtual Functions to Manage Document Creation

The CDocument class provides two virtual functions that can be overridden to provide for handling the document-creation process.
CDocument::OnNewDocument is called by the framework as part of the New command. The default implementation of this function calls DeleteContents to empty the document, and then marks the document as clean.

You can override this function to do per-document initialization instead of placing this code in the constructor for your document class.

CDocument::DeleteContents empties the document without destroying the document object itself. The default implementation of this function does nothing. Commonly, this function is overridden to delete dynamically allocated objects in your document, rather than using the destructor.

MDI vs. SDI

Because SDI applications use only a single document object, CDocument::DeleteContents is used to reuse the single document object whenever the user creates another document. No constructor or destructor for the associated document object is called on subsequent New operations.

In an MDI application, opening a new file causes a new document object to be created with its attendant views. The function CDocument::OnNewDocument is called for the document after it is constructed.

Opening an Existing File

When a user chooses the Open command on the File menu in an AppWizard-generated application, the default behavior is as follows:

1. Checks whether the current document has been modified and, if so, prompts the user to save it. Saves the current document if the user says yes.

2. Displays the Open common dialog box and accept the user's file selection.

3. Removes the contents of the old document.

4. Loads the new document by deserializing its data.



Internally, the process is much more complicated, but most of the details are encapsulated into the application framework. In fact, in most cases, you need concern yourself only with specifying which data to serialize and in what order. The application framework manages the opening and closing of files, and the instantiation of the document and view objects.

Virtual Functions for Special FileOpen Situations

The CDocument class provides two virtual functions that can be overridden to provide for the handling of special FileOpen operations:

® CDocument::OnOpenDocument provides a place to do per-document initialization when an existing file is opened. The framework calls OnOpenDocument as part of the file-opening process. The default implementation of this function opens the specified file, calls DeleteContents to empty the document, calls Serialize to read the file contents, and then marks the document as clean.

It is more rare to override OnOpenDocument than it is to override OnNewDocument, since serialization is usually sufficient to initialize the document when opening an existing file.

® CDocument::DeleteContents empties the document without destroying the document object itself. The default implementation of this function does nothing.



SDI vs. MDI

Because SDI applications use only a single document object for the duration of the application, CDocument::DeleteContents is used to reuse the single document object whenever the user opens another document. No constructor or destructor for the associated document object is called during FileOpen operations.

In an MDI application, opening an existing file causes a new document object and its attendant views to be created. The CDocument::OnNewDocument function is called for the document after it is constructed.

Saving or Closing a File

Saving a file involves having the document store its data and objects by calling its Serialize function.

Before closing a document, the framework calls CDocument::IsModified to determine if the document data has changed. If data has changed, the framework displays a dialog box to ask the user whether or not the modified data should be saved.

Marking a Document as Modified

It is the developer's responsibility to ensure that the modified flag is set when the document data has changed. In general, the program should call CDocument::SetModifiedFlag whenever a document's data has changed. This guarantees that no changed document will be closed without first asking the user if the data should be saved.

MDI vs. SDI

In an MDI application, when a document is closed, CDocument::DeleteContents is called before the destructor for the associated document object.

Because an SDI application must have exactly one document open at a time, the Close command is not usually available on the File menu.

Serializing a Document Class

If you generate a nondatabase application, AppWizard overrides CDocument::Serialize for your application's document class. However, AppWizard supplies only an almost empty implementation for this member function. It is your responsibility to add the proper implementation code to the Serialize function based upon the details of your application's document class. The following example code shows a typical Serialize function that is generated by AppWizard:

void CMyDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
}
else
{
// TODO: add loading code here
}
}


Serialization Helper Functions

MFC serialization is responsible for both storing and loading data. To allow the Serialize function to handle both cases, two adjunct functions exist: CArchive::IsLoading returns TRUE if reading from the file; CArchive::IsStoring returns TRUE if writing to the file.


Note The order in which members are loaded and stored must match exactly, or the data in the document will be corrupted. Neither the Visual C++ compiler nor the application framework can check this for you.


Serializing Built-in Data Types

Similar to the standard Visual C++ iostream class library, CArchive provides overloaded insertion (<<) and extraction (>>) operators for data insertion and extraction in the following portable Visual C++ and Microsoft Windows simple built-in data types.

CTime and CTimeSpan SIZE and CSize float

WORD CString POINT and CPoint

DWORD BYTE RECT and CRect

double LONG COLORREF

BOOL



Nonportable data types, such as int, do not have corresponding overloaded CArchive serialization operators. If the document class contains members of these nonportable data types, the developer can cast them to their equivalent portable types for serialization.

To see sample code that serializes document class members that are built-in data types, click this icon.

// Class definition

class CSerialDocumentDoc : public CDocument
{
...
CString m_phrase;
CPoint m_location;
COLORREF m_color;
...
};
// Class definition
void CSerialDocumentDoc::Serialize(CArchive& ar)
{//
if (ar.IsStoring())
ar << m_phrase << m_location << m_color;
else
ar >> m_phrase >> m_location >> m_color;
}

Implementing Persistence

Implementing Persistence
Application persistence is the act of saving information about the application between program sessions. MFC provides support for two forms of persistence: serialization and application-state persistence.

Serialization is a mechanism for preserving application data and consists of streaming data out to a data file. MFC provides much of the structure for implementing serialization through its application framework. The developer completes the serialization structure by implementing application-specific code to serialize the data that is to be preserved.

Application-state persistence saves information about the user's session. The state information that is saved depends upon the application and can include such information as the application window's size and position on the desktop and any operating modes that the user last selected, as well as an application's option settings. While serialization saves data to a data file, state persistence uses the operating system's registry to store its data.

This chapter discusses both forms of persistence: implementing document serialization through the use of data files, and preserving application state information through the use of the operating system's registry.

Objectives

After completing this chapter, you will be able to:

® Define serialization and how it is integrated in MFC.
® Describe how MFC supports persistent storage.
® Create a serializable class.
® Create and use serializable objects.
® Describe the registry.
® View and modify the registry.
® Programmatically update the registry.

Serialization
Serialization is the process of storing data from the application to a data file or loading data from a data file to the application. Serialization is integrated within the MFC's document/view architecture and can occur as a result of the user's explicitly saving or loading a data file. Serialization can also occur as a side effect of modifying the document data. In this case, the MFC application framework will prompt the user to save the data before deleting the data from the document.

The approach to serialization within MFC is that the document object begins the serialization of data. The document object either serializes data directly, or it delegates the task of serialization to the data objects contained within the document. The objects, in turn, implement the functionality to save their data members. Later, these objects can restore their data members by reading, or "deserializing," the data from persistent storage. A key point is that the objects themselves are responsible for reading and writing their own state. For a class to be persistent, it must implement the basic serialization operations.

In the document/view architecture the serialization process starts at the developer's CDocument-derived class where AppWizard has generated a Serialize function. From the Serialize function, the developer creates application-specific code that transfers the data. The framework passes in a reference to an archive object when the Serialize function is called. The archive object acts as an intermediate object between the document and the data file. The document's Serialize function uses the archive object directly or, for more complicated document objects, the document will pass the archive object to the document's data objects, which will then serialize themselves.

To see an illustration of the serialization process, click this icon.





Serialization in MFC depends upon a number of classes in your application's framework. The following table lists the primary classes and their purpose.

Class Purpose


CObject Serves as a base class for objects that are to be serialized. The member function CObject::Serialize is overridden by the developer to implement serialization for the data object.


CDocument Contains the information (data and objects) to be serialized. The member function CDocument::Serialize specifies what portion of this information is to be serialized.


CArchive Provides a context for serialization. CArchive handles process-dependent factors, such as media access and buffering. During construction, a CFile object is "attached" to the archive. A single CArchive object can be used for either storing or loading data, but not for both.


CFile Represents the file on a storage device, such as a hard disk. CFile directly provides unbuffered, binary disk input/output services, and it indirectly supports text files and memory files through its derived classes.



This section explains the default behavior for serialization that is provided by the framework. It also reviews the process of declaring, implementing, and using a new user-defined serializable class.

This section includes the following topics:

Serialization Support Implemented by MFC
The FileNew, FileOpen, and FileSave commands are three common ways to explicitly initiate serialization. This topic describes the MFC classes and functions available to help you implement your serialization code, including the differences between SDI and MDI applications during the serialization operation.

Serialization and MFC

Important points to remember about serialization support as implemented by MFC are:

® Actual data serialization begins with the CDocument::Serialize function.
® All objects are transferred in totality — that is, partial serialization is not allowed.
® Objects are loaded in the same order that they were saved.
® Synchronize documents by using a schema number.

Cameron Diaz

CLICK HOT PHOTO AND GET THE GALLERY


Cameron Diaz cameron diaz camron cameron's diaz'sRare Arrives Awards Functions Ballet Shoes Beautiful Bikini Boyfriend bra Burberry Cleavage Cute Drawing Fake Fakes Family Fashion feet Funny Gallery Hot Interview Magazine Mini Skirt News panties Party Photo effect Photo Shoot Photos Polo Day Premiere Pretty Private Pictures Rupert Grint Sexy shorts Style Pose thongs videos Wallpaper with Celebrities Young screen saver huge Photo Gallery of Share hot Sexy clip of video of Movies Videos Watch video about boom hott,scene fearless myspace FEARLESS Lyrics Music site for music videos, songs, photos, live performances and more Music video Pictures, Biography, Discography, News, Ringtones American Music Awards Nominees ... one of countrypop's brightest ! Picture, Video, Wallpaper, Profile, Gossip, and News at Celebrity Women Celebrities Profile – Biography, Latest Photos, Pics, News, Gossip, Comments, Success and Sexiness Rating! Check out Get the latest news, pictures and videos and learn all about from Hollyscoop, your celebrity news source Picture, Video, Wallpaper, Profile, Gossip, and News at Celebrity sports illustrated project pictures of Recent images Hot! View the latest photos. Large gallery of pics hot photos, hot pictures, news, videos, movies, songs, lyrics, music albums, filmography, discography, biography Photos, Bio, News and Message Board on TVGuide pictures and photos in a high quality gallery of the beautiful born supermodel Fansite with blogs, news, filmography, awards, video, wallpaper and anything and everything about Super sexy model Gallery Home Gallery Videos Forum Personal News Links Contact Editorial Covers Campaigns Events Extras Secret News SEXY EVENING GOWN Pictures, Videos, Wallpapers, Screensavers, Downloads, News Headlines and Linkshe photo galleries, information, tags, stats picture sexy bikni free celebrities, 3d , actress, art nature, travel, abstract, game, car Get free Desktop Wallpapers for your PC. Fast and Easy Satanic Celebrities?The Horned Hand Not Just Rock? Free to Join Online Fellowships Celebrity Charity Profile Check out the latest Cecile de France photo gallery, biography, pics, pictures, interviews, news, forums and blogs Sexy Pictures, Sexy Girls naked, beautiful girls sexy, black girls sexy, asian girls sexy, Lesbians pictures, big small images, lady pictures ownload latest bollywood actor, fan club, biography, roles, images, photos, profile news, gossip, photos of biography, boyfriend and relationship info Hindi music, Indian songs, Bollywood Movie soundtracks, desi videos, trailors and news. Hindi, Tamil, Telugu and Malayalam Songs MUMBAI, India: Bollywood beauty got engaged to Londonbased millionaire businessman at his Mumbai apartment Bollywood Actors Actresses Directors Bollywood Movies, Bollywood DVD, Hindi Movies, Hindi DVD, Punjabi Movies, Punjabi DVD, DVD, Songs Check out Actress Latest News, Photos, Videos, Actress Images, Pictures, Gallery, Photo Gallery information about of Cruise with Celebrity Cruises Voted one of the World's Best Cruise Lines by Condé Nast Traveler Cruise deals on toprated vacation cruises to premier Celebrity photo, video, and gossip blog featuring the latest hot celebrities including Nude Celebrities, celebrity Sex, Pussy, Upskirts, Thong Slips, Tit Slips, Celebrity Sex Tapes, Sex Pictures Offers celebrity news, new movie reviews, trailers and celeb photos lyrics, Profile, Biography, Credits, Image Gallery





















camron cameron diaz cameron's diaz's

screen saver huge Photo Gallery of Share hot Sexy clip of video of Movies Videos Watch video about boom hott,scene fearless myspace FEARLESS Lyrics Music site for music videos, songs, photos, live performances and more Music video Pictures, Biography, Discography, News, Ringtones American Music Awards Nominees ... one of countrypop's brightest ! Picture, Video, Wallpaper, Profile, Gossip, and News at Celebrity Women Celebrities Profile – Biography, Latest Photos, Pics, News, Gossip, Comments, Success and Sexiness Rating! Check out Get the latest news, pictures and videos and learn all about from Hollyscoop, your celebrity news source Picture, Video, Wallpaper, Profile, Gossip, and News at Celebrity sports illustrated project pictures of Recent images Hot! View the latest photos. Large gallery of pics hot photos, hot pictures, news, videos, movies, songs, lyrics, music albums, filmography, discography, biography Photos, Bio, News and Message Board on TVGuide pictures and photos in a high quality gallery of the beautiful born supermodel Fansite with blogs, news, filmography, awards, video, wallpaper and anything and everything about Super sexy model Gallery Home Gallery Videos Forum Personal News Links Contact Editorial Covers Campaigns Events Extras Secret News SEXY EVENING GOWN Pictures, Videos, Wallpapers, Screensavers, Downloads, News Headlines and Linkshe photo galleries, information, tags, stats picture sexy bikni free celebrities, 3d , actress, art nature, travel, abstract, game, car Get free Desktop Wallpapers for your PC. Fast and Easy Satanic Celebrities?The Horned Hand Not Just Rock? Free to Join Online Fellowships Celebrity Charity Profile Check out the latest Cecile de France photo gallery, biography, pics, pictures, interviews, news, forums and blogs Sexy Pictures, Sexy Girls naked, beautiful girls sexy, black girls sexy, asian girls sexy, Lesbians pictures, big small images, lady pictures ownload latest bollywood actor, fan club, biography, roles, images, photos, profile news, gossip, photos of biography, boyfriend and relationship info Hindi music, Indian songs, Bollywood Movie soundtracks, desi videos, trailors and news. Hindi, Tamil, Telugu and Malayalam Songs MUMBAI, India: Bollywood beauty got engaged to Londonbased millionaire businessman at his Mumbai apartment Bollywood Actors Actresses Directors Bollywood Movies, Bollywood DVD, Hindi Movies, Hindi DVD, Punjabi Movies, Punjabi DVD, DVD, Songs Check out Actress Latest News, Photos, Videos, Actress Images, Pictures, Gallery, Photo Gallery information about of Cruise with Celebrity Cruises Voted one of the World's Best Cruise Lines by Condé Nast Traveler Cruise deals on toprated vacation cruises to premier Celebrity photo, video, and gossip blog featuring the latest hot celebrities including Nude Celebrities, celebrity Sex, Pussy, Upskirts, Thong Slips, Tit Slips, Celebrity Sex Tapes, Sex Pictures Offers celebrity news, new movie reviews, trailers and celeb photos lyrics, Profile, Biography, Credits, Image Gallery
Free Bangladeshi Girls Photos Indian girls Photos Pakistan Girls pic bikini girls photos Bangladeshi sexy downloads. Photo Gallery. Bangla babe . Girlfriend. sexy Model. Brazil girls, Russian girls, Paris girls. Asian sexy girls photos, American sexy girls image, african hot girls pic, bikini girls beach girls photos. desi girls masala girls. Arab girls, dubai girls photos images pic. girls, teen models, hot teens, sexy teens, naket girls, free teen sexy, teen sexy pics, huge selection of free teen sexy pictures galleries. you will find only hot teen models girls posing for you. Cute and sexy teens afghanistan, armenia, azerbaijan, bangladesh, bhutan, brunei, cambodia, china, georgia, hailand, india, indonesia, japan, kazakhstan, kyrgyzstan, laos, malaysia, maldives, myanmar, vietnam, korea, pakistan, philippines, russia, singapore, south, korea, sri lanka, taiwan, uzbekistan. Sexy Pictures, Sexy Girls naket, beautiful girls sexy, black girls sexy, asian girls sexy, Lesbians pictures, big small images, lady pictures Vanessa Minnillo