Změna backgroundu a stylu okna za běhu aplikace ve Win32 API – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Změna backgroundu a stylu okna za běhu aplikace ve Win32 API – C / C++ – Fórum – Programujte.comZměna backgroundu a stylu okna za běhu aplikace ve Win32 API – C / C++ – Fórum – Programujte.com

 

Loli
~ Anonymní uživatel
33 příspěvků
20. 10. 2010   #1
-
0
-

Myslím, že název vlákna mluví za vše

Nahlásit jako SPAM
IP: 78.80.70.–
liborb
~ Redaktor
+18
Guru
20. 10. 2010   #2
-
0
-

Styl změníš přes SetWindowLong (pro dané okno), štětec na vykreslení pozadí přes SetClassLong (pro danou třídu oken). Pokud je to okno v tvé moci, tj. reaguješ přímo na WM_ zprávy, tak pozadí změníš reakcí na WM_ERASEBKGND.

Nahlásit jako SPAM
IP: 195.189.142.–
Loli
~ Anonymní uživatel
33 příspěvků
21. 10. 2010   #3
-
0
-

Takže styl mi změnit jde ale mám problé se změnou backgroundu.

SetClassLong(hlavni_okno, GCL_HBRBACKGROUND,(LONG) MAKEINTRESOURCE(BCK));


Zobrazí se šedé okno. V čem je chyba?

Nahlásit jako SPAM
IP: 78.80.70.–
liborb
~ Redaktor
+18
Guru
22. 10. 2010   #4
-
0
-

Co je to za okno? Pokud je "tvoje", tak používej WM_ERASEBKGND.

Nahlásit jako SPAM
IP: 78.80.52.–
Loli
~ Anonymní uživatel
33 příspěvků
22. 10. 2010   #5
-
0
-

Je to moje okno. I když použiju WM_ERASEBKGND tak to vyhodí zase šedou obrazovku.
Neexistuje nějaká aspoň nějaká funkce na vykreslení bitmapy do okna?

Nahlásit jako SPAM
IP: 78.80.70.–
liborb
~ Redaktor
+18
Guru
22. 10. 2010   #6
-
0
-

Takže když v WM_ERASEBKGND zavoláš toto:

RECT	rtRect;

GetClientRect(hWnd, &rtRect);
FillRect(hDC, &rtRect, (HBRUSH)(COLOR_INFOBK + 1));
// mazeme sami
return(TRUE);


tak máš pořád hnus šedivej? :)

Jinak sem musíš šoupnout kód, bez něj se dál asi nepohneme. A bitmapu vykreslíš do HDC, stejně jako cokoliv jiného grafického.

Nahlásit jako SPAM
IP: 78.80.52.–
Loli
~ Anonymní uživatel
33 příspěvků
22. 10. 2010   #7
-
0
-



#include "main.h"
#include <commctrl.h>
#include <tchar.h>
#include <mmsystem.h>
#define _MainClassName TEXT("WinAPIMainClass")
#define _AppName TEXT("System info")
#define _TimerClock 1
#pragma comment(lib, "user32.lib")

HINSTANCE g_hInstance;
TCHAR name [ UNLEN + 1 ];
DWORD size = UNLEN + 1;

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK DialogProc(HWND, UINT, WPARAM,LPARAM);
HWND konec, text[100];

HWND g_hwndMain;
HWND g_hwndStatusBar;
HWND hlavni_okno;

int setfont (HWND hwnd)
{
HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
SendMessage(hwnd,WM_SETFONT, (WPARAM)hFont, (LPARAM)TRUE);
return 0;
}
TCHAR ch[20];
MSG msg;
BOOL DumpResource(WORD id, char *filename)
{
HRSRC rsrc;
HGLOBAL load;
LPVOID data;
DWORD size;
BOOL status = FALSE;

if ((rsrc = FindResource(NULL, MAKEINTRESOURCE(id), "BINARY")) != NULL &&
(load = LoadResource(NULL, rsrc)) != NULL &&
(data = LockResource(load)) != NULL &&
(size = SizeofResource(NULL, rsrc)) != 0)
{
FILE *file;
if ((file = fopen(filename, "wb")) != NULL) {
if (fwrite(data, 1, size, file) == size)
status = TRUE;
fclose(file);
}
}

return status;
} //DumpResource(IDR_SOUBOR1, "hudba.mp3");
LRESULT CALLBACK WindowProcMain(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
TCHAR chText[200];
SYSTEMTIME sysTime;
INT_PTR dlgResult;
switch ( message )
{
case WM_COMMAND:
switch ( LOWORD(wParam) )
{


case IDB_KONEC:
DestroyWindow(konec);
DestroyWindow(g_hwndStatusBar);
SetWindowLong(hlavni_okno, GWL_STYLE, WS_OVERLAPPEDWINDOW);
ShowWindow(hlavni_okno, SW_SHOWDEFAULT);
UpdateWindow(hlavni_okno);

SendMessage(hwnd,WM_ERASEBKGND,NULL,NULL);
break;

}







case WM_CREATE:
konec = CreateWindowEx(NULL,"BUTTON", "Konec", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON , 500,320,70,25,hwnd,(HMENU)IDB_KONEC, NULL,NULL);
setfont(text[1]);
setfont(konec);

break;


case WM_SIZE:
SendMessage(g_hwndStatusBar, WM_SIZE, wParam, lParam);
break;

case WM_TIMER:
GetLocalTime(&sysTime);
_stprintf(chText, TEXT(" Dnes je: %d.%d.%d, %d:%.2d:%.2d hod."), sysTime.wDay, sysTime.wMonth, sysTime.wYear, sysTime.wHour, sysTime.wMinute, sysTime.wSecond); SetWindowText(g_hwndStatusBar, chText);
break;

case WM_CLOSE:
if ( MessageBox(hwnd, TEXT("Opravdu ukončit?"), _AppName, MB_YESNO | MB_ICONWARNING | MB_TASKMODAL) != IDYES )
return 0;
KillTimer(hwnd, _TimerClock);
break;

case WM_ERASEBKGND:
HDC hDC;
RECT rtRect;
GetClientRect(hwnd, &rtRect);
FillRect(hDC, &rtRect, (HBRUSH)(COLOR_INFOBK + 1));
SetClassLong(hwnd, GCL_HBRBACKGROUND,(LONG) MAKEINTRESOURCE(BCK));
break;

case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}

BOOL InitApp()
{
INITCOMMONCONTROLSEX icc;
icc.dwSize = sizeof(INITCOMMONCONTROLSEX);
icc.dwICC = ICC_WIN95_CLASSES;
if ( !InitCommonControlsEx(&icc) )
return FALSE;

WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wc.hCursor = LoadCursor(g_hInstance, MAKEINTRESOURCE(IDC_MAIN));
wc.hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDR_MAIN));
wc.hIconSm = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDR_MAIN));
wc.hInstance = g_hInstance;
wc.lpfnWndProc = WindowProcMain;
wc.lpszClassName = _MainClassName;
wc.lpszMenuName = NULL;//MAKEINTRESOURCE(IDR_MAINMENU);
wc.lpszMenuName = NULL;
wc.style = CS_HREDRAW | CS_VREDRAW | DS_CENTER;
if ( !RegisterClassEx(&wc) )
return FALSE;

g_hwndMain = CreateWindowEx(0, _MainClassName, _AppName, WS_CAPTION | WS_SYSMENU | WS_VISIBLE, 100, 100, 600, 400, NULL, NULL, g_hInstance, NULL);
ShowWindow(g_hwndMain, SW_SHOWDEFAULT);
UpdateWindow(g_hwndMain);
hlavni_okno = g_hwndMain;

g_hwndStatusBar = CreateWindowEx(0, STATUSCLASSNAME, TEXT("Stavový řádek"), WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, g_hwndMain, (HMENU)NULL, g_hInstance, NULL);

SetTimer(g_hwndMain, _TimerClock, 1000, NULL);
SendMessage(g_hwndMain, WM_TIMER, _TimerClock, NULL);

return TRUE;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nShow)
{

g_hInstance = hInstance;
if ( !InitApp() )
return FALSE;
while ( GetMessage(&msg, NULL, 0, 0) )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}


Opět šedé okno.

Nahlásit jako SPAM
IP: 78.80.70.–
liborb
~ Redaktor
+18
Guru
22. 10. 2010   #8
-
0
-

SetClassLong použiješ na okno, které není tvoje, takže tenhle řádek pryč. Dále, aby se ti volalo WM_ERASEBKGND, musíš mít brush při registraci okna nastaven na NULL. Nebo si tam nastav jiný brush než šedý, když ho nechceš.

Nahlásit jako SPAM
IP: 195.189.142.–
Loli
~ Anonymní uživatel
33 příspěvků
23. 10. 2010   #9
-
0
-

#include "main.h" 

#include <commctrl.h>
#include <tchar.h>
#include <mmsystem.h>
#define _MainClassName TEXT("WinAPIMainClass")
#define _AppName TEXT("System info")
#define _TimerClock 1
#pragma comment(lib, "user32.lib")

HINSTANCE g_hInstance;
TCHAR name [ UNLEN + 1 ];
DWORD size = UNLEN + 1;

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK DialogProc(HWND, UINT, WPARAM,LPARAM);
HWND konec, text[100];

HWND g_hwndMain;
HWND g_hwndStatusBar;
HWND hlavni_okno;

int setfont (HWND hwnd)
{
HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
SendMessage(hwnd,WM_SETFONT, (WPARAM)hFont, (LPARAM)TRUE);
return 0;
}
TCHAR ch[20];
MSG msg;
BOOL DumpResource(WORD id, char *filename)
{
HRSRC rsrc;
HGLOBAL load;
LPVOID data;
DWORD size;
BOOL status = FALSE;

if ((rsrc = FindResource(NULL, MAKEINTRESOURCE(id), "BINARY")) != NULL &&
(load = LoadResource(NULL, rsrc)) != NULL &&
(data = LockResource(load)) != NULL &&
(size = SizeofResource(NULL, rsrc)) != 0)
{
FILE *file;
if ((file = fopen(filename, "wb")) != NULL) {
if (fwrite(data, 1, size, file) == size)
status = TRUE;
fclose(file);
}
}

return status;
} //DumpResource(IDR_SOUBOR1, "hudba.mp3");
LRESULT CALLBACK WindowProcMain(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
TCHAR chText[200];
SYSTEMTIME sysTime;
INT_PTR dlgResult;
switch ( message )
{
case WM_COMMAND:
switch ( LOWORD(wParam) )
{


case IDB_KONEC:
DestroyWindow(konec);
DestroyWindow(g_hwndStatusBar);
SetWindowLong(hlavni_okno, GWL_STYLE, WS_OVERLAPPEDWINDOW);
ShowWindow(hlavni_okno, SW_SHOWDEFAULT);
UpdateWindow(hlavni_okno);

SendMessage(hwnd,WM_ERASEBKGND,NULL,NULL);
break;

}







case WM_CREATE:
konec = CreateWindowEx(NULL,"BUTTON", "Konec", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON , 500,320,70,25,hwnd,(HMENU)IDB_KONEC, NULL,NULL);
setfont(text[1]);
setfont(konec);

break;


case WM_SIZE:
SendMessage(g_hwndStatusBar, WM_SIZE, wParam, lParam);
break;

case WM_TIMER:
GetLocalTime(&sysTime);
_stprintf(chText, TEXT(" Dnes je: %d.%d.%d, %d:%.2d:%.2d hod."), sysTime.wDay, sysTime.wMonth, sysTime.wYear, sysTime.wHour, sysTime.wMinute, sysTime.wSecond); SetWindowText(g_hwndStatusBar, chText);
break;

case WM_CLOSE:
if ( MessageBox(hwnd, TEXT("Opravdu ukončit?"), _AppName, MB_YESNO | MB_ICONWARNING | MB_TASKMODAL) != IDYES )
return 0;
KillTimer(hwnd, _TimerClock);
break;

case WM_ERASEBKGND:
HDC hDC;
RECT rtRect;
GetClientRect(hwnd, &rtRect);
FillRect(hDC, &rtRect, (HBRUSH) MAKEINTRESOURCE(BCK));
break;

case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}

BOOL InitApp()
{
INITCOMMONCONTROLSEX icc;
icc.dwSize = sizeof(INITCOMMONCONTROLSEX);
icc.dwICC = ICC_WIN95_CLASSES;
if ( !InitCommonControlsEx(&icc) )
return FALSE;

WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = NULL;//(HBRUSH)(COLOR_BTNFACE + 1);
wc.hCursor = LoadCursor(g_hInstance, MAKEINTRESOURCE(IDC_MAIN));
wc.hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDR_MAIN));
wc.hIconSm = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDR_MAIN));
wc.hInstance = g_hInstance;
wc.lpfnWndProc = WindowProcMain;
wc.lpszClassName = _MainClassName;
wc.lpszMenuName = NULL;//MAKEINTRESOURCE(IDR_MAINMENU);
wc.lpszMenuName = NULL;
wc.style = CS_HREDRAW | CS_VREDRAW | DS_CENTER;
if ( !RegisterClassEx(&wc) )
return FALSE;

g_hwndMain = CreateWindowEx(0, _MainClassName, _AppName, WS_CAPTION | WS_SYSMENU | WS_VISIBLE, 100, 100, 600, 400, NULL, NULL, g_hInstance, NULL);
ShowWindow(g_hwndMain, SW_SHOWDEFAULT);
UpdateWindow(g_hwndMain);
hlavni_okno = g_hwndMain;

g_hwndStatusBar = CreateWindowEx(0, STATUSCLASSNAME, TEXT("Stavový řádek"), WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, g_hwndMain, (HMENU)NULL, g_hInstance, NULL);

SetTimer(g_hwndMain, _TimerClock, 1000, NULL);
SendMessage(g_hwndMain, WM_TIMER, _TimerClock, NULL);

return TRUE;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nShow)
{

g_hInstance = hInstance;
if ( !InitApp() )
return FALSE;
while ( GetMessage(&msg, NULL, 0, 0) )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}


Nějak to stále nefunguje

Nahlásit jako SPAM
IP: 78.80.70.–
liborb
~ Redaktor
+18
Guru
23. 10. 2010   #10
-
0
-

:)
V tom kousku kódu jsem měl return(TRUE) a úmyslně i s komentářem, aby si věděl, proč jsem ho tam dal. Ty pak uděláš break a zavoláš DefWindowProc, u který můžeš hádat 2x, co udělá :) ... Ano, přesně. Když mažeš pozadí sám, tak to návratovou hodnotou daš systému vědět, ale to se všechno píše v dokumentaci ;)

Nahlásit jako SPAM
IP: 195.189.142.–
Loli
~ Anonymní uživatel
33 příspěvků
23. 10. 2010   #11
-
0
-

OK upravil jsem WM_ERASEBKGND

 

case WM_ERASEBKGND:
HDC hDC;
RECT rtRect;
GetClientRect(hwnd, &rtRect);
FillRect(hDC, &rtRect, (HBRUSH) MAKEINTRESOURCE(BCK));
return(TRUE);


A zprávu volám po stisknutí tlačítka "KONEC" takto
SendMessage(hwnd,WM_ERASEBKGND,NULL,NULL);


A stejně to nefuguje, tentokrát žádná změna v barvě pozadí.

Mě osobně příde zpráva WM_ERASEBKGN "použitelná" pouze v případě, že chci pozadí změňit pouze jednou. Jak by se to řešilo kdybych chtěl (a jako že chci) aby se background změnil vícekrát?

Nahlásit jako SPAM
IP: 78.80.70.–
liborb
~ Redaktor
+18
Guru
23. 10. 2010   #12
-
0
-

Vymazání pozadí se volá vždy, když je potřeba překreslit resp. vymazat obsah okna. To nevoláš ty, to volá systém sám. Když to chceš dělat na povel, tak se to dělá tak, že se znesplatní obsah okna/obdélníka (Invalidate...). Ale čeho jsem si nevšimnul dřív je to, že ty vůbec nepoužíváš HDC, které ti tou zprávou přijde, ale používáš neinicializovanou proměnou. Schválně se podívej, co obsahují WPARAM a LPARAM.

Nahlásit jako SPAM
IP: 195.189.142.–
Loli
~ Anonymní uživatel
33 příspěvků
24. 10. 2010   #13
-
0
-

Nefunguje mi to, přestože inicializuji hDC.

hDC = BeginPaint(hlavni_okno, &ps);


Možná by mi stačilo, kdybych věděl jak vykreslit bitmapu. Už umím ikony, ale bitmapy ne.

Nahlásit jako SPAM
IP: 78.80.70.–
liborb
~ Redaktor
+18
Guru
26. 10. 2010   #14
-
0
-

Nechal jsem si vygenerovat WinAPI aplikaci ve VS (VS 2008).

1) Zkouším změnit hodnotu hbrBackground ve struktuře WNDCLASSEX při registraci okna na barvu pozadí tooltipu tj.:

wcex.hbrBackground	= (HBRUSH)(COLOR_INFOBK+1);
Funguje.

2) Zkouším zachytávat zprávu WM_ERASEBKGND a vracet jenom TRUE, tj. nebude se provádět výmaz pozadí:
case(WM_ERASEBKGND):

return(TRUE);
Funguje.

BTW to je jediná mystifikace, kterou jsem se dopustil ... hbrBackground nemusí být NULL, aby se volalo WM_ERASEBKGND. Mám to jenom "špatně" zažité. V dokumentaci se píše, že když NULL, tak musíš :)

3) Vymazání pozadí vlastními silami, ani to nebudu komentovat:
case(WM_ERASEBKGND):

{
HDC hDC = (HDC)wParam;
RECT rtRect;
GetClientRect(hWnd, &rtRect);
FillRect(hDC, &rtRect, (HBRUSH)(COLOR_INFOBK + 1));
return(TRUE);
}
Funguje.

BTW při WM_ERASEBKGND se HDC předává jako wParam.

Nahlásit jako SPAM
IP: 78.80.52.–
liborb
~ Redaktor
+18
Guru
26. 10. 2010   #15
-
0
-

A co se týká bitmapy v pozadí, tak to je podobné ... musíš ji do DC prostě vykreslit.

1) Nahraješ si bitmapu (řekněme jako globální proměnou) někde na začátku WinMain:

g_hBitmap	= LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_POZADI));


2) IDB_POZADI je samozřejmě definována v resource.h a je jí přiřazena nějaká bitmapa v resource.rc

3) V WM_ERASEBKGND musíš poprvé inicializovat kompatibilní DC, přiřadit mu tuto bitmapu a následně přes BitBlt dostat data z tvojí bitmapy do DC (a samozřejmě vracet TRUE):
case(WM_ERASEBKGND):

{
HDC hDC = (HDC)wParam;
RECT rtRect;

if (g_hDC == NULL) {
g_hDC = CreateCompatibleDC(hDC);
SelectObject(g_hDC, g_hBitmap);
}

GetClientRect(hWnd, &rtRect);
BitBlt(hDC, 0, 0, rtRect.right, rtRect.bottom, g_hDC, 0, 0, SRCCOPY);
return(TRUE);
}


Nezapomeň ještě bitmapu a DC při ukončení programu rušit.

Nahlásit jako SPAM
IP: 78.80.52.–
Loli
~ Anonymní uživatel
33 příspěvků
29. 10. 2010   #16
-
0
-

Dík, barva pozadí už změnit jde ,ale nedaří se mi ty bitmapy.
Hlavní problém je v tom že nevím co má být to g_hDC

Nahlásit jako SPAM
IP: 78.80.70.–
liborb
~ Redaktor
+18
Guru
29. 10. 2010   #17
-
0
-

Globální proměnná - handle DC.

HDC g_hDC;

Nahlásit jako SPAM
IP: 78.80.52.–
Loli
~ Anonymní uživatel
33 příspěvků
29. 10. 2010   #18
-
0
-

To znamená?

HDC g_hDC = (HDC)wParam;

a kde ji mam deklarovat?

Nahlásit jako SPAM
IP: 78.80.70.–
liborb
~ Redaktor
+18
Guru
29. 10. 2010   #19
-
0
-

Je to globální proměnná, protože ji potřebuješ jen jednou po celou dobu běhu programu a při jeho ukončení ji pak musíš uvolnit. Počáteční hodnota bude NULL, to jsem tam zapomněl připsat :). A vytvoření se provede při prvním průchodu reakcí na WM_ERASEBKGND, tj. vytvoříš si kompatibilní DC, kterému přiřadíš tu tvoji bitmapu. To všechno máš v tom příkladu o několik příspěvků výše.

Nahlásit jako SPAM
IP: 195.189.142.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 51 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý