"Kulatý" progressbar - winapi – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

"Kulatý" progressbar - winapi – C / C++ – Fórum – Programujte.com"Kulatý" progressbar - winapi – C / C++ – Fórum – Programujte.com

 

Toto vlákno bylo označeno za vyřešené.
ProXicT0
Návštěvník
26. 3. 2014   #1
-
0
-

Zdravím, má tu někdo zkušenosti s ručně kreslěným progressbarem? Chtěl bych udělat jakousi minutku na odpočet času a indikovat zbývající čas na "kulatém" progressbaru. Předem díky ;-]

Nahlásit jako SPAM
IP: 77.240.98.–
Radek Chalupa
~ Redaktor
+1
Super člen
26. 3. 2014   #2
-
0
-

#1 ProXicT
ProgressBar nepodporuje WM_OWNERDRAW, takže buď si ho subclassovat (přesměrovat jeho proceduru okna na vlastní) a v obsluze WM_PAINT si tam podle libosti nějak vykreslit ten stav, nebo vůbec nepoužít progress bar jako control (okno) ale v obsluze WM_PAINT toho "rodičovského okna" na příslušné místo vykreslovcat stav (samozřejmě při požadavku na "posun" zavolat ručně RedrawWindow, čímž se vyvolá výše zmíněná obsluha WM_PAINT.

Radek Chalupa 
- vývoj software na zakázku 
- školení programování (C/C++, WinAPI, ATL, COM, ActiveX, C#, NET Framework, MFC) 
http://www.radekchalupa.cz

Nahlásit jako SPAM
IP: 89.177.51.–
ProXicT0
Návštěvník
26. 3. 2014   #3
-
0
-

Zkoušel jsem nejprve nakreslit jednoduchou kružnici pomocí (cos(x), sin(y)) a snažil jsem se vykreslit pixel, pomocí SetPixel(), vždy se mi ale vykreslil pouze jeden bod. Hlavně pro přesnou krunici bych měl použít double nebo float, ale to je v rastru nemožné...

Nahlásit jako SPAM
IP: 77.240.98.–
ProXicT0
Návštěvník
26. 3. 2014   #4
-
0
-

Objevil jsem skvělou funkci koláč :D Myslím, že se pro to co potřebuju náramně hodí: 

Pie(hdc, RESx / 2 - 20, RESy / 2 - 20, RESx / 2 + 20, RESy / 2 + 20, RESx / 2, RESy / 2 - 20, RESx / 2 + 20, RESy / 2);
Nahlásit jako SPAM
IP: 77.240.98.–
Radek Chalupa
~ Redaktor
+1
Super člen
27. 3. 2014   #5
-
+1
-
Zajímavé

#4 ProXicT
A pokud to chceš mít "hezčí", tj. s vyhlazením hran a oblouků, můžeš použít GDI+, např. takhle: 

Gdiplus::Graphics* g = new Gdiplus::Graphics(hdc);
Gdiplus::SolidBrush br(Gdiplus::Color(0xA0,0,0));
Gdiplus::Rect rect(10, 10, 100, 100);
g->SetSmoothingMode(Gdiplus::SmoothingModeHighQuality);
g->FillPie(&br, rect, 0.0f, 145.0f);
delete g;

Radek Chalupa 
- vývoj software na zakázku 
- školení programování (C/C++, WinAPI, ATL, COM, ActiveX, C#, NET Framework, MFC) 
http://www.radekchalupa.cz

Nahlásit jako SPAM
IP: 89.177.51.–
ProXicT0
Návštěvník
27. 3. 2014   #6
-
0
-

#5 Radek Chalupa
Celý den se náhodou snažím vymyslet, jak bych to mohl vyhladit, přemýšlel jsem nad vykreslením všeho do bitmapy několikrát větší něž rozměr okna a pak tu bitmapu zmenšit a vykreslit. Vždy se mi ale vykresluje bílé okno. S GDI+ zatím nemám žádné zkušenosti, ale časem bych se to chtěl také naučit.

hdc = BeginPaint(hwnd, &ps);
		HDC mdc = CreateCompatibleDC(hdc);
		HBITMAP mbmp = CreateBitmap(960, 600, 1, 24, NULL);
		HBITMAP moldbmp = (HBITMAP)SelectObject(mdc, mbmp);


		HBRUSH brush = CreateSolidBrush(RGB(255, 0, 0));
		HBRUSH brush2 = CreateSolidBrush(RGB(240, 240, 240));
		HPEN pen = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
		HPEN pen2 = CreatePen(PS_SOLID, 1, RGB(240, 240, 240));
		
		int CenterX = RESx / 2;
		int CenterY = RESy / 2;
		int Radius = 30;
		int StartptX = RESx / 2;
		int StartptY = RESy / 2 - Radius;
		int EndptX = RESx / 2 + Radius;
		int EndptY = RESy / 2;
		int width = 5;

		SelectObject(mdc, brush);
		SelectObject(mdc, pen);
		Pie(mdc, CenterX - Radius, CenterY - Radius, CenterX + Radius, CenterY + Radius, StartptX, StartptY, EndptX, EndptY);

		SelectObject(mdc, brush2);
		SelectObject(mdc, pen2);
		Ellipse(mdc, CenterX - Radius + width, CenterY - Radius + width, CenterX + Radius - width, CenterY + Radius - width);

		StretchBlt(hdc, 0, 0, RESx, RESy, mdc, 0, 0, 960, 600, SRCCOPY);

		SelectObject(mdc, moldbmp);
		DeleteObject(mbmp);
		DeleteDC(mdc);

		EndPaint(hwnd, &ps);
Nahlásit jako SPAM
IP: 77.240.98.–
z
~ Anonymní uživatel
268 příspěvků
27. 3. 2014   #7
-
+1
-
Zajímavé

Předpokládám, že ti to takhle fungovalo a jen jsi přidal ten memory DC/BMP.

  1. CreateCompatibleBitmap
  2. Souřadnice a rozměry máš původní
  3. SetStretchBltMode

Nahlásit jako SPAM
IP: 88.101.8.–
Radek Chalupa
~ Redaktor
+1
Super člen
27. 3. 2014   #8
-
0
-

#6 ProXicT
Odhadoval bych že důvod bílého okna bude v CreateBitmap. Místo toho bys v tomhle případě  měl použít CreateCompatibleBitmap.

Jinak pokud jde o použití paměťového HDC, ukázku  s vysvětlením najdeš tady: http://www.radekchalupa.cz/clanky/default.aspx?kod=205&obsah=6

Radek Chalupa 
- vývoj software na zakázku 
- školení programování (C/C++, WinAPI, ATL, COM, ActiveX, C#, NET Framework, MFC) 
http://www.radekchalupa.cz

Nahlásit jako SPAM
IP: 89.177.51.–
ProXicT0
Návštěvník
27. 3. 2014   #9
-
0
-

#7 z
Fungovalo to, když jsem to kreslil přímo do DC toho okna, ale když to kreslím do DC té bitmapy, kterou chci následně vykreslit, tak se nevykreslí nic. Předtím to vypadalo takto: 

hdc = BeginPaint(hwnd, &ps);
HBRUSH brush = CreateSolidBrush(RGB(255, 0, 0));
HBRUSH brush2 = CreateSolidBrush(RGB(240, 240, 240));
HPEN pen = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
HPEN pen2 = CreatePen(PS_SOLID, 1, RGB(240, 240, 240));
		
int CenterX = RESx / 2;
int CenterY = RESy / 2;
int Radius = 30;
int StartptX = RESx / 2;
int StartptY = RESy / 2 - Radius;
int EndptX = RESx / 2 + Radius;
int EndptY = RESy / 2;
int width = 5;

SelectObject(hdc, brush);
SelectObject(hdc, pen);
Pie(hdc, CenterX - Radius, CenterY - Radius, CenterX + Radius, CenterY + Radius, StartptX, StartptY, EndptX, EndptY);

SelectObject(hdc, brush2);
SelectObject(hdc, pen2);
Ellipse(hdc, CenterX - Radius + width, CenterY - Radius + width, CenterX + Radius - width, CenterY + Radius - width);
EndPaint(hwnd, &ps);

Je to ale šíleně kostrbaté.

Nahlásit jako SPAM
IP: 77.240.98.–
ProXicT0
Návštěvník
27. 3. 2014   #10
-
0
-

#8 Radek Chalupa
Neuvěřitelné, na všechno znáte odpověď ;] Bylo to tím, jen jsem čekal, že to bude vyhlazené, to jsem asi čekal špatně :-D Kód vypadá takto:

hdc = BeginPaint(hwnd, &ps);
		HDC mdc = CreateCompatibleDC(hdc);
		HBITMAP mbmp = CreateCompatibleBitmap(hdc, 960, 600);
		HBITMAP moldbmp = (HBITMAP)SelectObject(mdc, mbmp);
		RECT r;
		SetRect(&r, 0, 0, 960, 600);

		HBRUSH brush = CreateSolidBrush(RGB(255, 0, 0));
		HBRUSH brush2 = CreateSolidBrush(RGB(240, 240, 240));
		HPEN pen = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
		HPEN pen2 = CreatePen(PS_SOLID, 1, RGB(240, 240, 240));
		
		FillRect(mdc, &r, CreateSolidBrush(RGB(240, 240, 240)));

		int CenterX = 480;
		int CenterY = 300;
		int Radius = 75;
		int StartptX = CenterX;
		int StartptY = CenterY - Radius;
		int EndptX = CenterX + Radius;
		int EndptY = CenterY;
		int width = 15;

		SelectObject(mdc, brush);
		SelectObject(mdc, pen);
		Pie(mdc, CenterX - Radius, CenterY - Radius, CenterX + Radius, CenterY + Radius, StartptX, StartptY, EndptX, EndptY);

		SelectObject(mdc, brush2);
		SelectObject(mdc, pen2);
		Ellipse(mdc, CenterX - Radius + width, CenterY - Radius + width, CenterX + Radius - width, CenterY + Radius - width);

		StretchBlt(hdc, 0, 0, RESx, RESy, mdc, 0, 0, 960, 600, SRCCOPY);

		SelectObject(mdc, moldbmp);
		DeleteObject(mbmp);
		DeleteDC(mdc);

		EndPaint(hwnd, &ps);

Výsledek je však nemilý:

Připojen obrázek.

Nahlásit jako SPAM
IP: 77.240.98.–
Radek Chalupa
~ Redaktor
+1
Super člen
27. 3. 2014   #11
-
0
-

#10 ProXicT
Možná by pomohlo jak výše naznačil kolega použít SetStretchBltMode; Ale z důvodu rychlosti bych cestu zmenšování neviděl jako nejlepší, myslím že GDI+ by bylo lepší řešení.

A pokud chceš zůstat u tohoto, a nemění se velikost cílové plochy tu bitmapu bych vytvořil jednou a nechal v globální proměnné než znova při každém předkreslení. Stejně tak je možné dát do globálu ty štětce a pera.

Radek Chalupa 
- vývoj software na zakázku 
- školení programování (C/C++, WinAPI, ATL, COM, ActiveX, C#, NET Framework, MFC) 
http://www.radekchalupa.cz

Nahlásit jako SPAM
IP: 89.177.51.–
ProXicT0
Návštěvník
27. 3. 2014   #12
-
0
-

#11 Radek Chalupa
Klidně bych to udělal pomocí GDI+, ale zatím je to pro mě španělská vesnice. Zkusil jsem ten SetStretchBltMode a nějaký rozdíl tam je. Pořád to není tak "dokonalé" jak jsem čekal, ale myslím, že to postačí. Ty proměnné jsem nechal ve funkci, ale se static. Jsem na to zvyklý. 

hdc = BeginPaint(hwnd, &ps);
		static HDC mdc = CreateCompatibleDC(hdc);
		static HBITMAP mbmp = CreateCompatibleBitmap(hdc, 960, 600);
		static HBITMAP moldbmp = (HBITMAP)SelectObject(mdc, mbmp);
		static RECT r;
		SetRect(&r, 0, 0, 960, 600);

		static HBRUSH brush = CreateSolidBrush(RGB(255, 0, 0));
		static HBRUSH brush2 = CreateSolidBrush(RGB(240, 240, 240));
		static HPEN pen = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
		static HPEN pen2 = CreatePen(PS_SOLID, 1, RGB(240, 240, 240));
		
		FillRect(mdc, &r, CreateSolidBrush(RGB(240, 240, 240)));

		static int CenterX = 480;
		static int CenterY = 300;
		static int Radius = 75;
		static int StartptX = CenterX;
		static int StartptY = CenterY - Radius;
		static int EndptX = CenterX + Radius;
		static int EndptY = CenterY;
		static int width = 15;

		SelectObject(mdc, brush);
		SelectObject(mdc, pen);
		Pie(mdc, CenterX - Radius, CenterY - Radius, CenterX + Radius, CenterY + Radius, StartptX, StartptY, EndptX, EndptY);

		SelectObject(mdc, brush2);
		SelectObject(mdc, pen2);
		Ellipse(mdc, CenterX - Radius + width, CenterY - Radius + width, CenterX + Radius - width, CenterY + Radius - width);

		SetStretchBltMode(hdc, HALFTONE);
		StretchBlt(hdc, 0, 0, RESx, RESy, mdc, 0, 0, 960, 600, SRCCOPY);

		SelectObject(mdc, moldbmp);
		DeleteObject(mbmp);
		DeleteDC(mdc);

		EndPaint(hwnd, &ps);

Ještě k tomu GDI+...zatím bych se chtěl naučit "čisté" winapi na nějakou slušnou úroveň a pak bych šel dál. Nedávno jsem začal číst váš článek o winapi, tak uvidíme, co z toho poberu.

Nahlásit jako SPAM
IP: 77.240.98.–
Radek Chalupa
~ Redaktor
+1
Super člen
27. 3. 2014   #13
-
0
-

#12 ProXicT
U těch grafických objektů jde spíš než o static (ušetříš jen opakované vytváření na stacku) o to, že pokud se z nějaké příčiny bude za běhu rychle opakovat překreslování, tak vytvoření (a rušení) těch GDI objektů (zejména té bitmapy) má určitou časovou režii, která samozřejmě může nebo nemusí být významná, záleží na situaci.

Radek Chalupa 
- individuální konzultace, školení programování (C/C++, WinAPI, COM, ActiveX, ATL, C#, NET Framework, MFC) 
- vývoj software na zakázku 
http://www.radekchalupa.cz

Nahlásit jako SPAM
IP: 89.177.51.–
ProXicT0
Návštěvník
27. 3. 2014   #14
-
0
-

#13 Radek Chalupa
Na složitější animace se zatím nechystám, okno se bude překreslovat zhrube jednou za sekundu. Díky moc za rady ;-)

Nahlásit jako SPAM
IP: 77.240.98.–
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, 18 hostů

Podobná vlákna

ProgressBar — založil Frank

ProgressBar — založil Anderos

Multithread a progressbar — založil aerkain

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ý