Click here to Skip to main content
15,885,953 members
Articles / Mobile Apps / Windows Mobile

How to generate a log file in VC++ or Embedded VC++ (For Pocket PC or WinCE devices)

Rate me:
Please Sign up or sign in to vote.
4.52/5 (15 votes)
29 Jun 2006CPOL2 min read 54.3K   43   9
Log generation functions including COM error information logging and MFC exception information logging.

Introduction

Back in 2001-2002, when I was working on a project that needed some Windows services to be built, I needed information on how the same service would run on Win 2K/XP, Pocket PC, and Win CE devices along with the data getting manipulated. I had written some functions that will log the required information into a text file. The function could take any number of arguments to be logged into the log file.

This article describes how to log the required information along with a date and time stamp into a predefined text file.

Using the code

There are three functions shown below, and the detailed information about each function is mentioned in the function comment block.

To use the code, replace CKishoreResearch in this code with your project class name, or you can place these three functions in some common.h file and use them as global functions in your project.

In the .h file, declare as follows:

// File pointer that will be used
// in the log functions to write to a valid file 
FILE *m_fp;
// Logs the Pointer to a null-terminated
// string of 16-bit Unicode characters 
void log(LPWSTR str, ...);
// Logs the Pointer to a null-terminated string
// of 8-bit Windows (ANSI) characters.
void log(LPSTR str, ...);

In the .CPP file, in the class constructor, use the following code:

m_fp = NULL;
m_fp = _wfopen(L"C:\\KishoreLog.txt", L"a");

Following is the implemented code that actually does the logging functionality:

/*
Function        : void log(LPWSTR str, ...)
Return Type     : void
parameters      : LPWSTR,Ellipsis
Use             : Logs the information onto a text file 
                  with any number of input parameters
                : Pointer to a constant null-terminated 
                  string of 16-bit Unicode characters.
Author          : Kishore Gaddam
Date            : 03 December 2002
Version         : 1.0
*/

void CKishoreResearch::log(LPWSTR str, ...)
{
    if (m_fp)
    // m_fp Contains the pointer
    // to the log file to log the information
    {
        va_list arg_ptr;
        va_start(arg_ptr, str);
        SYSTEMTIME st;
        GetLocalTime(&st);
          fwprintf(m_fp, L"[%d/%d/%d - %d:%d:%d:%d]", 
                   st.wMonth, st.wDay, st.wYear, st.wHour, 
                   st.wMinute, st.wSecond, st.wMilliseconds);
        vfwprintf(m_fp, str, arg_ptr);
        fwprintf(m_fp, L"\n");
        fflush(m_fp);
    }
}

/*
Function        : void log(LPSTR str, ...)
Return Type     : void
parameters      : LPSTR,Ellipsis
Use             : Logs the information onto a text file
                  with any number of input parameters
                : Pointer to a null-terminated string 
                  of 8-bit Windows (ANSI) characters.
Author          : Kishore Gaddam
Date            : 03 December 2002
Version         : 1.0
*/

void CKishoreResearch::log(LPSTR str, ...)
{
    if (m_fp)
    // m_fp Contains the pointer
    // to the log file to log the information
    {
        va_list arg_ptr;
        va_start(arg_ptr, str);
        SYSTEMTIME st;
        GetLocalTime(&st);
          fprintf(m_fp, "[%d/%d/%d - %d:%d:%d:%d]", st.wMonth, 
                  st.wDay, st.wYear, st.wHour, st.wMinute, 
                  st.wSecond, st.wMilliseconds);
        vfprintf(m_fp, str, arg_ptr);
        fprintf(m_fp, "\n");
        fflush(m_fp);
    }
}

/*
Function        : ComErrorMessageLog(_com_error &e)
Return Type     : void
parameters      : _com_error
Use             : Logs the COM error information to a text file
Author          : Kishore Gaddam
Date            : 03 December 2004
Version         : 1.0
*/
void CKishoreResearch::ComErrorMessageLog(_com_error &e)
{
    bstr_t bstrSource(e.Source());
    bstr_t bstrDescription(e.Description());

    log( _T("Code = 0x%08lx\n"), e.Error());
    log( _T("Code meaning = %s\n"), e.ErrorMessage());
    log( _T("IErrorInfo.Source = %s\n"), (LPTSTR)bstrSource );
    log( _T("IErrorInfo.Description = %s"), 
           (LPTSTR)bstrDescription );
}

Copy the above three functions into your code. Again, to use the code, replace the class CKishoreResearch in the above code with your project class name. Once these three functions are copied, you can just make a call to the log(..) function and pass the required information that needs to be logged into the text file.

Logging commonly used data types

Listed below are the examples of some commonly used data types.

For example, if you have a _bstr_t data type variable and you want to log the value of the same using the log function:

//bsSelection is the value that needs
//to be logged into the log file.
_bstr_t bsSelection;
//Make a call to Log function and pass 
//(LPTSTR)bsSelection as the parameter.
log((LPTSTR)bsSelection);

To log a TCHAR data type value:

TCHAR szSql[256];
log(szSql);

To log an int data type value along with some user defined strings:

int nData;
log("Item Select = %d", nData);

To log multiple UINT data type values along with some user defined strings:

UINT cbID1,cbID2;
log(L" ID1 is %d and ID2 is %d", cbID1, cbID2);

To log a TCHAR data type value along with some user defined strings:

TCHAR *szFolderName
log("Folder: [%s]", szFolderName);

Points of interest

Apart from logging the required information, you can also use these functions in exception handling to log the reason for the exception.

Following is the code that will go in catch block, in case of a COM exception:

catch(_com_error &e)
{
  ::MessageBox(NULL, (char*)e.Description(), 
               "Application Error", MB_OK|MB_ICONERROR);
  ComErrorMessageLog(e);
  CoUninitialize();
}

Following is the code that will go in the catch block, in case of a normal exception, in MFC:

catch(CException* e)
/ Handle all other types of exceptions here.
{
  TCHAR szErr[1024];
  e->GetErrorMessage(szErr, 1024);
  ::MessageBox(NULL, (char*)szErr, "Application Error", 
               MB_OK|MB_ICONERROR);
  log(szErr);
}

Well, the list of things on using the log function will go on and on. So, I will stop here and let the users use the above code to log their information. :)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
CEO Astrani Technology Solutions
United States United States
Kishore Babu Gaddam is a Senior Technology Consultant, Technology Evangelist turned Technology Entrepreneur and a regular speaker at national conferences, regional code camps and local user groups with over 14 years of experience in software product development. His experience includes building & managing award-winning software development teams, managing customer relationships, marketing and launching new software products & services. Kishore launched his technology career almost 15 years ago with a Robotics software development startup and has served in multiple roles since including developer, innovation leader, consultant, technology executive and business owner.

A technology specialist in C++, C#, XAML and Azure, he successfully published two applications to Windows store http://bit.ly/WinStoreApp and http://bit.ly/FlagsApp.

Kishore is the author of the popular Microsoft Technologies blog at http://www.kishore1021.wordpress.com/ and his work on Portable Class Library project in Visual Studio 2012– .NET 4.5 was featured on Channel 9 at http://bit.ly/msdnchannel9. Kishore enjoys helping people understand technical concepts that may initially seem complex and perform lot of Research & Development on emerging technologies to help solve some of the toughest customer issues. Kishore spends a lot of time teaching and mentoring developers to learn new technologies and to be better developers. He is a speaker at various code camps around Washington DC area, mainly at Microsoft Technology Center for NOVA code camp (http://bit.ly/novacc12), CMAP Code Camp Fall 2012 (http://bit.ly/novacc12), etc. The majority of his software development experience has centered on Microsoft technologies including MFC, COM, COM+, WCF, WPF, winRT, HTML5, RestAPI and SQL Server. You can follow Kishore on Twitter at www.twitter.com/kishore1021. He can be reached on email at researcherkishore@outlook.com

Comments and Discussions

 
Questionhow to use the ComErrorMessageLog ? Pin
darlyxp13-Jul-09 15:39
darlyxp13-Jul-09 15:39 
GeneralWrite data to text files and every 3 seconds see updates written to the text when it is kept open . Pin
Divya Lalwani9-Mar-09 21:10
Divya Lalwani9-Mar-09 21:10 
GeneralMuch Appreciated Pin
isdi13-Feb-07 4:24
isdi13-Feb-07 4:24 
GeneralRe: Much Appreciated Pin
Y Mahi8-May-08 2:01
Y Mahi8-May-08 2:01 
Generalnice artical Pin
Chetan Sheladiya4-Jul-06 22:20
professionalChetan Sheladiya4-Jul-06 22:20 
GeneralRe: nice artical Pin
kishore Gaddam5-Jul-06 0:34
kishore Gaddam5-Jul-06 0:34 
GeneralThread safety Pin
RichardLH4-Jul-06 4:40
RichardLH4-Jul-06 4:40 
QuestionExcellent article. Worked well on Windows XP but i could see the logfile generated on the Windows CE Device Pin
ShaumikUS29-Jun-06 7:04
ShaumikUS29-Jun-06 7:04 
AnswerRe: Excellent article. Worked well on Windows XP but i could see the logfile generated on the Windows CE Device Pin
kishore Gaddam29-Jun-06 19:44
kishore Gaddam29-Jun-06 19:44 

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

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