13.1.2002
V předchozím článku jsme si ukázali, jak vytvořit ten nejjednodušší dialog, založený na standardní třídě dialogových oken. Umíme už zjistit, jakým způsobem uživatel dialog ukončil, tedy v typickém případě rozlišit stisk "OK" a "Storno". V tomto pokračování se začneme zabývat prací s běžnými dialogovými prvky. Jedním ze specifických rysů dialogového okna je, že prvky na něm umístěné definujeme ve skriptu zdrojů a nemusíme je vytvářet "ručně" pomocí CreateWindowEx. Výhodou je kromě zjednodušení kódu snadná práce s rozmístěním prvků na dialogu (pokud samozřejmě používáme nějaký vizuální editor zdrojů). Začneme tím, že si na dialog umístíme jedno editační pole (IDC_EDIT1), tlačítko (IDC_ZOBRAZ_TEXT), prvek Static text (IDC_KOPIE) a check-box (IDC_SLEDOVAT). Identifikátory prvků uvedené v závorkách si samozřejmě můžete zvolit podle svého, pak budete muset upravit i zdrojový kód. Cílem v této fázi bude naučit se jak získat text obsahu edit-boxu, jak zjistit okamžitý stav zaškrtnutí check-boxu a jak zachytit událost, kdy dojde ke změně obsahu edit-boxu, tedy když uživatel zapíše či smaže znak. Řekněme, že budeme chtít po stisknutí tlačítka přenést aktuální obsah edit-boxu do titulku hlavního okna aplikace. Tím se také přesvědčíme o tom, že i když je otevřen modální dialog, další okna aplikace mohou běžně přijímat zprávy a reagovat na ně, i když pro uživatele jsou v té době nedostupná. V proceduře dialogu již máme handler zprávy WM_COMMAND, kde zachytáváme stisk tlačítek "OK" a "Storno". Přidejme tedy do handleru WM_COMMAND následující case:case IDC_ZOBRAZ_TEXT: GetDlgItemText(hwndDlg, IDC_EDIT1, chText, 200); SendMessage(g_hwndMain, WM_SETTEXT, 0, (LPARAM)chText); break;To je vše co musíme udělat pro přenesení textu edit-boxu do titulku hlavního okna. Jak je vidět, pro získání textu prvku na dialogu můžeme použít funkci GetDlgItemText:
UINT GetDlgItemText( HWND hDlg, // handle okna dialogu int nIDDlgItem, // identifikátor prvku LPTSTR lpString, // buffer pro text int nMaxCount // maximální počet zkopírovaných znaků );Samozřejmě bychom mohli použít již dříve uvedenou funkci GetWindowText. Pak bychom ale museli získat handle (HWND) prvku (edit-boxu). K získání handle kteréhokoli prvku na dialogu slouží funkce GetDlgItem:
HWND GetDlgItem( HWND hDlg, // handle okna dialogu int nIDDlgItem // identifikátro prvku );Řekněme si ještě o funkci, která nám vrátí číselnou hodnotu (pokud ji lze převést) obsahu prvku dialogu. U edit-boxu je možné a výhodné pro tento případ nastavit v editoru zdrojů vlastnost "Number" odpovídající stylu okna ES_NUMBER. Příslušnou funkcí je pak GetDlgItemInt:
UINT GetDlgItemInt( HWND hDlg, // handle okna dialogu int nIDDlgItem, // identifikátor prvku BOOL *lpTranslated, // indikátor úspešného převodu BOOL bSigned // zda jde o hodnotu se znaménkem );Tato funkce nám vrátí číselnou hodnotu obsahu prvku, pokud má obsah číselný smysl. Úspěšnost převodu je uložena do parametru lpTranslated. Dále si řekneme, jak zjistíme v požadovaném okamžiku stav zaškrtnutí check-boxu. Zde zjistíme, že jednou z nejčastěji používaných funkcí je SendMessage, tedy funkce která pošle zvolenému oknu zprávu, která může sloužit k "ovládání" okna, tedy například nastavení textu, přidání řádku do list-boxu a stovky podobných. Kromě toho tato funkce vrací výsledek zpracování zprávy v příslušném okně. Mnoho zpráv je totiž dotazovacích, kterými požadujeme od cílového okna nějakou informaci, například právě stav zaškrtnutí check-boxu. V dialogových oknem můžeme místo SendMessage použít funkci SendDlgItemMessage:
LRESULT SendDlgItemMessage( HWND hDlg, // handle okna dialogu int nIDDlgItem, // identifikátor prvku UINT Msg, // kód zprávy WPARAM wParam, // 1. parametr zprávy LPARAM lParam // 2. parametr );V této funkci nemusíme uvádět handle okna, ale místi toho identifikátor prvku dialogu a systém si handle zjistí sám. Je to obdobná jako u vztahu funkcí GetWindowText a GetDlgItemText. V případě zjištení stavu check-boxu použijeme zprávu BM_GETCHECK. Identifikátor zprávy začíná na "BM", což je ze slov "button message". Znamená to, že check-box je prvek třídy "BUTTON". Návratová hodnota zprávy (tedy to co nám vrátí funkce SendMessage nebo SendDlgItemMessage) pak může být jednou ze 3 hodnot:
case IDC_EDIT1: if ( HIWORD(wParam) == EN_CHANGE ) { if ( SendDlgItemMessage(hwndDlg, IDC_SLEDOVAT, BM_GETCHECK, 0,0) == BST_CHECKED ) { GetDlgItemText(hwndDlg, IDC_EDIT1, chText, 200); SetDlgItemText(hwndDlg, IDC_KOPIE, chText); } } break;Výsledek "v akci" vidíte na následujícím obrázku: Ještě si můžeme nastavit výchozí stav check-boxu na zaškrtnutý v handleru zmíněné zprávy WM_INITDIALOG:
case WM_INITDIALOG: SendDlgItemMessage(hwndDlg, IDC_SLEDOVAT, BM_SETCHECK, BST_CHECKED, 0); break;Tolik pro toto pokračování a příště se samozřejmě budeme prvkům na dialogu dále věnovat, neboť jde o základní část většiny programů, tedy uživatelské rozhraní. Doprovodný projekt (Visual C++ 6) je ke stažení zde: win_api_13.zip
Školení
Kontakt
739 219 991
live:radekchalupa_1
Nové články