Solved

GetDibBits doesn't work!!!

Posted on 1998-12-17
14
670 Views
Last Modified: 2013-11-20
Hi :
  actually the GetDibBits() function work, but after i get the bits, the window lost its thread, the memory seem has been moved and the control can't get back to the calling function, why ? the addresses are all ??? ??? ???, can anybody tell me why ?
0
Comment
Question by:eugeneng
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 5
  • 3
14 Comments
 
LVL 6

Expert Comment

by:snoegler
ID: 1326299
Sounds like you are overwriting the stack frame or the process data ...
Where do you store the DibBits? Could you give a short code sample of what you're doing?
0
 

Author Comment

by:eugeneng
ID: 1326300
first of all, snoegler, thanx for your response,
I create a DIB hBitmap as below function ;

BOOL CreateMapDIB(HBITMAPA hBitmap,RGBQUAD *pColorTable[65])
{
   if (hBitmap){
       DeleteObject(hBitmap);
       hBitmap= NULL;
   }

            
LPBITMAPINFO lpbi;

       lpbi = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER)+
               (65*sizeof(RGBQUAD))];

      lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
      lpbi->bmiHeader.biWidth = 80;
      lpbi->bmiHeader.biHeight = 80;
      lpbi->bmiHeader.biPlanes = 1;
      lpbi->bmiHeader.biBitCount = 8;
      lpbi->bmiHeader.biCompression = BI_RGB;
      lpbi->bmiHeader.biSizeImage = 0;
      lpbi->bmiHeader.biXPelsPerMeter = 0;
      lpbi->bmiHeader.biYPelsPerMeter = 0;
      lpbi->bmiHeader.biClrUsed = 65;
      lpbi->bmiHeader.biClrImportant = 0;

      int buf=0;
      //fill bk palette color
      memcpy(&lpbi->bmiColors,pColorTable,sizeof(RGBQUAD)*65);
      CDC *ScreenDC = GetDC(NULL);

      hBitmap =CreateDIBSection(ScreenDC->m_hDC,
                                  lpbi,DIB_RGB_COLORS,
                                  NULL,NULL,0);
      ReleaseDC(ScreenDC);
      delete [](BYTE *)lpbi;

      if (hBitmap == NULL)
            return FALSE;

      //initialize bitmap bits
      BYTE * pByte = new BYTE[80*80];
      memset(pByte,0,80*80);
      SetBitmapBits(hBitmap,80*80,pByte);
      delete [] (BYTE*) pByte;

return TRUE;
}

ok, i've created the hBitmap successfully, at sometime, i want to change a particular part of bit data in the hBitmap, but there is not function like SetDIBitsToDevice() where i can specify a rectangle and update the bits data, so i have to use GetDIBits() to get the entire bits data from hBitmap and update the entire scanline at a time, so i do like :

void MyClass::PenTile(CPoint pnt)
{
    //assume size of hBitmap is 80*80
   // if size is huge, this statement might take cause delay.
     BYTE *pBuf= new BYTE[80*80];

    int h,w;
    BITMAPINFO bmpInfo;
    bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmpInfo.bmiHeader.biWidth = 80;
    bmpInfo.bmiHeader.biHeight = 80;
    bmpInfo.bmiHeader.biPlanes = 1;
    bmpInfo.bmiHeader.biBitCount = 8;
    bmpInfo.bmiHeader.biCompression = BI_RGB;

    CDC *pDC = GetDC();
    int h;
    int x,y;

    x = pnt.x; //i do this becaue i don't know why after
    y = pnt.y;//executed GetDIBits, value of pnt will be modified

    h = 80-pnt.y; //because bitmap will be drawn bottom-up right?
      err = GetDIBits(NULL,hBitmap,
                        h,8,&pBuf,
                       (LPBITMAPINFO)&bmpInfo,
                        DIB_RGB_COLORS);

         
      if (!err)
            err = GetLastError();
        pnt.x = x;
        pnt.y = y;

      MyUpdateBits(pBuf,pnt.y);

        //set the bits back to hBitmap
      err = SetDIBits(pDC->GetSafeHdc(),hBitmap,
                        h,8,pBuf,(LPBITMAPINFO)lpbi,
                        DIB_RGB_COLORS);

      if (!err)
            err = GetLastError();


      ReleaseDC(pDC);
      delete [] (BYTE*) lpbi;
      delete [] (BYTE*) pBuf;
        return;
}

ok. this is the function that i want to update bits data of dib bitmap. My problem is :

    1. how can i update a certain part of bitmap without have to get the entire bits data of bitmap ? like SetDIBitsToDevice where i can specify a rectangle that need to be updated. Because when the bitmap grows to huge size, it will take some time to allocate memory for pBuf that will be used to receive the bits data.
 
   2. Don't know why in the above code, the value of function argument "pnt" will be modified after executed GetDIBits();


  Thanx for you help.


0
 
LVL 6

Expert Comment

by:snoegler
ID: 1326301
I know some ways to do this, but neither of them is really convenient :)
First of all, you could deal with the DIB low-level, meaning to keep all data in your application,
and creating the real DIB only if needed (passing the pDibBits parameter to CreateDIBitmap).
As CreateDIBitmap uses your memory without modification, this could solve (1).

Another possibility is to use DirectX using memory surfaces. But i think this isn't a solution for
you.

Then, there is a CImage class which allows to modify the bits directly. You can download it
at www.visualc.com. It has several high-level and low-level methods to work with bitmap data.
Maybe you take a look at it.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 6

Expert Comment

by:snoegler
ID: 1326302
BTW: 'pnt' is overwritten due a stack frame overflow. The size of the array [80*80] is too small.
Maybe you're using 16- or 24 Bit DIBs? If yes, then the size would be 80*80*3 ...
Fact is, the array is too small - the memory 'behind' the array is overwritten, and this is why
your application will produce errors. When the 'return pointer' is overwritten, then the whole
application will crash. Try increasing the size of the array.
0
 

Author Comment

by:eugeneng
ID: 1326303
thanx a lot man, i haven't try yet, but it seems like helpful. i'll get back latter. But isn't there a way can modify the dib bits directly ?
0
 
LVL 6

Expert Comment

by:snoegler
ID: 1326304
I don't know any ;)
0
 
LVL 2

Expert Comment

by:zyqwert
ID: 1326305
Yes, you can modify the bits directly.
When you call CreateDibSection, fill in the 4th parameter and you'll have a pointer to a pointer to the bits.  Then you can change them whenever you like.
You don't need GetDIBits or SetDIBits.
Does this help?


0
 

Author Comment

by:eugeneng
ID: 1326306
but, after i modified the bits, do i need to rebuild the HBITMAP ?
0
 
LVL 2

Expert Comment

by:zyqwert
ID: 1326307
Not at all.  A Dib Section bitmap, unlike a regular bitmap from CreateBitmap, you can change by writing directly to the bits.  The change won't manifest itself on screen until you do a BitBlt from a memory DC that has the hBitmap selected into it.  Try it, you'll see.

From the documentation at msdn.microsoft.com:
Windows NT: You need to guarantee that the GDI subsystem has completed any drawing to a bitmap created by CreateDIBSection
before you draw to the bitmap yourself. Access to the bitmap must be synchronized. Do this by calling the GdiFlush
function.

0
 

Author Comment

by:eugeneng
ID: 1326308
thanx a lots zyqwert, you are my lifesaver man, I've tested it and it works perfectly, thanx a lots
0
 
LVL 2

Accepted Solution

by:
zyqwert earned 200 total points
ID: 1326309
You're welcome eugeneng -- can we close this case?
0
 

Author Comment

by:eugeneng
ID: 1326310
yape, the has been closed.
0
 
LVL 6

Expert Comment

by:snoegler
ID: 1326311
eugeneng, how about giving the points to zyqwert?
I think he solved your problem - so you should award him his
points :)
0
 

Author Comment

by:eugeneng
ID: 1326312
oops..sorry, i've forgotten, thanx for reminding me.
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Turn a spreadsheet into a vba executable. 2 98
Unix Command -- Challenging  question 7 101
wordmultiple challenge 12 155
Can not remove SSL certificate on iPhone 6 - iOS10.2 12 1,282
Here is how to use MFC's automatic Radio Button handling in your dialog boxes and forms.  Beginner programmers usually start with a OnClick handler for each radio button and that's just not the right way to go.  MFC has a very cool system for handli…
Introduction: Hints for the grid button.  Nested classes, templated collections.  Squash that darned bug! Continuing from the sixth article about sudoku.   Open the project in visual studio. First we will finish with the SUD_SETVALUE messa…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…

756 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question