Kurz2 - Kapitola8

17. června 2007 v 15:59 | http://www.sweb.cz/kurz_evt/ |  Programování pro WinCE

4.9 Vlastní dialog

Nemůže-li hora k Mohamedovi, ...
Protože jsme zjistili, že alespoň některé PalmPC přístroje společný dialog ChooseColor nepodporují a na obrazovce nevyloudíme tento dialog,...

obr. 46 Společný dialog volby barvy
...uděláme malou (původně nezamýšlenou) odbočku a vytvoříme si vlastní dialog pro výběr barvy pozadí.
Ve správci Resources klepněte pravým tlačítkem na složku Dialog a zvolte položku Insert Dialog. Otevře se vám editor dialogů s připraveným dialogem k editaci. Jeho dvě tlačítka využijeme - změníme pouze velikost dialogu tak, aby se vešel na malý displej PPC a tlačítka přesuneme. Zarovnání tlačítek jistě objevíte v menu eVT v položce Layout -> Align. Prvky, které hodláme zarovnat označujeme pomocí Shift+Kliknutí myši.
Do dialogu doplníme ještě další 3 prvky:
  • Posuvník (Vertical Scroll Bar) - IDC_SCROLLBAR
  • Statický text (Static Text) - IDC_PAINT
  • Skupinový rámeček (Group box) - IDC_STATIC
Jejich ID a "Caption" upravíme podle výše uvedeného a podle obrázku:

obr. 47 Tvorba vlastního dialogu
Tlačítka zůstala beze změn a mají IDOK a IDCANCEL. Posuvník bude sloužit k nastavení barvy, statický text pro kontrolní zobrazení nastavené barvy. V rámci jednoduchosti jsem použil pouze jeden posuvník - budeme nastavovat pouze odstíny šedé barvy. (Druhým a podstatným důvodem bylo, že program testuji na starším přístroji s monochromatickým displejem). Skupinový rámeček nemá praktický význam, přidal jsem jej pouze pro okrasu.
Výsledný dialog by měl odpovídat uvedenému obrázku. Na kartě Properties ještě upravte ID dialogu na IDD_DIALOG_BG a jeho "Caption" na "Background Color".
Protože se Posuvník nevykresloval v emulátoru tak, jak bych si jej představoval, udělal jsem ještě jednu jeho úpravu. Na kartě Properties posuvníku je sice možné nastavit některé vlastnosti, bohužel rámeček tam zvolit nelze. Úplně mimo eVT si proto otevřete v nějakém vhodném editoru (stačí Poznámkový blok) soubor Fifteen.rc. Najděte řádek s IDC_SCROLLBAR a na jeho konec přidejte další vlastnost " | WS_BORDER ". Takže by měl vypadat podobně jako:
    
SCROLLBAR IDC_SCROLLBAR,13,7,10,81,SBS_VERT | WS_BORDER
Protože všechny prvky dialogu jsou vlastně samostatná okna, tímto jsme přikázali, aby okno Posuvníku mělo kolem sebe rámeček.
Jestliže jste zatím nezrušili změny provedené v minulé části, udělejte to teď:
- zrušte proměnné pro ChooseColor ve funkci WndProc
- zrušte řádek s #include commdlg....
- upravte obsluhu zpracování WM_COMMAND na:
   case ID_BACKGROUNDCOLOR:
if (DialogBox(hInst, (LPCTSTR)IDD_DIALOG_BG, hWnd, (DLGPROC)Pozadi)) {
dwBarva=RGB(byPozadi,byPozadi,byPozadi);
DeleteObject(hPozadi);
hPozadi=CreateSolidBrush(dwBarva);
InvalidateRect(hWnd,NULL,TRUE);
}
break;
Z uvedeného kousku je zřejmé, že nám chybí 2 věci:
1) V globálních proměnných si doplníme pomocnou proměnnou (opravdu už poslední :-)
BYTE       byPozadi;       // Pomocna promenna pri nastaveni barvy
2) Chybí procedura našeho dialogu, který jsme si již namalovali. Na úvod programu vložte prototyp funkce:
LRESULT CALLBACK Pozadi (HWND, UINT, WPARAM, LPARAM);
Funkce popisující proceduru dialogu odpovídá proceduře okna v celém programu. Jejím úkolem je zpracovat zprávy přicházející oknu dialogu. Při její tvorbě jsem zkopíroval a jenom upravil funkci, která byla vytvořená pro dialog About. Výsledkem pak vzniklo:
// Kresleni ukazkove barvy pozadi v dialogu
void UkazBarvu(HWND hPaint, BYTE byBarva)
{
RECT rtUk;
HDC hPaintDC;
HBRUSH hPaintBr;

// Ziskam potrebne DC
hPaintDC=GetDC(hPaint);
// Zjistim umisteni statickeho okna
GetClientRect(hPaint, &rtUk);
// Vytvorim si stetec odpovidajici barvy a vykreslim
hPaintBr=CreateSolidBrush(RGB(byBarva,byBarva,byBarva));
FillRect(hPaintDC,&rtUk,hPaintBr);
// Na zaver uklid
DeleteObject(hPaintBr);
ReleaseDC(hPaint,hPaintDC);
}

// Zpracovani zprav pro dialog barvy pozadi
LRESULT CALLBACK Pozadi(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
RECT rt, rt1;
int DlgWidth, DlgHeight; // dialog width and height in pixel units
int NewPosX, NewPosY;
// Handle pro okna posuvniku a statickeho okna
static HWND hScroll,hPaintRect;

switch (message)
{
case WM_INITDIALOG:
// trying to center the About dialog
if (GetWindowRect(hDlg, &rt1)) {
GetClientRect(GetParent(hDlg), &rt);
DlgWidth = rt1.right - rt1.left;
DlgHeight = rt1.bottom - rt1.top ;
NewPosX = (rt.right - rt.left - DlgWidth)/2;
NewPosY = (rt.bottom - rt.top - DlgHeight)/2;

// if the About box is larger than the physical screen
if (NewPosX < 0) NewPosX = 0;
if (NewPosY < 0) NewPosY = 0;
SetWindowPos(hDlg, 0, NewPosX, NewPosY,
0, 0, SWP_NOZORDER | SWP_NOSIZE);

// Hodnotu pozadi na aktualni barvu
byPozadi=LOBYTE(dwBarva);
// Nastaveni handle posuvniku a ukazkoveho okna
hScroll=GetDlgItem(hDlg,IDC_SCROLLBAR);
hPaintRect=GetDlgItem(hDlg,IDC_PAINT);
// Nastavim posuvnik - rozsah a aktualni pozici
SetScrollRange(hScroll,SB_CTL,0,254,FALSE);
SetScrollPos(hScroll,SB_CTL,byPozadi,FALSE);
SetTimer(hDlg,2,10,NULL);
}
return TRUE;

// Uprava obsluhy tlacitek pro OK a CANCEL - nyni ruzne akce
case WM_COMMAND:
if (LOWORD(wParam) == IDOK)
{
EndDialog(hDlg, TRUE);
return TRUE;
}
if (LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, FALSE);
return TRUE;
}
break;

// Velmi jednoducha obsluha zpravy od posuvniku
case WM_VSCROLL:
switch (LOWORD(wParam))
{
case SB_THUMBPOSITION:
case SB_THUMBTRACK:
byPozadi=LOBYTE(HIWORD(wParam));
SetScrollPos(hScroll,SB_CTL,byPozadi,TRUE);
UkazBarvu(hPaintRect,byPozadi);
}
break;

// Pouziti casovace - po vymalovani casovac rusim
case WM_TIMER:
UkazBarvu(hPaintRect,byPozadi);
KillTimer(hDlg,2);
break;
}
return FALSE;
}
Funkce UkazBarvu vykresluje vzorek vybrané barvy ve statickém okně ID_PAINT. Ve funkci About->Pozadi jsem upravil zprávu WM_COMMAND tak, aby dialog vracel TRUE při volbě OK, jinak vrací FALSE. Zpráva WM_INITDIALOG je zpracována při inicializaci dialogu. V jejím rámci jsem si vytvořil časovač, jehož zprávu použiji pouze na první vykreslení vzorku barvy a pak časovač zruším. Jediná zpráva, která provádí většinu práce, je WM_VSCROLL.
Zprávu WM_SCROLL by bylo vhodné ošetřit lépe - můžete si to vyzkoušet sami (viz příklad tvorby HexaView).
Z provedených úprav je zřejmé, že okno dialogu potřebuje funkci pro zpracování zpráv velmi podobnou funkci pro hlavní okno programu. V rámci dialogu si můžeme posílat vlastní zprávy a vytvořit např. časovač.
Nyní již můžeme nastavit pozadí hracího pole:

obr. 48 Vlastní dialog volby barvy

Co bychom si měli z této lekce zapamatovat?

  • Pro naše potřeby si můžeme vytvořit vlastní dialog.
  • Dialog může obsahovat různé prvky - samostatná malá okna.
  • Obsluha dialogu potřebuje funkci "Procedura dialogu" pro zpracování zpráv.
 

Buď první, kdo ohodnotí tento článek.

Nový komentář

Přihlásit se
  Ještě nemáte vlastní web? Můžete si jej zdarma založit na Blog.cz.