Thread: Win Api Basics...

  1. #16
    Code Monkey Davros's Avatar
    Join Date
    Jun 2002
    Posts
    812
    >i think the above posts explain it pretty well...
    >hDC = GetDC(hwnd);

    I tried all that.

    I also searched for example code written by other people, but nothing worked. What I ever I did, it would fail one in 20 times or so.

    I do read the manuals. Whatever was wrong with my code, it was something subtle that I couldn't figure out.
    OS: Windows XP
    Compilers: MinGW (Code::Blocks), BCB 5

    BigAngryDog.com

  2. #17
    * Death to Visual Basic * Devil Panther's Avatar
    Join Date
    Aug 2001
    Posts
    768
    what do you mean it would fail one in 20 times?

    does it compile?
    "I don't suffer from insanity but enjoy every minute of it" - Edgar Allen Poe

    http://www.Bloodware.net - Developing free software for the community.

  3. #18
    Code Monkey Davros's Avatar
    Join Date
    Jun 2002
    Posts
    812
    >does it compile?

    Of course. And it ran. And it worked - 1 in 20 times. But when it failed, GetDIBits would return invalid colour values in around half the image.

    I tried other's people code which was doing exactly the same thing I was, and that had the same problem. I have no issues with stability on my machine (i.e. no graphic card problems).

    Withouta really proper understanding of what was going on, and how the API was being used (which I have been unable to get from MSDN), I was unable to find a solution.

    In the end, I resolved my problem by calling a third party API, which I guess just wrapped GetDIBits, but it worked. So it must have been something wrong with what I was doing.

    Here was my code. Although I got my application to work now, I would still be interested to know what I did wrong.

    Code:
    int Gfx::create(Gfx& dst, void* src, int y, int cnt)
    {
      // (this code DOES NOT seem to work reliably)
      // Creates gfx data and fills it with contents of bitmap from
      // platform specific bitmap object src. At the moment, this method
      // only works under windows. Does nothing under any other platform.
      // If this method fails, rslt.data is NULL(0) & returns
      // platform specific error code. Error is -1 if operation
      // is not supported on platform.
      int err;
      if (y < 0) y = 0;
    
      // Ensure existing is destroyed.
      destroy(dst);
    
    #ifdef AIDAWIN
      // WINDOWS IMPLEMENTATION
      // src must not be 'selected into a device'
      err = 0;
      HDC hdc = 0;
      BITMAPINFO bmi;
      memset(&bmi, 0, sizeof(BITMAPINFO));
      bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    
      try
      {
        // Make temporary compatible device
        hdc = GetDC(0); // CreateCompatibleDC
        GdiFlush();
    
        // Get dimensions first
        GetDIBits(hdc, (HBITMAP)src, 0, 0, 0, &bmi, DIB_RGB_COLORS);
    
        // We always want positive height (bottom up bmp)
        bmi.bmiHeader.biHeight = abs(bmi.bmiHeader.biHeight);
    
        // Work out full size count if needed
        if (cnt <= 0) cnt = bmi.bmiHeader.biHeight - y;
    
        // Fill data
        dst.pDim.x = bmi.bmiHeader.biWidth;
        dst.pDim.y = cnt;
    
        // Check we can handle range
        err = ERROR_INVALID_PARAMETER;
    
        if (y + cnt <= bmi.bmiHeader.biHeight && cnt > 0)
        {
          // Set pixel format to be retrieved
          bmi.bmiHeader.biBitCount = 24;
          bmi.bmiHeader.biCompression = BI_RGB;
    
    ** HERE sz includes packing bytes
          int sz = dst.rowsz() * dst.pDim.y;
    
          if (sz > 0)
          {
            // Create memory array
            dst.pData = new char[sz];
    
    ** HERE  GetDiBits
            err = 0;
            if (GetDIBits(hdc, src, y, cnt, dst.pData,
              &bmi, DIB_RGB_COLORS) == 0)
            {
              // Error - destroy memory and
              // error code will be set below
              destroy(dst);
    ShowMessage("Y " + IntToStr(y));
    ShowMessage("CNT : " +IntToStr(cnt));
    
            throw Exception("Error " + IntToStr(GetLastError()));
            }
          }
        }
    
        // If no data - set error code
        if (dst.pData == 0)
        {
          dst.pDim = Axy();
          if (err == 0) err = GetLastError();
        }
    
        // Free temporary device context
        ReleaseDC(0, hdc);
      }
      catch(...)
      {
        // Clean-up
        destroy(dst);
        ReleaseDC(hdc);
        throw;
      }
    #else
      // NOT SUPPORTED
      err = -1;
    #endif
    
      return err;
    }
    OS: Windows XP
    Compilers: MinGW (Code::Blocks), BCB 5

    BigAngryDog.com

  4. #19
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Davros: I can't explain your problem, and I have no intention of reading through your code since I don't remember what parameters do what, and have no desire to read the documentations again But I did use GetDIBits once when I was trying to generate rotated bitmaps for my GDI graphics library, and never had any problems with it; if you care, you can sift through this and see if anything helps:
    Code:
    HBITMAP GFX::getRotatedBmp(HBITMAP orig, double angle, int rPointX, int rPointY)
    {
    	if(orig == NULL)
    		return NULL;
    
    	HBITMAP img;
    	HDC dcSrc = CreateCompatibleDC(dcFront);
    
    	RECT bounds = getBmpDimensions(orig);
    	int width = bounds.right + 1;
    	int height = bounds.bottom + 1;
    
    	img = CreateCompatibleBitmap(dcFront, width, height);
    
    	BITMAPINFO bi = {0};
    
    	bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
    	bi.bmiHeader.biWidth = width;
    	bi.bmiHeader.biHeight = height;
    	bi.bmiHeader.biPlanes = 1;
    	bi.bmiHeader.biBitCount = 32;
    	bi.bmiHeader.biCompression = BI_RGB;
    
    	unsigned char* srcBits = new unsigned char[4 * width * height];
    	if(!GetDIBits(dcSrc, orig, 0, height, srcBits, &bi, DIB_RGB_COLORS))
    	{
    		delete[] srcBits;
    		return NULL;
    	}
    	unsigned char* destBits = new unsigned char[4 * width * height];
    
    	float sine = (float)sin(angle), cosine = (float)cos(angle); //Store result to save time
    	float cX = (float)rPointX, cY = (float)(bounds.bottom - rPointY); //Typecast & convert from normal coords
    	float tempX, tempY; //Offset on source to centre the image
    
    	tempX = (cX*(cosine-1) - cY*sine);
    	tempY = (cY*(cosine-1) + cX*sine);
    
    	int origX, origY;
    
    	unsigned char* destLine = destBits;
    	for(int y = 0; y < height; ++y)
    	{
    		for(int x = 0; x < width; ++x)
    		{
    			origX = (int)(((float)x + tempX)*cosine + ((float)y + tempY)*sine);
    			origY = (int)(((float)y + tempY)*cosine - ((float)x + tempX)*sine);
    
    			if(origX >= 0 && origY >= 0 && origX < bounds.right && origY < bounds.bottom)
    			{
    				destLine[(x << 2)    ] = srcBits[((origX + width*origY) << 2)    ];
    				destLine[(x << 2) + 1] = srcBits[((origX + width*origY) << 2) + 1];
    				destLine[(x << 2) + 2] = srcBits[((origX + width*origY) << 2) + 2];
    			}
    			else
    			{
    				destLine[(x << 2)    ] = 0;
    				destLine[(x << 2) + 1] = 0;
    				destLine[(x << 2) + 2] = 0;
    			}
    		}
    		destLine += (width << 2);
    	}
    
    	SetDIBits(dcSrc, img, 0, height, destBits, &bi, DIB_RGB_COLORS);
    
    	DeleteDC(dcSrc);
    
    	delete[] srcBits;
    	delete[] destBits;
    
    	return img;
    }
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  5. #20
    Code Monkey Davros's Avatar
    Join Date
    Jun 2002
    Posts
    812
    >I have no intention of reading through your code

    I can understand that. I did try simplifying my code in a previous post, but found I made so many typo errors in the simplification, that it made the effort pointless.

    >if you care, you can sift through this and see if anything helps

    Thanks. I will do so.

    Cheers for the reply.
    OS: Windows XP
    Compilers: MinGW (Code::Blocks), BCB 5

    BigAngryDog.com

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. help with this
    By tyrantil in forum C Programming
    Replies: 18
    Last Post: 01-30-2005, 04:53 PM
  2. Getting Hold of win API Refernce
    By Davros in forum Windows Programming
    Replies: 2
    Last Post: 08-29-2004, 04:01 PM
  3. win api literature
    By DMaxJ in forum Windows Programming
    Replies: 5
    Last Post: 04-30-2004, 03:25 PM
  4. Win API
    By Marky_Mark in forum Windows Programming
    Replies: 4
    Last Post: 10-23-2001, 12:57 PM
  5. Rich edit control example Win API
    By Echidna in forum Windows Programming
    Replies: 1
    Last Post: 09-17-2001, 02:12 AM