c++ win32 program nie zmienia wczytanej bitmapy an inną. Invalidate/RedrawWindow/UpdateWindow

0

zadaniem programu to naprzemienne zmienianie 3 bitmap i rysowanie ich w tym samym okienku
jednak program tylko wczytuje bitmapę i jej już nie zmienia, w tej formie jaka jest tu podana nie przechodzi dalej niż do

ShowWindow(hOkno, SW_SHOW );

na linijce 115







	//#include "stdafx.h"
	//#include "GDIWin32.h"
    #include <windows.h>
	#include <windowsx.h>  // include useful macros
    //#include <stdlib.h>
	#include <cstdlib> // for srand, rand
	//#include <time.h> 
	#include <ctime>   // for time
	#include <string.h>
	#include <tchar.h>
    #include <CommCtrl.h>
	#include <sstream>



	// Window client size
	const int width = 375;
	const int height = 375;
	const int fps = 4;
	const WORD ID_TIMER = 1;

	HINSTANCE* hInst;//globalny wskaźnik na uchwyt naszego programu
// FUNCTIONS ////////////////////////////////////////////////////////////
	void GameMain(HWND hWnd);


	LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );

// WINMAIN ////////////////////////////////////////////////
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpsCmdLine, int nShowCmd)
{
	//uchwyt okna
    HWND hOkno;
	hInst=&hInstance;//pobieramy uchwyt programu do globalnego wskaźnika	 
	WNDCLASSEX okno1;
	MSG message;
/////////////////////////////////////
	// Init okno1
	okno1.cbClsExtra = 0;
	okno1.cbWndExtra = 0;
	okno1.cbSize = sizeof( WNDCLASSEX );
	okno1.hbrBackground = CreateSolidBrush( 0 );
	//czarny kolor
    //okno7890.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
	okno1.hCursor = LoadCursor( NULL, IDC_ARROW );
	okno1.hIcon = LoadIcon( NULL, IDI_APPLICATION );
	okno1.hIconSm = LoadIcon( NULL, IDI_APPLICATION );
	//okno1.hInstance = hInstance;
	okno1.hInstance = *hInst;//uchwyt programu do globalnego wskaźnika
	okno1.lpfnWndProc = WndProc;
	okno1.lpszClassName = _T("animation_class01");
	//okno1.lpszClassName = L"animation_class";
	okno1.lpszMenuName = NULL;
	okno1.style = 0;
	
	// Register okno1
	if ( !RegisterClassEx(&okno1) )
	{
	MessageBox( NULL, L"Failed to register window class.01", L"Error01", MB_OK );
	return 0;
	}
/////////////////////////////////////
	// Make window
	 hOkno = CreateWindowEx(
			WS_EX_APPWINDOW,
			L"animation_class01",
			L"Animation",
			WS_MINIMIZEBOX | WS_SYSMENU | WS_POPUP | WS_CAPTION,
			300, 200, width, height,
			NULL, NULL, hInstance, NULL );
	 if( hOkno == NULL )
    {
        MessageBox( NULL, _T("Okno odmówiło przyjścia na świat!"), _T("Error02"), MB_ICONEXCLAMATION );
        return 1;
    }
/////////////////////////////////////
	RECT rcClient, rcWindow;
	POINT ptDiff;
	ZeroMemory(&rcClient, sizeof(RECT));
	// Get window and client sizes
	GetClientRect( hOkno, &rcClient );
	GetWindowRect( hOkno, &rcWindow );
	// Find offset between window size and client size
	ptDiff.x = (rcWindow.right - rcWindow.left) - rcClient.right;
	ptDiff.y = (rcWindow.bottom - rcWindow.top) - rcClient.bottom;
	// Resize client
	MoveWindow( hOkno, rcWindow.left, rcWindow.top, width + ptDiff.x, height + ptDiff.y, false);
/////////////////////////////////////
	// Milliseconds to wait each frame
	Sleep( 400 );
	//ShowWindow(hOkno, SW_SHOW );
	//InvalidateRect(hOkno, 0, TRUE);
	//UpdateWindow( hOkno );
	//RedrawWindow(hOkno,0,0,RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE );
	//SendMessage(hOkno, WM_PAINT, 0, 0);
	//PostMessage(hOkno, WM_PAINT, 0, 0);//
/////////////////////////////////////	
	while(TRUE)
    {	
		//while( GetMessage( & message, NULL, 0, 0 ) )
		// is there a message in queue, if so get it
		if (PeekMessage(&message,NULL,0,0,PM_REMOVE))
		{
			// test if this is a quit
			if (message.message == WM_QUIT) break;
			TranslateMessage( & message );
			DispatchMessage( & message );
		}  
	////////////////////////

		///source code here: 	
		ShowWindow(hOkno, SW_SHOW );

		srand((unsigned) time(NULL));
		int flaga1=rand()%300+240;	
		Sleep(flaga1);
		GameMain(hOkno);  // game main processing function called here

		UpdateWindow( hOkno );


		//MessageBox( hOkno, _T("Nie można utworzyć timera!"), _T("Error06"), MB_ICONSTOP );
		//ShowWindow(hOkno, SW_SHOW );
		//MessageBox( hOkno, _T("Nie można utworzyć timera!"), _T("Error07"), MB_ICONSTOP );
		//InvalidateRect(hOkno, &rcClient, TRUE);

		if( SetTimer( hOkno, ID_TIMER, 1200, NULL ) == 0 )
		MessageBox( hOkno, _T("Nie można utworzyć timera!"), _T("Error03"), MB_ICONSTOP );

	}

    return message.wParam;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

// OBSŁUGA ZDARZEŃ
// WINPROC /////////////////////////////////////////////////////////////
LRESULT CALLBACK WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{ 
	HDC hdcBitmapy;//zmienne na 2 konteksty
	//  Windows/Drawing variables
 	HBITMAP bitmapa;//uchwyt naszej bitmapy
	BITMAP info_bitmapy;//struktura inforamcyjna bitmapy

	//LPCREATESTRUCT lpCreate = (LPCREATESTRUCT)lParam;

    switch( msg )
    {
	case WM_CREATE:    
        //funkcja tworząca kontrolkę
		HWND hButton;
		hButton=CreateWindowEx(0,WC_BUTTON,_T("Przycisk"),WS_CHILD|WS_VISIBLE,20,20,200,70,hWnd,(HMENU)1,*hInst,0);
		 break;
    case WM_COMMAND:
        if(wParam==1) MessageBox(hWnd,_T("Przycisk naciśnięty"),_T(":>"),MB_OK);     
		//jeżeli został naciśnięty przycisk o identyfikatorze numer 1 wyświetli się komunikat  
		break;
    case WM_DESTROY:
		KillTimer( hWnd, ID_TIMER );
		DestroyWindow(hButton);
        PostQuitMessage( 0 );
        break;
	case WM_CLOSE:
		{
		DestroyWindow(hWnd);
		}
		break;	
    case WM_PAINT: 
		{ 
		MessageBox(HWND_DESKTOP,_T("Treść komunikatu125"),_T("Tytuł komunikatu125"),MB_OK);//Komunikat okienkowy
		PAINTSTRUCT ps;
		HDC hdc = BeginPaint( hWnd, &ps );
		//wczytywanie bitmapy z dysku i pobranie informacji
		int flaga1=1;
		if(flaga1==1)
		{
		bitmapa= (HBITMAP)LoadImage(GetModuleHandle(NULL), L"e:\\1test_1\\sample1.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
		}
		else if(flaga1==2)
		{
		bitmapa= (HBITMAP)LoadImage(GetModuleHandle(NULL), L"e:\\1test_1\\sample2.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
		}
		else if(flaga1==3)
		{
		bitmapa= (HBITMAP)LoadImage(GetModuleHandle(NULL), L"e:\\1test_1\\sample3.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
		}
		else{}

		_TCHAR szBuffer[100];
		_stprintf(szBuffer, _T("bitmapa= %i ..."), bitmapa);
			//std::ostringstream sout;//sout<<liczba;
		//hBitmap = (HBITMAP)LoadImage(hInst, L"c:\\test.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
		if(bitmapa==0)
		{ 
		MessageBox(0,szBuffer,_T("Brak pliku"),MB_ICONSTOP);
		return 0;//zamkniecie programu w razie braku pliku bitmapy
		}
		GetObject(bitmapa,sizeof(BITMAP),&info_bitmapy);//pobieramy informacje o bitmapie, potrzebujemy jej wymiarów
		//InvalidateRect ();
		hdcBitmapy=CreateCompatibleDC(hdc);
		//teraz musimy utworzyć kontekst pamięciowy dla bitmapy
		//bitmapa=(HBITMAP)SelectObject(hdcBitmapy,bitmapa);//zamieniamy konteksty wiążąc bitmapę z kontekstem
		SelectObject(hdcBitmapy,bitmapa);
		BitBlt( hdc, 0, 0, width, height, hdcBitmapy, 0, 0, SRCCOPY );
		//BitBlt(hdc,0,0,info_bitmapy.bmWidth,info_bitmapy.bmHeight,hdcBitmapy,0,0,SRCCOPY);

		//bitmapa=(HBITMAP)SelectObject(hdcBitmapy,bitmapa);//z powrotem zamieniamy bitmapy w kontekście
		DeleteDC(hdcBitmapy);//usuwamy kontekst pamięciowy bitmapy
		DeleteObject(bitmapa);
		EndPaint(hWnd,&ps);

		//ShowWindow(hWnd, SW_SHOW );
		//UpdateWindow(hWnd);
		}
		break;	

		case WM_TIMER:
			{

			}
		break;	
    default:
		//MessageBox(HWND_DESKTOP,_T("Treść komunikatu99"),_T("Tytuł komunikatu99"),MB_OK);//Komunikat okienkowy
        return DefWindowProc( hWnd, msg, wParam, lParam );
    }
   
    return 0;
}


void GameMain(HWND hWnd)
{	
	HDC hdcBitmapy;//zmienne na 2 konteksty
	//  Windows/Drawing variables
 	HBITMAP bitmapa;//uchwyt naszej bitmapy
	BITMAP info_bitmapy;//struktura inforamcyjna bitmapy

	srand((unsigned) time(NULL));
	int flaga1=rand()%3+1;
	TCHAR szBuffer2[100];
	_stprintf(szBuffer2, _T("flaga1= %i ...!!!0980!!"), flaga1);
	MessageBox(0,szBuffer2,_T("test random_002"),MB_ICONSTOP);	////

		Sleep( 400 );
	MessageBox(HWND_DESKTOP,_T("Treść komunikatu356"),_T("Tytuł komunikatu356"),MB_ICONSTOP);//Komunikat okienkowy
	HDC hdc = GetDC( hWnd );
	//wczytywanie bitmapy z dysku i pobranie informacji
		if(flaga1==1)
		{
		bitmapa= (HBITMAP)LoadImage(GetModuleHandle(NULL), L"e:\\1test_1\\sample1.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
		}
		else if(flaga1==2)
		{
		bitmapa= (HBITMAP)LoadImage(GetModuleHandle(NULL), L"e:\\1test_1\\sample2.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
		}
		else if(flaga1==3)
		{
		bitmapa= (HBITMAP)LoadImage(GetModuleHandle(NULL), L"e:\\1test_1\\sample3.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
		}
		else
		{
			MessageBox(0,szBuffer2,_T("test random_004"),MB_ICONSTOP);	
		}
	_TCHAR szBuffer[100];
	_stprintf(szBuffer, _T("bitmapa= %i ..."), bitmapa);
	//std::ostringstream sout;//sout<<liczba;
	//hBitmap = (HBITMAP)LoadImage(hInst, L"c:\\test.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
	if(bitmapa==0)
	{ 
	MessageBox(0,szBuffer,_T("Brak pliku"),MB_ICONSTOP);
	//return 0;//zamkniecie programu w razie braku pliku bitmapy
	}
	GetObject(bitmapa,sizeof(BITMAP),&info_bitmapy);//pobieramy informacje o bitmapie, potrzebujemy jej wymiarów
	hdcBitmapy=CreateCompatibleDC(hdc);
	//teraz musimy utworzyć kontekst pamięciowy dla bitmapy
	//bitmapa=(HBITMAP)SelectObject(hdcBitmapy,bitmapa);//zamieniamy konteksty wiążąc bitmapę z kontekstem
	SelectObject(hdcBitmapy,bitmapa);
	BitBlt( hdc, 0, 0, width, height, hdcBitmapy, 0, 0, SRCCOPY );
	ReleaseDC( hWnd, hdc );
	//bitmapa=(HBITMAP)SelectObject(hdcBitmapy,bitmapa);//z powrotem zamieniamy bitmapy w kontekście
	SelectObject(hdcBitmapy,bitmapa);
	DeleteDC(hdcBitmapy);//usuwamy kontekst pamięciowy bitmapy
	DeleteObject(bitmapa);
	//ShowWindow(hWnd, SW_SHOW );
	//UpdateWindow(hWnd);

} // END OF GameMain








 
0

Po 1 powinieneś te bitmapy wczytać raz i już tylko używać, po 2gie przerost formy nad treścią. Wywal cały kod dotyczący rysowania bitmap, zostaw sam kod podstawowego okna. Rysowanie WM_PAINT nie przyniesie Ci zamierzonego efektu, bo zakładam że chcesz aby bitmapy zmieniały się np co 3 s - komunikat WM_PAINT wysyłany jest za każdym razem kiedy okno trzeba odrysować od nowa tzn przy przesunięciu itd... WM_PAINT zostawiłbym w spokoju, ustaw sobie timer i tam odrysowuj bitmapy na okno główne. Hmm tylko WM_PAINT chyba zamaluje bitmapę(nie jestem pewny). Jeżeli tak będzie możesz też rysować bitmapy w WM_PAINT ze wskaźnika na HBITMAP, a w timerze co 3s przypisywać mu losowo adresy 3 różnych bitmap.

 
...
	case WM_PAINT:
		{

			HDC hdcBitmapy, hdc;
			PAINTSTRUCT ps;
			hdc = BeginPaint( hwnd, &ps );
			hdcBitmapy=CreateCompatibleDC(hdc);
			HBITMAP hdcStary=(HBITMAP)SelectObject(hdcBitmapy,bitmapa);
			BitBlt(hdc,0,0,info_bitmapy.bmWidth,info_bitmapy.bmHeight,hdcBitmapy,0,0,SRCCOPY);
			SelectObject(hdcBitmapy,hdcStary);
			DeleteDC(hdcBitmapy);
			ReleaseDC(hwnd, hdcBitmapy );
			EndPaint(hwnd,&ps);
		}
		break

...
0

program zaczął działać w pętli i odświeżać okienko po zablokowaniu:

     case WM_PAINT: 
		{ 
		//MessageBox(HWND_DESKTOP,_T("Treść komunikatu125"),_T("Tytuł komunikatu125"),MB_OK);//Komunikat okienkowy
		PAINTSTRUCT ps;

MessageBox w WM_PAINT

z tym że tera okno całe się zamalowuje na nowo razem z

hButton=CreateWindowEx(0,WC_BUTTON,_T("Przycisk"),WS_CHILD|WS_VISIBLE,20,20,200,70,hWnd,(HMENU)1,*hInst,0);

jednak w tym programie nie jest istotne dlatego że za zadanie ma tylko wyświetlać bitmapę podawaną jako screnschot pulpitu i robić z tego film

0

Dodaj do okna (hOkno) styl WS_CLIPCHILDREN to nie będzie zamalowywać okien-dzieci.

1 użytkowników online, w tym zalogowanych: 0, gości: 1