dcsimg
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 20

Thread: [RESOLVED] GDI - can i speed up the DIB code?

Hybrid View

  1. #1
    Join Date
    Apr 2009
    Posts
    1,268

    [RESOLVED] GDI - can i speed up the DIB code?

    i have these 2 functions for create regions:
    Code:
    BYTE* Get24BitPixels(HBITMAP pBitmap, WORD *pwWidth, WORD *pwHeight)
        {
            // a bitmap object just to get bitmap width and height
            BITMAP bmpBmp;
    
            // pointer to original bitmap info
            LPBITMAPINFO pbmiInfo;
    
            // bitmap info will hold the new 24bit bitmap info
            BITMAPINFO bmiInfo;
    
            // width and height of the bitmap
            WORD wBmpWidth, wBmpHeight;
    
            // ---------------------------------------------------------
            // get some info from the bitmap
            // ---------------------------------------------------------
            GetObject(pBitmap, sizeof(bmpBmp),&bmpBmp);
            pbmiInfo   = (LPBITMAPINFO)&bmpBmp;
    
            // get width and height
            wBmpWidth  = (WORD)pbmiInfo->bmiHeader.biWidth;
            wBmpWidth -= (wBmpWidth%4);                       // width is 4 byte boundary aligned.
            wBmpHeight = (WORD)pbmiInfo->bmiHeader.biHeight;
    
            // copy to caller width and height parms
            *pwWidth  = wBmpWidth;
            *pwHeight = wBmpHeight;
            // ---------------------------------------------------------
    
            // allocate width * height * 24bits pixels
            //BYTE *pPixels = new BYTE[wBmpWidth*wBmpHeight*3];
            BYTE *pPixels = new (std::nothrow) BYTE[wBmpWidth*wBmpHeight*3];
            if (pPixels==0)
                return NULL;
    
            // get user desktop device context to get pixels from
            HDC hDC = GetWindowDC(NULL);
    
            // fill desired structure
            bmiInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
            bmiInfo.bmiHeader.biWidth = wBmpWidth;
            bmiInfo.bmiHeader.biHeight = -wBmpHeight;
            bmiInfo.bmiHeader.biPlanes = 1;
            bmiInfo.bmiHeader.biBitCount = 24;
            bmiInfo.bmiHeader.biCompression = BI_RGB;
            bmiInfo.bmiHeader.biSizeImage = wBmpWidth*wBmpHeight*3;
            bmiInfo.bmiHeader.biXPelsPerMeter = 0;
            bmiInfo.bmiHeader.biYPelsPerMeter = 0;
            bmiInfo.bmiHeader.biClrUsed = 0;
            bmiInfo.bmiHeader.biClrImportant = 0;
    
            // get pixels from the original bitmap converted to 24bits
            int iRes = GetDIBits(hDC,pBitmap,0,wBmpHeight,(LPVOID)pPixels,&bmiInfo,DIB_RGB_COLORS);
    
            // release the device context
            ReleaseDC(NULL,hDC);
    
            // if failed, cancel the operation.
            if (!iRes)
            {
                delete[] pPixels;
                return NULL;
            };
    
            // return the pixel array
            return pPixels;
        }
    
        HRGN RegionbyBitmap(HBITMAP pBitmap,COLORREF clrTransparent=-1 )
        {
            BYTE jTranspR = GetRValue(clrTransparent), jTranspG=GetGValue(clrTransparent), jTranspB=GetBValue(clrTransparent);
            // bitmap width and height
            WORD wBmpWidth,wBmpHeight;
    
            // the final region and a temporary region
            HRGN hRgn, hTmpRgn;
    
            // 24bit pixels from the bitmap
            BYTE *pPixels = Get24BitPixels(pBitmap, &wBmpWidth, &wBmpHeight);
            if (!pPixels) return NULL;
    
            // create our working region
            hRgn = CreateRectRgn(0,0,wBmpWidth,wBmpHeight);
            if (!hRgn)
            {
                delete[] pPixels;
                return NULL;
            }
    
            // ---------------------------------------------------------
            // scan the bitmap
            // ---------------------------------------------------------
    
    
            DWORD p=0;
            for (WORD y=0; y<wBmpHeight; y++)
            {
                for (WORD x=0; x<wBmpWidth; x++)
                {
                  BYTE jRed   = pPixels[p+2];
                  BYTE jGreen = pPixels[p+1];
                  BYTE jBlue  = pPixels[p+0];
    
                  if ((jRed == jTranspR && jGreen == jTranspG && jBlue == jTranspB))
                  {
                    // remove transparent color from region
                    hTmpRgn = CreateRectRgn(x,y,x+1,y+1);
                    CombineRgn(hRgn, hRgn, hTmpRgn, RGN_XOR);
                    DeleteObject(hTmpRgn);
    
    
                  }
    
                  // next pixel
                  p+=3;
                }
            }
    
            // release pixels
            delete[] pPixels;
    
            return hRgn;
        }
    they work fine. but if i have images with 100X40, it can be very slow
    so imagine if the control region is 200X200.
    anotherthing: whe it's very slow(i use a timer on animation), i can lose the window control messages(freezes the application).
    can i speed up the DIB's code?
    Last edited by Cambalinho; July 24th, 2015 at 08:39 AM.

  2. #2
    Join Date
    Aug 2000
    Location
    New York, NY, USA
    Posts
    5,656

    Re: GDI - can i speed up the DIB code?

    Did you profile your code? Do you know which part takes most of the time? Is it Get24BitPixels() or RegionbyBitmap()?
    Do you have a lot of transparent pixels in your bitmap?
    I assume that most of the time is spent in the inner-most loop, where you repeatedly create and destroy a one-pixel region.
    I would try to create that region once (outside of the loop) and use OffsetRgn function to move it to the current transparent point.
    Next, you can try to look ahead and see if there are multiple consecutive transparent pixels in your bitmap, then you can create a bigger region and combine it once instead of for each pixel.
    Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
    Convenience and productivity tools for Microsoft Visual Studio:
    FeinWindows - replacement windows manager for Visual Studio, and more...

  3. #3
    Join Date
    Apr 2009
    Posts
    1,268

    Re: GDI - can i speed up the DIB code?

    Quote Originally Posted by VladimirF View Post
    Did you profile your code? Do you know which part takes most of the time? Is it Get24BitPixels() or RegionbyBitmap()?
    Do you have a lot of transparent pixels in your bitmap?
    I assume that most of the time is spent in the inner-most loop, where you repeatedly create and destroy a one-pixel region.
    I would try to create that region once (outside of the loop) and use OffsetRgn function to move it to the current transparent point.
    Next, you can try to look ahead and see if there are multiple consecutive transparent pixels in your bitmap, then you can create a bigger region and combine it once instead of for each pixel.
    i belive the problem is on my region code:
    Code:
    // create our working region
            hRgn = CreateRectRgn(0,0,wBmpWidth,wBmpHeight);
            if (!hRgn)
            {
                delete[] pPixels;
                return NULL;
            }
    
            // ---------------------------------------------------------
            // scan the bitmap
            // ---------------------------------------------------------
    
    
            DWORD p=0;
            for (WORD y=0; y<wBmpHeight; y++)
            {
                for (WORD x=0; x<wBmpWidth; x++)
                {
                  BYTE jRed   = pPixels[p+2];
                  BYTE jGreen = pPixels[p+1];
                  BYTE jBlue  = pPixels[p+0];
    
                  if ((jRed == jTranspR && jGreen == jTranspG && jBlue == jTranspB))
                  {
                    // remove transparent color from region
                    hTmpRgn = CreateRectRgn(x,y,x+1,y+1);
                    CombineRgn(hRgn, hRgn, hTmpRgn, RGN_XOR);
                    DeleteObject(hTmpRgn);
    
    
                  }
    
                  // next pixel
                  p+=3;
                }
            }
    
            // release pixels
            delete[] pPixels;
    because using the CombineRgn() in pixel way is slow. maybe with time, i can change it, but isn't easy

  4. #4
    Join Date
    Aug 2000
    Location
    New York, NY, USA
    Posts
    5,656

    Re: GDI - can i speed up the DIB code?

    Quote Originally Posted by Cambalinho View Post
    maybe with time, i can change it, but isn't easy
    Try this in place of your scanning code:
    Code:
    // ---------------------------------------------------------
    // scan the bitmap
    // ---------------------------------------------------------
    
    DWORD p = 0;
    int xStart = 0;
    bool bTransp(false);
    hTmpRgn = CreateRectRgn(0, 0, 1, 1);
    for (WORD y = 0; y<wBmpHeight; y++)
    {
    	for (WORD x = 0; x<wBmpWidth; x++)
    	{
    		BYTE jRed = pPixels[p + 2];
    		BYTE jGreen = pPixels[p + 1];
    		BYTE jBlue = pPixels[p + 0];
    
    		if ((jRed == jTranspR && jGreen == jTranspG && jBlue == jTranspB))
    		{
    			if (!bTransp)
    			{
    				xStart = x;
    				bTransp = true;
    			}
    		}
    		else
    		{
    			if (bTransp)
    			{
    				SetRectRgn(hTmpRgn, xStart, y, x - xStart, y + 1);
    				CombineRgn(hRgn, hRgn, hTmpRgn, RGN_XOR);
    				bTransp = false;
    			}
    		}
    
    		// next pixel
    		p += 3;
    	}
    	if (bTransp)
    	{
    		SetRectRgn(hTmpRgn, xStart, y, wBmpWidth - xStart, y + 1);
    		CombineRgn(hRgn, hRgn, hTmpRgn, RGN_XOR);
    		bTransp = false;
    	}
    }
    DeleteObject(hTmpRgn);
    Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
    Convenience and productivity tools for Microsoft Visual Studio:
    FeinWindows - replacement windows manager for Visual Studio, and more...

  5. #5
    Join Date
    Apr 2009
    Posts
    1,268

    Re: GDI - can i speed up the DIB code?

    Quote Originally Posted by VladimirF View Post
    Try this in place of your scanning code:
    Code:
    // ---------------------------------------------------------
    // scan the bitmap
    // ---------------------------------------------------------
    
    DWORD p = 0;
    int xStart = 0;
    bool bTransp(false);
    hTmpRgn = CreateRectRgn(0, 0, 1, 1);
    for (WORD y = 0; y<wBmpHeight; y++)
    {
        for (WORD x = 0; x<wBmpWidth; x++)
        {
            BYTE jRed = pPixels[p + 2];
            BYTE jGreen = pPixels[p + 1];
            BYTE jBlue = pPixels[p + 0];
    
            if ((jRed == jTranspR && jGreen == jTranspG && jBlue == jTranspB))
            {
                if (!bTransp)
                {
                    xStart = x;
                    bTransp = true;
                }
            }
            else
            {
                if (bTransp)
                {
                    SetRectRgn(hTmpRgn, xStart, y, x - xStart, y + 1);
                    CombineRgn(hRgn, hRgn, hTmpRgn, RGN_XOR);
                    bTransp = false;
                }
            }
    
            // next pixel
            p += 3;
        }
        if (bTransp)
        {
            SetRectRgn(hTmpRgn, xStart, y, wBmpWidth - xStart, y + 1);
            CombineRgn(hRgn, hRgn, hTmpRgn, RGN_XOR);
            bTransp = false;
        }
    }
    DeleteObject(hTmpRgn);
    seems much more faster, but very pixels aren't transparent
    see the image:
    Name:  region problems.jpg
Views: 45
Size:  12.4 KB
    Last edited by Cambalinho; July 23rd, 2015 at 03:58 PM.

  6. #6
    Join Date
    Aug 2000
    Location
    New York, NY, USA
    Posts
    5,656

    Re: GDI - can i speed up the DIB code?

    Quote Originally Posted by Cambalinho View Post
    seems much more faster, but very pixels aren't transparent
    see the image:
    Could you please attach the original bitmap you are trying to convert?
    Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
    Convenience and productivity tools for Microsoft Visual Studio:
    FeinWindows - replacement windows manager for Visual Studio, and more...

  7. #7
    Join Date
    Apr 2009
    Posts
    1,268

    Re: GDI - can i speed up the DIB code?

    heres the original transparent:
    Name:  region original.jpg
Views: 46
Size:  13.2 KB

  8. #8
    Join Date
    Aug 2000
    Location
    New York, NY, USA
    Posts
    5,656

    Re: GDI - can i speed up the DIB code?

    This is JPEG (compressed).
    Do you have the original BMP image? And what color is used to convert to transparent?
    Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
    Convenience and productivity tools for Microsoft Visual Studio:
    FeinWindows - replacement windows manager for Visual Studio, and more...

  9. #9
    Join Date
    Apr 2009
    Posts
    1,268

    Re: GDI - can i speed up the DIB code?

    Quote Originally Posted by VladimirF View Post
    This is JPEG (compressed).
    Do you have the original BMP image? And what color is used to convert to transparent?
    that image is drawed with WM_PAINT, i draw the image and then the text. my last image was the transparent, but it's very slow. and your code don't do the transparent correctly
    Last edited by Cambalinho; July 23rd, 2015 at 05:02 PM.

  10. #10
    Join Date
    Aug 2000
    Location
    New York, NY, USA
    Posts
    5,656

    Re: GDI - can i speed up the DIB code?

    Quote Originally Posted by Cambalinho View Post
    that image is drawed with WM_PAINT, i draw the image and then the text. my last image was the transparent, but it's very slow. and your code don't do the transparent correctly
    I might have missed something.
    Could you please upload your zipped test project (without Debug/Release folders) here?
    What bitmap do you pass to function HRGN RegionbyBitmap(HBITMAP pBitmap,COLORREF clrTransparent)? And what color?
    Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
    Convenience and productivity tools for Microsoft Visual Studio:
    FeinWindows - replacement windows manager for Visual Studio, and more...

  11. #11
    Join Date
    Apr 2009
    Posts
    1,268

    Re: GDI - can i speed up the DIB code?

    Quote Originally Posted by VladimirF View Post
    I might have missed something.
    Could you please upload your zipped test project (without Debug/Release folders) here?
    What bitmap do you pass to function HRGN RegionbyBitmap(HBITMAP pBitmap,COLORREF clrTransparent)? And what color?
    the h files it's to big for add here
    in these case, don't matter what bitmap is used... realy. the image is drawed using GDI functions(of course with objective is accept all diferent images)
    the funcion do:
    - create the pixels array, using the Get24BitPixels() function;
    - then i create a new region for add all data and for return it;
    - i cycle the pixels for test if the color is for be transparent or not;
    - return the region
    Last edited by Cambalinho; July 24th, 2015 at 08:23 AM.

  12. #12
    Join Date
    Apr 2009
    Posts
    1,268

    Re: GDI - can i speed up the DIB code?

    with more search, i found 1 code much more faster:
    Code:
    HRGN RegionbyBitmap( HBITMAP hBmp, COLORREF color =-1)
        {
            // get image properties
            BITMAP bmp = { 0 };
            GetObject( hBmp, sizeof(BITMAP), &bmp );
            // allocate memory for extended image information
            LPBITMAPINFO bi = (LPBITMAPINFO) new BYTE[ sizeof(BITMAPINFO) + 8 ];
            memset( bi, 0, sizeof(BITMAPINFO) + 8 );
            bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
            // set window size
            int m_dwWidth    = bmp.bmWidth;        // bitmap width
            int m_dwHeight    = bmp.bmHeight;        // bitmap height
            // create temporary dc
            HDC dc = CreateIC( "DISPLAY",NULL,NULL,NULL );
            // get extended information about image (length, compression, length of color table if exist, ...)
            DWORD res = GetDIBits( dc, hBmp, 0, bmp.bmHeight, 0, bi, DIB_RGB_COLORS );
            // allocate memory for image data (colors)
            LPBYTE pBits = new BYTE[ bi->bmiHeader.biSizeImage + 4 ];
            // allocate memory for color table
            if ( bi->bmiHeader.biBitCount == 8 )
            {
                // actually color table should be appended to this header(BITMAPINFO),
                // so we have to reallocate and copy it
                LPBITMAPINFO old_bi = bi;
                // 255 - because there is one in BITMAPINFOHEADER
                bi = (LPBITMAPINFO)new char[ sizeof(BITMAPINFO) + 255 * sizeof(RGBQUAD) ];
                memcpy( bi, old_bi, sizeof(BITMAPINFO) );
                // release old header
                delete old_bi;
            }
            // get bitmap info header
            BITMAPINFOHEADER& bih = bi->bmiHeader;
            // get color table (for 256 color mode contains 256 entries of RGBQUAD(=DWORD))
            LPDWORD clr_tbl = (LPDWORD)&bi->bmiColors;
            // fill bits buffer
            res = GetDIBits( dc, hBmp, 0, bih.biHeight, pBits, bi, DIB_RGB_COLORS );
            DeleteDC( dc );
    
            BITMAP bm;
            GetObject( hBmp, sizeof(BITMAP), &bm );
            // shift bits and byte per pixel (for comparing colors)
            LPBYTE pClr = (LPBYTE)&color;
            // swap red and blue components
            BYTE tmp = pClr[0]; pClr[0] = pClr[2]; pClr[2] = tmp;
            // convert color if curent DC is 16-bit (5:6:5) or 15-bit (5:5:5)
            if ( bih.biBitCount == 16 )
            {
                // for 16 bit
                color = ((DWORD)(pClr[0] & 0xf8) >> 3) |
                        ((DWORD)(pClr[1] & 0xfc) << 3) |
                        ((DWORD)(pClr[2] & 0xf8) << 8);
                // for 15 bit
        //        color = ((DWORD)(pClr[0] & 0xf8) >> 3) |
        //                ((DWORD)(pClr[1] & 0xf8) << 2) |
        //                ((DWORD)(pClr[2] & 0xf8) << 7);
            }
    
            const DWORD RGNDATAHEADER_SIZE    = sizeof(RGNDATAHEADER);
            const DWORD ADD_RECTS_COUNT        = 40;            // number of rects to be appended
                                                            // to region data buffer
    
            // BitPerPixel
            BYTE    Bpp = bih.biBitCount >> 3;                // bytes per pixel
            // bytes per line in pBits is DWORD aligned and bmp.bmWidthBytes is WORD aligned
            // so, both of them not
            DWORD m_dwAlignedWidthBytes = (bmp.bmWidthBytes & ~0x3) + (!!(bmp.bmWidthBytes & 0x3) << 2);
            // DIB image is flipped that's why we scan it from the last line
            LPBYTE    pColor = pBits + (bih.biHeight - 1) * m_dwAlignedWidthBytes;
            DWORD    dwLineBackLen = m_dwAlignedWidthBytes + bih.biWidth * Bpp;    // offset of previous scan line
                                                            // (after processing of current)
            DWORD    dwRectsCount = bih.biHeight;            // number of rects in allocated buffer
            INT        i, j;                                    // current position in mask image
            INT        first = 0;                                // left position of current scan line
                                                            // where mask was found
            bool    wasfirst = false;                        // set when mask has been found in current scan line
            bool    ismask;                                    // set when current color is mask color
    
            // allocate memory for region data
            // region data here is set of regions that are rectangles with height 1 pixel (scan line)
            // that's why first allocation is <bm.biHeight> RECTs - number of scan lines in image
            RGNDATAHEADER* pRgnData =
                (RGNDATAHEADER*)new BYTE[ RGNDATAHEADER_SIZE + dwRectsCount * sizeof(RECT) ];
            // get pointer to RECT table
            LPRECT pRects = (LPRECT)((LPBYTE)pRgnData + RGNDATAHEADER_SIZE);
            // zero region data header memory (header  part only)
            memset( pRgnData, 0, RGNDATAHEADER_SIZE + dwRectsCount * sizeof(RECT) );
            // fill it by default
            pRgnData->dwSize    = RGNDATAHEADER_SIZE;
            pRgnData->iType        = RDH_RECTANGLES;
    
            for ( i = 0; i < bih.biHeight; i++ )
            {
                for ( j = 0; j < bih.biWidth; j++ )
                {
                    // get color
                    switch ( bih.biBitCount )
                    {
                    case 8:
                        ismask = (clr_tbl[ *pColor ] != color);
                        break;
                    case 16:
                        ismask = (*(LPWORD)pColor != (WORD)color);
                        break;
                    case 24:
                        ismask = ((*(LPDWORD)pColor & 0x00ffffff) != color);
                        break;
                    case 32:
                        ismask = (*(LPDWORD)pColor != color);
                    }
                    // shift pointer to next color
                    pColor += Bpp;
                    // place part of scan line as RECT region if transparent color found after mask color or
                    // mask color found at the end of mask image
                    if ( wasfirst )
                    {
                        if ( !ismask )
                        {
                            // save current RECT
                            pRects[ pRgnData->nCount++ ] ={first, i, j, i + 1 };
                            // if buffer full reallocate it with more room
                            if ( pRgnData->nCount >= dwRectsCount )
                            {
                                dwRectsCount += ADD_RECTS_COUNT;
                                // allocate new buffer
                                LPBYTE pRgnDataNew = new BYTE[ RGNDATAHEADER_SIZE + dwRectsCount * sizeof(RECT) ];
                                // copy current region data to it
                                memcpy( pRgnDataNew, pRgnData, RGNDATAHEADER_SIZE + pRgnData->nCount * sizeof(RECT) );
                                // delte old region data buffer
                                delete pRgnData;
                                // set pointer to new regiondata buffer to current
                                pRgnData = (RGNDATAHEADER*)pRgnDataNew;
                                // correct pointer to RECT table
                                pRects = (LPRECT)((LPBYTE)pRgnData + RGNDATAHEADER_SIZE);
                            }
                            wasfirst = false;
                        }
                    }
                    else if ( ismask )        // set wasfirst when mask is found
                    {
                        first = j;
                        wasfirst = true;
                    }
                }
    
                if ( wasfirst && ismask )
                {
                    // save current RECT
                    pRects[ pRgnData->nCount++ ] = {first, i, j, i + 1 };
                    // if buffer full reallocate it with more room
                    if ( pRgnData->nCount >= dwRectsCount )
                    {
                        dwRectsCount += ADD_RECTS_COUNT;
                        // allocate new buffer
                        LPBYTE pRgnDataNew = new BYTE[ RGNDATAHEADER_SIZE + dwRectsCount * sizeof(RECT) ];
                        // copy current region data to it
                        memcpy( pRgnDataNew, pRgnData, RGNDATAHEADER_SIZE + pRgnData->nCount * sizeof(RECT) );
                        // delte old region data buffer
                        delete pRgnData;
                        // set pointer to new regiondata buffer to current
                        pRgnData = (RGNDATAHEADER*)pRgnDataNew;
                        // correct pointer to RECT table
                        pRects = (LPRECT)((LPBYTE)pRgnData + RGNDATAHEADER_SIZE);
                    }
                    wasfirst = false;
                }
    
                pColor -= dwLineBackLen;
            }
            // release image data
            delete pBits;
            delete bi;
    
            // create region
            HRGN hRgn = ExtCreateRegion( NULL, RGNDATAHEADER_SIZE + pRgnData->nCount * sizeof(RECT), (LPRGNDATA)pRgnData );
            // release region data
            delete pRgnData;
    
            return hRgn;
        }
    maybe i need more work for correct the color=-1. but works fine.
    i found it(on source code): http://www.********.net/VC_Library_C...VC_Example.htm

    thanks for all

  13. #13
    Join Date
    Aug 2000
    Location
    New York, NY, USA
    Posts
    5,656

    Re: GDI - can i speed up the DIB code?

    Quote Originally Posted by Cambalinho View Post
    with more search, i found 1 code much more faster:
    That's cool, but I wonder if it will be any faster than my last posted code.
    This example does pretty much the same thing, but it manipulates region data directly.
    Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
    Convenience and productivity tools for Microsoft Visual Studio:
    FeinWindows - replacement windows manager for Visual Studio, and more...

  14. #14
    Join Date
    Apr 2009
    Posts
    1,268

    Re: [RESOLVED] GDI - can i speed up the DIB code?

    VladimirF : i'm sorry, but i can't rate you
    but thanks for help me

  15. #15
    Join Date
    Aug 2000
    Location
    New York, NY, USA
    Posts
    5,656

    Re: [RESOLVED] GDI - can i speed up the DIB code?

    Quote Originally Posted by Cambalinho View Post
    VladimirF : i'm sorry, but i can't rate you
    but thanks for help me
    you are welcome
    Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
    Convenience and productivity tools for Microsoft Visual Studio:
    FeinWindows - replacement windows manager for Visual Studio, and more...

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width




On-Demand Webinars (sponsored)