I have an old application written in Visual C ++ 6. Part of this application draws text into a bitmap. This works fine in Windows XP, but when the same code runs in Windows 7, all text is shifted by one place in the ASCII table.
For example, "Category"it becomes "B'sdfnqx".
Any ideas what causes this and how to fix it?
Edit: Sorry, but the above is a bit wrong. When I saw the DrawText function in the code, I assumed that it was a GDI function. When I enter it, it turns out that the author created his own function DrawTextthat uses OpenGL. I don't know anyone OpenGL, so now he's out of control. It calls glCallListsthat passes the text (stored in CString) to this function.
Full class code below. Note. This glCallLists function in the DrawText function is causing the problem.
OGLFontClass::OGLFontClass()
{
m_id = -1;
}
OGLFontClass::~OGLFontClass()
{
Clear();
}
void OGLFontClass::Clear()
{
if( m_id != -1 )
{
glDeleteLists(m_id,255);
m_id = -1;
}
}
void OGLFontClass::Initialise(CString fontname, int size, HDC hDC)
{
m_HDC = hDC;
m_id = glGenLists(255);
::DeleteObject( m_FONT );
m_FONT = CreateFont( -size,
0,
0,
0,
FW_NORMAL,
FALSE,
FALSE,
FALSE,
ANSI_CHARSET,
OUT_TT_PRECIS,
CLIP_DEFAULT_PRECIS,
ANTIALIASED_QUALITY,
FF_DONTCARE|DEFAULT_PITCH,
fontname);
HFONT oldfont = (HFONT)SelectObject(hDC, m_FONT);
wglUseFontBitmaps(hDC, 0, 255, m_id );
::SelectObject( hDC, oldfont );
}
void OGLFontClass::DrawText( float x, float y, CString str )
{
glRasterPos3f(x,y, 0);
glPushAttrib(GL_LIST_BIT);
glListBase(m_id);
glCallLists(str.GetLength(), GL_UNSIGNED_BYTE, str.GetBuffer(0));
glPopAttrib();
}
void OGLFontClass::DrawText(int x, int y, int r, int g, int b, CString text)
{
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
HWND hWnd = ::WindowFromDC(wglGetCurrentDC() );
RECT rc;
::GetClientRect( hWnd, &rc );
int CX = rc.right;
int CY = rc.bottom;
gluOrtho2D (0,::GetSystemMetrics(SM_CXSCREEN),::GetSystemMetrics(SM_CYSCREEN), 0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glColor3ub(r,g,b);
glRasterPos2d( x, y );
glPushAttrib(GL_LIST_BIT);
glListBase(m_id);
unsigned char* szTemp = new unsigned char[text.GetLength()+1];
strcpy((char*)szTemp, text);
glCallLists(strlen((char*)szTemp), GL_UNSIGNED_BYTE, szTemp);
delete[] szTemp;
glPopAttrib();
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
}
void OGLFontClass::DrawRightText( int x, int y, int r, int g, int b, CString text )
{
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
HWND hWnd = ::WindowFromDC(wglGetCurrentDC() );
RECT rc;
::GetClientRect( hWnd, &rc );
float CX = (float)::GetSystemMetrics( SM_CXSCREEN );
float CY = (float)::GetSystemMetrics( SM_CYSCREEN );
float fMultiplier = CX / CY;
gluOrtho2D (0,::GetSystemMetrics(SM_CXSCREEN),::GetSystemMetrics(SM_CYSCREEN), 0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
int nPos = x;
glColor3ub(r,g,b);
glPushAttrib(GL_LIST_BIT);
glListBase(m_id);
for( int i = text.GetLength() - 1; i >= 0; i-- )
{
CString sChar = text.GetAt(i);
glRasterPos2d(nPos,y);
glCallLists(1, GL_UNSIGNED_BYTE, sChar);
if ( i > 0 )
{
CString sNextChar = text.GetAt(i-1);
SIZE szWidth = GetTextExtent(sNextChar);
szWidth.cx += 1;
szWidth.cx *= fMultiplier;
szWidth.cx += 1;
nPos -= szWidth.cx;
}
}
glPopAttrib();
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
}
CSize OGLFontClass::GetTextExtent(CString text, float fFactor)
{
SIZE sz;
HFONT oldfont = (HFONT) SelectObject(m_HDC, m_FONT);
GetTextExtentPoint32(m_HDC,text,strlen(text),&sz);
SelectObject(m_HDC, oldfont);
sz.cx *= 0.2;
sz.cy *= 0.2;
return sz;
}
Now I don’t know openGL at all, but I assume that since it glCallListsjust reinterprets the string as an array of bytes, something is wrong with Windows XP and Windows 7. Perhaps a problem with unicode or something else? Perhaps a 32-bit Windows OS or a 64-bit OS?
?