General Information for COP4226

Back to Index


HOW TO change the name of the WM_LBUTTONDOWN, WM_LBUTTONUP, and WM_MOUSEMOVE message handler functions.

Back to Index


Why am I running out of fonts?

When working with GDI objects, you cannot destroy them if they are still attached to the device context. Suppose you wanted to reuse the same font again and again, instead of using several different font objects. The goal would be to reduce the load on system resources. The following code has the exact opposite effect. If you were to continually redraw a program that contains this code, then eventually you would run out of fonts.

	CFont fontTest;
	fontTest.CreateFont(-500,0,0,0,400,FALSE,FALSE,0,
		ANSI_CHARSET,OUT_DEFAULT_PRECIS,
		CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_SWISS,"Arial");
	CFont* pFontOld = (CFont*) pDC->SelectObject(&fontTest);
	pDC->TextOut(0,0,"Hello");
	fontTest.DeleteObject();
	fontTest.CreateFont(-500,0,-900,0,400,FALSE,FALSE,0,
		ANSI_CHARSET,OUT_DEFAULT_PRECIS,
		CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_SWISS,"Arial");
	pDC->SelectObject(&fontTest);
	pDC->TextOut(15000,-25000,"World");
	pDC->SelectObject(pFontOld);

The reason is that the call to DeleteObject is unable to delete the GDI object because it is still attached to the device context. It appears that the delete worked, because you will be able to create a new font using fontTest. Only the CFont object has been deleted. Think of the CFont object as having a pointer to a GDI object in it. The CFont is destroyed, but the GDI object is not released because it is still attached to the device context. When the next call to SelectObject succeeds, there is a GDI font object that did not get destoyed. Eventually, the application will be unable to create new fonts.

It is possible to fix this problem by detaching the GDI object from the device context before deleting the CFont object.

	CFont fontTest;
	fontTest.CreateFont(-500,0,0,0,400,FALSE,FALSE,0,
		ANSI_CHARSET,OUT_DEFAULT_PRECIS,
		CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_SWISS,"Arial");
	CFont* pFontOld = (CFont*) pDC->SelectObject(&fontTest);
	pDC->TextOut(0,0,"Hello");
	pDC->SelectObject(pFontOld);
	fontTest.DeleteObject();
	fontTest.CreateFont(-500,0,-900,0,400,FALSE,FALSE,0,
		ANSI_CHARSET,OUT_DEFAULT_PRECIS,
		CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_SWISS,"Arial");
	pDC->SelectObject(&fontTest);
	pDC->TextOut(15000,-25000,"World");
	pDC->SelectObject(pFontOld);

You could acheive the same effect by removing the last line of code from this example.

All GDI objects will exhibit this behavior, so remember to detach them from the device context before destroying them, or letting them go out of scope.

Back to Index


You are visitor number to visit this page since 5/5/02.