BUG: GDI Leaks Memory When Font Selected In MM_ANISOTROPIC Mode

ID: Q149289


The information in this article applies to:


SYMPTOMS

When a window's map mode is set to either MM_ISOTROPIC or MM_ANISOTROPIC, and the window extents or viewport extents are changed, then a previously selected font instance cannot be found in the GDI font instance heap because the extents are part of the lookup comparison criteria. This results in 52 bytes of lost heap space for each new font instance.

The system may eventually hang due to lack of memory.

The window's map mode setting is not exposed directly in the user interface of a program, whereas a change in a font or a window's "zoom factor" (often controlled by the extents) is exposed directly in the user interface. Therefore, you are limited in what you can do to minimize the effects of this problem.


CAUSE

When a font is selected into a device context, the current window and viewport extents are copied to a structure that is stored in an internal "font instance" heap. A search is conducted in this heap for the current font, so that it can be freed. The lookup criteria to find this includes the window and viewport extents. If either of these extents have changed since the current font was selected, then the lookup fails and the item is not removed from the heap, which results in a loss of 52 bytes of memory.

Note that the values for the window and viewport origin do not affect this problem. In addition, the trouble only manifests when either the MM_ISOTROPIC and MM_ANISOTROPIC mapping modes are set.


RESOLUTION

The following algorithm is recommended for WM_PAINT handling, and it assumes that:

To use this algorithm:
  1. Select a new font.


  2. Set new extents.


  3. Draw, output text, and so on.


  4. Restore original extents.


  5. Select the original font.


A standard method for storing data unique to a window procedure and instance is through the GetWindowLong() and SetWindowLong() API calls. You use the value DWL_USER for the nIndex parameter to save the address of data allocated during WM_CREATE code execution. Please refer to the Win32 Programmer's Reference for additional information.

The C code fragment below is an example that describes the algorithm mentioned above, and assumes that the map mode and the values in the global SIZE structure "sWinExt" are being modified elsewhere in the program:

Sample Code


   SIZE sWinExt = {1,1};
   SIZE sOldWinExt = {1,1};

   LRESULT APIENTRY WndProc(HWND hwnd, UINT message, WPARAM wParam,
                            LPARAM lParam)
   {
      HDC hDC;
      HFONT hFont;
      PAINTSTRUCT ps;

      switch (message) {
      case WM_PAINT:
         hDC = BeginPaint(hwnd,&ps);
         hFont = SelectObject(hDC,GetStockObject(ANSI_VAR_FONT));
         SetWindowExtEx(hDC,sWinExt.cx,sWinExt.cy,&sOldWinExt);
         // Draw, output text, and so on.
         SetWindowExtEx(hDC,sOldWinExt.cx,sOldWinExt.cy,NULL);
         SelectObject(hDC,hFont);
         EndPaint(hwnd, &ps);
         return 0; 
WARNING: ANY USE BY YOU OF THE CODE PROVIDED IN THIS ARTICLE IS AT YOUR OWN RISK. Microsoft provides this code "as is" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and/or fitness for a particular purpose.


STATUS

Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article.


MORE INFORMATION

Fonts are normally selected in the code that handles a WM_PAINT message for a given window. Window and viewport extents are typically modified according to the user's choice for a window "zoom factor" by resizing the window itself or by predetermined factors involving screen resolution and presentation data, such as that used for CAD.

Additional query words: GDI font heap leak 52 UniSys


Keywords          : kbSDKWin32 kbWinOS95 kbDSupport 
Version           : WINDOWS:95
Platform          : WINDOWS 
Issue type        : kbbug 

Last Reviewed: June 25, 1999