I am trying to list all the available fonts in a CListBox within a dialog.
First I create a dialog box with an Embedded listbox.
I named the class for the dialog based as CTestDialog.
I declare a control variable m_ctlListFonts corresponding to the List Box i had inserted using Class Wizard
Then i add the available fonts by using callback function describe below
int CALLBACK EnumFontFamProc(LPENUMLOGFONT lpelf,LPNEWTEXTMETRIC lpntm, DWORD nFontType, LONG lParam)
{
//Create a pointer to the Dialog Window
CTestDlg* pDlg = (CTestDlg*) lParam;
//Add font name to the list Box
pDlg->m_ctlListFonts.AddString(lpelf->elfLogFont.lfFaceName);
return 1;
}
This Callback function is called from within the FillFontBox() memeber function
void CTestDlg::FillFontBox()
{
LOGFONT lf;
//initilize the logfont struc Enumerates all fonts in all Chracter sets
lf.lfCharSet = DEFAULT_CHARSET;
strcpy(lf.lfFaceName,""
;
//Clear the listBox
m_ctlListFonts.ResetContent();
//Create the Device context Variable
CClientDC dc (this);
//Call the Enum proc
EnumFontFamiliesEx( (HDC) dc, &lf, (FONTENUMPROC) EnumFontFamProc, (LPARAM)this, 0);
}
When i run my application(by calling FillFontBox() from OnInitDialog() function). The list box is filled with the names of all the fonts available on the system. But many dupli-cate entries are seen in the list of fonts in the list box.
It turns out that the EnumFontFamiliesEx function call is synchronous in nature. This means that it doesn’t return until all the fonts in the system are listed in calls to your callback function.
To eliminate the duplicate enteries i modify the FillFontBox() to be
void CTestDlg::FillFontBox()
{
LOGFONT lf;
//initilize the logfont struc Enumerates all fonts in all Chracter sets
lf.lfCharSet = DEFAULT_CHARSET;
strcpy(lf.lfFaceName,""
;
//Clear the listBox
m_ctlListFonts.ResetContent();
//Create the Device context Variable
CClientDC dc (this);
//Call the Enum proc
EnumFontFamiliesEx( (HDC) dc, &lf, (FONTENUMPROC) EnumFontFamProc, (LPARAM)this, 0);
//Code added to delete the duplicate enteries
CString sCurFontName;
CString sPrevFontName = "";
int iCurCount,iCount
//Get the number of Fonts listed
iCount = m_ctlListFonts.GetCount();
//Loop all the Font list entries to remove Duplicates
//for(iCurCount = iCount-1; iCurCount >= 0; iCurCount--)
for(iCurCount = 0; iCurCount <iCount ; iCurCount++)
{
//Get the current Font Name
m_ctlListFonts.GetText(iCurCount, sCurFontName);
//Delete the duplicates
if(sCurFontName == sPrevFontName)
{
m_ctlListFonts.DeleteString(iCurCount);
}
sPrevFontName = sCurFontName;
}
}
When i run the application i get an assert in function
LPTSTR CString::GetBufferSetLength(int nNewLength)
{
ASSERT(nNewLength >= 0); //nNewLength = -1
GetBuffer(nNewLength);
GetData()->nDataLength = nNewLength;
m_pchData[nNewLength] = '\0';
return m_pchData;
}
This function is called by
void CListBox::GetText(int nIndex, CString& rString) const
{
ASSERT
:IsWindow(m_hWnd));
GetText(nIndex, rString.GetBufferSetLength(GetTextLen(nIndex)));
rString.ReleaseBuffer();
}
In other words GetTextLen function returns -1 to cause Assert to happen.
The interesting part is that if i run the application starting at the end of the list and worked Backward the application runs fine without any Assert.
i.e writing ForLoop as for(iCurCount = iCount; iCurCount <=0 ; iCurCount--) //NO assert generated
What is wrong can anybody help ?
First I create a dialog box with an Embedded listbox.
I named the class for the dialog based as CTestDialog.
I declare a control variable m_ctlListFonts corresponding to the List Box i had inserted using Class Wizard
Then i add the available fonts by using callback function describe below
int CALLBACK EnumFontFamProc(LPENUMLOGFONT lpelf,LPNEWTEXTMETRIC lpntm, DWORD nFontType, LONG lParam)
{
//Create a pointer to the Dialog Window
CTestDlg* pDlg = (CTestDlg*) lParam;
//Add font name to the list Box
pDlg->m_ctlListFonts.AddString(lpelf->elfLogFont.lfFaceName);
return 1;
}
This Callback function is called from within the FillFontBox() memeber function
void CTestDlg::FillFontBox()
{
LOGFONT lf;
//initilize the logfont struc Enumerates all fonts in all Chracter sets
lf.lfCharSet = DEFAULT_CHARSET;
strcpy(lf.lfFaceName,""
//Clear the listBox
m_ctlListFonts.ResetContent();
//Create the Device context Variable
CClientDC dc (this);
//Call the Enum proc
EnumFontFamiliesEx( (HDC) dc, &lf, (FONTENUMPROC) EnumFontFamProc, (LPARAM)this, 0);
}
When i run my application(by calling FillFontBox() from OnInitDialog() function). The list box is filled with the names of all the fonts available on the system. But many dupli-cate entries are seen in the list of fonts in the list box.
It turns out that the EnumFontFamiliesEx function call is synchronous in nature. This means that it doesn’t return until all the fonts in the system are listed in calls to your callback function.
To eliminate the duplicate enteries i modify the FillFontBox() to be
void CTestDlg::FillFontBox()
{
LOGFONT lf;
//initilize the logfont struc Enumerates all fonts in all Chracter sets
lf.lfCharSet = DEFAULT_CHARSET;
strcpy(lf.lfFaceName,""
//Clear the listBox
m_ctlListFonts.ResetContent();
//Create the Device context Variable
CClientDC dc (this);
//Call the Enum proc
EnumFontFamiliesEx( (HDC) dc, &lf, (FONTENUMPROC) EnumFontFamProc, (LPARAM)this, 0);
//Code added to delete the duplicate enteries
CString sCurFontName;
CString sPrevFontName = "";
int iCurCount,iCount
//Get the number of Fonts listed
iCount = m_ctlListFonts.GetCount();
//Loop all the Font list entries to remove Duplicates
//for(iCurCount = iCount-1; iCurCount >= 0; iCurCount--)
for(iCurCount = 0; iCurCount <iCount ; iCurCount++)
{
//Get the current Font Name
m_ctlListFonts.GetText(iCurCount, sCurFontName);
//Delete the duplicates
if(sCurFontName == sPrevFontName)
{
m_ctlListFonts.DeleteString(iCurCount);
}
sPrevFontName = sCurFontName;
}
}
When i run the application i get an assert in function
LPTSTR CString::GetBufferSetLength(int nNewLength)
{
ASSERT(nNewLength >= 0); //nNewLength = -1
GetBuffer(nNewLength);
GetData()->nDataLength = nNewLength;
m_pchData[nNewLength] = '\0';
return m_pchData;
}
This function is called by
void CListBox::GetText(int nIndex, CString& rString) const
{
ASSERT
GetText(nIndex, rString.GetBufferSetLength(GetTextLen(nIndex)));
rString.ReleaseBuffer();
}
In other words GetTextLen function returns -1 to cause Assert to happen.
The interesting part is that if i run the application starting at the end of the list and worked Backward the application runs fine without any Assert.
i.e writing ForLoop as for(iCurCount = iCount; iCurCount <=0 ; iCurCount--) //NO assert generated
What is wrong can anybody help ?