home account info subscribe login search My ITKnowledge FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
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

Bookmark It

Search this book:
 
Previous Table of Contents Next


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, it’s very difficult to fix—entire 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 don’t 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.cpp’s 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 we’re 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, we’re 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. We’re 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 we’ve created our new registry entry, it’s 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 there’s a file to read in. We do that in the application object’s 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()){          ⇐
    .
    .
    .
}


Previous Table of Contents Next


Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.