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:
However, sometimes the %
switches are shown instead of the data and then it looks like:
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.
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With