Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailem Win32 API - změna pozadí

Chtěl bych se zeptat jak je možné změnit barvu pozadí v okně v aplikaci Win32 API ?

Konkrétně při tvorbě instance okna:

int ColorR,ColorG,ColorB = 0; //rozsah mozny 0 ~ 255


WNDCLASSEX	wcex;	
wcex.hbrBackground = (HBRUSH)COLOR_WINDOW;
wcex.hbrBackground = CreateSolidBrush(RGB(ColorR,ColorG,ColorB));

Uvedena ukazka funguje pri prvotnim spusteni instance okna.
Pokud je pozdeji kdekoliv ve funkci pouzito:

ColorR=100;
ColorG=255;
ColorB=100;

InvalidateRect(hWnd, NULL, TRUE); // Prekresleni okna

Tak to samozrejme nefunguje....... :-D

Předmět Autor Datum
Musis pri WM_ERASEBACKGROUND (doufam, ze se tak ta zprava jmenuje) zajistit, aby se okno prekreslilo…
Jan Fiala 04.01.2007 17:29
Jan Fiala
Jo. :-) To bude ono. Ale nedari se mi najit priklad z kama by to slo pochopit (hotový)
Flash_Gordon 04.01.2007 17:46
Flash_Gordon
Najprv by si mal napisat ako ten program robis, mas vlastnu WindowProc alebo pouzivas nejaky "framew…
MM.. 04.01.2007 18:33
MM..
Samozrejme ze menit tie premenne po zavolani CreateSolidBrush (po vytvoreni triedy okna) je uz nanic…
MM.. 04.01.2007 18:28
MM..
Díky. Někdo se mě ptá a má to takto: HINSTANCE hInst; // current instance TCHAR szTitle[MAX_LOADSTR…
Flash_Gordon 04.01.2007 18:56
Flash_Gordon
case WM_MOUSEMOVE: if(wParam == MK_LBUTTON) { DrawMousePointer(hWnd,LOWORD(lParam), HIWORD(lParam));…
Flash_Gordon 04.01.2007 18:58
Flash_Gordon
... a konečně vytvoření instance okna atd..... Při volání funkcí: SetZelenou SetCervenou By se tak…
Flash_Gordon 04.01.2007 19:00
Flash_Gordon
Uz som pisal vyssie co treba robit, wcex.hbrBackground = NULL a potom musi zmenit MyWndProc, bud tam…
MM.. 04.01.2007 19:18
MM..
Dobré toho si nevšímej. Přesnější nápověda by nebyla ? Píšeš co změnit, ale ne jak to změnit. Když…
Flash_Gordon 04.01.2007 19:34
Flash_Gordon
Programovat za druhych sa mi fakt nechce. Na konkretnu otazku poradim, ale nie ze budem pisat kod za…
MM.. 04.01.2007 19:40
MM..
Máš pravdu. Těch pět řádků by bylo moc. :-D
Flash_Gordon 04.01.2007 19:45
Flash_Gordon
Nejde mi o 5riadkov ale ide mi o princip :-) (poradit vs. robit nieco za niekoho) Inac moze tam byt…
MM.. 04.01.2007 19:48
MM..
... například on tam má funkce void...
Flash_Gordon 04.01.2007 19:51
Flash_Gordon
co? Inac este jedna vec ktoru budes potrebovat: V tom case WM_ERASEBKGND: budes mat HDC v premenn… poslední
MM.. 04.01.2007 19:57
MM..

Najprv by si mal napisat ako ten program robis, mas vlastnu WindowProc alebo pouzivas nejaky "framework" (MFC apod).
Co na tom treba pochopit, zavesis sa na ten message a vykreslis obdlznik (PatBlt()) podla toho ktory obdlznik je invalidovany (GetClipBox()), pozri si MSDN.
P.S. a vratis nenulovu hodnotu.

P.S.2. inac aj google najde toho dost:
WM_ERASEBKGND sample

Samozrejme ze menit tie premenne po zavolani CreateSolidBrush (po vytvoreni triedy okna) je uz nanic, ani si nemusel robit tie premenne staci dat do toho RGB(...) konstanty.
BTW. naco tam mas wcex.hbrBackground = (HBRUSH)COLOR_WINDOW; ?

Ak to chces dynamicky menit tak napr. nastavit wcex.hbrBackground = NULL a pozadie si kreslit sam, bud spracovat message WM_ERASEBKGND, alebo vo WM_PAINT po BeginPaint testovat polozku fErase v PAINTSTRUC a ak je true tak prekreslit najprv pozadie v invalidovanom rectangle.

Ak budes chciet aj ovplyvnovat pozadie child dialogovych komponentov, tak potom je asi zaujimava aj notifikacia WM_CTLCOLOR.

Díky. Někdo se mě ptá a má to takto:

HINSTANCE hInst;								// current instance
TCHAR szTitle[MAX_LOADSTRING];					// The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];			// the main window class name
TCHAR szText[MAX_LOADSTRING];

int ColorR=0,ColorG=200,ColorB=255;

void SetDefalut(HWND hWnd);
void SetCervenou(HWND hWnd);
void SetZelenou(HWND hWnd);

void DrawWndContent (HWND hWnd, HDC hDc);
void DrawMousePointer (HWND hWnd, int x, int y);



LRESULT CALLBACK Title(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
	case WM_INITDIALOG:
		
		{
			HWND hEdit = GetDlgItem(hDlg,IDC_EDIT1);
			SetWindowText(hEdit, szText);
		}
		return TRUE;

	case WM_COMMAND:
		switch(LOWORD(wParam))
		{
			case IDCANCEL:
				EndDialog(hDlg, LOWORD(wParam));
				return TRUE;
			
			case IDOK:
				{
					HWND hEdit = GetDlgItem(hDlg, IDC_EDIT1);
					GetWindowText(hEdit,szText,MAX_LOADSTRING);
				}
			break;
		}

		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
		{
			EndDialog(hDlg, LOWORD(wParam));
			return TRUE;
		}
		break;
	}
	return FALSE;
}



LRESULT CALLBACK About(HWND hWnd, UINT message, UINT wParam, UINT lParam)
{
	if (message == WM_COMMAND && (LOWORD(wParam) == IDOK))
	{
		EndDialog(hWnd, IDOK);
		return TRUE;
	}
	return FALSE;
}

LRESULT CALLBACK MyWndProc(HWND hWnd, UINT message, UINT wParam, UINT lParam)
{	
	int wmId;

	PAINTSTRUCT ps;
	HDC hdc;

    switch(message)
	{

	case WM_COMMAND:
		
		wmId = LOWORD(wParam);
		switch (wmId)
		{
		
		case IDM_ABOUT:
			DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, (DLGPROC)About);
			break;

				
		case IDM_EXIT:
		if(MessageBox(hWnd, "Chcete ukoncit aplikaci?","WinHello", MB_YESNO | MB_ICONQUESTION)==IDYES)
		{
			DestroyWindow(hWnd);
			break;
		}
			break;

		case IDM_SETTINGS_EDITTITLE:
			DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG2), hWnd, (DLGPROC)Title); 
			InvalidateRect(hWnd, NULL, TRUE); // prekresleni okna
			break;


		case ID_DEFALUT:
				
			if(MessageBox(hWnd, "Opravdu chcete barvu změnit na původní?", "Změna barvy",MB_YESNO | MB_ICONQUESTION)==IDYES)
			{
				SetDefalut(hWnd);
			}
			break;

		case ID_RED:
					
			if(MessageBox(hWnd, "Opravdu chcete barvu změnit na červenou?", "Změna barvy",MB_YESNO | MB_ICONQUESTION)==IDYES)
			{
				SetCervenou(hWnd);
			}
			break;

		case ID_GREEN:
					
			if(MessageBox(hWnd, "Opravdu chcete barvu změnit na zelenou?", "Změna barvy",MB_YESNO | MB_ICONQUESTION)==IDYES)
			{
				SetZelenou(hWnd);
			}
			break;
		
		}
		return 0;
		

	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		DrawWndContent (hWnd, hdc);
		EndPaint(hWnd, &ps);
		break;

case WM_MOUSEMOVE:
		if(wParam == MK_LBUTTON)
		{
			DrawMousePointer(hWnd,LOWORD(lParam), HIWORD(lParam));
		}
		break;

	
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;


	case WM_CLOSE: 
		if(MessageBox(hWnd, "Chcete ukoncit aplikaci?","WinHello", MB_YESNO | MB_ICONQUESTION)==IDYES)
		{
		PostQuitMessage(0);
		}
		return 0;
		
	}

	return DefWindowProc(hWnd, message, wParam, lParam);
}


void DrawWndContent (HWND hWnd,HDC hDc)
{
	RECT wrct;
	SIZE tsize;
	COLORREF zelena = RGB(0,255,0);
	HBRUSH stetec, stary_stetec;

	//vytvoreni noveho stetce
	stetec = CreateSolidBrush(zelena);


	// zjisteni velikosti okna
	GetClientRect(hWnd, &wrct);

	// zjisteni velikosti textu
	GetTextExtentPoint32(hDc, szText, strlen(szText),&tsize);
	
	// priradime  novy stetec do kontextu zarizeni
	stary_stetec = (HBRUSH)SelectObject(hDc,stetec);


	//zaramovani textu
	Rectangle (hDc, wrct.right/2-tsize.cx/2-5,wrct.bottom/2 - tsize.cy/2-5,
		wrct.right/2+tsize.cx/2 + 5,wrct.bottom/2+tsize.cy/2 +5 );

	//nastaveni pozadi textu
	SetBkColor(hDc,zelena);

	// nastaveni modu pozadi textu s pruhlednzm pozadim - transparant
	SetBkMode(hDc, TRANSPARENT);


	//tisk textu do okna
	TextOut(hDc, wrct.right/2-tsize.cx/2,
		wrct.bottom/2 - tsize.cy/2,
		szText, strlen(szText));
		
	// vraceni stareho stetce do kontextu zarizeni
	SelectObject(hDc,stary_stetec);

	// smazani objektu noveho stetce
	DeleteObject(stetec);
       
}


void DrawMousePointer(HWND hWnd, int x,int y)
{
	// ziskat kontext zarizeni
	HDC hDc = GetDC(hWnd);

    Ellipse(hDc,x -10,y-10,x+10,y+10);

	// uvolneni kontextu zarizeni
	ReleaseDC(hWnd, hDc);
}


void SetDefalut(HWND hWnd)
{
	HMENU hMenu;
	
	hMenu = GetMenu(hWnd);
			
	CheckMenuItem(hMenu, ID_DEFALUT, MF_CHECKED);
	CheckMenuItem(hMenu, ID_RED, MF_UNCHECKED);
	CheckMenuItem(hMenu, ID_GREEN, MF_UNCHECKED);

	ColorR=100;
	ColorG=100;
	ColorB=255;

	InvalidateRect(hWnd, NULL, TRUE);

}


... a konečně vytvoření instance okna atd.....

Při volání funkcí:
SetZelenou
SetCervenou

By se tak mělo stát......

void SetCervenou(HWND hWnd)
{
	HMENU hMenu;

	hMenu = GetMenu(hWnd);
	
	CheckMenuItem(hMenu, ID_DEFALUT, MF_UNCHECKED);
	CheckMenuItem(hMenu, ID_RED, MF_CHECKED);
	CheckMenuItem(hMenu, ID_GREEN, MF_UNCHECKED);

	ColorR=255;
	ColorG=100;
	ColorB=100;
	
	InvalidateRect(hWnd, NULL, TRUE);

}

void SetZelenou(HWND hWnd)
{
	HMENU hMenu;

	hMenu = GetMenu(hWnd);
	wcex´.WM_ERASEBACKGROUND;
	CheckMenuItem(hMenu, ID_DEFALUT, MF_UNCHECKED);
	CheckMenuItem(hMenu, ID_RED, MF_UNCHECKED);
	CheckMenuItem(hMenu, ID_GREEN, MF_CHECKED);

	ColorR=100;
	ColorG=255;
	ColorB=100;

	InvalidateRect(hWnd, NULL, TRUE);

}



int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,		// prikazovy radek
                     int       nCmdShow)

{	

	strcpy (szText, "Jarda");


 	WNDCLASSEX	wcex;		// struktura tridy okna
	MSG			message;	// zprava

	// vytvoreni a registrace tridy okna
	if(!hPrevInstance)
	{
		ZeroMemory(&wcex, sizeof(WNDCLASSEX));

		wcex.cbSize = sizeof(WNDCLASSEX);
		wcex.hInstance = hInstance;
		wcex.lpszClassName = "MyWindowClass";
		wcex.lpfnWndProc =(WNDPROC)MyWndProc;
		wcex.style = CS_HREDRAW | CS_VREDRAW;
		wcex.hbrBackground = (HBRUSH)COLOR_WINDOW;
		wcex.hbrBackground = CreateSolidBrush(RGB(ColorR,ColorG,ColorB));
		wcex.hCursor = LoadCursor (NULL, IDC_CROSS);
		wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_WINAPITUT);
		wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
		wcex.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);	//prirazeni menu

		RegisterClassEx(&wcex);

	}

	// vytvoreni hlavniho okna aplikace
	HWND hMainWnd = CreateWindow("MyWindowClass","Win32API Hello World",
		WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
		NULL, NULL, hInstance, NULL);

	// zobrazeni okna
	ShowWindow(hMainWnd, nCmdShow);

	// aktualizace obsahu zobrazeneho okna
	UpdateWindow(hMainWnd);

	//vytvoreni akceleratoru
	HACCEL hAccel = LoadAccelerators(hInst, MAKEINTRESOURCE(ID_ACC));

	// smycka zprav
	while(GetMessage(&message, NULL, 0, 0))
	{
		if(!TranslateAccelerator(hMainWnd, hAccel, &message))		//výběr zpravy (když jde o zprávu akcelerátoru)
		{

		TranslateMessage(&message);
		DispatchMessage(&message);

		}

	}

	return message.wParam;


}

Uz som pisal vyssie co treba robit, wcex.hbrBackground = NULL a potom musi zmenit MyWndProc, bud tam pridat dalsi case (pre WM_ERASEBKGND) alebo pridat mazanie pozadia v sekcii ktora tam je pre WM_PAINT. Pouzit moze tie 3premenne co uz ma, nebude musiet menit funkcie SetZelenou, SetCervenou atd.
To

wcex´.WM_ERASEBACKGROUND;

je preboha co.

Programovat za druhych sa mi fakt nechce. Na konkretnu otazku poradim, ale nie ze budem pisat kod za druhych. Preco chce ten niekto "programovat" ak nezvladne ani tak jednoduchu zalezitost?
Pisal som vyssie aj o google, ako inspiracia sa da pouzit napr. http://support.microsoft.com/?scid=kb%3Ben-us%3B103 786&x=10&y=19 ten prvy sample code, je to ale pisane pre MFC staci to zmenit na ciste WinAPI volania (nazvy fcii su tie iste). A to co tam je (upravene) vlozis do novej sekcie case WM_ERASEBKGND: v MyWndProc

P.S. na popis WinAPI funkcii pouzivaj MSDN, ak nemas lokalne, tak msdn.microsoft.com

Nejde mi o 5riadkov ale ide mi o princip :-) (poradit vs. robit nieco za niekoho)
Inac moze tam byt tych riadkov aj viac, fcia GetClipBox ma podla MSDN aj navratovu hodnotu, ktoru by bolo dobre asi aj testovat, to chce ale najprv si poriadne precitat popis tej fcie v MSDN, a prip. ak to nie je pochopitelne z popisu fcie ako to funguje tak pouzit v MSDN aj linky na suvisiace temy (clipping regions apod)...

Zpět do poradny Odpovědět na původní otázku Nahoru