Thread: autoredraw

  1. #16
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Hard to tell without code. Too many options.

    Post your OnPaint() handler as I think this is where the solution lies.


    I suggest you look at DC's.
    DC = Device Context. (MFC class CDC)
    A DC contains a bitmap and the current font, brush, pen ect. The bitmap will retain the last image until you 'draw' on it.
    You can dynamically create DC's and their contents (bmp, font ect). Using SelectObject() you 'push' the old object out (with the newly created one).

    GetDC()
    CreateCompatibleDC()
    CreateCompatibleBitmap()
    ReleaseDC()
    DeleteDC()
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  2. #17
    Registered User
    Join Date
    Dec 2004
    Posts
    103
    well here is my paint code anyway
    Code:
    void CblaDlg::OnPaint() 
    {
    	if (IsIconic())
    	{
    		CPaintDC dc(this); // device context for painting
    
    		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
    
    		// Center icon in client rectangle
    		int cxIcon = GetSystemMetrics(SM_CXICON);
    		int cyIcon = GetSystemMetrics(SM_CYICON);
    		CRect rect;
    		GetClientRect(&rect);
    		int x = (rect.Width() - cxIcon + 1) / 2;
    		int y = (rect.Height() - cyIcon + 1) / 2;
    
    		// Draw the icon
    		dc.DrawIcon(x, y, m_hIcon);
    	}
    	CPaintDC dc(this);
    	CBitmap Bitmap;
    	CDC MemDC;
    
    	Bitmap.LoadBitmap(IDB_BITMAP1);
    	MemDC.CreateCompatibleDC(&dc);
    	MemDC.SelectObject(&Bitmap);
    
    	//Draw sides
    	dc.StretchBlt(16,0,m_CX-32,16,&MemDC,16,0,16,16,SRCCOPY);
    	dc.StretchBlt(0,16,16,m_CY-32,&MemDC,0,16,16,16,SRCCOPY);
    	dc.StretchBlt(m_CX-16,16,16,m_CY-32,&MemDC,32,16,16,16,SRCCOPY);
    	dc.StretchBlt(16,m_CY-16,m_CX-32,16,&MemDC,16,32,16,16,SRCCOPY);
    
    	//Draw corners
    	dc.StretchBlt(0,0,16,16,&MemDC,0,0,16,16,SRCCOPY);
    	dc.StretchBlt(m_CX-16,0,16,16,&MemDC,32,0,16,16,SRCCOPY);
    	dc.StretchBlt(0,m_CY-16,16,16,&MemDC,0,32,16,16,SRCCOPY);
    	dc.StretchBlt(m_CX-16,m_CY-16,16,16,&MemDC,32,32,16,16,SRCCOPY);
    
    	//Draw center
    	dc.StretchBlt(16,16,m_CX-32,m_CY-32,&MemDC,16,16,16,16,SRCCOPY);
    	MemDC.DeleteDC();
    	Bitmap.DeleteObject();
    }
    hope you can understand what it does

    ah btw m_CY is the dlg window height and m_CX is the dlg window width i got these in the onsize event is there a way to get them like in visual basic if you know Me.width Me.height i dunno how to get this in c++ im just starting to learn it
    Last edited by eXistenZ; 12-07-2004 at 07:24 AM.

  3. #18
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    OK, some code.....

    I'm not surprised thats slow! StretchBlt() is terrible, avoid its use. Better to draw to a full screen sized BMP then stretch back to the current size.

    For what you want this will come close. I suggest you look at CDC's MoveTo(), LineTo, CreatePatternBrush(). Also LoadImage()
    try

    Code:
    CBrush              BlackBrush,GreenBrush;
    CRect                Rect;
    CPaintDC          dc(this); // device context for painting
    
    //find where to draw
    GetUpdateRect(&Rect,0);
    if(IsRectEmpty(&Rect))
         GetClientRect(&Rect);
    
    //create the brushes
    BlackBrush.CreateSolidBrush(RGB(0,0,0));
    GreenBrush.CreateSolidBrush(RGB(0,255,0));
    //erase background and fill with green
    dc.FillRect(Rect,&GreenBrush);
    //draw black edge
    dc.FrameRect(Rect,&BlackBrush);
    
    //clean up
    //not selected into a DC so can just delete
    BlackBrush.DeleteObject();
    GreenBrush.DeleteObject();
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  4. #19
    Registered User
    Join Date
    Dec 2004
    Posts
    103
    i guess those are for creating the background by code but i really need to resize the 48x48 bmp file so users can change it and make their own i know strechblt isn't that fast but it works good on good video cards like nvidia and ati if you have another idea to resize a 48x48 bmp file without it losing its quality the center is pure color just some borders to resize check out the image
    thx

  5. #20
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Resize the image once after loading and hold it in memory. That suffices.

    As for resizing this kind of image, take the center vertical and horizontal rows and duplicated them as necessary.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #21
    Registered User
    Join Date
    Dec 2004
    Posts
    103
    yeah you're right i should load it only once but anyway if strechblt is so slow is there another better function i could use ?

  7. #22
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    No, StretchBlt is the only resizing blitting function Windows has. You could write your own, but it wouldn't be faster. StretchBlt is fast at what it does, but what it does is slow by nature.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  8. #23
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    OK, to use StretchBlt(), but IMHO not OK to use it in a paint handler more than once.

    Break the drawing into smaller parts. One DC for the frame and one DC for the text.
    When the app inits create a compatible DC and compatible bmp (to the max screen size) then draw the 'frame' on it. When you need the frame 'stretch' this DC to the paint one.

    Same for the text.

    Return them to default and delete them when the app closes.

    This will not be 100% as StretchBlt() works best when the two sizes are int multiples of one another ie 320x240 -> 640x480

    Look at 'double buffering', you WILL need it to get the best results. Particularly if the update area is not the entire client area.

    or

    Load the bmp and use it to create a pattern brush.

    or

    Use two different green pens / brushes.
    Draw the dark green, then the light edges.

    EDIT:
    Depending on the version of MSVC (pre .NET).

    You CAN NOT delete a bmp that is currently selected into a DC. A DC MAY not delete if it contains non default GDI objects. That is you must put the DC back the way you created / got it.

    Code:
    HBITMAP    hOldBmp = SelectObject(hdc, hNewBmp);
    //use
    
    //set back to default GDI objects
    SelectObject(hdc, hOldBmp);
    //now can delete the BMP and hdc.
    In the task manager you can watch the count of GDI objects your app is using. Watch for leaks.
    Last edited by novacain; 12-07-2004 at 10:40 PM.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  9. #24
    Registered User
    Join Date
    Dec 2004
    Posts
    103
    lol thx alot guys i just gotta put all of this together

Popular pages Recent additions subscribe to a feed