3.22. MFC i elementy zaawansowanego interfejsu użytkownika.txt

(55 KB) Pobierz
Rozdzia� 22.
MFC i elementy zaawansowanego interfejsu u�ytkownika


W tym rozdziale:

Zyskanie wi�kszej kontroli nad aplikacj�
P�tla modalna
Funkcja RunModalLoop ()
Okna modalne: nie tylko okna dialogowe
Wewn�trz p�tli modalnej
Tworzenie i zamykanie okien modalnych
Dalsza rozbudowa okna modalnego
Rysowanie poza obszarem roboczym
Budowa przezroczystych bitmap w kontek�cie urz�dzenia


Ten rozdzia� rozszerzy Tw� wiedz� o Windows i o bibliotece MFC. Klasy biblioteki MFC i ich domy�lne metody s� pot�nym narz�dziem, kt�re z pewno�ci� wystarczy w ogromnej wi�kszo�ci przypadk�w. Jednak posiadanie wiedzy o bardziej zaawansowanych w�a�ciwo�ciach oraz niskopoziomowych strukturach, na kt�rych zbudowana jest ca�a biblioteka, z pewno�ci� rozszerzy Twoje mo�liwo�ci jako programisty Windows. Na tych podstawach zosta�y zbudowane kolejne warstwy, za� same podstawowe klasy posiadaj� solidne fundamenty w postaci GDI API i definiowanych przez nie typ�w danych i struktur. W tym rozdziale nie b�dziesz tworzy� w�asnych obiekt�w interfejsu, lecz zamiast tego skorzystasz z pewnych niskopoziomowych w�a�ciwo�ci.
Czasem potrzeba wi�kszej kontroli
W pewnych sytuacjach wa�ne jest, by m�c starannie okre�li� spos�b, w jaki u�ytkownik mo�e wsp�pracowa� z aplikacj�. W rzeczywisto�ci, w pewnych przypadkach konieczne jest ograniczenie u�ytkownikowi mo�liwo�ci interakcji z ca�� reszt� systemu operacyjnego Windows. Nie trzeba jednak tego robi� tylko po to, by go ogranicza�. Na przyk�ad, modalne okna dialogowe omawiane w rozdziale 13., dawa�y programi�cie pewn� dodatkow� kontrol� na tym, co u�ytkownik m�g� zrobi� z aplikacj�. Modalne okno dialogowe jest sposobem na skierowanie uwagi u�ytkownika na pewn� operacj�. Aby m�c przej�� do interakcji z pozosta�� cz�ci� aplikacji, u�ytkownik musi zamkn�� okno dialogowe.
Wszystkim nam od czasu do czasu zdarza si� denerwowa� na okna dialogowe, kt�re staj� si� modalne dla ca�ego systemu, mimo �e nie jest to w�a�ciwie konieczne. Pami�tasz te systemowe okna dialogowe, uniemo�liwiaj�ce prac� z systemem przed zamkni�ciem okna? Wi�c znajdujesz si� w takim dialogu, kt�ry chcia�by� pozostawi� otwarty, a w tym samym czasie zrobi� co� innego, cho�by skopiowa� plik. Jednak nie mo�esz tego zrobi�, zanim nie zamkniesz okna dialogowego. Musisz wi�c je zamkn��, trac�c wszystkie ustawienia tylko po to, aby m�c przenie�� plik z jednego miejsca w inne. Takie nieprzemy�lane wymuszanie kolejno�ci pracy z aplikacj� nie jest dobr� praktyk�. Jednak w pewnych sytuacjach konieczne jest zabezpieczenie u�ytkownika przed wykonaniem pewnych dzia�a� lub skupienie jego uwagi na pewien obszar w celu zapewnienia, �e zadanie zostanie doko�czone.
Na przyk�ad, za��my, �e w pracowni komputerowej uczniowie korzystaj� z komputerowego samouczka na temat jakiej� aplikacji Windows. Za��my, �e lekcje zosta�y opracowane jako serie krok�w, w kt�rych s� przedstawiane kolejne polecenia i opcje aplikacji. Je�li kiedykolwiek zajmowa�e� si� uczeniem, z pewno�ci� wiesz, �e uczniowie niekoniecznie pod��aj� krok po kroku zgodnie z przebiegiem prezentacji. Zdarzaj� si� uczniowie, kt�rzy boj� si� nawet czegokolwiek dotkn��. Postawieni przed zbyt wieloma przyciskami i opcjami natychmiast si� gubi�, gdy� nie potrafi� odszuka� w�a�ciwych element�w na ekranie, pr�cz samej aplikacji istnieje przecie� tak�e sam system Windows, z jego oknami, paskiem zada�, ikonami, paskami stanu itd. Z kolei inni uczniowie, bardzo ciekawscy i niezale�ni, bez namys�u rzucaj� si� w wir opcji, aby zobaczy�, do czego s�u��. Otwieraj� menu po menu i zmieniaj� ustawienia, kt�rych znaczenia nie znaj�, a� w ko�cu nie mog� wr�ci� do stanu pocz�tkowego. Tak wi�c biedny instruktor musi po�wi�ci� sporo czasu, aby przywr�ci� aplikacj� do odpowiedniego stanu. W�a�nie w takich sytuacjach dobrze jest mie� pe�n� kontrol� nad tym, czego u�ytkownik mo�e dokona�.
Aby pozna� tego rodzaju mo�liwo�ci, opracujesz dwa przyk�adowe programy. Poka�emy w nich, jak mo�na obs�u�y� niekt�re z omawianych przed chwil� zagadnie�. Pierwszy program demonstruje spos�b utworzenia okna modalnego. To znaczy, zamiast po prostu tworzy� modalne okno dialogowe za pomoc� AppWizarda, nauczysz si� samemu tworzy� modalne okno, nie b�d�ce oknem dialogowym. Nast�pnie rozszerzysz to okno o kilka dodatkowych element�w, kt�re przygotuj� Ci� do drugiego programu demonstracyjnego.
Ten drugi program, oparty na pierwszym, umo�liwi Ci rysowanie na obszarze pulpitu, poza obszarem roboczym aplikacji. Cho� ta mo�liwo�� jest przydatna g��wnie w po��czeniu z oknami modalnymi, jednak takie rysowanie nie jest domen� wy��cznie takich okien.
P�tla modalna
Modalno�� okna osi�ga si�, korzystaj�c z metody odziedziczonej od klasy cwnd. Okna, bez wzgl�du na to czy s� to okna ramki, okna dialogowe czy jakiekolwiek inne okna wyprowadzone z klasy cwnd, posiadaj� wbudowan� mo�liwo�� stania si� modalnymi. Innymi s�owy, nie musisz wyprowadza� w tym celu swojej w�asnej, specjalnie modalnej klasy, gdy� mo�liwo�� uzyskania modalno�ci jest ju� wbudowana w klas� cwnd.
Klasa cwnd posiada funkcj� sk�adow� o nazwie RunModalLoop (), bardzo prost� w wywo�aniu. Wymaga ona tylko jednego parametru, znacznika, wi�c mo�e si� wydawa� r�wnie� prosta w u�yciu. Jednak, tak jak cz�sto dzieje si� to w przypadkach korzystania z pewnych specjalnych mo�liwo�ci, u�ycie jej wymaga specjalnej obs�ugi zar�wno tworzenia, jak i niszczenia okna, kt�re ma sta� si� modalne. Oba zagadnienia zostan� om�wione w trakcie tworzenia aplikacji w tym rozdziale. Sama funkcja jest zadeklarowana nast�puj�co:
int RunModa1Loop ( DWORD dwFlags);
Przekazywany jest jej pojedynczy argument, okre�laj�cy, jakie komunikaty maj� by� przekazywane do okna - zajmiemy si� tym za moment. Teraz jednak przyjrzyjmy si�, co w�a�ciwie ta klasa robi.
Wn�trze funkcji RunModalLoop()
Dokumentacja Windows niewiele ma do powiedzenia na temat tej p�tli modalnej. Poza kr�tkim opisem sposobu wywo�ywania funkcji RunModalLoop() w celu pobierania, t�umaczenia i rozsy�ania komunikat�w, nie ma ani s�owa o jej dzia�aniu oraz o specjalnych przygotowaniach do jej u�ycia. Na szcz�cie, w takich przypadkach jak ten masz do dyspozycji ca�y kod �r�d�owy biblioteki MFC, dostarczany jako cz�� pakietu Yisual C++. Gdy kiedykolwiek natkniesz si� na co�, czego nie mo�esz zrozumie�, nie wahaj si� zajrze� �pod mask�". Z pewno�ci� natrafisz tam na rzeczy nie do ko�ca zrozumia�e, jednak znajdziesz tak�e odpowied� na wiele pyta�. Czytaj pliki nag��wkowe. Czytaj pliki .cpp, w kt�rych s� zdefiniowane klasy. W ten spos�b poszerzysz swoj� wiedz� i mo�liwo�ci programistyczne. Podobnie post�pimy w tym rozdziale w przypadku funkcji RunModalLoop(). Cho� poni�sza dyskusja dotyczy bezpo�rednio okien, pomo�e Ci jednak w zrozumieniu dzia�ania tak�e modalnych okien dialogowych. Pami�taj, �e klasa CDialog jest wyprowadzona z klasy cwnd, wi�c proces dzia�ania jest taki sam. Listing 22.1 zawiera aktualny kod implementuj�cy funkcj� RunModalLoop(), odczytany z pliku Wincore.cpp, dostarczanym przez Microsoft wraz z Visual C++.
Odczytuj�c ten kod, mo�na natychmiast stwierdzi�, �e funkcja RunModalLoop () sk�ada si� w zasadzie z dw�ch p�tli zawartych w p�tli niesko�czonej. Niesko�czona p�tla ko�czy dzia�anie w momencie otrzymania przez okno komunikatu wyj�cia lub wyzerowania znacznika WF_CONTINUEMODAL. Zajmiemy si� tym za chwil�.
Listing 22.1. Fragment kodu z pliku Wincore.cpp Microsoftu
int CWnd::RunModalLoop(DWORD dwFlags)
{
// Okno musi by� utworzone ASSERT(::IsWindow(m_hWnd));
// Okno nie mo�e by� ju� w trybie modalnym ASSERT(!(m_nFlags & WF_MODALLOOP));
// Dla sprawdzania trybu pracy ja�owej
BOOL bldle = TRUE;
LONG lldleCount = 0;
BOOL bShowIdle = (dwFlags & MLF_SHOWONIDLE) && !(GetStyle()&WS_VISIBLE);
HWND hWndParent = ::GetParent(m_hWnd); m_nFlags 1= (WF_MODALLOOPlWF_CONTINUEMODAL); MSG* pMsg = &AfxGetThread()->m_msgCur;
// pobieranie i rozprowadzanie komunikat�w a� do wyj�cia // z trybu ja�owego for (;;)
{
ASSERT(ContinueModal());
// faza 1: sprawdzenie, czy mo�na wykonywa� prac� // czasu ja�owego while (bldle &&
!::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE))
{
ASSERT(ContinueModal());
// wy�wietlenie dialogu, gdy kolejka komunikat�w // staje si� pusta if (bShowIdle)
{
ShowWindow(SW_SHOWNORMAL); UpdateWindow(); bShowIdle = FALSE;
}
// wywo�anie OnldleO w trybie bldle
if (.'(dwFlags & MLF_NOIDLEMSG) && hWndParent != NULL &&
lldleCount == 0) {
// wys�anie komunikatu WM_ENTERIDLE do
// okna nadrz�dnego
::SendMessage(hWndParent, WM_ENTERIDLE,
MSGF DIALOGBOK, (LPARAM)m hWnd);
}
if
((dwFlags & MLF_NOKICKIDLE) || !SendMessage(WM_KICKIDLE, MSGF_DIALOGBOX, HdleCount++) )
{
// nast�pnym razem zatrzymanie przetwarzania // w trybie ja�owym bldle = FALSE;
}
}
// faza 2: pompowanie dost�pnych komunikat�w do
{
ASSERT(ContinueModal());
// pompowanie komunikat�w, ale wyj�cie przy WM_QUIT if (!AfxGetThread()->PumpMessage())
{
AfxPostQuitMessage(0); return -1;
}
// pokazanie okna po zarejestrowaniu pewnych // specjalnych komunikat�w if (bShowIdle &&
(pMsg->message == 0x118 || pMsg->message==
WM_SYSKEYDOWN))

ShowWindow(SW_SHOWNORMAL); UpdateWindow(); bShowIdle = FALSE;
}
if (! ContinueModal () ) goto ExitModal;
// zerowanie stanu ja�owego po "wypompowaniu
// zwyk�ego komunikatu
if (AfxGetThread ( ) ->IsIdleMessage (pMsg) )
{
bldle = TRUE;
HdleCount = 0;
}
} while( : : PeekMessage (pMsg, NULL, NULL, NULL,
PM_NOREMOVE) );
}
ExitModal:
m_nFlags &= ~(WF_MODALLOOPlWF_CONTINUEMODAL); return m_nModalResult;
}
Pierwsza z wewn�trznych p�tli sprawdza, czy s� obs�ugiwane i zwracane do okna nadrz�dnego komunikaty -trybu ja�owego. Zapewnia tak�e, �e je�li w wywo�aniu funkcji zosta� przekazany parametr MLF_SHOWONIDLE, okno zostanie wy�wietlone po przej�ciu kolejki komunikat�w do trybu ja�owego.
Prawdziwa praca odbywa si� w drugiej p�tli. Zwr�� uwag�, �e kod najpierw sprawdza, czy funkcja ContinueModal () zwr�...
Zgłoś jeśli naruszono regulamin