Click here to Skip to main content
15,880,608 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I try to use a method to save the DC, so that it only needs to call drawfun once when it is created, and directly recover from the memory DC at other times
C++
int dystate = 1;
	void CreatePanelDynamic(HWND h, HDC hdc, DRAWPANEL DrawFun, int Flag = 0)
	{

		//On hMemDC.
		if (PanelID == PrevPanelID)
		{
			if (dystate == 0)
			{ 
				//BitBlt
				RECT rc;
				GetClientRect(h, &rc);
				HDC         hMemDC;
				HBITMAP     hBmpMem;
				HBITMAP     hPreBmp;

				hMemDC = CreateCompatibleDC(hdc);

				hBmpMem = CreateCompatibleBitmap(hdc, rc.right - rc.left, rc.bottom - rc.top);

				hPreBmp = (HBITMAP)SelectObject(hMemDC, hBmpMem);
				//On hMemDC.
				
				BitBlt(hMemDC, 0, 0, rc.right - rc.left, rc.bottom - rc.top, inhdc, 0, 0, SRCCOPY);
				BitBlt(hdc, 0, 0, rc.right - rc.left, rc.bottom - rc.top, hMemDC, 0, 0, SRCCOPY);


				SelectObject(hMemDC, hPreBmp);


				DeleteObject(hBmpMem);

				DeleteDC(hMemDC);
			}
			if (dystate == 1) //First time
			{

				HBITMAP     hBmpMem;
				HBITMAP     hPreBmp;
				RECT rc;
				GetClientRect(h, &rc);
				inhdc = CreateCompatibleDC(hdc);

				hBmpMem = CreateCompatibleBitmap(hdc, rc.right - rc.left, rc.bottom - rc.top);

				hPreBmp = (HBITMAP)SelectObject(inhdc, hBmpMem);
				//On hMemDC.
				DrawFun(h, inhdc);//Draw something there

				BitBlt(hdc, 0, 0, rc.right - rc.left, rc.bottom - rc.top, inhdc, 0, 0, SRCCOPY);


				SelectObject(inhdc, hPreBmp);


				DeleteObject(hBmpMem);
				//gindc = SaveDC(inhdc);
				//DeleteDC(hMemDC);
				dystate = 0;
			}
			anistat = 0;
		}
}

But the fact is that except for the first time, when dystate = 0, the whole window turns black and nothing is drawn.
What is the problem and how to solve it? thank you.

What I have tried:

Does it needs to store a HBITMAP?I don't know.
Posted
Updated 21-Nov-21 6:49am

When dystate == 1 (first time), you do the drawing into inhdc, and then blit it to the Window DC. But then before you leave, you do this:
C++
SelectObject(inhdc, hPreBmp);

thus losing the BitMap that contains the drawing. Then when you come back and dystate == 0, your BitBlt code will be copying a black screen. Also you should not need to blit from inhdc to a memory DC, but should be able to copy direct to the Window.
 
Share this answer
 
Richard is correct.

Here's a memory DC class I use. It was adapted from one I found here written by Keith Rule a long time ago but this does not use MFC.
C++
class CMemoryDC
{
    private:
        HBITMAP     m_hbitmap;
        HBITMAP     m_holdbmp;
        HDC         m_hDC;
        HDC         m_holdDC;
        RECT        m_rBounds;
        int         m_Width;
        int         m_Height;

    public:
        CMemoryDC( HDC hDC, const RECT *rBounds )
        {
            m_holdDC = hDC;
            m_hDC = CreateCompatibleDC( hDC );
            memcpy( &m_rBounds, rBounds, sizeof( RECT ) );
            m_Width = m_rBounds.right - m_rBounds.left;
            m_Height = m_rBounds.bottom - m_rBounds.top;
            m_hbitmap = CreateCompatibleBitmap( hDC, m_Width, m_Height );
            m_holdbmp = (HBITMAP)SelectObject( m_hDC, m_hbitmap );
        }

        ~CMemoryDC()
        {
            BitBlt( m_holdDC, m_rBounds.left, m_rBounds.top, m_Width, m_Height,
                        m_hDC, m_rBounds.left, m_rBounds.top, SRCCOPY );
            SelectObject( m_holdDC, m_holdbmp );
            if( m_hbitmap != NULL ) DeleteObject( m_hbitmap );
            if( m_hDC != NULL ) DeleteDC( m_hDC );
        }

        HDC GetDC()         { return m_hDC; }

        HDC	operator->()    { return m_hDC; }
};
You can use an instance of this class as the DC to draw to. Your code can then become this :
C++
{
    RECT rc;
    GetClientRect( hdc, & rc );
    CMemoryDC memdc( hdc, & rc );

    DrawFun( memdc );   // Draw something there

    dystate = 0;
}
 
Share this answer
 
You need to debug your code because the dystate flag isnt correctly set in the other loop. Try an else or switch for better control.

For optimizing draw code double buffering is best. Read this article Flicker Free Text Scrolling with Double Buffering to understand its basics.

It is always best to store stable data instead of creating and computing it again and again. But important is some check that there isnt a change happen.
 
Share this answer
 
Comments
EnderMo233 21-Nov-21 5:23am    
After debugging, this has nothing to do with the value of dystate, but the value of inhdc is not saved, so the interface is black
EnderMo233 21-Nov-21 7:55am    
store stable data,That's what I want.
but when I try to display it,it is all black.
EnderMo233 21-Nov-21 8:19am    
SelectObject(inhdc, hPreBmp);
When I delected this,it works.but why?Can you answer it?thank you

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900