KnowledgeBase Archive

An Archive of Early Microsoft KnowledgeBase Articles

View on GitHub

Q111864: BUG: GP Fault When Drawing on a Memory-Based DC

Article: Q111864
Product(s): Microsoft Windows Software Development Kit
Version(s): WINDOWS:3.1
Operating System(s): 
Keyword(s): 
Last Modified: 06-NOV-1999

-------------------------------------------------------------------------------
The information in this article applies to:

- Microsoft Windows Software Development Kit (SDK) 3.1 
-------------------------------------------------------------------------------

SYMPTOMS
========

A general protection (GP) fault can occur on a memory-based device context (DC)
when a bitmap previously selected in the DC is selected out and another is
selected in. This is a common problem when using the SaveDC() and RestoreDC()
functions with a memory DC.

CAUSE
=====

In a regular (nonmemory-based) DC, when the SaveDC() and RestoreDC() functions
are used, the size of the window client area of the DC does not change. The size
of the drawable area in a memory-based DC is dependent on the size of the
current bitmap selected in the DC.

For example, suppose the default 1 x 1 monochrome bitmap is selected in a memory
DC and you call SaveDC(). Now, you select a 200 x 200 color bitmap into the DC
and you perform some drawing commands. Then, you call RestoreDC() to restore the
DC. This action will select the old 1 x 1 bitmap back into the DC.
Unfortunately, GDI does not update the clipping region when this happens, and
when you draw outside the 1 x 1 region, you can receive a GP fault.

RESOLUTION
==========

After you call RestoreDC() on a memory-based DC, you need to call SelectObject()
to select the bitmap that was selected in the DC before RestoreDC() was called.

STATUS
======

Microsoft has confirmed this to be a bug in Windows version 3.1. We are
researching this problem and will post new information here in the Microsoft
Knowledge Base as it becomes available.

MORE INFORMATION
================

The following code exhibits the problem outlined above. When
CreateCompatibleDC() is called, a default 1 x 1 monochrome bitmap is selected
into the DC returned from the function. By restoring the initial 1 x 1 bitmap
after getting a visible region of 200 x 200, GDI thinks the 1 x 1 surface has a
clipping rectangle of 200 x 200. This is what causes the overwrite.

Sample Code
-----------

     HBITMAP hbm1,hbm2;
     HDC     hdcBits,hdcScreen;

     hdcScreen = GetDC(NULL);
     hdcBits = CreateCompatibleDC(hdcScreen);
     hbm1 = CreateCompatibleBitmap(hdcScreen,200,200);
     hbm2 = CreateCompatibleBitmap(hdcScreen,200,200);

     SaveDC(hdcBits);
     SelectObject(hdcBits,hbm1);
     PatBlt(hdcBits,0,0,200,200,WHITENESS);
     RestoreDC(hdcBits,-1);
     SaveDC(hdcBits);
     SelectObject(hdcBits,hbm2);
     PatBlt(hdcBits,0,0,200,200,WHITENESS);
     Ellipse(hdcBits,0,0,200,200);
     RestoreDC(hdcBits,-1);
     Rectangle(hdcBits,0,0,200,200);

Additional query words: buglist3.10 3.10 gpf gp-fault 1x1 200x200

======================================================================
Keywords          :  
Technology        : kbAudDeveloper kbWin3xSearch kbSDKSearch kbWinSDKSearch kbWinSDK310
Version           : WINDOWS:3.1

=============================================================================

THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Copyright Microsoft Corporation 1986-2002.