Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a function for displaying status updates with printf style string formatting on an MFC control

I needed to display status updates on a dialog box, and wanted to be able to send printf style formatted strings to it. In addition I would like that function to call a similar function which will add the formatted data to a log file.

Assuming my Static control is called IDC_MYSTATUSBAR, the function looks like this:

void MyDialog::ShowStatus(LPCWSTR lpText, ...)
{
    CString sMsg;
    va_list ptr;
    va_start(ptr, lpText);
    if (*ptr == 0)
       sMsg = lpText;
    else
       sMsg.FormatV(lpText, ptr);
    va_end(ptr);
    CWinApp *myApp = AfxGetApp();
    if (myApp)
    {
        CWnd *pWnd = myApp->m_pMainWnd;
        if (pWnd)
        {
            ::SetDlgItemText(pWnd->GetSafeHwnd(), IDC_MYSTATUSBAR, sMsg.GetString());
        }
    }
    myLogFunction(L"%s", sMsg.GetString());
}

The function is called as follow:

ShowStatus(L"The results are %d.", 100);

or

ShowStatus(L"Server returned the following result: %s", L"result");

However other modules and libraries calls my function by having a member variable called logfunc which is defined as:

typedef void(*logFunc)(LPCWSTR lpText, ...);

and in that case, the code from the other module will look like:

logFunc m_logfunc;      
if (m_logfunc) m_logfunc(L"Internet Time: (%d) %s Local Time = %s", result, TimeResult.FormatGmt(L"%d.%m.%Y %H:%M"), CurrentTime.FormatGmt(L"%d.%m.%Y %H:%M"));
        

In most cases it works perfectly and the output looks like this: enter image description here

However, sometimes the % switches are shown instead of the data and then it looks like: enter image description here

I tried to understand further why it fails, so the function call that fails is:

int ct = GetCurrentTransactionNo();
if (m_logfunc)
    m_logfunc(L"Checking transaction no. %d.", ct);

But if I change it to:

int ct = 15;
if (m_logfunc)
    m_logfunc(L"Checking transaction no. %d.", ct);

I get a correct formattted string. enter image description here

like image 790
Michael Haephrati Avatar asked Mar 02 '23 14:03

Michael Haephrati


1 Answers

When the first parameter passed to the function is 0 or "", *ptr (which is in fact *ptr[0] or *(ptr + 0), hence the first block in memory) will hold null, thus the function printed the string literally, without formatting it with FormatV().

You need to replace the following block

if (*ptr == 0)
    sMsg = lpText;
else
    sMsg.FormatV(lpText, ptr);

with just

sMsg.FormatV(lpText, ptr);
like image 124
WStar Avatar answered Apr 27 '23 22:04

WStar