none
GDI clipping function behave different on DC from EMF and BMP

    질문

  • Our application use GDI functions to draw graphics and save to image file. The workflow is as follows:

    1. Create image file;
    2. Get Device Context (DC) from image;
    3. Draw on DC;
    4. Save Image

    However, one GDI function (ExtSelectClipRgn)behaved differently on DC from EMF and BMP. See the following code. When the hdc is from bitmap, the return value is 2(SimpleRectangle); while for hdc from EMF metafile, the return value is 1 (NULL REGION). 

    // render to DC

           static void DrawWithGDI(IntPtr hdc, int iWidth, int iHeight)
            {
                IntPtr hRgnClip = CreateRectRgn(0, 1, 992, 1400);            
                SelectClipRgn(hdc, hRgnClip);
    
                IntPtr brush = CreateSolidBrush(ColorTranslator.ToWin32(Color.Red));
                IntPtr region = CreateRectRgn(857, 1370, 992, 1399);
                           
                IntPtr hOldRgn = CreateRectRgn(0, 0, 3, 3);
                if (GetClipRgn(hdc, hOldRgn) != 1)
                {
                    DeleteObject( hOldRgn );
                    hOldRgn = IntPtr.Zero;
                }
                if (hOldRgn != IntPtr.Zero)
                {
                    int iResult = ExtSelectClipRgn(hdc, region, 1);
                    if (iResult == 1 || iResult == 0)       //1 NULLREGION 0 ERROR
                    {
                        SelectClipRgn( hdc, hOldRgn );
                        if( hOldRgn != IntPtr.Zero )
                            DeleteObject( hOldRgn );
                        return;
                    }
                }
                else
                {
                    SelectClipRgn(hdc, region);
                }
    
                FillRgn(hdc, region, brush);
                DeleteObject(region);
                DeleteObject(brush);
                SelectClipRgn(hdc, IntPtr.Zero);            
            }

    // create image and get DC

           static Image CreateImage(float width, float height, ImageFormat fileformat)
            {
                Image img = null;
                if (fileformat == ImageFormat.Emf)
                    img = CreateMetaFile(width, height);
                else
                {
                    System.IntPtr hdc = GetDC(IntPtr.Zero);
                    using (Graphics gfxzero = Graphics.FromHdc(hdc))
                    {
                        img = new Bitmap((int)(width * gfxzero.DpiX), (int)(height * gfxzero.DpiY));
                    }
                    ReleaseDC(IntPtr.Zero, hdc);
                }
                return img;
            }
    
            static Metafile CreateMetaFile(float width, float height)
            {
                Metafile metafile = null;
                IntPtr hdc = GetDC(IntPtr.Zero);
    
                using (Graphics gfxzero = Graphics.FromHdc(hdc))
                {
                    metafile = new Metafile(hdc,
                                             new RectangleF(0.0f, 0.0f, (float)(width * gfxzero.DpiX), (float)(height * gfxzero.DpiY)),
                                             MetafileFrameUnit.Pixel,
                                             EmfType.EmfOnly);
                }
    
                ReleaseDC(IntPtr.Zero, hdc);
                return metafile;        
            }
    
            static void RenderToImage(Image image, float width, float height)
            {
                using (Graphics g = Graphics.FromImage(image))
                {
                    g.SmoothingMode = SmoothingMode.AntiAlias; // smooth
                    int iWidth = (int) Math.Floor(width * g.DpiX);
                    int iHeight = (int) Math.Floor(height * g.DpiY);
                    IntPtr hdc = g.GetHdc();
                    DrawWithGDI(hdc, iWidth, iHeight);
                    g.ReleaseHdc(hdc);
                }
            }


    • 편집됨 fiony 2012년 3월 13일 화요일 오전 9:36
    2012년 3월 13일 화요일 오전 9:26

답변

  • fiony wrote:
    >
    >However, one GDI function (ExtSelectClipRgn)behaved differently on DC
    >from EMF and BMP. See the following code. When the hdc is from bitmap,
    >the return value is 2(SimpleRectangle); while for hdc from EMF metafile,
    >the return value is 1 (NULL REGION).
     
    Some GDI functions cannot be embedded in a metafile.  ExtSelectClipRgn is a
    relatively recent addition to GDI (Windows 2000), and is probably in the
    list of unsupported functions.
    --
    Tim Roberts, timr@probo.com
    Providenza & Boekelheide, Inc.
     

    Tim Roberts, VC++ MVP Providenza & Boekelheide, Inc.
    2012년 3월 14일 수요일 오전 5:26