Click here to Skip to main content
Licence 
First Posted 20 Oct 2002
Views 89,375
Bookmarked 31 times

Using Text File Resources in VC++

By | 21 Oct 2002 | Article
Use the Resource Editor to load a text file and use it inside a C++ app.

Introduction

This article explains how to use plain text files such as *.XML and others inside the MS Visual Studio Resource Editor for your C++ applications. The benefits to do so are:

  1. You don't have to worry about external files such as XML files your application may use, if they become corrupted by a virus or an experimental user.
  2. Your external files are kept in one central location; inside your binary application file. You are not concerned over where the location of your external files are.
  3. During deployment, there is no concern over where to place your external files, like what the user's computer directory structure is and etc; again, they are included inside your EXE or DLL application.

Now let's take a look at some disadvantages:

  1. The size of your EXE/DLL file will increase in size to account for resource file(s) you added.
  2. If your resource file changes, you have to re-load your resource into the Resource Editor to make sure the changes are reflected, and then re-compile your EXE/DLL program.
  3. The more complex your resource file is, and how it is used in your application, will undoubtedly mean that your code to use the resource file will be complex, and difficult to code.

So as we can see, there are certain situations where this might not be the best solution for the goal at hand. Yet, this does supply a viable solution to other type of applications.

In our sample program, we have a standard XML template file where for any given application, we want to maybe replace a re-occurring substring of data with another. This goal can be accomplished in many ways such as using the XML technologies, string search and replace methods by using code loops and etc. However, we want to keep things as simple as possible and use the standard template library.

Using the standard template library allows our code to be small, compact and extremely portable to other solutions. In any case, the only un-portable code would be the loading and retrieving of the resource text file itself: which is the basis for this article.

Shall we begin?

We start inside Visual Studio, creating a new console application type project and inserting a custom resource into our Resource Editor as the pictures show below:

Once we have our resource file added, we start our code by including the files and declarations here:

// Author: Dwight N. Goins 
// For Servell Computer Resources
// Date: 10/14/2002
// CreateXMLFiles.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"

//Needed for Resource Files inside Resource Editor of XML data
#include <windows.h>

//Needed for low level file operations
#include <conio.h>
#include <io.h>
#include <sys/stat.h>

//Used to find pos of sub string in XML String
//resource
#include <string>
//Namespace for string operations
using namespace std;

Here is our main procedure and the source of the application:

int _tmain(int argc, _TCHAR* argv[])
{
  if (argc <= 2 || argc > 3) 
  {
    _tcprintf(_T("This Program's Expected Usage is:\n" 
          " %s PathDefault PathToWriteXmlFiles"), argv[0]);
    return 1;
  }

    //Getting Arguments
    LPTSTR sArgv = argv[1];
    LPTSTR sArgv2 = argv[2];

    //Getting Resource Info
    //And Storing as String Data
        //Once the Resource Editor has store our file.
        // Open up the resouce.h file in a text editor to
        // see what the number assignment for the resource is
        // in this case it is 103, this will be the resources
        // name internally
    TCHAR  sResName[5]  = _T("#103");

        // Now because we choose to represent the resource type
        // as a custom
        // type we just tell use this type to locate the
        // resource in the application

    TCHAR sRestype[13] = _T("TIMELISTINGS");
    HRSRC hres = FindResource(NULL, sResName, sRestype);
       if (hres == 0)
       { 
      _tcprintf(_T("An Error Occurred.\n Could Not Locate Resource File."));
        return 1;
        }
        
        //If resource is found a handle to the resource is returned
        //now just load the resource
    HGLOBAL    hbytes = LoadResource(NULL, hres);
        
        // Lock the resource
    LPVOID pdata = LockResource(hbytes);

        //Convert the resource text file to data we can use
    LPBYTE sData = (LPBYTE)pdata;
    LPTSTR sXml = (LPTSTR)sData;



        //That's it!
        //The rest of the application follows...
    size_t iArgLen = _tcslen(sArgv2);
    size_t iLen = _tcslen(sXml);
    string strXml = string(sXml);
    LPTSTR sDefault = sArgv;
    size_t iDefLen = _tcslen(sDefault);
    size_t iPos = strXml.find(string(sDefault), 0);

    //Determine the size to write the file
    //If length is greater, then nothing to worry about
    //if smaller, then we must calculate size to shrink
    //file in order to cut off excess superflous data
    size_t iSizeToWrite = (iDefLen > iArgLen ? 
            (iLen -(iDefLen - iArgLen) * 15) : iLen);

    if (iPos > iLen || iPos < 0)
    {
        _tcprintf(_T("Could Not Find %s inside" 
          " the Xml Resource Structure"), argv[1]);
        return 2;
    }

    //Using the Replace Function To change 
    //String Data
    strXml.replace(iPos ,iDefLen, sArgv2);
    
    //Now Loop Through until end of String Resource
    //To Replace the whole file
    while (iPos < iLen )
    {
    iPos = strXml.find(string(sDefault), 0);
    if (iPos > iLen)
        break;
    strXml.replace(iPos ,iDefLen, sArgv2);
    }

    //Get Default String for Replacement
    LPTSTR sReplace = new TCHAR[_tcslen(sArgv2)];
    _tcscpy(sReplace, sArgv2);

    //Set 9am file string
    LPTSTR s9amFile = _tcsncat(sArgv2, _T("\\9AM.xml"),
                iLen + 10);

    //Create the file for writting
    int fh = _tcreat(s9amFile, _S_IWRITE );
    if (fh == -1)
    { 
      _tcprintf(_T("An Error Occurred.\n " 
        "9AM XML File Could Not Be Created."));
        return 3;
    }
    //Write the String Data to file
    int iBytesWritten = _write(fh, (LPVOID)strXml.c_str(),
            iSizeToWrite);
    if (iBytesWritten == 0)
    {
        _tcprintf(_T("An Error Occurred.\n 9AM XML" 
            " File Could Not Be Written To."));
        _close(fh);
        return 4;
     }
        
        //Close the file
    _close(fh);

    //Repeat for 9PM and 3PM files
    _tcscpy(sArgv2, sReplace);
    LPTSTR s9pmFile = _tcsncat(sArgv2, _T("\\9PM.xml"),
            iLen + 10);
    fh = _tcreat(s9pmFile, _S_IWRITE );
    if (fh == -1)
    { 
       _tcprintf(_T("An Error Occurred.\n 9PM"
              " XML File Could Not Be Created."));
       return 3;
    }

    iBytesWritten = _write(fh, (LPVOID)strXml.c_str(),
          iSizeToWrite);
    if (iBytesWritten == 0)
    {
      _tcprintf(_T("An Error Occurred.\n " 
          "9PM XML File Could Not Be Written To."));
      _close(fh);
      return 4;
    }
    _close(fh);
    _tcscpy(sArgv2,sReplace);
    LPTSTR s3pmFile = _tcsncat(sArgv2, _T("\\3PM.xml"),
         iLen + 10);
     fh = _tcreat(s3pmFile, _S_IWRITE );
    if (fh == -1)
    { 
      _tcprintf(_T("An Error Occurred.\n 3PM" 
                 " XML File Could Not Be Created."));
      return 3;
    }

     iBytesWritten = _write(fh, (LPVOID)strXml.c_str(), 
             iSizeToWrite);
    if (iBytesWritten == 0)
    {
        _tcprintf(_T("An Error Occurred.\n "
                "3PM XML File Could Not Be Written To."));
           _close(fh);
        return 4;
    }

    _close(fh);

    //Program Completed Successful
    _tcprintf(_T("Program Completed Successfully."
           "\n 3 Files were written to:\n%s\n%s\n%s\n"),
           s9amFile, s3pmFile, s9pmFile);
    return 0;

}

That's all folks for now.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

DGoins

Web Developer

United States United States

Member

Dwight N. Goins, MCT, MCSD, MCAD
 
Is a Microsoft Education Consultant with Hewlett-Packard. He teaches Microsoft Official Cirriculum with HP (formerly Extreme Logic).
He has also authored Courseware and Manuals for BizTalk Server 2004 and Microsoft Partners.
 
Dwight.Goins@hp.com
dngoins@hotmail.com


Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralMy vote of 4 PinmemberRajesh Parejiya2:53 30 Jun '11  
GeneralProblem when there is more tha one xml file in the resources repo PinmemberREDSERPENT74:20 2 Jun '09  
GeneralThis does not work Pinmemberscreig3:37 16 Jun '08  
GeneralCode does not work for me Pinmemberpdong5:34 4 Jan '06  
Generallooks nice but doesn't work PinsussAnonymous8:03 8 Jun '05  
GeneralRe: looks nice but doesn't work PinmemberDyaj3:49 29 Dec '05  
GeneralNicely done Pinmembersammyc5:23 20 Jun '04  
GeneralRe: Nicely done Pinmembersammyc15:00 20 Jun '04  
GeneralMultiple Resources of the same type PinmemberMHillary0:11 22 May '04  
GeneralRe: Multiple Resources of the same type PinmemberBrad Bruce9:56 20 Jun '04  
GeneralRe: Multiple Resources of the same type PinmemberMichael Chapman17:54 6 Jan '05  
GeneralInsert a few NULLs between Resources PinmemberMike O'Neill5:29 15 Feb '05  
GeneralWOW! PinmemberBeer16:34 8 Dec '02  
GeneralRe: WOW! PinmemberDGoins6:34 9 Dec '02  
GeneralDo it again PinmemberAndreas Saurwein23:32 22 Oct '02  
GeneralRe: Do it again PinmemberHarold Bamford8:33 31 Oct '02  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web02 | 2.5.120517.1 | Last Updated 22 Oct 2002
Article Copyright 2002 by DGoins
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid