Results 1 to 11 of 11

Thread: Automatic double buff and blit to screen

  1. #1

    Thread Starter
    Frenzied Member aewarnick's Avatar
    Join Date
    Dec 2002
    Posts
    1,037

    Automatic double buff and blit to screen

    I have a graphics class that encapsulates BitBlt. I use it like this:
    Code:
    case WM_PAINT:
    {
      PAINTSTRUCT lpPaintStruct;
      HDC hdc= ::BeginPaint(Form.Handle, &lpPaintStruct);
      a::graphics g(hdc, &lpPaintStruct.rcPaint);
      g.DrawImage(Form.Handle, &abmp, &lpPaintStruct.rcPaint, &lpPaintStruct.rcPaint);
      g.DrawImage(Form.Handle, &abmp, &drawRect, true);
      g.Show(); //blits the memDC to screen.
      ::EndPaint(Form.Handle, &lpPaintStruct);
      break;
    }
    The graphics constructor:
    Code:
    graphics(HDC hdc, RECT* invalRect)
        {
          this->invalLocation= *invalRect;
          this->hdc= hdc;
          this->memDC= ::CreateCompatibleDC(hdc);
          this->hMemBmp= ::CreateCompatibleBitmap(hdc, invalLocation.right-invalLocation.left, invalLocation.bottom-invalLocation.top);
          ::SelectObject(memDC, hMemBmp);
        }
    The constructor code is used for double buffing.
    The issue with doing it this way is that I have to call Show() to blit the memDC to the screen.

    I tried putting the Show() code in the destructor but by that time blitting fails because the members are NULL.

    Is there any way my graphics class can automatically know when Painting is finished?

    Note: the only reason I am asking this is because that is the way C# works. Everything is automatically buffed and sent to the screen.

  2. #2
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Actually no members should be NULL or anything the like in the destructor unless you set them to it first. C++ is explicit about the order of destruction, and it's the reverse of construction order: first the class itself, then contained classes and finally subclasses.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  3. #3

    Thread Starter
    Frenzied Member aewarnick's Avatar
    Join Date
    Dec 2002
    Posts
    1,037
    I don't think I explained things well enough. Here is the graphics class (the beginning, that is):
    Code:
    class graphics
    {
        HWND hwnd;
        HDC hdc;
        RECT invalLocation;
        HBITMAP hMemBmp;
        public:
        HDC memDC;
        graphics(){}
        graphics(HWND hwnd, HDC hdc, RECT* invalRect)
        {
        this->hwnd= hwnd;
        this->invalLocation= *invalRect;
        this->hdc= hdc;
        this->memDC= ::CreateCompatibleDC(hdc);
        this->hMemBmp= ::CreateCompatibleBitmap(hdc, invalLocation.right-invalLocation.left, invalLocation.bottom-invalLocation.top);
        ::SelectObject(memDC, hMemBmp);
        }
        ~graphics()
        {
        ::DeleteObject(hMemBmp);
        ::DeleteDC(hdc);
        ::DeleteDC(memDC);
        }
        inline void Show()
        {
        ::BitBlt(hdc, invalLocation.left, invalLocation.top, invalLocation.right-invalLocation.left, invalLocation.bottom-invalLocation.top, memDC, invalLocation.left, invalLocation.top, SRCCOPY);
        }
    Before I had the BitBlt in Show in the destructor, but when from there I could not blit. I checked for instance the memDC member like this:
    if(memDC==NULL)
    Messagebox();......
    The messagebox showed.
    I do the same thing with the code in Show and everything works fine.

  4. #4
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    But then the DeleteDC call would somehow have to fail too. And various other stuff too...

    Weird.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  5. #5

    Thread Starter
    Frenzied Member aewarnick's Avatar
    Join Date
    Dec 2002
    Posts
    1,037
    No error was produced that gave me a messsagebox when I called the cleanup functions. I never tested what the ruturn values were though. Should there have been a noticable error?

  6. #6
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    No, they usually silently fail, giving only a return value for indication.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  7. #7

    Thread Starter
    Frenzied Member aewarnick's Avatar
    Join Date
    Dec 2002
    Posts
    1,037
    Ok, got it. I had to explicitly call the destructor. Because by the time it was called the block had passed EndPaint. Thanks CornedBee.

  8. #8
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Maybe you should instead place a block within the BeginPaint/EndPaint calls.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  9. #9

    Thread Starter
    Frenzied Member aewarnick's Avatar
    Join Date
    Dec 2002
    Posts
    1,037
    I'm not sure what you mean by that, CornedBee. Here is the code I have
    Code:
    case WM_PAINT:
    {
      PAINTSTRUCT lpPaintStruct;
      HDC hdc= ::BeginPaint(Form.Handle, &lpPaintStruct);
      a::graphics g(Form.Handle, hdc, &lpPaintStruct.rcPaint);
      HBRUSH brush= ::CreateSolidBrush(RGB(255,0,0));
      ::FillRect(g.memDC, &lpPaintStruct.rcPaint, brush/*(HBRUSH)::GetStockObject(LTGRAY_BRUSH)*/);
      ::DeleteObject(brush);
      g.DrawImage(&abmp, &lpPaintStruct.rcPaint);
      g.DrawImage(&abmp, &drawRect,true);
      g.~graphics();
      ::EndPaint(Form.Handle, &lpPaintStruct);
      break;
    }

  10. #10
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Code:
    case WM_PAINT:
    {
      PAINTSTRUCT lpPaintStruct;
      HDC hdc= ::BeginPaint(Form.Handle, &lpPaintStruct);
      { // Anonymous block for the destructor
        a::graphics g(Form.Handle, hdc, &lpPaintStruct.rcPaint);
        HBRUSH brush= ::CreateSolidBrush(RGB(255,0,0));
        ::FillRect(g.memDC, &lpPaintStruct.rcPaint, brush/*(HBRUSH)::GetStockObject(LTGRAY_BRUSH)*/);
        ::DeleteObject(brush);
        g.DrawImage(&abmp, &lpPaintStruct.rcPaint);
        g.DrawImage(&abmp, &drawRect,true);
      } // Destructor called here
      ::EndPaint(Form.Handle, &lpPaintStruct);
      break;
    }
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  11. #11

    Thread Starter
    Frenzied Member aewarnick's Avatar
    Join Date
    Dec 2002
    Posts
    1,037
    Oh, sort of like an organizational block. I see.

Posting Permissions

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



Click Here to Expand Forum to Full Width