To access the contents, click the chapter and section titles.
Fast Track Visual C++ 6.0 Programming
(Publisher: John Wiley & Sons, Inc.)
Author(s): Steve Holzner
ISBN: 0471312908
Publication Date: 09/01/98
Chapter 14 The Windows Registry and Version Tracking
In this chapter, we look at several professional Windows programming topics. In particular, we look at using the Windows registry and the Version resource that comes in Visual C++ resource files.
The Windows registry is both famous and infamous. Programs use the registry to store configuration data, such as the names of files or initialization data. However, when the registry becomes corrupted, its very difficult to fixentire sub-industries have sprung up to address this problem. We stick to the standard registry calls in our example program to make sure as little as possible can go wrong.
The Version resource that Visual C++ programs include is often overlooked, but should be used in professional programs. This information is available to the user through utilities such as the Windows Explorer and is often the only way users have of querying programs to find out what they do and who wrote them. In this chapter, we put together an application that makes use of the information in the Version resource and displays that information in the About box that is part of AppWizard .exe projects.
We begin by working with the registry, which we turn to now.
Using the Registry: The Remember Application
We use the Windows registry to store the name of the current file the user is working on. For example, if the user is editing a file named Remember.txt and quits, we can automatically reopen that file when the user starts our program again. This is one of the standard uses of the registry.
-----------------------------------------------
| |
|----------------------------------------------- |
| |
| |
| ----------------------- |
| |Remember.txt | |
| |----------------------- | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| ----------------------- |
| |
------------------------------------------------
You use several standard functions to work with the registry. To write integers or strings to the registry, you use WriteProfileInt() or WriteProfileString().
BOOL WriteProfileInt(LPCTSTR lpszSection, LPCTSTR lpszEntry,
int nValue);
BOOL WriteProfileString(LPCTSTR lpszSection, LPCTSTR
lpszEntry, LPCTSTR lpszValue);
Here we supply a section and entry in the registry to work with. If those items dont exist, these functions create them.
To read integers or strings, you use GetProfileInt() or GetProfileString().
UINT GetProfileInt(LPCTSTR lpszSection, LPCTSTR lpszEntry,
int nDefault);
CString GetProfileString(LPCTSTR lpszSection, LPCTSTR
lpszEntry, LPCTSTR lpszDefault = NULL);
Create the Remember project now using Visual C++s AppWizard, making it an MDI project.
This program is already designed to use the registry. In Remember.cpps InitInstance() function, the program calls SetRegistryKey() to create the registry key Local AppWizard-Generated Applications. The registry operates with these keys, and the data a program stores or retrieves comes from its key.
BOOL CRememberApp::InitInstance()
{
AfxEnableControlContainer();
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared
DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
// Change the registry key under which our settings are stored.
// You should modify this string to be something appropriate
// such as the name of your company or organization.
SetRegistryKey(_T(Local AppWizard-Generated Applications)); ⇐
.
.
.
We change the registry key to Remember Application.
BOOL CRememberApp::InitInstance()
{
AfxEnableControlContainer();
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared
DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
// Change the registry key under which our settings are stored.
// You should modify this string to be something appropriate
// such as the name of your company or organization.
//SetRegistryKey(_T(Local AppWizard-Generated Applications));
SetRegistryKey(_T(Remember Application)); ⇐
.
.
.
Now were ready to store the name of the file the user is working on so we can open it automatically when the user starts the program again.
Storing Data in the Registry
In this example, we store the name of the file the user is working on when he or she saves it, so connect a function to OnSaveDocument() in the Document class now. This function is passed the name of the file to store, along with its path. We store that information in the registry with WriteProfileString(). That function is a member of the application object, so we use AfxGetApp() to get the application object, then call WriteProfileString().
BOOL CRememberDoc::OnSaveDocument(LPCTSTR lpszPathName)
{
AfxGetApp()->WriteProfileString(Open, FileName, lpszPathName); ⇐
return CDocument::OnSaveDocument(lpszPathName);
}
In this case, were creating (unless it already exists) a new section under our key in the registry and naming it Open. You usually divide registry keys by task, and each task, such as opening files, has its own section. Were also creating a new entry in that section named FileName and storing the name of the file to open there.
You can see our new registry entry in the Microsoft Registry Editor in Figure 14.1.
Figure 14.1 Our new registry entries in the Registry Editor.
Now that weve created our new registry entry, its time to put it to work when the user starts our program.
Reading Data from the Registry
When the user opens the program again, we can check whether theres a file to read in. We do that in the application objects InitInstance() function. In that function, we call GetProfileString() to search for a filename to open.
BOOL CRememberApp::InitInstance()
{
AfxEnableControlContainer();
.
.
.
CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(
IDR_REMEMBTYPE,
RUNTIME_CLASS(CRememberDoc),
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
RUNTIME_CLASS(CRememberView));
AddDocTemplate(pDocTemplate);
.
.
.
// Dispatch commands specified on the command line
if (!ProcessShellCommand(cmdInfo))
return FALSE;
CString FileName = AfxGetApp()->GetProfileString(Open,FileName); ⇐
.
.
.
Next we check whether that filename is empty.
BOOL CRememberApp::InitInstance()
{
AfxEnableControlContainer();
.
.
.
CString FileName = AfxGetApp()->GetProfileString(Open, FileName);
if(!FileName.IsEmpty()){ ⇐
.
.
.
}
|