#1
  1. not a fan of fascism (n00b)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Feb 2003
    Location
    ct
    Posts
    2,756
    Rep Power
    95

    win32 screensaver


    i have a screen saver that "bounces" an image around teh screen. currently, as it moves the area behind it doesn get redrawn so it leaves a trail behind it. All i want is for the screen to be painted black each WM_PAINT, and then to move the image over. what's the easiest wayto do this w/o flicker?
    Last edited by infamous41md; June 30th, 2003 at 11:16 PM.
  2. #2
  3. No Profile Picture
    Offensive Member
    Devshed Novice (500 - 999 posts)

    Join Date
    Oct 2002
    Location
    in the perfect world
    Posts
    622
    Rep Power
    28
    Try

    Code:
    BitBlt(hdcScreen,  0,  0,  iWidth, iHeight, hdcScreen, 0, 0, BLACKNESS);
    The essence of Christianity is told us in the Garden of Eden history. The fruit that was forbidden was on the Tree of Knowledge. The subtext is, All the suffering you have is because you wanted to find out what was going on. You could be in the Garden of Eden if you had just kept your f***ing mouth shut and hadn't asked any questions.

    Frank Zappa
  4. #3
  5. not a fan of fascism (n00b)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Feb 2003
    Location
    ct
    Posts
    2,756
    Rep Power
    95
    thanks, that was a much easier solution than the crazy hack i was running... i have a new problem now, i thought that by drawing the whole screen into a temp HDC and then BitBlt()'ing that whole completed HDC onto my screen's HDC i would be making the animation smoother. but instead its choppier, here is my code:
    btw the refresh rate is 20 frms/second and i offset the bmp +3 x/y each time
    Code:
    case WM_PAINT:
    		
    		hDC = BeginPaint(hWnd, &ps);
    
    		// prepare to draw in memory
    		hdcBuffer = CreateCompatibleDC(hDC);
    		hbmBuffer = CreateCompatibleBitmap(hDC, xpos, ypos);
    		hbmOldBuffer = (HBITMAP) SelectObject(hdcBuffer, hbmBuffer);
    		hdcMem = CreateCompatibleDC(hDC);
    		hbmOld = (HBITMAP )SelectObject(hdcMem, my_pic.logo);
    		GetObject(my_pic.logo, sizeof(bm), &bm);
    
    		// draw in memory
    		BitBlt(hdcBuffer,  0,  0,  xpos, ypos, hdcMem, 0, 0, BLACKNESS);
    		BitBlt(hdcBuffer, my_pic.x1, my_pic.y1, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
    
    		// determine if this is a preview or real thing
    		if(fChildPreview)
    		{
    			SetBkColor(hdcBuffer, RGB(0, 0, 0));
    			SetTextColor(hdcBuffer, RGB(255, 255, 0));
    			TextOut(hdcBuffer, 25, 45, "preview", strlen("preview"));
    		}
    		else
    		{
    			SetBkColor(hdcBuffer, RGB(0, 0, 0));
    			SetTextColor(hdcBuffer, RGB(120, 120, 120));
    			TextOut(hdcBuffer, 0, ypos - 40, PROGRAM, strlen(PROGRAM));
    			TextOut(hdcBuffer, 0, ypos - 25, AUTHOR, strlen(AUTHOR));
    		}
    
    		//draw on the screen
    		BitBlt(hDC, 0, 0, xpos, ypos, hdcBuffer, 0, 0, SRCCOPY);
    
    		// cleanup
    		SelectObject(hdcBuffer, hbmOldBuffer);
    		SelectObject(hdcMem, hbmOld);
    		
    		DeleteDC(hdcMem);
    		DeleteDC(hdcBuffer);
    		DeleteObject(hbmBuffer);
    		DeleteObject(hbmOldBuffer);
    		DeleteObject(hbmOld);
    
    		EndPaint(hWnd, &ps);
    		break;
    Last edited by infamous41md; July 1st, 2003 at 01:58 PM.
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Oct 2000
    Location
    Back in the real world.
    Posts
    5,966
    Rep Power
    191
    I think you should not create the dc, bitmap and select and so on on each frame. Instead do it at the beginning of the program and destroy them at the end. Probably this steals your time. Ressource allocation is always expensive.
  8. #5
  9. not a fan of fascism (n00b)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Feb 2003
    Location
    ct
    Posts
    2,756
    Rep Power
    95
    i tried doing what you said, but perhaps i am doing it wrong? the logo doesnt move now, it just stays in the same place. here is the code:
    Code:
    switch(message)
    	{
    	case WM_CREATE:
    		my_pic.logo = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_CED_LOGO));
    		my_pic.x1 = 200; my_pic.y1 = 100;
    
    		hBrush = CreateSolidBrush(RGB(0, 0, 0));
    		uTimer = SetTimer(hWnd, ID_TIMER, TIMEOUT, NULL);
    
    		// prepare to draw in memory
    		hDC = GetDC(hWnd);
    		hdcBuffer = CreateCompatibleDC(hDC);
    		hbmBuffer = CreateCompatibleBitmap(hDC, xpos, ypos);
    		hdcMem = CreateCompatibleDC(hDC);
    		
    		break;
    		
        case WM_DESTROY:
    		if(uTimer)
    			KillTimer(hWnd, uTimer);
    
    		if(hBrush)
    			DeleteObject(hBrush);
    
    		ReleaseDC(hWnd, hDC);
    		// cleanup
    		SelectObject(hdcBuffer, hbmOldBuffer);
    		SelectObject(hdcMem, hbmOld);
    		
    		DeleteDC(hdcMem);
    		DeleteDC(hdcBuffer);
    		DeleteObject(hbmBuffer);
    		DeleteObject(hbmOldBuffer);
    		DeleteObject(hbmOld);
    
    		PostQuitMessage(0);
    		break;
    
    	case WM_TIMER:
    		//check for top bounc
    		if(my_pic.y1 < 10)
    			y_dir = 1;
    
    		//check for bottom bounce
    		if((my_pic.y1 + bm.bmHeight ) > (ypos - 10))
    			y_dir = -1;
    
    		//check for left bounce
    		if( my_pic.x1 < 10)
    			x_dir = 1;
    
    		//check for right bounce
    		if( (my_pic.x1 + bm.bmWidth ) > (xpos - 10))
    			x_dir = -1;
    
    		my_pic.x1 += x_dir;
    		my_pic.y1 += y_dir;
    
    		InvalidateRect(hWnd, 0, 0);
    
    		break;
    
    	case WM_PAINT:
    //		hDC = BeginPaint(hWnd, &ps);
    
    		hbmOldBuffer = (HBITMAP) SelectObject(hdcBuffer, hbmBuffer);
    		hbmOld = (HBITMAP )SelectObject(hdcMem, my_pic.logo);
    		GetObject(my_pic.logo, sizeof(bm), &bm);
    
    		// draw in memory
    		BitBlt(hdcBuffer,  0,  0,  xpos, ypos, hdcMem, 0, 0, BLACKNESS);
    		BitBlt(hdcBuffer, my_pic.x1, my_pic.y1, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
    
    		// determine if this is a preview or real thing
    		if(fChildPreview)
    		{
    			SetBkColor(hdcBuffer, RGB(0, 0, 0));
    			SetTextColor(hdcBuffer, RGB(255, 255, 0));
    			TextOut(hdcBuffer, 25, 45, "preview", strlen("preview"));
    		}
    		else
    		{
    			SetBkColor(hdcBuffer, RGB(0, 0, 0));
    			SetTextColor(hdcBuffer, RGB(120, 120, 120));
    			TextOut(hdcBuffer, 0, ypos - 40, PROGRAM, strlen(PROGRAM));
    			TextOut(hdcBuffer, 0, ypos - 25, AUTHOR, strlen(AUTHOR));
    		}
    		//draw on the screen
    		BitBlt(hDC, 0, 0, xpos, ypos, hdcBuffer, 0, 0, SRCCOPY);
    
    //		EndPaint(hWnd, &ps);
    		break;
    
        default: 
    		return DefScreenSaverProc(hWnd, message, wParam, lParam);
    	}
    	
    	return 0;
    }
    Last edited by infamous41md; July 1st, 2003 at 10:52 PM.
  10. #6
  11. No Profile Picture
    Offensive Member
    Devshed Novice (500 - 999 posts)

    Join Date
    Oct 2002
    Location
    in the perfect world
    Posts
    622
    Rep Power
    28
    You are selecting in the bmp over and over again. This is a problem as you will loose the original BMP.

    Are the variables all static in the callback?

    All painting to the HDC's should have been compleated BEFORE the app calls for a WM_PAINT.
    The area that needs repainting should be determined before a call to BeginPaint() with GetUpdateRect() . Only this rect should then be repainted to increase speed.

    Remember that other events (like a messagebox appearing) can make the OS call for a paint.

    this is my standard paint function. The hdc is assembled from many smaller ones. If a paint msg arrives while the app is redrawing the screen it redraws the last frame. When the new frame is assemble it is Blited to the screen buffer and I call InvalidateRect() with the area redrawn.

    Code:
    void	RepaintDlg(HWND hWnd, HDC hdcScreen)
    {
    	RECT		theRect;
    	PAINTSTRUCT	ps;
    
    	GetUpdateRect(hwnd, &theRect, 0);
    	if (IsRectEmpty(&theRect))
    	{
    		GetClientRect(hwnd,&theRect);
    	}
    	BeginPaint(hwnd, &ps);
    	BitBlt(ps.hdc, theRect.left, theRect.top, theRect.right - theRect.left, theRect.bottom - theRect.top, hdcScreen, theRect.left, theRect.top, SRCCOPY);
    	EndPaint(hwnd, &ps);
    }
    The essence of Christianity is told us in the Garden of Eden history. The fruit that was forbidden was on the Tree of Knowledge. The subtext is, All the suffering you have is because you wanted to find out what was going on. You could be in the Garden of Eden if you had just kept your f***ing mouth shut and hadn't asked any questions.

    Frank Zappa

IMN logo majestic logo threadwatch logo seochat tools logo